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