Меню Рубрики

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

Что такое файловая система /proc в Linux

Сегодня мы заглянем во внутрь директории /proc, познакомимся с её функцией и строением. Директория /proc присутствует на всех системах Linux независимо от дистрибутива и архитектуры.

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

Значение файлов в /proc

Для начала давайте перейдём в директорию /proc и оглядимся там:

В глаза бросаются несколько файлов со знакомыми названиями, а также множество директорий название которых состоит из цифр.

Директория с числами в качестве названий представляют процессы и названы по их PID, а внутри них информация о команде, к которой они относятся.

Файлы содержат информацию о системе, такую как память (meminfo), информация о центральном процессоре (cpuinfo) и доступных файловых системах.

Давайте начнём с того, что взглянем на один из этих файлов:

Мы увидем что-то вроде такого:

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

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

Пробежимся быстро по файлам из директории /proc:

  • /proc/bus/input/devices – Информация о всех устройствах ввода.
  • /proc/bus/pci/devices – Информация о каждом PCI устройстве.
  • /proc/cmdline – информация о строке запуска ядра.
  • /proc/config.gz – Полная информация о конфигурации ядра. Это единственный сжатый файл, для его просмотра используйте команду zcat /proc/config.gz
  • /proc/consoles – Информация о текущих консолях включая tty.
  • /proc/crypto – Поддерживаемые данным ядром методы шифрования
  • /proc/devices – Драйверы устройств настроенные в данный момент для запущенного ядра.
  • /proc/dma – Информация о текущих DMA каналах.
  • /proc/fb – Framebuffer устройства.
  • /proc/filesystems – Файловые системы поддерживающие текущим ядром.
  • /proc/iomem – Текущая карта системной памяти для устройств.
  • /proc/ioports – Зарегистрированные регионы портов для связи ввода-вывода с устройством.
  • /proc/kmsg – Лог системных событий
  • /proc/loadavg – Средняя загрузка системы.
  • /proc/locks – Файлы, заблокированные в настоящее время ядром.
  • /proc/meminfo – Информация о памяти системы (смотрите пример выше).
  • /proc/misc – Разные драйверы зарегистрированы для разных основных устройств.
  • /proc/modules – Загруженные в настоящее время модули ядра.
  • /proc/mounts – Список всех монтирований, используемых системой.
  • /proc/net/ – Папка, в которой собрано несколько файлов, содержащих информацию связанную с сетью (интерфейсы, файерволы и прочее)
  • /proc/net/dev – Сетевые интерфейсы системы
  • /proc/net/wireless – Устройства для подключения к Wi-Fi сетям
  • /proc/net/route – Сетевые маршруты
  • /proc/partitions – Информация о доступных в системе разделах.
  • /proc/stat – Записи или различные статистики хранимые с последней перезагрузки.
  • /proc/swaps – Информация о swap разделе.
  • /proc/uptime – Информация об аптайме (времени работы) (в секундах).
  • /proc/version – Версия ядра, версия gcc, и установленный дистрибутив Linux.

Что означают папки с цифрами в /proc

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

Я получил следующее:

Так что это значит? Итак, важная часть находится наверху. Из файла статуса мы можем видеть, что этот процесс принадлежит rcub. Его текущее состояние sleeping и, очевидно, ID этого процесса равно 12. Мы также можем видеть кто запустил его, поскольку UID и GID равны 0, то это значит, что процесс принадлежит пользователю root.

В любой пронумерованной директории вы сможете увидеть похожую структуру файлов. Самые важные и их краткое описание такие:

  • cmdline – строка команды процесса
  • environ – переменные окружения
  • fd – файловые дескрипторы
  • limits – содержит информацию о лимитах процесса
  • mounts – связанная с монтированием информация

Также в пронумерованных директориях вы можете увидеть ряд ссылок:

  • cwd – ссылка на текущую рабочую директорию процесса
  • exe – ссылка на исполнимый файл процесса
  • root – ссылка на рабочую директорию процесса

Информация о видеокарте в /proc

Информация о PCI устройствах содержится в файле /proc/bus/pci/devices, а также в поддиректориях /proc/bus/pci. Как и с другими устройствами, здесь нет информации о производителе — только тип устройства и, видимо, используемое адресное пространство.

