Linux программирование в примерах - Арнольд Роббинс
Шрифт:
Интервал:
Закладка:
Функция print_mount() выводит информацию из struct mnent. Вывод во многом напоминает вывод 'cat /etc/mtab':
$ ch08-mounted /* Запуск программы */
/dev/hda2 / ext3 rw 0 0
none /proc proc rw 0 0
usbdevfs /proc/bus/usb usbdevfs rw 0 0
/dev/hda5 /d ext3 rw 0 0
none /dev/pts devpts rw,gid=5,mode=620 0 0
none /dev/shm tmpfs rw 0 0
none /proc/sys/fs/binfmt_misc binfmt_misc rw 0 0
/dev/hda1 /win vfat rw,noexec,nosuid,nodev,uid=2076,gid=10,user=arnold 0 0
8.3. Получение сведений о файловой системе
Вывод сведений о файловой системе, рассмотренный ранее — это хорошо и замечательно, но это не захватывает. Раз мы знаем, что определенная точка монтирования представляет файловую систему, нам нужны сведения о файловой системе. Это даст нам возможность выводить вещи наподобие сведений, полученных с помощью df и 'df -i'.
$ df /* Показать свободное/используемое пространство */
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/hda2 6198436 4940316 943248 84% /
/dev/hda5 61431520 27618536 30692360 48% /d
none 256616 0 256616 0% /dev/shm
/dev/hda1 8369532 2784700 5584832 34% /win
$ df -i /* Показать свободные/используемые индексы */
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/hda2 788704 233216 555488 30% /
/dev/hda5 7815168 503243 7311925 7% /d
none 64154 1 64153 1% /dev/shm
/dev/hda1 0 0 0 - /win
8.3.1. Стиль POSIX: statvfs() и fstatvfs()
На ранних системах Unix была только одна разновидность файловой системы. Для них было достаточно, если df считывала суперблок каждой смонтированной файловой системы, извлекала значимые сведения и красиво форматировала их для отображения. (Суперблок обычно был вторым блоком в файловой системе; первым был загрузочный блок, содержащий загрузочный код).
Однако в современном мире такой подход был бы непригодным. POSIX предоставляет расширение XSI для получения доступа к этой информации. Главная функция называется statvfs() («vfs» часть происходит от лежащей в основе технологии SunOS, использованной позже в System V Release 4, которая называется виртуальной файловой системой.) Имеется две функции:
#include <sys/types.h> /* XSI */
#include <sys/statvfs.h>
int statvfs(const char *path, struct statvfs *buf);
int fstatvfs(int fd, struct statvfs *buf);
statvfs() использует для любого файла имя пути; она возвращает сведения о файловой системе, содержащей файл. fstatvfs() принимает в качестве первою аргумента дескриптор открытого файла, здесь также возвращается информация о файловой системе, содержащей открытый файл, struct statvfs содержит следующие члены:
struct statvfs {
unsigned long int f_bsize; /* Размер блока */
unsigned long int f_frsize;
/* Размер фрагмента («основной размер блока») */
fsblkcnt_t f_blocks; /* Общее число блоков */
fsblkcnt_t f_bfree; /* Общее число свободных блоков */
fsblkcnt_t f_bavail; /* Число доступных блоков (≤f_bfree) */
fsfilcnt_t f_files; /* Общее число индексов */
fsfilcnt_t f_ffree; /* Общее число свободных индексов */
fsfilcnt_t f_favail; /* Число доступных индексов (≤f_files) */
unsigned long int f_fsid; /* ID файловой системы */
unsigned long int f_flag; /* Флаги: ST_RDONLY и/или ST_NOSUID */
unsigned long int f_namemax; /* Максимальная длина имени файла */
};
Сведений, которые в ней содержатся, достаточно для написания df:
unsigned long int f_bsize
Размер блока является предпочтительным размером для осуществления ввода/вывода. Файловая система пытается хранить по крайней мере f_bsize байтов стоящих данных в смежных секторах на диске. (Сектор является наименьшим количеством адресуемых данных на диске. Обычно дисковый сектор равен 512 байтам.)
unsigned long int f_frsize
Некоторые файловые системы (такие, как BSD Fast Filesystem) проводят различие между блоками и фрагментами блоков. Небольшие файлы, общий размер которых меньше размера блока, находятся в некотором числе фрагментов. Это позволяет избежать пустой потери дискового пространства (за счет допустимой цепы большей сложности кода ядра). Размер фрагмента выбирается во время создания файловой системы.
fsblkcnt_t f_blocks
Общее число блоков (в единицах f_bsize) в файловой системе.
fsblkcnt_t f_bfree
Общее число свободных блоков в файловой системе.
fsblkcnt_t f_bavail
Число блоков, которые действительно могут использоваться. Некоторые файловые системы резервируют часть блоков файловой системы для использования суперпользователем при заполнении файловой системы. Современные системы резервируют около 5 процентов, хотя это число может быть изменено администратором. (См. tune2fs(8) на системе GNU/Linux и tunefs(8) на системах Unix.)
fsfilcnt_t f_files
Общее число индексов («порядковых номеров файлов» на языке POSIX) в файловой системе. Это число обычно инициализируется и делается постоянным при создании файловой системы.
fsfilcnt_t f_ffree
Общее число свободных узлов.
fsfilcnt_t f_favail
Число индексов, которые действительно могут быть использованы. Некоторая часть индексов резервируются для суперпользователя, точно так же, как для блоков.
unsigned long int f_fsid
ID файловой системы. POSIX не определяет, что оно представляет, и это под Linux не используется.
unsigned long int f_flag
Флаги, дающие информацию о файловой системе. POSIX определяет два флага: ST_RDONLY для файловых систем только для чтения (таких, как CD-ROM) и ST_NOSUID, который запрещает использование битов setuid и setgid в исполняемых файлах. Системы GNU/Linux предусматривают дополнительные флаги: они перечислены в табл. 8.2.
Таблица 8.2. Значения GLIBC для f_flag
Флаг POSIX Значение ST_MANDLOCK Осуществляет принудительное блокирование (см. раздел 14.2). ST_NOATIME Не обновлять при каждом доступе время доступа ST_NODEV Запрещает доступ через файлы устройств ST_NODIRATIME Не обновлять поле времени доступе каталогов ST_NOEXEC Запрещает исполнение двоичных файлов ST_NOSUID √ Файловая система запрещает использование битов setuid и setgid. ST_RDONLY √ Файловая система только для чтения. ST_SYNCHRONOUS Любая запись осуществляется синхронно (см. раздел 4.6.3).unsigned long int f_namemax
Максимальная длина имени файла. Это относится к каждому отдельному компоненту в имени пути; другими словами, максимальная длина для элемента каталога
Типы fsblkcnt_t и fsfilcnt_t определены в <sys/types.h>. Они обычно являются unsigned long, но на современных системах они могут быть даже 64-разрядными, поскольку диски стали очень большими. Следующая программа, ch08-statvfs.c, показывает, как использовать statvfs():
1 /* ch08-statvfs.с --- демонстрация statvfs */
2
3 /* ЗАМЕЧАНИЕ: специфично для GNU/Linux! */
4
5 #include <stdio.h>
6 #include <errno.h>
7 #include <mntent.h> /* для getmntent(), et al. */
8 #include <unistd.h> /* для getopt() */
9 #include <sys/types.h>
10 #include <sys/statvfs.h>
11
12 void process(const char *filename);
13 void do_statvfs(const struct mntent *fs);
14
15 int errors = 0;
16 char *myname;
17
18 /* main --- обработка опций */
19
20 int main(int argc, char **argv)
21 {
22 int c;
23 char *file = "/etc/mtab"; /* файл для чтения по умолчанию */
24
25 myname = argv[0];
26 while ((c = getopt(argc, argv, "f:")) != -1) {
27 switch (c) {
28 case 'f':
29 file = optarg;
30 break;
31 default:
32 fprintf(stderr, "usage: %s [-f fstab-file]n", argv[0]);
33 exit(1);
34 }