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 {
from(value: usize) -> Self30     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 
do_syslog( syslog_action_type: usize, buf: &mut [u8], len: usize, ) -> Result<usize, SystemError>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