我需要编写一个程序,该程序接收块设备作为输入,例如 /dev/sda1,并且必须根据内部文件系统当前是否正在运行来执行一组操作。
我们假设输入总是有一个正确的 Linux 目录树,我唯一需要知道的是是否有特定的目录结构或文件可以可靠地确定内部系统是否正在运行。我的意思是文件系统是否包含已开机系统的根目录。
它应该适用于任何文件系统或 Linux 内核版本。
谢谢!
答案1
我编写了一个函数,1
如果参数是根设备,则返回,
0
如果不是,则返回负值:
#include <stdio.h> #include <stdlib.h> #include <sys/stat.h> 静态整型 root_check(const char *disk_dev) { 静态 const char root_dir[] = "/"; struct stat root_statb; struct stat dev_statb; if (stat(root_dir, &root_statb) != 0) { 错误(root_dir); 返回-1; } if (!S_ISDIR(root_statb.st_mode)) { fprintf(stderr, "错误: %s 不是目录!\n", root_dir); 返回-2; } 如果(root_statb.st_ino <= 0) { fprintf(stderr, "警告: %s inode 号为 %d;" "不太可能有效。\n", root_dir、root_statb.st_ino); } 否则如果 (root_statb.st_ino > 2) { fprintf(stderr, "警告: %s inode 号为 %d;" "可能不是根 inode。\n", root_dir、root_statb.st_ino); } if (stat(disk_dev, &dev_statb) != 0) { perror(disk_dev); 返回-1; } 如果(S_ISBLK(dev_statb.st_mode)) /* 那挺好的。 */; 否则如果 (S_ISCHR(dev_statb.st_mode)) { fprintf(stderr, "警告:%s 是字符特殊设备;" “可能不是磁盘。\n”, disk_dev); } 别的 { fprintf(stderr, "警告: %s 不是设备。\n", disk_dev); 返回(0); } if (dev_statb.st_rdev == root_statb.st_dev) { printf("看来 %s 是根文件系统 (%s)。\n", 磁盘_dev、根目录); 返回(1); } // 别的 printf("(看起来 %s 不是根文件系统。)\n", disk_dev); 返回(0); }
前两个测试基本上是健全性检查:如果stat("/", …)
失败或“ /
”不是目录,则您的文件系统已损坏。这些st_ino
测试有点像是在黑暗中进行的测试。 AFAIK,索引节点号永远不应该为负数或零。从历史上看(我指的是 30 年前),根目录的 inode 号始终为 1。对于 *nix 的某些风格(有人听说过“Minix”吗?),这可能仍然是正确的,对于特殊的文件系统,如/proc
Windows (FAT) 文件系统,但大多数现代 Unix 和类 Unix 系统似乎使用索引节点号 1 来跟踪坏块,将根推到索引节点号 2。
S_ISBLK
对于“块设备”来说是正确的,例如/dev/sda1
,其中的输出ls -l
以“ ”开头b
。同样,S_ISCHR
对于“字符设备”也是如此,其中的输出ls -l
以“”开头c
。 (您可能偶尔会看到类似的磁盘名称/dev/rsda1
;“ r
”代表“原始”。原始磁盘设备有时用于fsck
备份,但不用于安装。)每个 inode 都有一个st_dev
,它表示该 inode 所在的文件系统。设备的索引节点也有st_rdev
字段,说明它们是什么设备是。 (当您ls -l
使用设备时,您在文件大小处看到的两个逗号分隔的数字是 的两个字节st_rdev
。)
所以,关键是看st_rdev
磁盘设备的与st_dev
根目录的是否匹配;即,指定的设备是“ /
”所在的设备吗?
答案2
您可以检查设备是否已安装以及安装位置:
awk -v device=/dev/sda1 ' $1 == device {print $2}' /proc/mounts
这不会检测内核子系统(例如 mdraid 或 LVM)使用的设备。这些通过/sys/class/block/sda1/holders
(该目录包含指向使用该设备的设备映射器项的符号链接)可见。