Detect read-only partition in Linux

In some sort of problems, ext3 goes read-only to protect the filesystem against further damages. What could cause such a readonly problem? It’s difficult to get an exact answer, but I’m inclined to take it as a file-system issue, though some hardware problems will trigger this error as well.

This issue is common on Linux server which has high disk I/O. As busy I/O retry error would mark low level disk calls as failed, this will force ext3 to go into read-only mode.

We get a question here: Is there a way to detect read-only disk partition in Linux?
Yes, sure we have. Admon has this feature integrated when it was came out some years ago. Here we’ll show two smart ways on detecting read-only partitions.

Detecting Read-Only partition in C
You can copy the follow code into a file, and save it as fs_readonly.c

#include <stdio.h>
#include <sys/statvfs.h>

int main(){
        char *path;
        struct statvfs fs_stat;

        path="/home";
        statvfs(*path, &fs_stat);
        printf("Filesystem: %s, status: %Xn", path,fs_stat.f_flag);
}

After compiled the code, you can run is in normal user mode like this:

$ ./fs_readonly
Filesystem: /home, status: 1

Here the status code 1 means it’s a Read-only partition. More details about statvfs is available here at linux.die.net. It tells us that we can check a readonly partition in normal user mode.

The second way is even easier.

Detecting Read-only partition in Shell/perl

Basically you just need to run this command:

$ LANG=C touch /home 2>&1 | grep Read-only
touch: setting times of `/home': Read-only file system

The 2>&1 means all standard error message is redirected to standard output so that grep can catch the error. The Read-only in output is a typical string which can be used to monitor read-only file systems. Note that this error message is slightly different from normal ones:

$ LANG=C touch /usr
touch: setting times of `/usr': Permission denied

Which the help of this method, you can now monitor your disk parition status more efficiently.

Share this post

One thought on “Detect read-only partition in Linux

  1. The first argument in the statvfs() call above should be “path” and not “*path”. Using * means you’re passing only first character of path string, which would be an invalid pointer (to something that may or may not be readable).

    Given that the code above did output something without crashing, you were being lucky. The result, however, is not reliable as it’s taking an invalid chunk of memory, assuming it to be a null terminated string, treating it as a real path and trying to see if that is mounted read-only.

    It would also be a good idea to check what statvfs() returns. You would have caught the error if you checked the return value from the method. Ignoring return values is not a good idea. I believe with your code above in its original shape, statvfs() would very likely fail.

    Now why you got read-only status as result? That is because you did not initialize “fs_stat” by null characters. Remember your structure object “fs_stat” is placed on stack because of the way you declared it in a method. The stack, however, has a previous state in memory which can be anything random, so the value of fs_stat.f_flag is any random garbage that was there previously because as I said likely statvfs() failed and did not modify fs_stat. That garbage is what you end up outputing as “status”. Not something you would want.

    Also, assume for a moment all the code was right, when analyzing result you should not assume “fs_stat.f_flag” would be 1 to indicate read only mount. You should do an operation “fs_stat.f_flag && ST_RDONLY” and if the result comes out to be true, only then this means the mount was read-only (of course, first of all you would check the return value from statvfs() ). The operation && is required as the flag can indicate a combination of bits so you should not be comparing to 1 directly. Also, it is not a good idea to assume that ST_RDONLY would be 1, just use the defined string ST_RDONLY when comparing.

    I hope this helps anyone reading this blog.

Post Comment