Jeremy Friesner
Jeremy Friesner

Reputation: 73219

Is there a Linux C API call to query a mounted filesystem to see if it is read-only?

First, a little background information to provide some motivation for this question: I've got a program that runs on a headless Linux server and reads/writes files on several removable external hard drives, each of which is formatted with ext4 filesystem. Very occasionally, the filesystem metadata on one of these drives gets corrupted for whatever reason (ext4 journalling notwithstanding), which can cause the ext4 filesystem drive to detect a problem and remount the partition as read-only, presumably as a precaution against cascading errors corrupting the drive further.

Okay, fair enough; but what I'd like to do now is add a function to my program that can detect when the drive is in this remounted-read-only state, so that it can pro-actively notify the user that his drive is in trouble.

My question is, what is an elegant/supported way to query a filesystem to find out if it is mounted read-only?

Attempting to write a file to the filesystem isn't good enough, because that could fail for other reasons, and also because I don't want to write to the filesystem if I don't have to.

My program could fopen("/proc/mounts", "r") and parse the lines of text that it generates (grepping for the "rw," token on the line corresponding to my partition), and I will if I have to, but that solution seems a bit hacky (too much like screen-scraping, liable to break if the text format ever changes).

So, is there some lightweight/purpose-built Linux system call that I could use that would tell me whether a given filesystem mount point (e.g. "/dev/sda1") is currently mounted read-only? It seems like stat() might be able to do it, but I can't see how.

Upvotes: 3

Views: 4851

Answers (2)

Luis Colorado
Luis Colorado

Reputation: 12708

The easiest way to check that the filesystem of an open file for writing has become mounted read-only is to check the errno variable for EROFS error.

If you don't have the possibility of having a writable directory or file in that filesystem, you cannot get a portable way of checking if the filesystem has become read only (more if it has become so due to device errors)

Another way is to ask the administrator to check, or try to read the /proc/mounts file yourself. But this is linux specific only.

Upvotes: 2

Andrew Henle
Andrew Henle

Reputation: 1

The getmntent() family should meet your needs.

NAME

getmntent, setmntent, addmntent, endmntent, hasmntopt, getmntent_r - get filesystem descriptor file entry

SYNOPSIS

   #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);

DESCRIPTION

These routines are used to access the filesystem description file /etc/fstab and the mounted filesystem description file /etc/mtab.

The setmntent() function opens the filesystem description file filename and returns a file pointer which can be used by getmntent(). The argument type is the type of access required and can take the same values as the mode argument of fopen(3).

The getmntent() function reads the next line of the filesystem description file from stream and returns a pointer to a structure containing the broken out fields from a line in the file. The pointer points to a static area of memory which is overwritten by subsequent calls to getmntent().

The addmntent() function adds the mntent structure mnt to the end of the open stream.

The endmntent() function closes the stream associated with the filesystem description file.

The hasmntopt() function scans the mnt_opts field (see below) of the mntent structure mnt for a substring that matches opt. See and mount(8) for valid mount options.

The reentrant getmntent_r() function is similar to getmntent(), but stores the struct mount in the provided *mntbuf and stores the strings pointed to by the entries in that struct in the provided array buf of size buflen.

The mntent structure is defined in as follows:

       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 */
       };

...

Upvotes: 3

Related Questions