Ответы:
Всякий раз, когда вы читаете файл в /proc
, это вызывает некоторый код в ядре, который вычисляет текст для чтения в качестве содержимого файла. Тот факт, что контент генерируется на лету, объясняет, почему почти все файлы имеют свое время, указанное как сейчас, и их размер, равный 0 - здесь вы должны прочитать 0 как «не знаю». В отличие от обычных файловых систем, смонтированная файловая система /proc
, которая называется procfs , не загружает данные с диска или другого носителя (например, FAT, ext2, zfs,…) или по сети (например, NFS, Samba,…) и не вызывает код пользователя (в отличие от FUSE ).
Procfs присутствует в большинстве не-BSD устройств. Он начал свою жизнь в Bell Labs AT & T в 8-м выпуске UNIX как способ сообщать информацию о процессах (и ps
часто является симпатичным принтером для считывания информации /proc
). Большинство реализаций procfs имеют файл или каталог, вызываемые /proc/123
для сообщения информации о процессе с помощью PID 123. Linux расширяет файловую систему proc гораздо большим количеством записей, сообщающих о состоянии системы, включая ваш пример /proc/cpuinfo
.
В прошлом Linux /proc
приобретал различные файлы, которые предоставляют информацию о драйверах, но в настоящее время это использование устарело /sys
, а /proc
сейчас развивается медленно. Записи любят /proc/bus
и /proc/fs/ext4
остаются там, где они есть для обратной совместимости, но более новые подобные интерфейсы создаются в /sys
. В этом ответе я сосредоточусь на Linux.
Ваша первая и вторая точка входа для документации о /proc
Linux:
proc(5)
страница людей ;/proc
Файловая система в документации к ядру .Ваша третья точка входа, когда документация не покрывает это, читает источник . Вы можете скачать исходный код на своем компьютере, но это огромная программа, и LXR , перекрестная ссылка Linux, очень помогает. (Существует много вариантов LXR; один из них работает lxr.linux.no
лучше всех, но, к сожалению, сайт часто не работает.) Требуются небольшие знания C, но вам не нужно быть программистом, чтобы отследить таинственную ценность. ,
Основная обработка /proc
записей находится в fs/proc
каталоге. Любой драйвер может зарегистрировать записи в /proc
(хотя, как указано выше, это устарело в пользу /sys
), поэтому, если вы не можете найти то, что ищете fs/proc
, ищите везде. Драйверы вызывают функции, объявленные в include/linux/proc_fs.h
. Версии ядра до 3.9 предоставляют функции create_proc_entry
и некоторые оболочки (особенно create_proc_read_entry
), а версии ядра 3.10 и выше предоставляют только вместо них proc_create
и proc_create_data
(и еще несколько).
В /proc/cpuinfo
качестве примера, поиск "cpuinfo"
приводит вас к звонку proc_create("cpuinfo, …")
в fs/proc/cpuinfo.c
. Вы можете видеть, что код в значительной степени является стандартным кодом: поскольку большинство файлов /proc
просто сбрасывают некоторые текстовые данные, для этого есть вспомогательные функции. Существует просто seq_operations
структура, и реальный смысл находится в cpuinfo_op
структуре данных, которая зависит от архитектуры, обычно определяется в arch/<architecture>/kernel/setup.c
(или иногда в другом файле). Взяв x86 в качестве примера, мы привели к arch/x86/kernel/cpu/proc.c
. Там основная функцияshow_cpuinfo
, который распечатывает желаемый файл содержимого; остальная часть инфраструктуры предназначена для подачи данных в процесс чтения со скоростью, которую они запрашивают. Вы можете видеть, как данные собираются на лету из данных различных переменных в ядре, включая несколько чисел, вычисленных на лету, таких как частота процессора .
Большая часть информации о /proc
процессах в /proc/<PID>
. Эти записи зарегистрированы fs/proc/base.c
в tgid_base_stuff
массиве ; некоторые функции, зарегистрированные здесь, определены в других файлах. Давайте рассмотрим несколько примеров того, как генерируются эти записи:
cmdline
генерируется proc_pid_cmdline
в том же файле. Он находит данные в процессе и распечатывает их.clear_refs
в отличие от записей, которые мы видели до сих пор, доступен для записи, но не для чтения. Следовательно, proc_clear_refs_operations
структура определяет clear_refs_write
функцию, но не функцию чтения.cwd
является символической ссылкой (слегка магической), объявленной посредством proc_cwd_link
, которая ищет текущий каталог процесса и возвращает его в качестве содержимого ссылки.fd
это подкаталог. Операции над самим каталогом определены в proc_fd_operations
структуре данных (они являются шаблонными, за исключением функции, которая перечисляет записи proc_readfd
, которая перечисляет открытые файлы процесса), в то время как операции над записями находятся в `proc_fd_inode_operations .Другая важная область /proc
есть /proc/sys
, что является прямым интерфейсом к sysctl
. Чтение из записи в этой иерархии возвращает значение соответствующего значения sysctl, а запись устанавливает значение sysctl. Точки входа для sysctl находятся в fs/proc/proc_sysctl.c
. У Sysctls есть своя собственная система регистрации register_sysctl
и друзей.
Когда вы пытаетесь понять, какая магия происходит за кулисами, ваш лучший друг strace
. Научиться работать с этим инструментом - одна из лучших вещей, которую вы можете сделать, чтобы лучше понять, какая безумная магия происходит за кулисами.
$ strace -s 200 -m strace.log cat /proc/cpuinfo
...
read(3, "processor\t: 0\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 37\nmodel name\t: Intel(R) Core(TM) i5 CPU M 560 @ 2.67GHz\nstepping\t: 5\nmicrocode\t: 0x4\ncpu MHz\t\t: 1199.000\ncache size\t: 3072 KB\nphy"..., 65536) = 3464
write(1, "processor\t: 0\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 37\nmodel name\t: Intel(R) Core(TM) i5 CPU M 560 @ 2.67GHz\nstepping\t: 5\nmicrocode\t: 0x4\ncpu MHz\t\t: 1199.000\ncache size\t: 3072 KB\nphy"..., 3464) = 3464
read(3, "", 65536) = 0
close(3) = 0
...
Из вышеприведенного вывода вы можете видеть, /proc/cpuinfo
что это обычный файл или, по крайней мере, один из них. Так что давайте копать глубже.
Глядя на сам файл, он выглядит как «просто файл».
$ ls -l /proc/cpuinfo
-r--r--r--. 1 root root 0 Mar 26 22:45 /proc/cpuinfo
Но присмотритесь. Мы получаем первый намек на то, что он особенный, обратите внимание, что размер файла составляет 0 байт.
№ 2 - со стат ..Если мы теперь посмотрим на файл с помощью, stat
мы можем получить следующий намек, что есть что-то особенное /proc/cpuinfo
.
$ stat /proc/cpuinfo
File: ‘/proc/cpuinfo’
Size: 0 Blocks: 0 IO Block: 1024 regular empty file
Device: 3h/3dInode: 4026532023 Links: 1
Access: (0444/-r--r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Context: system_u:object_r:proc_t:s0
Access: 2014-03-26 22:46:18.390753719 -0400
Modify: 2014-03-26 22:46:18.390753719 -0400
Change: 2014-03-26 22:46:18.390753719 -0400
Birth: -
пробег № 2
$ stat /proc/cpuinfo
File: ‘/proc/cpuinfo’
Size: 0 Blocks: 0 IO Block: 1024 regular empty file
Device: 3h/3dInode: 4026532023 Links: 1
Access: (0444/-r--r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Context: system_u:object_r:proc_t:s0
Access: 2014-03-26 22:46:19.945753704 -0400
Modify: 2014-03-26 22:46:19.945753704 -0400
Change: 2014-03-26 22:46:19.945753704 -0400
Birth: -
Заметили время доступа, изменения и изменения? Они постоянно меняются для каждого доступа. Это очень необычно, что все 3 изменились бы так. Если атрибуты метки времени файла не редактируются, они обычно не изменяются.
№ 3 - с файлом ..Еще один признак того, что этот файл не является обычным файлом:
$ file /proc/cpuinfo
/proc/cpuinfo: empty
Если бы это было какое-то проявление именованного канала, показывалось бы подобное одному из этих файлов:
$ ls -l /dev/initctl /dev/zero
prw-------. 1 root root 0 Mar 26 20:09 /dev/initctl
crw-rw-rw-. 1 root root 1, 5 Mar 27 00:39 /dev/zero
$ file /dev/initctl /dev/zero
/dev/initctl: fifo (named pipe)
/dev/zero: character special
Если мы коснемся emptyfile
, /proc/cpuinfo
кажется, что он больше похож на файл, чем на канал:
$ touch emptyfile
$ ls -l emptyfile
-rw-rw-r--. 1 saml saml 0 Mar 27 07:40 emptyfile
$ file emptyfile
emptyfile: empty
№ 4 - с креплением ..
Поэтому на данный момент нам нужно сделать шаг назад и немного уменьшить масштаб. Мы смотрим на конкретный файл, но, возможно, нам стоит посмотреть на файловую систему, в которой находится этот файл. И для этого мы можем использовать mount
команду.
$ mount | grep " /proc "
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
Итак, тип файловой системы имеет тип proc
. Так /proc
что это другой тип файловой системы, это наш намек на то, что файлы /proc
являются специальными. Это не просто ваши файлы мельниц. Итак, давайте узнаем больше информации о том, что делает proc
файловую систему особенной.
Взгляните на mount
справочную страницу:
Файловая система proc не связана со специальным устройством, и при монтировании его можно использовать произвольное ключевое слово, такое как proc, вместо спецификации устройства. (Обычный выбор не менее удачен: сообщение об ошибке «не занят» от umount может сбить с толку.)
И если мы посмотрим на proc
справочную страницу:
Файловая система proc - это псевдо-файловая система, которая используется в качестве интерфейса для структур данных ядра. Обычно он монтируется в / proc. Большинство из них доступно только для чтения, но некоторые файлы позволяют изменять переменные ядра.
Чуть дальше на той же странице руководства:
/ Proc / CPUInfo
Это набор элементов, зависящих от ЦП и архитектуры системы, для каждой поддерживаемой архитектуры свой список. Две общие записи - это процессор, который дает номер процессора и bogomips; системная константа, которая вычисляется во время инициализации ядра. Машины SMP имеют информацию для каждого процессора. Команда lscpu (1) собирает информацию из этого файла.
Внизу справочной страницы находится ссылка на документ ядра, который вы можете найти здесь: THE / proc FILESYSTEM . Цитата из этого документа:
Файловая система proc действует как интерфейс для внутренних структур данных в ядре. Его можно использовать для получения информации о системе и для изменения определенных параметров ядра во время выполнения (sysctl).
Итак, что мы узнали здесь? Хорошо, учитывая, что /proc
это называется псевдофайловой системой, а также «интерфейсом к внутренним структурам данных», вероятно, можно с уверенностью предположить, что элементы внутри нее не являются реальными файлами, а скорее являются лишь проявлениями, которые выглядят как файлы, но на самом деле это не так.
Я закончу с этой цитатой, которая, очевидно, была в предыдущей версии man 5 proc
примерно с 2004 года, но по какой-либо причине больше не включена. ПРИМЕЧАНИЕ: я не уверен, почему он был удален, так как он очень хорошо описывает, что /proc
это:
Каталог / proc в системах GNU / Linux предоставляет файловый интерфейс, подобный интерфейсу ядра. Это позволяет приложениям и пользователям извлекать информацию и устанавливать значения в ядре, используя обычную операцию ввода-вывода файловой системы.
Файловая система proc иногда называется псевдофайловой системой с информацией о процессе. Он не содержит «настоящих» файлов, а содержит информацию о системе во время выполнения (например, системную память, подключенные устройства, конфигурацию оборудования и т. Д.). По этой причине его можно рассматривать как центр управления и информации для ядра. На самом деле, довольно много системных утилит - это просто вызовы файлов в этом каталоге. Например, команда lsmod, которая перечисляет модули, загруженные ядром, в основном такая же, как «cat / proc / modules», тогда как lspci, которая перечисляет устройства, подключенные к шине PCI системы, такая же, как «cat / Proc / PCI. Изменяя файлы, расположенные в этом каталоге, вы можете изменять параметры ядра во время работы системы.
Источник: псевдо файловая система proc
strace -o catcpuproc.txt cat /proc/cpuinfo
Ответ, данный @slm, очень исчерпывающий, но я думаю, что более простое объяснение может прийти из-за изменения перспективы.
При повседневном использовании мы можем думать о файлах как о физических вещах, т.е. порции данных, хранящихся на каком-либо устройстве. Это делает файлы вроде / proc / cpuinfo очень загадочными и запутанными. Однако все это имеет смысл, если мы думаем о файлах как об интерфейсе ; способ отправки данных в и из какой-либо программы.
Программы, которые отправляют и получают данные таким способом, являются файловыми системами или драйверами (в зависимости от того, как вы определяете эти термины, определение может быть слишком широким или слишком узким). Важным моментом является то, что некоторые из этих программ используют аппаратное устройство для хранения и извлечения данных, отправленных через этот интерфейс; но не все.
Некоторые примеры файловых систем, которые не используют запоминающее устройство (по крайней мере, напрямую):
ОС Plan9 ( http://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs ) является ярким примером использования файлов в качестве общего интерфейса программирования.