2017-02-07 11 views
3

Во-первых, небольшая справочная информация, чтобы обеспечить некоторую мотивацию для этого вопроса: у меня есть программа, которая работает на безголовом Linux-сервере и читает/записывает файлы на несколько съемных внешних жестких дисков, каждый из которых отформатирован с файловой системой ext4. Очень часто метаданные файловой системы на одном из этих дисков повреждаются по какой-либо причине (несмотря на отсутствие журналирования ext4), что может привести к тому, что диск файловой системы ext4 обнаружит проблему и перемонтирует раздел как доступный только для чтения, предположительно в качестве меры предосторожности против каскадных ошибок, развращающих привод дальше.Есть ли запрос API C API для запроса смонтированной файловой системы, чтобы узнать, доступна ли она только для чтения?

Хорошо, справедливо; но теперь я хочу добавить функцию в свою программу, которая может обнаружить, когда диск находится в состоянии перемонтированного состояния только для чтения, чтобы он мог активно уведомлять пользователя о том, что его диск находится в неисправности.

Мой вопрос: какой элегантный/поддерживаемый способ запросить файловую систему, чтобы узнать, смонтирован ли он только для чтения?

Пытаться записать файл в файловую систему недостаточно, потому что это может привести к поломке по другим причинам, а также потому, что я не хочу писать в файловую систему, если мне это не нужно.

Моя программа может fopen("/proc/mounts", "r") и разобрать строки текста, которые он генерирует (grepping для маркера «rw,» в строке, соответствующей моему разделу), и я буду, если придется, но это решение кажется немного взломанным (слишком сильно, как скрипинг экрана, который может сломаться, если текстовый формат когда-либо изменится).

Итак, есть ли какой-либо легкий/специально разработанный системный вызов Linux, который я мог бы использовать, что скажет мне, установлена ​​ли в данный момент точка монтирования файловой системы (например, «/ dev/sda1») только для чтения? Кажется, stat() может это сделать, но я не вижу, как это сделать.

+6

Существует даже функция POSIX.1 для этого: ['statvfs()' или 'fstatvfs()'] (http://man7.org/linux/man-pages/man3/statvfs.3.html) в любом файле на нужном жестком диске. Если '.f_flag & ST_RDONLY', он монтируется только для чтения. –

+0

Глупым решением будет использование ['access()'] (https://linux.die.net/man/2/access) – Stargateur

+1

_Side note: _ Если вы посмотрите на страницу man для 'statvfs' [as предложенный Nominal Animal], он отмечает, что _older_ версия 'statvfs' собрала флаги, проанализировав'/proc/mounts' - так что вы не были слишком далеко. На странице man также отмечается, что 'statvfs' вызывает linux syscall' statfs', чтобы получить эту информацию сейчас. –

ответ

3

getmntent() family должен соответствовать вашим потребностям.

ИМЯ

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

ОПИСАНИЕ

Эти процедуры используются для доступа к файлу описания файловой системы /etc/fstab и файлу описания смонтированной файловой системы/etc/mtab.

Функция setmntent() открывает файл описания файловой системы filename и возвращает указатель файла, который может использоваться getmntent(). Тип аргумента - это тип требуемого доступа и может принимать те же значения , что и аргумент режима fopen (3).

Функция getmntent() считывает следующую строку файловой системы файл описания из потока и возвращает указатель на структуру , содержащую разбитые поля из строки в файле. Указатель указывает на статическую область памяти, которая перезаписывается последующими вызовами getmntent().

Функция addmntent() добавляет структуру mntent mnt в конец открытого потока.

Функция endmntent() закрывает поток, связанный с файлом описания файловой системы .

Функция hasmntopt() сканирует поле mnt_opts (см. Ниже) структуры mntent mnt для подстроки, которая соответствует opt. См. и установите (8) для допустимых параметров монтирования.

возвратной getmntent_r() функция аналогична getmntent(), но сохраняет структуру монтирование в предоставленном * mntbuf и хранит строку , на который указуют записи в этих структурах в предоставленном массиве ЬиЕ из размера buflen ,

Структура mntent определяется следующим образом:

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

...

+0

Похоже, что это даст мне информацию о содержимом/etc/fstab, что может и не обязательно совпадать с текущим состоянием смонтированной файловой системы, если файловая система была повторно установлена ​​как доступная только для чтения из-за ошибки диска (?) –

+0

@JeremyFriesner Я не знаю, какой простой способ программно определить, была ли файловая система перемонтирована только для чтения из-за ошибки диска, кроме попытки записи на нее. Если это требование, с которым вам нужно встретиться, вы должны, вероятно, проверить его каким-то образом. Если вам повезет, видимые параметры монтирования будут изменены. Или вы можете задать другой, следующий вопрос - кто-то там, вероятно, уже знает. –

1

Самый простой способ проверить, что файловая система открытого файла для записи стал установлена ​​только для чтения является для проверки переменной errno на ошибку EROFS.

Если у вас нет возможности записывать каталог или файл в этой файловой системе, вы не сможете получить переносимый способ проверить, стала ли файловая система доступной только для чтения (больше, если это стало причиной из-за ошибок устройства)

Другой способ - попросить администратора проверить или попытаться прочитать файл /proc/mounts самостоятельно. Но это только конкретный Linux.