Що відбувається, коли я запускаю команду cat / proc / cpuinfo?


86

Що відбувається, коли я пишу cat /proc/cpuinfo. Це іменована труба (чи щось інше) в ОС, яка читає інформацію про процесор на льоту і генерує цей текст щоразу, коли я його закликаю?


Відповіді:


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

Це колекція елементів, залежних від процесора та системної архітектури, для кожної підтримуваної архітектури є інший список. Дві загальні записи - це процесор, який дає номер CPU та bogomips; системна константа, яка обчислюється під час ініціалізації ядра. Машини SMP мають інформацію для кожного процесора. Команда lscpu (1) збирає свою інформацію з цього файлу.

Внизу сторінки man є посилання на документ ядра, який ви можете знайти тут, з назвою: THE / proc FILESYSTEM . Цитуючи цей документ:

Файлова система proc діє як інтерфейс до внутрішніх структур даних у ядрі. Він може використовуватися для отримання інформації про систему та для зміни певних параметрів ядра під час виконання (sysctl).

Висновки

То що ми тут дізналися? Зважаючи на те, що /procце називається псевдофайловою системою, а також "інтерфейсом до внутрішніх структур даних", можливо, можна припустити, що елементи в ній не є фактичними файлами, а скоріше просто проявами, схожими на файли, але насправді це не так.

Я закінчу цю цитату, яка, мабуть, була в попередній версії man 5 procприблизно з 2004 року, але з будь-якої причини більше не включається. ПРИМІТКА. Я не впевнений, чому його видалено, оскільки він дуже добре описує, що /procтаке:

Каталог / proc в системах GNU / Linux забезпечує файлову систему, як інтерфейс до ядра. Це дозволяє програмам та користувачам отримувати інформацію з ядра та встановлювати значення в ядрі, використовуючи звичайні операції вводу / виводу файлової системи.

Файлову систему proc іноді називають псевдофайловою системою інформації про процес. Він не містить `` реальних '' файлів, а швидше системну інформацію (наприклад, системну пам'ять, встановлені пристрої, конфігурацію обладнання тощо). З цієї причини його можна розглядати як центр контролю та інформації для ядра. Насправді досить багато системних утиліт - це просто дзвінки до файлів у цьому каталозі. Наприклад, команда lsmod, яка перелічує модулі, завантажені ядром, в основному є такою ж, як 'cat / proc / module', тоді як lspci, який перераховує пристрої, підключені до шини PCI системи, такий же як 'cat / proc / pci '. Змінюючи файли, розташовані в цьому каталозі, ви можете змінювати параметри ядра під час роботи системи.

Джерело: Файлова система Pro псевдо

Список літератури


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, див:
Стівен Д,


1
@slm: +1, чудова відповідь. Але для мене, перша підказка, що це спеціальний файл - його розмір ^^ 0 байт, але ви можете вибирати з нього багато речей (трохи схожих на деякі файлові файли).
Олів'є Дулак

@OlivierDulac - хороший момент. Я вніс додаткові зміни на основі ваших відгуків. ЛМК, якщо я можу внести будь-які подальші вдосконалення. Дякую.
slm

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 ) є крайнім прикладом використання файлів як загального інтерфейсу програмування.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.