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 Close = 0, 13 /// Open the log. Currently a NOP. 14 Open = 1, 15 /// Read from the log. 16 Read = 2, 17 /// Read and clear all messages remaining in the ring buffer. 18 ReadClear = 4, 19 /// Clear ring buffer. 20 Clear = 5, 21 /// Set level of messages printed to console. 22 ConsoleLevel = 8, 23 /// Return size of the log buffer. 24 SizeBuffer = 10, 25 /// Invalid SyslogAction 26 Inval, 27 } 28 29 impl From<usize> for SyslogAction { 30 fn from(value: usize) -> Self { 31 match value { 32 0 => SyslogAction::Close, 33 1 => SyslogAction::Open, 34 2 => SyslogAction::Read, 35 4 => SyslogAction::ReadClear, 36 5 => SyslogAction::Clear, 37 8 => SyslogAction::ConsoleLevel, 38 10 => SyslogAction::SizeBuffer, 39 _ => SyslogAction::Inval, 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::Close => Ok(0), 68 SyslogAction::Open => Ok(0), 69 SyslogAction::Read => kmsg_guard.read(buf), 70 SyslogAction::ReadClear => kmsg_guard.read_clear(buf), 71 SyslogAction::Clear => kmsg_guard.clear(), 72 SyslogAction::SizeBuffer => kmsg_guard.data_size(), 73 SyslogAction::ConsoleLevel => kmsg_guard.set_level(len), 74 SyslogAction::Inval => return Err(SystemError::EINVAL), 75 } 76 } 77 } 78