syscall.rs 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. use system_error::SystemError;
  2. use crate::syscall::Syscall;
  3. use super::kmsg::KMSG;
  4. /// 操作内核环形缓冲区
  5. enum SyslogAction {
  6. /// Close the log. Currently a NOP.
  7. Close = 0,
  8. /// Open the log. Currently a NOP.
  9. Open = 1,
  10. /// Read from the log.
  11. Read = 2,
  12. /// Read and clear all messages remaining in the ring buffer.
  13. ReadClear = 4,
  14. /// Clear ring buffer.
  15. Clear = 5,
  16. /// Set level of messages printed to console.
  17. ConsoleLevel = 8,
  18. /// Return size of the log buffer.
  19. SizeBuffer = 10,
  20. /// Invalid SyslogAction
  21. Inval,
  22. }
  23. impl From<usize> for SyslogAction {
  24. fn from(value: usize) -> Self {
  25. match value {
  26. 0 => SyslogAction::Close,
  27. 1 => SyslogAction::Open,
  28. 2 => SyslogAction::Read,
  29. 4 => SyslogAction::ReadClear,
  30. 5 => SyslogAction::Clear,
  31. 8 => SyslogAction::ConsoleLevel,
  32. 10 => SyslogAction::SizeBuffer,
  33. _ => SyslogAction::Inval,
  34. }
  35. }
  36. }
  37. impl Syscall {
  38. /// # 操作内核环形缓冲区
  39. ///
  40. /// ## 参数
  41. /// - syslog_action_type: 操作码
  42. /// - buf:用户缓冲区
  43. /// - len: 需要从内核环形缓冲区读取的字节数。如果操作码为8,即SyslogActionConsoleLevel,则len为待设置的日志级别
  44. ///
  45. /// ## 返回值
  46. /// - 成功,Ok(usize)
  47. /// - 失败,Err(SystemError) 操作失败,返回posix错误码
  48. ///
  49. pub fn do_syslog(
  50. syslog_action_type: usize,
  51. buf: &mut [u8],
  52. len: usize,
  53. ) -> Result<usize, SystemError> {
  54. let syslog_action = SyslogAction::from(syslog_action_type);
  55. let mut kmsg_guard = unsafe { KMSG.as_ref().unwrap().lock_irqsave() };
  56. match syslog_action {
  57. SyslogAction::Close => Ok(0),
  58. SyslogAction::Open => Ok(0),
  59. SyslogAction::Read => kmsg_guard.read(buf),
  60. SyslogAction::ReadClear => kmsg_guard.read_clear(buf),
  61. SyslogAction::Clear => kmsg_guard.clear(),
  62. SyslogAction::SizeBuffer => kmsg_guard.data_size(),
  63. SyslogAction::ConsoleLevel => kmsg_guard.set_level(len),
  64. SyslogAction::Inval => return Err(SystemError::EINVAL),
  65. }
  66. }
  67. }