Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

实现内核日志系统 #489

Merged
merged 26 commits into from
Jan 24, 2024
Merged

实现内核日志系统 #489

merged 26 commits into from
Jan 24, 2024

Conversation

Jomocool
Copy link
Collaborator

@Jomocool Jomocool commented Jan 4, 2024

  • 实现环形缓冲区打日志 (可通过KMSG_BUFFER_CAPACITY设置最大日志数)
  • 实现用户态dmesg显示日志信息

dmesg使用说明:

  1. dmesg : 读取所有日志消息
  2. dmesg -C : 清空内核缓冲区
  3. dmesg -c : 读取内核缓冲区后,清空缓冲区
  4. dmesg -l : 读取指定level的日志消息
  5. dmesg -h : 打开帮助手册

@fslongjin
Copy link
Member

请编辑pr的名字,描述PR的内容

);

// 最后要把弹出的日志消息重新添加回来,否则只要调用一次open之后,缓冲区就空了
let _ = self.buffer.push(msg);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thingbuf提供了peek的功能,不用pop。不然的话日志顺序就混乱了。然后使用peek之后,感觉没必要把所有的日志都读出来,这个感觉很慢。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我没有在thingbuf中找到类似peek的接口。日志顺序应该不会乱,因为每次都是把所有日志消息依次pop出来后再push回去。然后我觉得可以加一个属性用来判断缓冲区是否有变化,这样就只需要在有变动的情况下才需要转成Vec

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

日志顺序应该不会乱,因为每次都是把所有日志消息依次pop出来后再push回去。

内核日志会不断产生的,这样会导致旧的日志和新的混杂在一起。

#include <unistd.h>
#include <string.h>

int main()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我看了一下linux的dmesg命令的代码(在busybox这个里面有,可以下个busybox的代码去搜),它不是直接读取文件的,并且我在linux直接cat /proc/kmsg也是会在那里等待,读不到东西的。因此这个机制应该是缺了几个系统调用。需要实现klog相关的系统调用接口。

@fslongjin
Copy link
Member

这是一个rust版本的dmesg的实现:
https://github.com/polyverse/rmesg

@fslongjin fslongjin requested a review from GnoCiYeH January 4, 2024 15:25
@Jomocool Jomocool changed the title Log 实现内核日志系统 Jan 5, 2024
/// 缓冲区字节数组
data: Vec<u8>,
/// 能够输出到控制台的日志级别
console_loglevel: usize,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

日志级别最好使用枚举,而不是仅仅一个数字


lazy_static! {
/// 全局环形缓冲区
static ref KMSG: Mutex<Kmsg> = Mutex::new(Kmsg::new());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

用spinlock

use super::KMSG;

/// Close the log. Currently a NOP.
pub const SYSLOG_ACTION_CLOSE: usize = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这改为枚举,枚举可以搞成待数字的

/// Return size of the log buffer.
pub const SYSLOG_ACTION_SIZE_BUFFER: usize = 10;

impl Syscall {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个写到单独的syscall.rs

Copy link
Member

@fslongjin fslongjin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

然后这里的代码需要接入kinfo等地方进行测试,因为现在很多是dead code,内核当前没有往这个缓冲区里面打日志

}

/// 读取缓冲区
pub fn read(&mut self, len: usize, buf: &mut [u8]) -> Result<usize, SystemError> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里可以设计为只传入buf的引用,按照buf的长度来读取。这样的话能简化代码。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好的

let mut data_level: Vec<u8> = Vec::new();

for msg in self.buffer.iter() {
if msg.level() == self.console_loglevel {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我感觉,level应该是个“大于”的关系。就比如我们使用日志库的时候,设置为debug级别,就是打印优先级大于等于debug的。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我测试了下,在Linux中,(dmesg -l notice) 和 (dmesg -l debug) 都不会打印 info 级别的日志消息(优先级:debug < info < notice)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

哦哦哦确实噢!

@fslongjin fslongjin merged commit 8d72b68 into DragonOS-Community:master Jan 24, 2024
7 checks passed
yuyi2439 pushed a commit to yuyi2439/DragonOS that referenced this pull request Feb 2, 2024
* 实现写日志和读取日志,并且能够在用户态下执行dmesg命令查看日志

* 通过klogctl实现dmesg

* 改用ConstGenericRingBuffer作内核缓冲区

* 更改缓冲区容量

* 将能够输出到控制台的日志级别改为日志级别枚举类,使用SpinLock控制KMSG,使用枚举类定义SYSLOG_ACTION,将do_syslog系统调用接口放在syscall.rs

* fix warning

* 完善do_syslog注释

* 将KMSG接入kinfo、kdebug等

* fix warning

* 修复显示的秒数不正确,·以及无法通过CI的问题
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants