Как работает / proc / *?


62

Есть много файлов в /proc, как /proc/cpuinfo, /proc/meminfo, /proc/devicesи так далее, что, когда открыт, возвращение системы информации.

Эти файлы, по-видимому, не существуют на самом деле, поскольку их запуск fileтолько говорит о том, что они пусты.

$ file /proc/cpuinfo
/proc/cpuinfo: empty

Как эти файлы работают точно?

Ответы:


72

Это на самом деле довольно просто, по крайней мере, если вам не нужны детали реализации.

Во-первых, в Linux все файловые системы (ext2, ext3, btrfs, reiserfs, tmpfs, zfs, ...) реализованы в ядре. Некоторые могут перенести работу в пользовательский код через FUSE, а некоторые приходят только в форме модуля ядра ( родной ZFS является ярким примером последнего из-за лицензионных ограничений), но в любом случае остается компонент ядра. Это важная основа.

Когда программа хочет читать из файла, он будет выдавать различные вызовы библиотек системы , которая в конечном счете , в конечном итоге в ядре в виде open(), read(), close()последовательность (возможно , с seek()добавленными для хорошей мерой). Ядро берет указанный путь и имя файла и через уровень файловой системы и устройства ввода / вывода преобразует их в физические запросы чтения (а во многих случаях также запросы записи - например, обновления времени) в некоторое хранилище.

Однако нет необходимости переводить эти запросы специально в физическое постоянное хранилище . Контракт ядра заключается в том, что при выдаче этого конкретного набора системных вызовов будет предоставлено содержимое рассматриваемого файла . Где именно в нашем физическом мире «файл» существует, это вторично.

На /procобычно устанавливается то, что известно как procfs. Это особый тип файловой системы, но поскольку это файловая система, она на самом деле не отличается от, например, ext3файловой системы, смонтированной где-то. Таким образом, запрос передается в код драйвера файловой системы procfs, который знает обо всех этих файлах и каталогах и возвращает определенные фрагменты информации из структур данных ядра .

«Уровень хранения» в данном случае представляет собой структуры данных ядра и procfsобеспечивает чистый, удобный интерфейс для доступа к ним. Имейте в виду, что монтирование procfs в /procэто просто соглашение; Вы могли бы так же легко установить его в другом месте. Фактически, это иногда делается, например, в chroot-тюрьмах, когда выполняющемуся там процессу по какой-то причине требуется доступ к / proc.

Это работает так же, если вы записываете значение в некоторый файл; на уровне ядра, что приводит к ряду open(), seek(), write(), close()вызовы , которые снова получить передаются драйверу файловой системы; опять же, в данном конкретном случае, код procfs.

Конкретная причина, по которой вы видите fileвозвращение, emptyзаключается в том, что многие файлы, представленные procfs, имеют размер 0 байт. Размер 0 байт, вероятно, является оптимизацией на стороне ядра (многие файлы в / proc являются динамическими и могут легко варьироваться по длине, возможно, даже от одного чтения к другому, и вычисление длины каждого файла в каждом прочитанном каталоге будет потенциально очень дорого). Переходя к комментариям к этому ответу, который вы можете проверить в своей системе, запустив strace или аналогичный инструмент, fileсначала выдает stat()вызов для обнаружения любых специальных файлов, а затем использует возможность, если размер файла указан как 0 , прервите и сообщите файл как пустой.

Это поведение на самом деле задокументировано и может быть отменено путем указания -sили --special-filesпри fileвызове, хотя, как указано на странице руководства, это может иметь побочные эффекты. Приведенная ниже цитата взята из справочной страницы 5.11 файла BSD от 17 октября 2011 года.

Как правило, file пытается только прочитать и определить тип файлов аргументов, отчеты stat (2) которых являются обычными файлами. Это предотвращает проблемы, потому что чтение специальных файлов может иметь особые последствия. Задание этой -sопции заставляет файл также читать файлы аргументов, которые являются блочными или символьными специальными файлами. Это полезно для определения типов файловой системы данных в разделах необработанного диска, которые являются блочными специальными файлами. Эта опция также заставляет файл игнорировать размер файла, как сообщает stat (2), поскольку в некоторых системах он сообщает нулевой размер для разделов необработанного диска.


5
Когда вы смотрите на это с помощью strace file /proc/versionили ltrace -S /proc/version, оптимизация довольно мала. stat()Сначала он выполняет вызов и обнаруживает, что размер равен 0, пропуская, таким образом, open()- но перед этим он загружает несколько магических файлов.
ot--

