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