Linux inside: what's /dev, /proc, /sys
Головна ідея: файл як інтерфейс до ядра
В Unix є принцип — «всe є файл». І Linux доводить цей принцип до логічного максимуму: навіть сам стан ядра, апаратура і запущені процеси — представлені у вигляді файлів.
Але є нюанс: ці файли не існують на диску. Вони генеруються ядром on-the-fly, прямо в момент коли ти їх читаєш. Відкрив файл — ядро виконало функцію і повернуло результат у вигляді тексту. Записав у файл — ядро застосувало зміну.
Це і є віртуальні файлові системи. Три головні з них: /dev, /proc і /sys.
/dev — файли-пристрої
Що це
/dev — це директорія де ядро Linux представляє фізичні і логічні пристрої у вигляді файлів. Хочеш читати з диска — відкрий /dev/sda. Хочеш генерувати нулі — читай з /dev/zero.
Типи файлів у /dev
В Linux є два типи device files:
Block devices (позначаються b в ls -la) — пристрої що передають дані блоками. Диски, розділи, USB-накопичувачі:
/dev/sda # перший SATA/SCSI диск
/dev/nvme0n1 # перший NVMe диск
/dev/sda1 # перший розділ на sda
Character devices (позначаються c) — пристрої що передають дані побайтово, потоком:
/dev/tty # поточний термінал
/dev/ttyS0 # перший serial port
/dev/input/mice # миша
Спеціальні файли які треба знати
/dev/null # «чорна діра» — все що пишеш туди зникає
/dev/zero # нескінченний потік нульових байт
/dev/random # криптографічно безпечні випадкові байти
/dev/urandom # те саме але non-blocking (не чекає entropy)
/dev/full # завжди повертає «диск повний» при записі (для тестів)
Практичний приклад — затерти диск нулями:
dd if=/dev/zero of=/dev/sdb bs=1M status=progress
Або перенаправити stderr в нікуди:
command 2>/dev/null
Хто керує /dev — демон udev
Файли в /dev не статичні. Коли ти підключаєш USB-флешку — файл /dev/sdb з’являється. Коли відключаєш — зникає. Хто це робить?
udev — userspace-демон (частина systemd), який слухає події від ядра і реагує на них. Детальніше про нього нижче.
/proc — вікно в середину ядра
Що це
/proc (procfs) — найстаріша з трьох. Виникла ще в Unix як інструмент для інтроспекції запущених процесів. Потім виросла в щось більше.
Вся ця директорія живе виключно в оперативній пам’яті. При перезавантаженні вміст зникає і генерується заново. Розмір на диску — нуль байт.
Директорії процесів
Для кожного запущеного процесу є своя директорія /proc/PID/:
ls /proc/1/ # процес з PID 1 (systemd)
# cmdline environ fd maps mem net ns status ...
Що там всередині:
cat /proc/1234/cmdline # команда з якою запущено процес
ls -la /proc/1234/fd/ # всі відкриті файлові дескриптори
cat /proc/1234/status # CPU, RAM, стан процесу
cat /proc/1234/maps # карта пам'яті процесу
ls /proc/1234/ns/ # namespace-и до яких належить процес
cat /proc/1234/environ # environ показує environment variables на момент запуску процесу
Системні файли — не тільки про процеси
З часом /proc перетворився на загальне місце для всього що ядро хоче показати назовні:
cat /proc/cpuinfo # детальна інфо про кожне ядро CPU
cat /proc/meminfo # стан оперативної пам'яті
cat /proc/loadavg # load average (те що показує top)
cat /proc/mounts # всі змонтовані файлові системи
cat /proc/net/dev # статистика мережевих інтерфейсів
cat /proc/interrupts # IRQ — які переривання і скільки разів
cat /proc/diskstats # I/O статистика дисків
/proc/sys — параметри ядра в реальному часі
Особлива піддиректорія. Файли тут читаються і записуються — це і є механізм sysctl:
# читаємо значення
cat /proc/sys/net/ipv4/ip_forward # → 0 або 1
# це ТОЧНО ТЕ САМЕ що:
sysctl net.ipv4.ip_forward
# записуємо (змінюємо поведінку ядра в реальному часі)
echo 1 > /proc/sys/net/ipv4/ip_forward
# або через sysctl
sysctl -w net.ipv4.ip_forward=1
sysctl — це просто зручна обгортка над читанням/записом файлів у /proc/sys/.
/sys — структурований інтерфейс до hardware
Чому з’явився sysfs
До появи /sys все лізло в /proc — і інфо про процеси, і про мережу, і про CPU, і про диски. Це ставало некерованим. Формати файлів були довільними, один файл міг містити 20 різних полів, треба було писати складний парсинг.
У Linux 2.6 (2003 рік) з’явився sysfs з чіткою концепцією:
Один файл = один атрибут. Крапка.
Структура sysfs
sysfs відображає реальну ієрархію об’єктів всередині ядра (так звані kobject):
/sys/
├── class/ # пристрої згруповані по класу
│ ├── net/ # мережеві інтерфейси
│ │ ├── eth0/
│ │ │ ├── speed → 1000
│ │ │ ├── mtu → 1500
│ │ │ ├── operstate → up
│ │ │ └── address → aa:bb:cc:dd:ee:ff
│ │ └── lo/
│ └── block/
├── block/ # блокові пристрої
│ └── sda/
│ └── queue/
│ └── scheduler → [mq-deadline] kyber bfq
├── devices/ # повне дерево всіх пристроїв
├── module/ # завантажені модулі ядра
└── kernel/ # параметри ядра
Практичні приклади
# стан мережевого інтерфейсу
cat /sys/class/net/eth0/operstate # up / down
# MTU
cat /sys/class/net/eth0/mtu # 1500
# швидкість лінка в Mbit/s
cat /sys/class/net/eth0/speed # 1000
# I/O scheduler диску (і змінити його)
cat /sys/block/sda/queue/scheduler
echo mq-deadline > /sys/block/sda/queue/scheduler
# NUMA топологія — скільки нод і які CPU до якої належать
cat /sys/devices/system/node/node0/cpulist
# вимкнути конкретне ядро CPU (обережно!)
echo 0 > /sys/devices/system/cpu/cpu3/online
# температура з thermal zone
cat /sys/class/thermal/thermal_zone0/temp # значення в мілліградусах
Все читається і пишеться без жодного парсингу — беруть значення і використовують.
udev — хто керує /dev
Загальна схема
Коли ти підключаєш новий пристрій, відбувається ось що:
Підключили USB-диск
↓
Ядро виявило новий пристрій → додало kobject у /sys/
↓
Ядро надіслало uevent через netlink socket
↓
udevd (демон) отримав подію
↓
udevd переглянув правила в /etc/udev/rules.d/ та /lib/udev/rules.d/
↓
Створив /dev/sdb, виставив права доступу, запустив скрипти
Ядро відповідає тільки за виявлення пристрою. Що з ним робити — вирішує udev у userspace. Це правильний поділ: механізм в ядрі, політика — зовні.
Правила udev
Правила зберігаються у файлах *.rules. Синтаксис — умова + дія:
# /etc/udev/rules.d/99-custom.rules
# Дати стабільне ім'я диску по серійному номеру
SUBSYSTEM=="block", ATTRS{serial}=="XYZ123", SYMLINK+="disk/my-backup"
# При підключенні USB Logitech — запустити скрипт
ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="046d", RUN+="/usr/local/bin/logitech-setup.sh"
# Виставити групу і права на відеопристрій
SUBSYSTEM=="video4linux", GROUP="video", MODE="0660"
Корисні команди udev
# Дивитися live-потік подій при підключенні пристроїв
udevadm monitor
# Всі атрибути конкретного пристрою (для написання rules)
udevadm info /dev/sda
udevadm info --attribute-walk /dev/sda # повне дерево атрибутів
# Перевірити які правила спрацюють для пристрою (dry-run)
udevadm test /sys/class/net/eth0
# Перечитати правила і перезапустити обробку
udevadm control --reload-rules
udevadm trigger
# Почекати поки всі події оброблені
udevadm settle
Порівняння: procfs vs sysfs
Це питання часто задають на співбесідах. Принципова різниця — не тільки в змісті, а в ідеології:
| /proc (procfs) | /sys (sysfs) | |
|---|---|---|
| Виник | 1980-ті, Unix | 2003, Linux 2.6 |
| Ідея | Дамп стану процесів | Структурована топологія ядра |
| Формат файлів | Довільний текст, багато полів | Один файл = одне значення |
| Структура | Органічно виросла, хаотична | Відображає kobject-ієрархію ядра |
| Записуваний? | Тільки /proc/sys | Більшість атрибутів — так |
| Парсинг | Потрібен (grep/awk) | Не потрібен |
| Нові підсистеми | Не додають | Так, це канонічне місце |
Чому /proc досі живий?
Тому що зворотна сумісність. Тисячі інструментів — ps, top, htop, netstat, lsof — читають /proc. Перенести все у /sys означало б зламати екосистему. Тому:
/proc/PID/— залишається канонічним місцем для інфо про процеси/proc/sys/— залишається дляsysctl- нові підсистеми ядра — ідуть у
/sys
Підсумок
/dev → файли-пристрої, якими керує udev
/proc → інтроспекція процесів і параметри ядра (sysctl)
/sys → структурована hardware-топологія, один файл = один атрибут
Всі три — не існують на диску. Це інтерфейси ядра у вигляді файлової системи. Читаєш файл — ядро виконує функцію. Пишеш у файл — ядро застосовує зміну.
Розуміння цих трьох директорій — це розуміння того як Linux влаштований зсередини. І це те що відрізняє системного адміністратора який «натискає кнопки» від того хто розуміє що відбувається насправді.