Больше информации вы сможете найти в папке /proc/driver, пример вывода данных о драйвере NVidia:

Здесь информация о модели, версии БИОСа, типе шине, находиться ли устройство в чёрном списке (для отключения) и некоторые другие данные.

Заключение

Эта заметка должна помочь вам в знакомстве с директорией /proc. Также она должна дать вам представление о том, как ряд команд получают свою информацию. Вот только несколько примеров команд, которые используют /proc для своей информации: uptime, lsof, mount и ps.

Источник

Доступ к ядру Linux через файловую систему /proc

Виртуальная файловая система /proc открывает окно из пользовательского пространства в ядро

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

Файловая система /proc содержит каталоги (для структурирования информации) и виртуальные файлы. Виртуальный файл, как уже было сказано, может предоставлять пользователю информацию, полученную из ядра и, кроме того, служить средством передачи в ядро пользовательской информации. На самом деле, виртуальный файл не обязательно выполняет обе функции, но в этой статье я расскажу о том, как настроить файловую систему как для ввода, так и для вывода.

В короткой статье нельзя описать файловую систему /proc во всех деталях, но вполне возможно продемонстрировать несколько вариантов ее использования, дающих представление о ее возможностях. В листинге 1 показан интерактивный обзор некоторых элементов /proc. Мы видим корневой каталог файловой системы /proc. Обратите внимание на файлы с номерными именами в левой части листинга. Это — каталоги, содержащие информацию о выполняющихся в системе процессах. Process-id равный 1 присвоен процессу init , который в системе GNU/Linux запускается первым. Если выполнить команду ls для такого каталога, будет отображен список находящихся в нем файлов. В каждом файле содержатся те или иные сведения о процессе. Например, для того, чтобы посмотреть сведения о параметрах командной строки, с которыми был запущен процесс init , достаточно просмотреть содержимое файла cmdline с помощью команды cat .

В /proc есть и другие интересные файлы. Например, cpuinfo , содержащий сведения о типе и производительности центрального процессора, pci , из которого можно получить информацию об устройствах на шине PCI и modules , в котором находится список загруженных в ядро модулей.

Листинг 1. Интерактивный обзор файловой системы /proc

В листинге 2 показаны чтение и запись параметров ядра в виртуальный файл, находящийся в /proc. Приведенный пример кода отображает значение параметра, управляющего режимом «IP forwarding» стека TCP/IP ядра и затем включает его.

Листинг 2. Чтение и запись /proc (конфигурирование ядра)

Другим способом изменения параметров конфигурации ядра является использование команды sysctl . Подробнее про эту команду можно прочитать в материалах раздела Ресурсы.

На самом деле, /proc — не единственная виртуальная файловая система в ОС GNU/Linux. Аналогичная файловая система sysfs имеет сходные функциональные возможности и немного более удачную структуру (при ее разработке был учтен опыт /proc). Тем не менее /proc является де-факто стандартом и, несмотря на то, что sysfs имеет некоторые преимущества, будет и впредь оставаться таковым. Можно упомянуть еще одну виртуальную файловую систему — debugfs, которая (как следует из ее названия), представляет собой скорее отладочный интерфейс. Ее преимуществом является простота, с которой происходит экспорт значения из ядра в пользовательское пространство (фактически, это требует единственного системного вызова).

Знакомство с модулями ядра

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

Если вам приходилось вручную собирать ядро Linux, вы, вероятно, обращали внимание на то, что многие драйверы устройств и другие компоненты ядра компилируются в виде модулей. Если драйвер скомпилирован как часть ядра, его код и статические данные занимают память даже тогда, когда он не используется. Но если скомпилировать драйвер как модуль, он будет занимать память только если он действительно необходим и загружен в ядро. Удивительно, но заметной потери производительности при использовании LKM не происходит. Это делает загружаемые модули незаменимым средством при сборке ядра с низкими требованиями к объему памяти и возможностью использования не только штатного набора оборудования, но и подключаемых устройств.

