Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否有Linux C API调用来查询已装入的文件系统以查看它是否为只读文件系统?_C_Linux_Filesystems_Stat - Fatal编程技术网

是否有Linux C API调用来查询已装入的文件系统以查看它是否为只读文件系统?

是否有Linux C API调用来查询已装入的文件系统以查看它是否为只读文件系统?,c,linux,filesystems,stat,C,Linux,Filesystems,Stat,首先,提供一些背景信息来说明这个问题:我有一个程序运行在无头Linux服务器上,在几个可移动外部硬盘上读/写文件,每个硬盘都使用ext4文件系统格式化。偶尔,这些驱动器之一上的文件系统元数据会因任何原因而损坏(尽管存在ext4日志记录),这可能会导致ext4文件系统驱动器检测到问题并以只读方式重新安装分区,可能是为了防止级联错误进一步损坏驱动器 好吧,很公平;但我现在想做的是在我的程序中添加一个函数,可以检测驱动器何时处于重新安装的只读状态,这样它就可以主动通知用户他的驱动器有问题 我的问题是,

首先,提供一些背景信息来说明这个问题:我有一个程序运行在无头Linux服务器上,在几个可移动外部硬盘上读/写文件,每个硬盘都使用ext4文件系统格式化。偶尔,这些驱动器之一上的文件系统元数据会因任何原因而损坏(尽管存在ext4日志记录),这可能会导致ext4文件系统驱动器检测到问题并以只读方式重新安装分区,可能是为了防止级联错误进一步损坏驱动器

好吧,很公平;但我现在想做的是在我的程序中添加一个函数,可以检测驱动器何时处于重新安装的只读状态,这样它就可以主动通知用户他的驱动器有问题

我的问题是,查询文件系统以确定它是否以只读方式装载的优雅/受支持的方法是什么

尝试将文件写入文件系统是不够好的,因为这可能会由于其他原因而失败,而且如果不需要,我也不想写入文件系统

我的程序可以
fopen(“/proc/mounts”,“r”)
并解析它生成的文本行(grepping for“rw”,对应于我的分区的行上的标记),如果必须的话,我也会这样做,但这个解决方案似乎有点老套(太像屏幕抓取,如果文本格式发生变化,很容易被破坏)

那么,我是否可以使用一些轻量级/专门构建的Linux系统调用来告诉我给定的文件系统装入点(例如“/dev/sda1”)当前是否以只读方式装入?似乎
stat()
可能可以做到,但我不知道如何做到。

应该满足您的需要

名称

getmntent,setmntent,addmntent,endmntent,hasmntopt,getmntent\r- 获取文件系统描述符文件项

简介

   #include <stdio.h>
   #include <mntent.h>

   FILE *setmntent(const char *filename, const char *type);

   struct mntent *getmntent(FILE *stream);

   int addmntent(FILE *stream, const struct mntent *mnt);

   int endmntent(FILE *streamp);

   char *hasmntopt(const struct mntent *mnt, const char *opt);

   /* GNU extension */
   #include <mntent.h>

   struct mntent *getmntent_r(FILE *streamp, struct mntent *mntbuf,
                              char *buf, int buflen);


检查用于写入的打开文件的文件系统是否已装载为只读的最简单方法是检查
errno
变量的
EROFS
错误

如果您不可能在该文件系统中有一个可写的目录或文件,那么您就无法获得一种可移植的方法来检查文件系统是否已变成只读(如果由于设备错误而变成只读,则更多)


另一种方法是让管理员检查,或者自己尝试读取
/proc/mounts
文件。但这只是linux特有的。

甚至有一个POSIX.1函数可以实现这一点:在所需装载的任何文件上。如果
.f_flag&ST_RDONLY
,它将以只读方式挂载。一个愚蠢的解决方案是使用旁注:如果您查看
statvfs
[如Nominal Animal建议的那样]的手册页,它会注意到一个较旧版本的
statvfs
通过解析
/proc/mounts
来收集标志,因此您离得不远。手册页还注意到,
statvfs
调用linux系统调用
statfs
立即获取此信息;如果你想把它作为一个答案重新发布,我会标记它。听起来这会给我关于/etc/fstab内容的信息,如果由于磁盘错误(?)文件系统被重新装载为只读,那么它可能不一定与已装载文件系统的当前状态相同@JeremyFriesner我不知道有什么简单的方法可以通过编程来确定文件系统是否因为磁盘错误而被只读重新安装,而不是试图写入它。如果这是您必须满足的要求,您可能应该以某种方式进行测试。如果幸运的话,可见的挂载选项将会改变。或者你可以问另一个后续问题-可能有人已经知道了。
getmntent
家族只需读取和解析
/etc/fstab
/etc/mtab
(实际上是调用
setmntent
时输入的任何文件),而且配对也很简单——它逐行读取文件,然后将行拆分为字段。不用说,程序员需要将拆分字段
mnt\u fsname
与要验证的文件系统进行比较,并且需要解析
mnt\u opts
中“ro”装载选项的字符串。当@Nominal Animal的comment
statvfs()
或simlar干净且更好时,这不是一个好的解决方案。要遵循
getmnent()
的解决方案并解决这个问题(即检查文件系统重新安装为只读),需要输入
/etc/mtab
,因为它是“已安装的文件系统描述文件”根据
getmntent()
的手册页。
       struct mntent {
           char *mnt_fsname;   /* name of mounted filesystem */
           char *mnt_dir;      /* filesystem path prefix */
           char *mnt_type;     /* mount type (see mntent.h) */
           char *mnt_opts;     /* mount options (see mntent.h) */
           int   mnt_freq;     /* dump frequency in days */
           int   mnt_passno;   /* pass number on parallel fsck */
       };