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