Что происходит, когда я запускаю команду cat / proc / cpuinfo?

86

Что происходит, когда я пишу cat /proc/cpuinfo. Это именованный канал (или что-то еще) к ОС, которая на лету читает информацию о процессоре и генерирует этот текст каждый раз, когда я его вызываю?

SLM
источник

Ответы:

72

Всякий раз, когда вы читаете файл в /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.

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

  1. proc(5)страница людей ;
  2. /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и друзей.

жилль
источник
59

Когда вы пытаетесь понять, какая магия происходит за кулисами, ваш лучший друг 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, вместо спецификации устройства. (Обычный выбор не менее удачен: сообщение об ошибке «не занят» от 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

Рекомендации

SLM
источник
1
Круто, :) это первое, что я попробовал, когда увидел вопрос:strace -o catcpuproc.txt cat /proc/cpuinfo
mkc
1
Хороший ответ! В Linux, если вы хотите копать глубже, исходный код для файловой системы proc находится в fs / proc в исходном коде ядра. Вы увидите, что существует файл fs / proc / cpuinfo.c, но, к сожалению, он довольно пустой, так как тяжелые работы распределены по всей арке /, поскольку зависят от архитектуры. Для более простого примера смотрите fs / proc / uptime.c. Взглянув на файл, мы можем догадаться, что uptime_proc_show является рабочей лошадкой того, что дает нам нужные нам данные, и мы могли бы исследовать их больше, углубившись в вызываемые им функции. Чтобы понять интерфейс seq_file и то, как он используется в procfs, смотрите:
Steven D
1
@slm: +1, отличный ответ. Но для меня первый намек на то, что это специальный файл, это его размер ^^ 0 байт, но вы можете от него многое узнать (немного похоже на некоторые трубочные файлы).
Оливье Дюлак
@OlivierDulac - хорошая мысль. Я сделал дополнительные изменения на основе ваших отзывов. ЛМК, если я могу сделать какие-либо дальнейшие улучшения. Благодарю.
СЛМ
14

Ответ, данный @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 ) является ярким примером использования файлов в качестве общего интерфейса программирования.

Warbo
источник