Что произойдет, если я запущу команду cat /proc/cpuinfo?

Что произойдет, если я запущу команду cat /proc/cpuinfo?

Что происходит, когда я пишу 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.

Первая и вторая точки входа для получения документации по /procLinux:

  1. the proc(5)страница руководства;
  2. Файловая /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.

забег №1
$ 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) — яркий пример использования файлов в качестве общего интерфейса программирования.

Связанный контент