xref: /DragonOS/kernel/src/filesystem/procfs/syscall.rs (revision 2eab6dd743e94a86a685f1f3c01e599adf86610a)
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