![Что произойдет, если я запущу команду cat /proc/cpuinfo?](https://rvso.com/image/52103/%D0%A7%D1%82%D0%BE%20%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%BE%D0%B9%D0%B4%D0%B5%D1%82%2C%20%D0%B5%D1%81%D0%BB%D0%B8%20%D1%8F%20%D0%B7%D0%B0%D0%BF%D1%83%D1%89%D1%83%20%D0%BA%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D1%83%20cat%20%2Fproc%2Fcpuinfo%3F.png)
Что происходит, когда я пишу cat /proc/cpuinfo
. Это именованный канал (или что-то еще) для ОС, который считывает информацию о ЦП на лету и генерирует этот текст каждый раз, когда я его вызываю?
решение1
Всякий раз, когда вы читаете файл в /proc
, это вызывает некоторый код в ядре, который вычисляет текст для чтения в качестве содержимого файла. Тот факт, что содержимое генерируется на лету, объясняет, почему почти все файлы имеют свое время, сообщаемое как текущее, а их размер, сообщаемый как 0 — здесь вы должны читать 0 как «не знаю». В отличие от обычных файловых систем, файловая система, которая смонтирована в /proc
, которая называетсяprocfs, не загружает данные с диска или другого носителя информации (например, FAT, ext2, zfs, …) или по сети (например, NFS, Samba, …) и не вызывает пользовательский код (в отличие отПРЕДОХРАНИТЕЛЬ).
Procfs присутствует в большинстве не-BSD юниксов. Он начал свою жизнь в Bell Labs компании AT&T вUNIX 8-е изданиекак способ сообщать информацию о процессах (и ps
часто является красивым принтером для чтения информации /proc
). Большинство реализаций procfs имеют файл или каталог, называемый /proc/123
для сообщения информации о процессе с PID 123. Linux расширяет файловую систему proc многими другими записями, которые сообщают о состоянии системы, включая ваш пример /proc/cpuinfo
.
В прошлом Linux /proc
имел различные файлы, содержащие информацию о драйверах, но теперь их использование устарело в пользу/sys
, и /proc
теперь медленно развивается. Записи вроде /proc/bus
и /proc/fs/ext4
остаются там, где они есть, для обратной совместимости, но более новые похожие интерфейсы создаются под /sys
. В этом ответе я сосредоточусь на Linux.
Первая и вторая точки входа для получения документации по /proc
Linux:
- the
proc(5)
страница руководства; - Файловая
/proc
системавдокументация ядра.
Третья точка входа, если документация ее не охватывает, — эточтение источника. Вы можете загрузить исходный код на свой компьютер, но это огромная программа, иЛХР, перекрестная ссылка 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
и друзья.
решение2
Когда вы пытаетесь получить представление о том, какая магия происходит за кулисами, ваш лучший друг — 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
это просто обычный файл, или, по крайней мере, он может таковым казаться. Так что давайте копнем глубже.
Более глубокое погружение
#1- с лс..Если взглянуть на сам файл, то может показаться, что это «просто файл».
$ 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. (Обычный выбор none менее удачен: сообщение об ошибке `none busy' от umount может сбивать с толку.)
А если мы посмотрим на proc
страницу руководства:
Файловая система proc — это псевдофайловая система, которая используется как интерфейс к структурам данных ядра. Обычно она монтируется в /proc. Большая ее часть доступна только для чтения, но некоторые файлы позволяют изменять переменные ядра.
Чуть ниже на той же странице руководства:
/proc/cpuinfo
Это набор элементов, зависящих от архитектуры ЦП и системы, для каждой поддерживаемой архитектуры свой список. Две общие записи — процессор, который указывает номер ЦП, и bogomips; системная константа, которая вычисляется во время инициализации ядра. SMP-машины имеют информацию для каждого ЦП. Команда lscpu(1) собирает информацию из этого файла.
В нижней части страницы руководства находится ссылка на документ ядра, который вы можете найти здесь, под названием:ФАЙЛОВАЯ СИСТЕМА /proc. Цитата из этого документа:
Файловая система proc действует как интерфейс к внутренним структурам данных в ядре. Она может использоваться для получения информации о системе и для изменения определенных параметров ядра во время выполнения (sysctl).
Выводы
Итак, что мы узнали здесь? Ну, учитывая, что это /proc
называется псевдофайловой системой, а также «интерфейсом к внутренним структурам данных», можно с уверенностью предположить, что элементы внутри неенетнастоящие файлы, а скорее просто проявления, выглядящие как файлы, но на самом деле таковыми не являющиеся.
Я закончу цитатой, которая, судя по всему, была в предыдущей версии, датируемой man 5 proc
примерно 2004 годом, но по какой-то причине больше не включена.ПРИМЕЧАНИЕ:Я не уверен, почему его удалили, так как он очень хорошо описывает то, что /proc
есть:
Каталог /proc в системах GNU/Linux предоставляет интерфейс для ядра, подобный файловой системе. Это позволяет приложениям и пользователям извлекать информацию и устанавливать значения в ядре, используя обычные операции ввода-вывода файловой системы.
Файловую систему proc иногда называют псевдофайловой системой информации о процессе. Она не содержит ``реальных'' файлов, а содержит системную информацию о времени выполнения (например, системную память, смонтированные устройства, конфигурацию оборудования и т. д.). По этой причине ее можно рассматривать как центр управления и информации для ядра. Фактически, довольно много системных утилит являются просто вызовами файлов в этом каталоге. Например, команда lsmod, которая выводит список модулей, загруженных ядром, в основном такая же, как 'cat /proc/modules', а lspci, которая выводит список устройств, подключенных к шине PCI системы, такая же, как 'cat /proc/pci'. Изменяя файлы, расположенные в этом каталоге, вы можете изменять параметры ядра во время работы системы.
Источник: Псевдофайловая система proc
Рекомендации
решение3
Ответ, данный @slm, весьма исчерпывающий, но я думаю, что более простое объяснение можно получить, изменив точку зрения.
В повседневном использовании мы можем думать о файлах как о физических вещах, т. е. о фрагментах данных, хранящихся на каком-то устройстве. Это делает файлы типа /proc/cpuinfo очень загадочными и запутанными. Однако все это имеет смысл, если мы думаем о файлах как оинтерфейс; способ отправки данных в некоторую программу и из нее.
Программы, которые отправляют и получают данные таким образом, являются файловыми системами или драйверами (в зависимости от того, как вы определяете эти термины, это может быть слишком широким или слишком узким определением). Важный момент заключается в том, чтонекоторыйиз этих программ используют аппаратное устройство для хранения и извлечения данных, отправленных через этот интерфейс; но не все.
Некоторые примеры файловых систем, которыенеиспользуют запоминающее устройство (по крайней мере, напрямую):
- Файловые системы, использующие просмотренные или вычисленные данные. Proc является примером, поскольку он получает данные из различных модулей ядра. Крайний пример — πfs ( github.com/philipl/pifs )
- Все файловые системы FUSE, которые обрабатывают данные с помощью обычной программы пользовательского пространства
- Файловые системы, которые преобразуют данные другой файловой системы «на лету», например, используя шифрование, сжатие или даже перекодирование звука ( khenriks.github.io/mp3fs/ )
Операционная система Plan9 (http://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs) — яркий пример использования файлов в качестве общего интерфейса программирования.