如何从/sys/block遍历块设备并输出至内核日志?代码异常求助
解决/sys/block目录遍历仅输出"."的问题
你的代码只输出"Block device: . "的核心原因有两点:一是未显式初始化dir_context的pos字段(部分内核版本依赖此字段跟踪遍历位置),二是部分内核中iterate_dir的行为已发生变化,推荐使用更可靠的vfs_iterate_dir。此外,你还需要过滤掉.和..这些无意义的特殊目录条目。
修正后的代码
static bool iterate_block_devices(struct dir_context *ctx, const char *name, int namelen, loff_t offset, u64 ino, unsigned int d_type) { // 跳过当前目录和上级目录的特殊条目 if ((namelen == 1 && name[0] == '.') || (namelen == 2 && name[0] == '.' && name[1] == '.')) return false; pr_info("Block device: %.*s\n", namelen, name); return false; // 返回false表示继续遍历后续条目 } int read_block_devices(void) { struct file *dir; struct dir_context ctx = { .pos = 0, // 显式初始化遍历起始位置 .actor = iterate_block_devices, }; dir = filp_open("/sys/block", O_DIRECTORY | O_RDONLY, 0); if (IS_ERR(dir)) { pr_err("Failed to open /sys/block: %ld\n", PTR_ERR(dir)); return PTR_ERR(dir); } // 使用vfs_iterate_dir替代iterate_dir,兼容性更好 if (vfs_iterate_dir(dir, &ctx) < 0) { pr_err("Failed to iterate /sys/block\n"); filp_close(dir, NULL); return -EIO; } filp_close(dir, NULL); return 0; }
dir_context与目录遍历的工作机制
dir_context是内核目录遍历的上下文结构体,核心字段包括:pos:记录当前遍历的位置,内核依赖它避免重复处理条目,每次处理完一个条目后会自动更新该值actor:回调函数,每个目录条目被解析后会调用此函数,参数包含条目名称、长度、类型等信息;返回false(0)表示继续遍历,返回true表示终止遍历
- 遍历流程:
- 用
filp_open打开目标目录,获取struct file指针 - 初始化
dir_context,设置起始位置pos=0和条目处理回调actor - 调用
vfs_iterate_dir,内核会遍历目录下所有条目,逐个调用actor函数处理 - 遍历完成后关闭文件指针,释放资源
- 用
额外注意事项
- 如果仍然无法正常遍历,检查模块是否具备
CAP_SYS_ADMIN权限,访问sysfs目录需要该权限 /sys/block下的条目多为符号链接,对应实际块设备的sysfs节点,你可以通过这些名称进一步读取设备的统计指标(如/sys/block/<dev>/stat)
内容的提问来源于stack exchange,提问作者Иван Мориков
相关产品推荐
相关产品推荐