2
@ ott-- Это действительно странная последовательность событий, но это может быть связано с тем, что вы можете передавать несколько имен файлов file. Таким образом, файл предварительно загружает магические файлы, а затем обрабатывает параметр командной строки по параметру; вместо того, чтобы перемещать загрузку магического файла в «сделайте это непосредственно перед попыткой определить, к какому типу файла относится именно этот файл», это часть кода, что увеличило бы сложность. Вызов stat()и действие по возвращаемому значению по сути безвредны; сложность в отслеживании дополнительных внутренних состояний рискует привнести ошибки.
CVn

@ ott - На самом деле, причина, по которой fileотчеты «файл пуст», заключается в том, что он вызывает statобнаружение специальных файлов (именованных каналов, устройств и т. д.) и использует эту возможность, чтобы остановить обработку пустых файлов. file -s /proc/versionсообщает «ASCII текст».
Жиль "ТАК - перестань быть злым"

4
@Gilles -sПредполагается для блочных / char специальных устройств. Наконец, я посмотрел на fileисточник, и в конце fsmagic.c я увидел это объяснение, почему он возвращается ASCII textвместо empty:If stat() tells us the file has zero length, report here that the file is empty, so we can skip all the work of opening and reading the file. But if the -s option has been given, we skip this optimization, since on some systems, stat() reports zero size for raw disk partitions.
ot--

15

В этом каталоге вы можете контролировать, как ядро ​​просматривает устройства, настраивать параметры ядра, добавлять устройства в ядро ​​и снова удалять их. В этом каталоге вы можете просматривать статистику использования памяти и ввода-вывода .

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

/procКаталог не обычный каталог. Если вы загрузитесь с загрузочного компакт-диска и посмотрите на этот каталог на жестком диске, вы увидите, что он пуст. Когда вы смотрите на нее под вашей обычной работающей системой, она может быть довольно большой. Однако, похоже, он не использует пространство на жестком диске. Это потому, что это виртуальная файловая система.

Поскольку /procфайловая система является виртуальной файловой системой и находится в памяти, новая /procфайловая система создается каждый раз, когда ваша машина Linux перезагружается.

Другими словами, это всего лишь средство, позволяющее легко заглядывать в кишки системы Linux через интерфейс типа файлов и каталогов. Когда вы смотрите на файл в /procкаталоге, вы смотрите непосредственно на диапазон памяти в ядре Linux и видите, что он может видеть.

Слои в файловой системе

Введите описание изображения здесь

Примеры:

  • Внутри /procесть каталог для каждого запущенного процесса, названный по его идентификатору процесса. Эти каталоги содержат файлы, которые содержат полезную информацию о процессах, например:
    • exe: символическая ссылка на файл на диске, с которого был запущен процесс.
    • cwd: это символическая ссылка на рабочий каталог процесса.
    • wchan: который при чтении возвращает ожидающий канал, на котором включен процесс.
    • maps: который при чтении возвращает карты памяти процесса.
  • /proc/uptime возвращает время работы в виде двух десятичных значений в секундах, разделенных пробелом:
    • количество времени с момента запуска ядра.
    • количество времени, в течение которого ядро ​​не использовалось.
  • /proc/interrupts: Для информации, связанной с прерываниями.
  • /proc/modules: Для списка модулей.

Для более подробной информации смотрите man proc или kernel.org .


«Если вы загрузитесь с загрузочного компакт-диска и посмотрите на этот каталог на жестком диске, вы увидите, что он пуст». Это не относится к / proc, это обычно для любой точки монтирования, где базовая файловая система не была смонтирована. Если вы загрузитесь с того же загрузочного компакт-диска и сделаете что-то подобное mount -t procfs procfs /mnt/proc, вы увидите работающее в настоящее время ядро ​​/ proc.
CVn

5

Вы правы, они не настоящие файлы.

Проще говоря, это способ общения с ядром с использованием обычных методов чтения и записи файлов вместо непосредственного вызова ядра. Это соответствует философии Unix «все - файл».

Файлы /procнигде физически не существуют, но ядро ​​реагирует на файлы, которые вы там читаете и записываете, и вместо записи в хранилище сообщает информацию или что-то делает.

Точно так же файлы в /devдействительности не являются файлами в традиционном смысле (хотя в некоторых системах файлы в /devдействительности могут существовать на диске, они не будут иметь к ним никакого отношения, кроме того, к какому устройству они относятся) - они позволяют вам говорить к устройству, использующему обычный API-интерфейс ввода-вывода файлов Unix, или все, что его использует, например оболочки


1
Больше похоже на * nix, что можно защитить только файл. Поскольку списки контроля доступа сохраняются в файловой системе, удобно защищать привилегированные ресурсы, используя общий механизм, уже предоставленный драйвером файловой системы. Это упрощает реализацию инструментов, обращающихся к структурам ядра, и позволяет им работать без повышенных разрешений, вместо этого читая из виртуальных файлов файловой системы proc.
Пекка

