Читать «Энциклопедия разработчика модулей ядра Linux» онлайн - страница 10

Ори Померанц

Файловая система /proc

В Linux имеется дополнительный механизм для ядра и ядерных модулей, чтобы они могли послать информацию процессам: файловая система /proc. Первоначально разработанная для свободного доступа к информации относительно процессов, она теперь используется каждым кусочком ядра, который может что-либо сообщить, например, /proc/modules, который имеет список модулей и /proc/meminfo, который имеет статистику использования памяти.

Метод использования файловой системы /proc очень похож на работу с драйверами устройства: Вы создаете структуру со всей информацией, необходимой для /proc файла, включая указатели на любые функции драйвера (в нашем случае имеется только один, вызываемый когда кто-то пытается читать из /proc файла). Затем init_module регистрирует структуру и cleanup_module отменяет регистрацию.

Причина по которой мы используем proc_register_dynamic в том, что мы не хотим определять inode номер, используемый для нашего файла заранее, но позволяем ядру определять его, чтобы предотвратить столкновения. В нормальных файловых системах размещенных на диске, а не только в памяти (как /proc) inode является указателем на то место, в котором на диске размещен индексный узел файла (кратко, inode). Inode содержит информацию относительно файла, например разрешения файла, вместе с указателем на то место, где могут быть найдены данные файла.

Поскольку никаких наших функций не вызывается когда файл открывается или закрывается, некуда поместить MOD_INC_USE_COUNT и MOD_DEC_USE_COUNT в этом модуле, и если файл открыт и затем модуль удален, не имеется никакого способа избежать проблем. В следующей главе мы рассмотрим более тяжелый в реализации, но более гибкий путь имеющий дело с файлами из /proc, который позволит нам защититься от этой проблемы.

procfs.c

/* procfs.c - create a "file" in /proc

* Copyright (C) 1998-1999 by Ori Pomerantz

*/

/* The necessary header files */

/* Standard in kernel modules */

#include <linux/kernel.h> /* We're doing kernel work */

#include <linux/module.h> /* Specifically, a module */

/* Deal with CONFIG_MODVERSIONS */

#if CONFIG_MODVERSIONS==1

#define MODVERSIONS

#include <linux/modversions.h>

#endif

/* Necessary because we use the proc fs */

#include <linux/proc_fs.h>

/* In 2.2.3 /usr/include/linux/version.h includes a

* macro for this, but 2.0.35 doesn't - so I add it

* here if necessary. */

#ifndef KERNEL_VERSION

#define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c))

#endif

/* Put data into the proc fs file.

 Arguments

 =========

 1. The buffer where the data is to be inserted, if you decide to use it.

 2. A pointer to a pointer to characters. This is useful if you don't want to use the buffer allocated by the kernel.