Марк Митчелл - Программирование для Linux. Профессиональный подход
Например, если в системе имеется IDE-дисковод CD-ROM, подключенный в качестве главного устройства к дополнительному IDE-контроллеру, соответствующий файл устройства будет называться /dev/hdc. Тогда компакт-диск извлекается из дисковода с помощью такой команды:
% ./cdrom-eject /dev/hdc
Глава 7
Файловая система /proc
Попробуйте запустить команду mount без аргументов — она выдаст список файловых систем, смонтированных в настоящий момент. Среди прочих строк будет и такая:
none on /proc type proc (rw)
Она указывает на специальную файловую систему /proc. Поле none говорит о том, что эта система не связана с аппаратным устройством, например жестким диском. Она является своего рода "окном" в ядро Linux. Файлам в системе /proc не соответствуют реальные файлы на физическом устройстве. Это особые объекты, которые ведут себя подобно файлам, открывал доступ к параметрам, служебным структурам и статистической информации ядра. "Содержимое" таких файлов генерируется ядром динамически в процессе чтения из файла. Осуществляя запись в некоторые файлы, можно менять конфигурацию работающего ядра системы. Рассмотрим пример:
% ls -l /proc/version
-r--r--r-- 1 root root 0 Jan 17 18:09 /proc/version
Обратите внимание на то, что размер файла равен нулю. Поскольку содержимое файла создается ядром "на лету", понятие размера файла здесь неприменимо. Соответственно время модификации файла равно времени запуска команды.
Что находится в файле /proc/version? Он содержит строку, описывающую номер версии ядра Linux. Сюда входит информация, возвращаемая системным вызовом uname() (описан в разделе 8.15, "Функция uname()"), а также номер версии компилятора, с помощью которого было создано ядро. Чтение из файла /proc/version осуществляется самым обычным образом, например с помощью команды cat:
% cat /proc/version
Linux version 2.2.14-5.0 ([email protected])
(gcc version egcs-2.91.66 19990314/Linux
(egcs-1.1.2 release)) #1 Tue Mar 7 21:07:39 EST 2000
Многие элементы файловой системы /proc описаны на man-странице proc (раздел 5). В этой главе будут рассмотрены те из них, которые чаще всего используются программистами и полезны при отладке.
Читатели, которых интересуют детали функционирования файловой системы /proc, могут просмотреть ее исходные коды в каталоге /usr/src/linux/fs/proc/.
7.1. Извлечение информации из файловой системы /proc
Большинство элементов файловой системы /proc выдает информацию в отформатированном виде. Например, файл /proc/cpuinfo содержит сведения о процессоре (или процессорах, если это многопроцессорный компьютер). Выходная информация представляется в виде таблицы значений, по одному на строку. Каждое значение сопровождается символическим идентификатором.
При обращении к файлу /proc/cpuinfo будет выдана примерно следующая информация:
% cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 5
model name : Pentium II (Deschutes)
stepping : 2
cpu MHz : 400.913520
cache size : 512 KB
fdiv_bug : no
hlt_bug : no
sep_bug : no
f00f_bug : no
coma_bug : no
fpu : yes
fpu_exception : yes
cpuid level : 2
wp : yes
flags : fpu vme de pse tsc msr рае mce cx8 apic sep
mtrr pge mce cmov pat pse36 mmx fxsr
bogomips : 399.77
Интерпретация некоторых значений даны в разделе 7.3.1. "Центральный процессор". Если нужно получить одно из этих значений в программе, проще всего загрузить файл в память и просканировать его функцией sscanf(). В листинге 7.1 показано, как это сделать. В программе имеется функция get_cpu_clock_speed(), которая загружает файл /proc/cpuinfo и определят частоту процессора.
Листинг 7.1. (clock-speed.c) Определение частоты процессора путем анализа файла /proc/cpuinfo#include <stdio.h>
#include <string.h>
/* Определение частоты процессора в мегагерцах на
основании данных файла /proc/cpuinfo. В
многопроцессорной системе будет найдена частота
первого процессора. В случае ошибки возвращается нуль. */
float get_cpu_clock_speed() {
FILE* fр;
char buffer[1024];
size_t bytes_read;
char* match;
float clock_speed;
/* Загрузка всего файла /proc/cpuinfo в буфер. */
fp = fopen("/proc/cpuinfo", "r");
bytes_read = fread(buffer, 1, sizeof(buffer), fp);
fclose(fp);
/* Выход, если прочитать файл не удалось или буфер оказался
слишком маленьким. */
if (bytes_read == 0 || bytes_read = sizeof(buffer))
return 0;
/* Буфер завершается нулевым символом. */
buffer[bytes_read] = ' ';
/* Поиск строки, содержащей метку "cpu MHz". */
match = strstr(buffer, "cpu MHz");
if (match == NULL)
return 0;
/* Анализ строки и выделение из нее значения частоты
процессора. */
sscanf(match, "cpu MHz ; %f" &clock_speed);
return clock_speed;
}
int main() {
printf("CPU clock speed: %4.0f Mhzn",
get_cpu_clock_speed());
return 0;
}
He забывайте о том. что имена, семантика и формат представления элементов файловой системы /proc меняются при обновлении ядра Linux. Программа должна вести себя корректно в случае, если нужный файл отсутствует или имеет иной формат.
7.2. Каталоги процессов
Файловая система /proc содержит по одному каталогу для каждого выполняющегося в данный момент процесса. Именем каталога является идентификатор процесса.[22] Каталоги появляются и исчезают динамически по мере запуска и завершения процессов. В каждом каталоге имеются файлы, предоставляющие доступ к различной информации о процессе. Собственно говоря, на основании этих каталогов файловая система /proc и получила свое имя.
В каталогах процессов находятся следующие файлы.
■ cmdline. Содержит список аргументов процесса; описан в разделе 7.2.2, "Список аргументов процесса".
■ cwd. Является символической ссылкой на текущий рабочий каталог процесса (задаётся, к примеру, функцией chdir()).
■ environ. Содержит переменные среды процесса; описан в разделе 7.2.3, "Переменные среды процесса".
■ exe. Является символической ссылкой на исполняемый файл процесса; описан в разделе 7.2.4. "Исполняемый файл процесса".
■ fd. Является подкаталогом, в котором содержатся ссылки на файлы, открытые процессом: описан в разделе 7.2.5, "Дескрипторы файлов процесса".
■ maps. Содержит информацию о файлах, отображаемых в адресном пространстве процесса. О механизме отображения файлов в памяти рассказывалось в главе 5. "Взаимодействие процессов". Для каждого такого файла выводится соответствующий диапазон адресов в адресном пространстве процесса, права доступа, имя файла и пр. К числу отображаемых файлов относятся исполняемый файл процесса, а также загруженные библиотеки.
■ root. Является символической ссылкой на корневой каталог процесса (обычно это /). Корневой каталог можно сменить с помощью команды chroot или функции chroot().
■ stat. Содержит статистическую информацию о процессе. Эти же данные представлены в файле status, но здесь они находятся в неотформатированном виде и записаны в одну строку. Такой формат труден для восприятия, зато проще в плане синтаксического анализа.
■ statm. Содержит информацию об использовании памяти процессом, описан в разделе 7.2.6. "Статистика использования процессом памяти".
■ status. Содержит статистическую информацию о процессе, причем в отформатированном виде; описан в разделе 7 2.7, "Статистика процесса".
■ cpu. Этот файл появляется только в симметричных многопроцессорных системах и содержит информацию об использовании процессорного времени (пользователями и системой).
Из соображений безопасности права доступа к некоторым файлам предоставляются только владельцу процесса и суперпользователю.
7.2.1. Файл /proc/self
В файловой системе /proc есть дополнительный элемент, позволяющий программам находить информацию о своем собственном процессе. Файл /proc/self является символической ссылкой на каталог, соответствующий текущему процессу. Естественно, содержимое ссылки меняется в зависимости от того, кто к ней обращается.
Например, программа, представленная в листинге 7.2, с помощью файла /proc/self определяет свой идентификатор процесса (это делается лишь в демонстрационных целях, гораздо проще пользоваться функцией getpid(), описанной в разделе 3.1.1, "Идентификаторы процессов"). Для чтения содержимого символической ссылки вызывается функция readlink() (описана в разделе 8.11, "Функция readlink(): чтение символических ссылок").