如何使用Linux C API将文件名映射到其对应的挂载/dev设备
问题解答
结论
完全可以通过Linux原生C API实现该需求
实现原理
- 首先通过
stat()系统调用读取目标文件的元数据,拿到st_dev字段:该字段是目标文件所在块存储设备的唯一设备编号,可通过major()、minor()宏拆分出主设备号和次设备号。 - 接下来将设备号匹配到
/dev下的对应设备文件,有两种常见实现方式:- 遍历
/dev目录下的所有块设备文件,对每个设备文件调用stat()读取其st_rdev字段(设备文件的st_rdev字段才对应该设备的实际编号,注意和普通文件的st_dev做区分),匹配到和目标文件st_dev一致的设备文件即可。 - 读取
/proc/mounts系统文件,直接匹配挂载点对应的设备路径,不需要遍历整个/dev目录,执行效率更高,更推荐生产环境使用。
- 遍历
简化示例代码
#include <stdio.h> #include <sys/stat.h> #include <sys/types.h> #include <dirent.h> #include <sys/sysmacros.h> #include <string.h> #include <limits.h> int main(int argc, char *argv[]) { if (argc != 2) { printf("用法:%s <目标文件路径>\n", argv[0]); return 1; } struct stat file_stat; if (stat(argv[1], &file_stat) != 0) { perror("获取目标文件属性失败"); return 1; } dev_t target_dev = file_stat.st_dev; printf("目标文件所在设备号:主=%d, 次=%d\n", major(target_dev), minor(target_dev)); // 遍历/dev目录匹配设备 DIR *dev_dir = opendir("/dev"); if (!dev_dir) { perror("打开/dev目录失败"); return 1; } struct dirent *entry; char dev_path[PATH_MAX]; while ((entry = readdir(dev_dir)) != NULL) { snprintf(dev_path, sizeof(dev_path), "/dev/%s", entry->d_name); struct stat dev_stat; if (stat(dev_path, &dev_stat) != 0) continue; // 只匹配块设备文件 if (!S_ISBLK(dev_stat.st_mode)) continue; if (dev_stat.st_rdev == target_dev) { printf("匹配到对应设备:%s\n", dev_path); break; } } closedir(dev_dir); return 0; }
注意事项
- 运行上述代码需要有
/dev目录的读取权限,以及目标文件的读取权限。 - 示例代码做了简化,实际使用时建议优先通过
/proc/mounts匹配,同时处理绑定挂载、伪文件系统等特殊场景。
内容的提问来源于stack exchange,提问作者Alexey Vukolov
相关产品推荐
相关产品推荐

