xref: /DragonOS/kernel/src/filesystem/procfs/kmsg.rs (revision 4ad52e57e612a88ab09413c7ac0072db96a93632)
1453452ccSLoGin use core::sync::atomic::{compiler_fence, Ordering};
2453452ccSLoGin 
38d72b68dSJomo use super::log::{LogLevel, LogMessage};
48d72b68dSJomo 
58d72b68dSJomo use crate::libs::spinlock::SpinLock;
68d72b68dSJomo 
78d72b68dSJomo use alloc::{borrow::ToOwned, string::ToString, vec::Vec};
88d72b68dSJomo 
98d72b68dSJomo use kdepends::ringbuffer::{AllocRingBuffer, RingBuffer};
108d72b68dSJomo 
118d72b68dSJomo use system_error::SystemError;
128d72b68dSJomo 
138d72b68dSJomo /// 缓冲区容量
148d72b68dSJomo const KMSG_BUFFER_CAPACITY: usize = 1024;
158d72b68dSJomo 
168d72b68dSJomo /// 全局环形缓冲区
178d72b68dSJomo pub static mut KMSG: Option<SpinLock<Kmsg>> = None;
188d72b68dSJomo 
198d72b68dSJomo /// 初始化KMSG
208d72b68dSJomo pub fn kmsg_init() {
21453452ccSLoGin     kinfo!("kmsg_init");
228d72b68dSJomo     let kmsg = SpinLock::new(Kmsg::new());
23453452ccSLoGin 
24453452ccSLoGin     compiler_fence(Ordering::SeqCst);
258d72b68dSJomo     unsafe { KMSG = Some(kmsg) };
26453452ccSLoGin     compiler_fence(Ordering::SeqCst);
27453452ccSLoGin     kinfo!("kmsg_init done");
288d72b68dSJomo }
298d72b68dSJomo 
308d72b68dSJomo /// 日志
318d72b68dSJomo pub struct Kmsg {
328d72b68dSJomo     /// 环形缓冲区
338d72b68dSJomo     buffer: AllocRingBuffer<LogMessage>,
348d72b68dSJomo     /// 缓冲区字节数组
358d72b68dSJomo     data: Vec<u8>,
368d72b68dSJomo     /// 能够输出到控制台的日志级别,当console_loglevel为DEFAULT时,表示可以打印所有级别的日志消息到控制台
378d72b68dSJomo     console_loglevel: LogLevel,
388d72b68dSJomo     /// 判断buffer在上一次转成字节数组之后是否发生变动
398d72b68dSJomo     is_changed: bool,
408d72b68dSJomo }
418d72b68dSJomo 
428d72b68dSJomo impl Kmsg {
438d72b68dSJomo     pub fn new() -> Self {
448d72b68dSJomo         Kmsg {
458d72b68dSJomo             buffer: AllocRingBuffer::new(KMSG_BUFFER_CAPACITY),
468d72b68dSJomo             data: Vec::new(),
478d72b68dSJomo             console_loglevel: LogLevel::DEFAULT,
488d72b68dSJomo             is_changed: false,
498d72b68dSJomo         }
508d72b68dSJomo     }
518d72b68dSJomo 
528d72b68dSJomo     /// 添加日志消息
538d72b68dSJomo     pub fn push(&mut self, msg: LogMessage) {
548d72b68dSJomo         self.buffer.push(msg);
558d72b68dSJomo         self.is_changed = true;
568d72b68dSJomo     }
578d72b68dSJomo 
588d72b68dSJomo     /// 读取缓冲区
598d72b68dSJomo     pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, SystemError> {
608d72b68dSJomo         self.tobytes();
618d72b68dSJomo 
628d72b68dSJomo         match self.console_loglevel {
638d72b68dSJomo             LogLevel::DEFAULT => self.read_all(buf),
648d72b68dSJomo             _ => self.read_level(buf),
658d72b68dSJomo         }
668d72b68dSJomo     }
678d72b68dSJomo 
688d72b68dSJomo     /// 读取缓冲区所有日志消息
698d72b68dSJomo     fn read_all(&mut self, buf: &mut [u8]) -> Result<usize, SystemError> {
708d72b68dSJomo         let len = self.data.len().min(buf.len());
718d72b68dSJomo 
728d72b68dSJomo         // 拷贝数据
738d72b68dSJomo         let src = &self.data[0..len];
74*4ad52e57S裕依2439         buf[0..len].copy_from_slice(src);
758d72b68dSJomo 
76*4ad52e57S裕依2439         return Ok(len);
778d72b68dSJomo     }
788d72b68dSJomo 
798d72b68dSJomo     /// 读取缓冲区特定level的日志消息
808d72b68dSJomo     fn read_level(&mut self, buf: &mut [u8]) -> Result<usize, SystemError> {
818d72b68dSJomo         let mut data_level: Vec<u8> = Vec::new();
828d72b68dSJomo 
838d72b68dSJomo         for msg in self.buffer.iter() {
848d72b68dSJomo             if msg.level() == self.console_loglevel {
858d72b68dSJomo                 data_level.append(&mut msg.to_string().as_bytes().to_owned());
868d72b68dSJomo             }
878d72b68dSJomo         }
888d72b68dSJomo 
898d72b68dSJomo         let len = data_level.len().min(buf.len());
908d72b68dSJomo 
918d72b68dSJomo         // 拷贝数据
928d72b68dSJomo         let src = &data_level[0..len];
93*4ad52e57S裕依2439         buf[0..len].copy_from_slice(src);
948d72b68dSJomo 
958d72b68dSJomo         // 将控制台输出日志level改回默认,否则之后都是打印特定level的日志消息
968d72b68dSJomo         self.console_loglevel = LogLevel::DEFAULT;
978d72b68dSJomo 
988d72b68dSJomo         return Ok(data_level.len());
998d72b68dSJomo     }
1008d72b68dSJomo 
1018d72b68dSJomo     /// 读取并清空缓冲区
1028d72b68dSJomo     pub fn read_clear(&mut self, buf: &mut [u8]) -> Result<usize, SystemError> {
1038d72b68dSJomo         let r = self.read_all(buf);
1048d72b68dSJomo         self.clear()?;
1058d72b68dSJomo 
1068d72b68dSJomo         return r;
1078d72b68dSJomo     }
1088d72b68dSJomo 
1098d72b68dSJomo     /// 清空缓冲区
1108d72b68dSJomo     pub fn clear(&mut self) -> Result<usize, SystemError> {
1118d72b68dSJomo         self.buffer.clear();
1128d72b68dSJomo         self.data.clear();
1138d72b68dSJomo 
1148d72b68dSJomo         return Ok(0);
1158d72b68dSJomo     }
1168d72b68dSJomo 
1178d72b68dSJomo     /// 设置输出到控制台的日志级别
1188d72b68dSJomo     pub fn set_level(&mut self, log_level: usize) -> Result<usize, SystemError> {
1198d72b68dSJomo         let log_level = log_level - 1;
1208d72b68dSJomo 
1218d72b68dSJomo         self.console_loglevel = match log_level {
1228d72b68dSJomo             0 => LogLevel::EMERG,
1238d72b68dSJomo             1 => LogLevel::ALERT,
1248d72b68dSJomo             2 => LogLevel::CRIT,
1258d72b68dSJomo             3 => LogLevel::ERR,
1268d72b68dSJomo             4 => LogLevel::WARN,
1278d72b68dSJomo             5 => LogLevel::NOTICE,
1288d72b68dSJomo             6 => LogLevel::INFO,
1298d72b68dSJomo             7 => LogLevel::DEBUG,
1308d72b68dSJomo             8 => LogLevel::DEFAULT,
1318d72b68dSJomo             _ => return Err(SystemError::EINVAL),
1328d72b68dSJomo         };
1338d72b68dSJomo 
1348d72b68dSJomo         return Ok(0);
1358d72b68dSJomo     }
1368d72b68dSJomo 
1378d72b68dSJomo     /// 将环形缓冲区的日志消息转成字节数组以拷入用户buf
1388d72b68dSJomo     fn tobytes(&mut self) -> usize {
1398d72b68dSJomo         if self.is_changed {
1408d72b68dSJomo             self.data.clear();
1418d72b68dSJomo 
1428d72b68dSJomo             if self.console_loglevel == LogLevel::DEFAULT {
1438d72b68dSJomo                 for msg in self.buffer.iter() {
1448d72b68dSJomo                     self.data.append(&mut msg.to_string().as_bytes().to_owned());
1458d72b68dSJomo                 }
1468d72b68dSJomo             }
1478d72b68dSJomo 
1488d72b68dSJomo             self.is_changed = false;
1498d72b68dSJomo         }
1508d72b68dSJomo 
1518d72b68dSJomo         return self.data.len();
1528d72b68dSJomo     }
1538d72b68dSJomo 
1548d72b68dSJomo     // 返回内核缓冲区所占字节数
1558d72b68dSJomo     pub fn data_size(&mut self) -> Result<usize, SystemError> {
1568d72b68dSJomo         return Ok(self.tobytes());
1578d72b68dSJomo     }
1588d72b68dSJomo }
159