1 use core::usize; 2 3 use system_error::SystemError; 4 5 use crate::syscall::Syscall; 6 7 use super::kmsg::KMSG; 8 9 /// 操作内核环形缓冲区 10 enum SyslogAction { 11 /// Close the log. Currently a NOP. 12 SyslogActionClose = 0, 13 /// Open the log. Currently a NOP. 14 SyslogActionOpen = 1, 15 /// Read from the log. 16 SyslogActionRead = 2, 17 /// Read and clear all messages remaining in the ring buffer. 18 SyslogActionReadClear = 4, 19 /// Clear ring buffer. 20 SyslogActionClear = 5, 21 /// Set level of messages printed to console. 22 SyslogActionConsoleLevel = 8, 23 /// Return size of the log buffer. 24 SyslogActionSizeBuffer = 10, 25 /// Invalid SyslogAction 26 SyslogActionInval, 27 } 28 29 impl From<usize> for SyslogAction { 30 fn from(value: usize) -> Self { 31 match value { 32 0 => SyslogAction::SyslogActionClose, 33 1 => SyslogAction::SyslogActionOpen, 34 2 => SyslogAction::SyslogActionRead, 35 4 => SyslogAction::SyslogActionReadClear, 36 5 => SyslogAction::SyslogActionClear, 37 8 => SyslogAction::SyslogActionConsoleLevel, 38 10 => SyslogAction::SyslogActionSizeBuffer, 39 _ => SyslogAction::SyslogActionInval, 40 } 41 } 42 } 43 44 impl Syscall { 45 /// # 操作内核环形缓冲区 46 /// 47 /// ## 参数 48 /// - syslog_action_type: 操作码 49 /// - buf:用户缓冲区 50 /// - len: 需要从内核环形缓冲区读取的字节数。如果操作码为8,即SyslogActionConsoleLevel,则len为待设置的日志级别 51 /// 52 /// ## 返回值 53 /// - 成功,Ok(usize) 54 /// - 失败,Err(SystemError) 操作失败,返回posix错误码 55 /// 56 57 pub fn do_syslog( 58 syslog_action_type: usize, 59 buf: &mut [u8], 60 len: usize, 61 ) -> Result<usize, SystemError> { 62 let syslog_action = SyslogAction::from(syslog_action_type); 63 64 let mut kmsg_guard = unsafe { KMSG.as_ref().unwrap().lock_irqsave() }; 65 66 match syslog_action { 67 SyslogAction::SyslogActionClose => Ok(0), 68 SyslogAction::SyslogActionOpen => Ok(0), 69 SyslogAction::SyslogActionRead => kmsg_guard.read(buf), 70 SyslogAction::SyslogActionReadClear => kmsg_guard.read_clear(buf), 71 SyslogAction::SyslogActionClear => kmsg_guard.clear(), 72 SyslogAction::SyslogActionSizeBuffer => kmsg_guard.data_size(), 73 SyslogAction::SyslogActionConsoleLevel => kmsg_guard.set_level(len), 74 SyslogAction::SyslogActionInval => return Err(SystemError::EINVAL), 75 } 76 } 77 } 78