os/uapi/
log.rs

1//! syslog 所需的 Commands
2
3use crate::uapi::errno::EINVAL;
4
5/// syslog 系统调用操作类型
6///
7/// 与 Linux 内核 `SYSLOG_ACTION_*` 常量完全兼容。
8/// 使用 enum 而非原始常量以提供类型安全和编译器优化。
9#[repr(i32)]
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum SyslogAction {
12    /// 关闭日志 (NOP)
13    ///
14    /// Linux 中此操作为空操作,保留用于历史兼容性。
15    Close = 0,
16
17    /// 打开日志 (NOP)
18    ///
19    /// Linux 中此操作为空操作,保留用于历史兼容性。
20    Open = 1,
21
22    /// 从日志读取(破坏性)
23    ///
24    /// 读取内核日志并从缓冲区移除已读条目。
25    /// 需要:bufp != NULL, len > 0
26    /// 权限:CAP_SYSLOG 或 CAP_SYS_ADMIN
27    Read = 2,
28
29    /// 读取所有日志(非破坏性)
30    ///
31    /// 读取内核日志但不从缓冲区移除。
32    /// 需要:bufp != NULL, len > 0
33    /// 权限:如果 dmesg_restrict=0,允许非特权访问
34    ReadAll = 3,
35
36    /// 读取并清空
37    ///
38    /// 先读取日志,然后清空缓冲区。
39    /// 需要:bufp != NULL, len > 0
40    /// 权限:CAP_SYSLOG 或 CAP_SYS_ADMIN
41    ReadClear = 4,
42
43    /// 清空缓冲区
44    ///
45    /// 清除所有已缓冲的日志条目。
46    /// 权限:CAP_SYSLOG 或 CAP_SYS_ADMIN
47    Clear = 5,
48
49    /// 禁用控制台输出
50    ///
51    /// 将 console_loglevel 设置为最小值(只显示 EMERG)。
52    /// 权限:CAP_SYSLOG 或 CAP_SYS_ADMIN
53    ConsoleOff = 6,
54
55    /// 启用控制台输出
56    ///
57    /// 恢复控制台输出到默认级别(通常为 WARNING)。
58    /// 权限:CAP_SYSLOG 或 CAP_SYS_ADMIN
59    ConsoleOn = 7,
60
61    /// 设置控制台日志级别
62    ///
63    /// 设置 console_loglevel,控制哪些日志显示在控制台。
64    /// len 参数范围:1-8
65    /// 权限:CAP_SYSLOG 或 CAP_SYS_ADMIN
66    ConsoleLevel = 8,
67
68    /// 获取未读字节数
69    ///
70    /// 返回当前缓冲区中未读日志的估计字节数。
71    /// 权限:如果 dmesg_restrict=0,允许非特权访问
72    SizeUnread = 9,
73
74    /// 获取缓冲区总大小
75    ///
76    /// 返回内核日志缓冲区的总容量(字节)。
77    /// 权限:如果 dmesg_restrict=0,允许非特权访问
78    SizeBuffer = 10,
79}
80
81impl SyslogAction {
82    /// 从原始 i32 值转换为 SyslogAction
83    #[inline]
84    pub const fn from_i32(value: i32) -> Result<Self, i32> {
85        match value {
86            0 => Ok(Self::Close),
87            1 => Ok(Self::Open),
88            2 => Ok(Self::Read),
89            3 => Ok(Self::ReadAll),
90            4 => Ok(Self::ReadClear),
91            5 => Ok(Self::Clear),
92            6 => Ok(Self::ConsoleOff),
93            7 => Ok(Self::ConsoleOn),
94            8 => Ok(Self::ConsoleLevel),
95            9 => Ok(Self::SizeUnread),
96            10 => Ok(Self::SizeBuffer),
97            _ => Err(EINVAL),
98        }
99    }
100
101    /// 检查操作是否需要有效的用户缓冲区
102    ///
103    /// # 返回值
104    ///
105    /// * `true` - 需要 bufp != NULL 且 len > 0
106    /// * `false` - 忽略 bufp 和 len 参数
107    #[inline]
108    pub const fn requires_buffer(self) -> bool {
109        matches!(self, Self::Read | Self::ReadAll | Self::ReadClear)
110    }
111
112    /// 检查操作是否需要特权
113    ///
114    /// 注意:ReadAll 和 SizeBuffer 在 dmesg_restrict=0 时允许非特权访问。
115    ///
116    /// # 返回值
117    ///
118    /// * `true` - 总是需要权限检查
119    /// * `false` - 可能允许非特权访问(需要进一步检查 dmesg_restrict)
120    #[inline]
121    pub const fn requires_privilege(self) -> bool {
122        !matches!(self, Self::ReadAll | Self::SizeBuffer)
123    }
124
125    /// 检查操作是否会修改日志缓冲区
126    ///
127    /// 用于并发控制和日志审计。
128    #[inline]
129    pub const fn is_destructive(self) -> bool {
130        matches!(self, Self::Read | Self::ReadClear | Self::Clear)
131    }
132
133    /// 检查操作是否影响控制台输出
134    #[inline]
135    pub const fn affects_console(self) -> bool {
136        matches!(
137            self,
138            Self::ConsoleOff | Self::ConsoleOn | Self::ConsoleLevel
139        )
140    }
141
142    /// 获取操作的字符串描述(用于日志和调试)
143    pub const fn as_str(self) -> &'static str {
144        match self {
145            Self::Close => "CLOSE",
146            Self::Open => "OPEN",
147            Self::Read => "READ",
148            Self::ReadAll => "READ_ALL",
149            Self::ReadClear => "READ_CLEAR",
150            Self::Clear => "CLEAR",
151            Self::ConsoleOff => "CONSOLE_OFF",
152            Self::ConsoleOn => "CONSOLE_ON",
153            Self::ConsoleLevel => "CONSOLE_LEVEL",
154            Self::SizeUnread => "SIZE_UNREAD",
155            Self::SizeBuffer => "SIZE_BUFFER",
156        }
157    }
158}