Сравним код простого загружаемого модуля, приведенный в листинге 3 и обычный код ядра (не загружаемый динамически). В листинге 3 приведен код простейшего загружаемого модуля. (Ниже, в разделе Загрузка, вы можете загрузить исходные коды всех примеров, приведенных в статье.

Код в листинге 3 начинается с обязательного заголовка (описывающего интерфейс модуля, типы и макросы). Затем, с помощью макроса MODULE_LICENSE , указывается тип лицензии, под которой распространяется модуль. В данном примере мы используем лицензию GPL, чтобы не получать предупреждений о «заражении» ядра проприетарным кодом.

Далее в листинге 3 следует определение функций модуля init и cleanup . Функция my_module_init вызывается при загрузке модуля и поэтому может использоваться для инициализации. Другая функция, my_module_cleanup , вызывается в момент выгрузки модуля. В ней происходит освобождение памяти и ликвидация следов пребывания модуля в ядре. Обратите внимание на то, что мы используем функцию printk : это аналог printf для ядра. С помощью макроса KERN_INFO можно записать в кольцевой буфер ядра произвольную строку (аналогично функции syslog ).

Функции, вызываемые при загрузке и выгрузке модуля, задаются в заключительных строках листинга с помощью макросов module_init and module_exit . Такой способ определения вспомогательных функций init and cleanup позволяет называть их как угодно. Достаточно лишь сообщить их имена ядру.

Листинг 3. Простой, но работоспособный загружаемый модуль (simple-lkm.c)

В листинге 3 приведен код простого, но работоспособного загружаемого модуля. Теперь мы соберем его и протестируем на ядре версии 2.6. Начиная с этой версии, в ядре появилась поддержка нового метода сборки модулей ядра, который, на мой взгляд, проще, чем методы, использовавшиеся ранее. Чтобы им воспользоваться, необходимо, помимо файла simple-lkm.c , создать make-файл, содержащий единственную строку, приведенную ниже:

Для сборки модуля, выполните команду make , как показано в листинге 4.

Листинг 4. Сборка модуля

После сборки должен появиться файл simple-lkm.ko . Новый способ именования позволяет легко отличать модули ядра от обыкновенных объектов. Теперь, когда модуль готов, можно его загрузить, затем выгрузить и посмотреть на выведенные при этом сообщения. Чтобы загрузить модуль, выполните команду insmod ; для выгрузки выполните команду rmmod . Команда lsmod выводит список модулей, загруженных в данный момент (см. листинг 5).

Листинг 5. Загрузка, проверка загрузки и выгрузка модуля

Следует учесть, что сообщения, генерируемые кодом ядра, выводятся в кольцевой буфер ядра, а не в stdout , поскольку последний привязан к конкретному процессу. Для просмотра сообщений в кольцевом буфере ядра, вы можете воспользоваться командой dmesg (или просмотреть сообщения в самой файловой системе /proc с помощью команды cat /proc/kmsg ). В листинге 6 приведены несколько последних сообщений, выведенных по команде dmesg .

Листинг 6. Сообщения, сгенерированные тестовым модулем

Сообщения, выведенные тестовым модулем, видны в общем потоке сообщений ядра. А теперь предлагаю перейти от нашего простого примера к интерфейсам ядра, позволяющим разрабатывать загружаемые модули.

Интеграция с файловой системой /proc

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

Создание и удаление виртуального файла в /proc

Для того, чтобы создать виртуальный файл в файловой системе /proc, используется функция create_proc_entry . Эта функция принимает в качестве параметров имя создаваемого файла, режим доступа к нему и один из подкаталогов /proc для его размещения. Функция create_proc_entry возвращает указатель на структуру proc_dir_entry (или NULL в случае возникновения ошибки). Полученный указатель можно использовать для настройки остальных параметров виртуального файла, таких, как функция, вызываемая при чтении из файла. Прототип функции create_proc_entry и фрагмент структуры proc_dir_entry показаны в листинге 7.

Листинг 7. Элементы интерфейсов управления виртуальными файлами /proc

Чуть позже вы узнаете, как использовать команды read_proc and write_proc для задания функций чтения и записи виртуального файла.

Для удаления файла из /proc, используйте функцию remove_proc_entry . При вызове в эту функцию передается строка, содержащая имя удаляемого файла и его местонахождение в файловой системе /proc (родительский каталог). Прототип этой функции приведен в листинге 7.

Параметр parent принимает значение NULL если файл находится непосредственно в каталоге /proc или другое значение, соответствующее каталогу, в который вы хотите поместить файл. В таблице 1 приведена часть предопределенных переменных proc_dir_entry , передаваемых как значение параметра parent, и соответствующих им каталогов файловой системы /proc.

Таблица 1. Список предопределенных переменных proc_dir_entry
Переменная proc_dir_entry Каталог
proc_root_fs /proc
proc_net /proc/net
proc_bus /proc/bus
proc_root_driver /proc/driver

Callback-функция записи

Вы можете записывать данные в виртуальный файл (из пользовательского пространства в ядро) с помощью функции write_proc . Эта функция имеет прототип следующего вида:

Параметр filp представляет собой структуру, соответствующую открытому файлу устройства (нам он не понадобится). Параметр buff соответствует строке, передаваемой в модуль. Поскольку буфер, в котором находится строка находится в пользовательском пространстве, к нему нельзя будет получить непосредственный доступ из модуля. Параметр len содержит количество подлежащих записи байт, находящихся в buff . Параметр data содержит указатель на локальные данные (см. листинг 7). В нашем тестовом модуле сallback-функция записи служит для обработки входящих данных.

В Linux предусмотрен набор API для перемещения данных между пользовательским пространством и пространством ядра. Для операций с данными, находящимися в пользовательском пространстве, в функции write_proc из нашего примера, используется семейство функций copy_from_user .

Callback-функция чтения

Вы можете считать данные из виртуального файла (из ядра в пользовательское пространство) с помощью функции read_proc . Ее прототип выглядит так:

Параметр page содержит указатель на буфер, в который будут записаны данные, полученные из ядра, при этом параметр count определяет максимальное число символов, которое может быть записано в данный буфер. Если планируется получить более одной страницы данных (обычно, 4KB), следует использовать параметры start и off . После того, как все данные получены, установите признак eof (конец файла). По аналогии с кодом функции write , параметр data соответствует локальным данным. Буфер page , используемый в данной функции располагается в пространстве ядра. Следовательно, для записи в него не требуется вызов функции copy_to_user .

Другие полезные функции

Кроме обыкновенных файлов, в файловой системе /proc можно создавать каталоги, используя функцию proc_mkdir и символьные ссылки ( symlinks ), используя proc_symlink . Файлы /proc, для которых определена только операция чтения (функция read ), можно создать единственным вызовом функции create_proc_read_entry , создающей файл и задающей для него функцию read_proc . Прототипы вышеупомянутых функций показаны в листинге 8.

Листинг 8. Прочие полезные функции для работы с /proc

Выдача ‘фортунок’ с помощью файловой системы /proc

В этом примере мы создадим загружаемый модуль ядра с поддержкой операций чтения и записи. Это простое приложение будет по запросу выдавать изречения-‘фортунки’. После загрузки модуля, пользователь сможет записать в него текст ‘фортунок’ с помощью команды echo и затем считывать их по одной в случайном порядке, используя команду cat .

Исходный код данного модуля приведен в листинге 9. Init -функция ( init_fortune_module ) выделяет блок памяти для хранения ‘фортунок’ вызовом vmalloc и затем заполняет его нулями с помощью memset . После того, как cookie_pot создан и обнулен, в каталоге /proc создается виртуальный файл (тип proc_dir_entry ) с именем fortune. После того, как файл ( proc_entry ) успешно создан, происходит инициализация локальных переменных и структуры proc_entry . В соответствующие поля этой структуры записываются указатели на функции модуля read и write (см. листинги 9 и 10, а также информация о владельце модуля. Функция cleanup удаляет файл из файловой системы /proc и освобождает память, занимаемую cookie_pot .

Хранилище ‘фортунок’ cookie_pot занимает страницу памяти (4KB) и обслуживается двумя индексами. Первый из них, cookie_index , определяет адрес, по которому будет записана следующая ‘фортунка’. торой индекс — переменная next_fortune , содержит адрес ‘фортунки’, которая будет выдана по следующему запросу. После того как выдана последняя ‘фортунка’, переменной next_fortune присваивается адрес первого элемента и выдача начинается сначала.

Листинг 9. Функции init/cleanup и переменные модуля.

Записать ‘фортунку’ в хранилище очень просто (см. листинг 10). Зная длину записываемой ‘фортунки’, можно определить, достаточно ли места для ее размещения. Если места недостаточно, модуль возвратит пользовательскому процессу код -ENOSPC . В противном случае строка копируется в cookie_pot с помощью функции copy_from_user . После этого происходит увеличение значения переменной cookie_index (на величину, зависящую от длины полученной строки), в конец строки дописывается NULL. Алгоритм завершает свою работу тем, что возвращает пользовательскому процессу количество символов фактически записанных в cookie_pot .

Листинг 10. Функция записи ‘фортунки’

Чтение ‘фортунки’ нисколько не сложнее ее записи. Поскольку буфер, в который нужно произвести запись ‘фортунки’ ( page ), уже находится в пользовательском пространстве, для вывода фортунки можно использовать непосредственно функцию sprintf . Если значение индекса next_fortune превышает значение cookie_index (индекс следующего свободного для записи элемента), переменной next_fortune присваивается 0, то есть, индекс первого элемента. После того, как фортунка записана в буфер пользовательского процесса, я увеличиваю индекс next_fortune на ее длину. Теперь этот индекс содержит адрес ‘фортунки’, которая будет выдана следующей . Длина ‘фортунки’ также передается пользовательскому процессу в качестве возвращаемого значения.

Листинг 11. Функция чтения ‘фортунки’

Это простой пример показывает что обмен данными между ядром и пользовательским процессом является тривиальной задачей. А сейчас предлагаю посмотреть на модуль выдачи ‘фортунок’ в действии (листинг 12).

Листинг 12. Загружаемый модуль выдачи ‘фортунок’ в действии

Виртуальная файловая система /proc широко используется как средство сбора информации о состоянии ядра и для его динамического конфигурирования. Она незаменима для разработки драйверов и модулей ядра, в чем несложно убедиться. Узнать о /proc больше вам помогут материалы раздела Ресурсы в конце статьи.

Ресурсы для скачивания

Похожие темы

  • Оригинал статьи Access the Linux kernel using the /proc filesystem (EN).
  • «Статья «Administer Linux on the fly» (EN) (developerWorks, май 2003 г.) содержит исчерпывающие сведения по основам администрирования операционной системы с помощью /proc, включая советы по изменению различных настроек без перезагрузки компьютера.
  • Узнайте больше о файлах и каталогах (EN) файловой системы /proc.
  • Детальное обсуждение модулей ядра можно найти в статье о переносе драйверов (EN) на ядро Linux версии 2.6.
  • Сайт LinuxHQ (EN) — отличный источник информации о ядре Linux.
  • Файловая система debugfs — альтернатива /proc, ориентированная на отладку.
  • Статья «Kernel comparison: Improvements in kernel development from 2.4 to 2.6» (EN) (developerWorks, февраль 2004 г.) позволит взглянуть на инструменты, тесты и методы в использовании которых заключается процесс создания ядра 2.6.
  • «Статья Kernel debugging with Kprobes» (EN) (developerWorks, август 2004 г.) рассказывает об использовании ядра версии 2.6 совместно с мощным и, в то же время, простым и незаметным инструментом Kprobes для динамического добавления вызовов функции printk .
  • Распространенными инструментами отладки ядра являются функция printk и команда dmesg . В этой главе (EN) книги Алессандро Рубини Linux Device Drivers рассказывается о методах отладки ядра.
  • Еще одним способом динамического конфигурирования ядра является использование команды sysctl.
  • На сайте kernel.org можно найти последнюю версию ядра Linux.
  • Документация по утилите GNU make находится на сайте gnu.org.
  • В пакет Modutils входят утилиты для работы с модулями ядра.
  • В разделе Linux сайта developerWorks можно найти другие материалы для Linux-разработчиков.
  • Начните ваш следующий проект для Linux с ознакомительными версиями ПО IBM, загрузить которые можно непосредственно с сайта developerWorks.

Комментарии

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

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

  • Файловая система embedded linux
  • Файловая система btrfs linux
  • Файл сервер linux с контролем доступа
  • Файл с пользователями linux
  • Файл менеджер для linux