3

Внутри /procкаталога есть два типа контента: первый нумерованный каталог, а второй - файл системной информации.

/procвиртуальная файловая система Например, если вы это сделаете ls -l /proc/stat, вы заметите, что он имеет размер 0 байт, но если вы сделаете «cat / proc / stat», вы увидите некоторый контент внутри файла.

Сделайте ls -l /proc, и вы увидите много каталогов только с номерами. Эти числа представляют идентификаторы процесса (PID). Файлы внутри этого пронумерованного каталога соответствуют процессу с этим конкретным PID.

Некоторые файлы, доступные в разделе /proc, содержат системную информацию, такую ​​как cpuinfo, meminfo и loadavg.

Некоторые команды Linux считывают информацию из этих /procфайлов и отображают ее. Например, команда free считывает информацию о памяти из /proc/meminfoфайла, форматирует ее и отображает.

Чтобы узнать больше об отдельных /procфайлах, выполните «man 5 FILENAME».

/proc/cmdline – Kernel command line
/proc/cpuinfo – Information about the processors.
/proc/devices – List of device drivers configured into the currently running kernel.
/proc/dma – Shows which DMA channels are being used at the moment.
/proc/fb – Frame Buffer devices.
/proc/filesystems – File systems supported by the kernel.
/proc/interrupts – Number of interrupts per IRQ on architecture.
/proc/iomem – This file shows the current map of the system’s memory for its various devices
/proc/ioports – provides a list of currently registered port regions used for input or output communication with a device
/proc/loadavg – Contains load average of the system
The first three columns measure CPU utilization of the last 1, 5, and 10 minute periods.
The fourth column shows the number of currently running processes and the total number of processes.
The last column displays the last process ID used.
/proc/locks – Displays the files currently locked by the kernel
Sample line:
1: POSIX ADVISORY WRITE 14375 08:03:114727 0 EOF
/proc/meminfo – Current utilization of primary memory on the system
/proc/misc – This file lists miscellaneous drivers registered on the miscellaneous major device, which is number 10
/proc/modules – Displays a list of all modules that have been loaded by the system
/proc/mounts – This file provides a quick list of all mounts in use by the system
/proc/partitions – Very detailed information on the various partitions currently available to the system
/proc/pci – Full listing of every PCI device on your system
/proc/stat – Keeps track of a variety of different statistics about the system since it was last restarted
/proc/swap – Measures swap space and its utilization
/proc/uptime – Contains information about uptime of the system
/proc/version – Version of the Linux kernel, gcc, name of the Linux flavor installed.

2
Это звучит для меня больше как "как использовать то, что находится в / proc?" а не "как работает / proc?" Полезная информация, но не обязательно отвечающая на этот конкретный вопрос .
CVn

Каждый файл в / proc является информацией времени выполнения, это означает, что когда вы используете cat / proc / meminfo, часть ядра запускает функцию, которая генерирует содержимое файла.
Шайлеш

3

Минимальный исполняемый пример

На мой взгляд, лучший способ понять эти вещи - поэкспериментировать с ними, поэтому вот модуль ядра, который создает запись в procfs:

myprocfs.c

#include <linux/debugfs.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h> /* seq_read, seq_lseek, single_open, single_release */
#include <uapi/linux/stat.h> /* S_IRUSR */

static const char *filename = "lkmc_procfs";

static int show(struct seq_file *m, void *v)
{
    seq_printf(m, "abcd\n");
    return 0;
}

static int open(struct inode *inode, struct  file *file)
{
    return single_open(file, show, NULL);
}

static const struct file_operations fops = {
    .llseek = seq_lseek,
    .open = open,
    .owner = THIS_MODULE,
    .read = seq_read,
    .release = single_release,
};

static int myinit(void)
{
    proc_create(filename, 0, NULL, &fops);
    return 0;
}

static void myexit(void)
{
    remove_proc_entry(filename, NULL);
}

module_init(myinit)
module_exit(myexit)
MODULE_LICENSE("GPL");

и тогда мы взаимодействуем с ним как:

insmod procfs.ko
cat /proc/lkmc_procfs

и это производит вывод:

abcd

Из этого примера мы ясно видим, что procфайлы позволяют нам реализовывать произвольные «системные вызовы, связанные с файлами», такие как open, readи llseek.

Эти системные вызовы могут затем использоваться для произвольной связи с ядром.

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

Например, в нашем небольшом примере мы просто создаем бесполезный файл, который readвсегда возвращается abcd\n.

Вот моя полностью автоматизированная установка QEMU + Buildroot, чтобы легко и безопасно создавать и играть с этим модулем ядра:

Некоторые другие подобные интерфейсы включают в себя:

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.