Каждый, кто запускает ps, top, free или ss на Linux, уже пользуется /proc - просто не всегда это осознаёт. Все эти утилиты не имеют собственного доступа к памяти ядра, не делают специализированных системных вызовов для получения данных о процессах. Они просто открывают файлы в /proc и читают то, что ядро туда записало. По сути, весь пользовательский мониторинг в Linux стоит на фундаменте одной виртуальной файловой системы.
Впервые /proc появился в Linux в сентябре 1992 года в версии 0.97.3, а уже в декабре того же года начал расширяться за пределы чисто процессной информации. Концепция "процессы как файлы" была предложена Томом Килианом ещё в 1984 году на конференции USENIX, задолго до Linux. Но именно в Linux procfs вырос в нечто большее, чем просто удобный API для ps - в полноценную систему интроспекции ядра в реальном времени.
Почему proc не хранит никаких данных на диске
Файлы в /proc не существуют на диске. От слова совсем. Когда процесс открывает /proc/meminfo и читает её содержимое, ядро в этот момент формирует ответ прямо в оперативной памяти, собирая актуальные данные из своих внутренних структур. Файл создаётся в момент чтения и исчезает сразу после. Именно поэтому размер большинства файлов в /proc равен нулю байт по мнению ls -la - статическое поле размера просто не имеет смысла для динамически генерируемого содержимого.
Монтируется procfs при старте системы автоматически:
# Убедиться что procfs смонтирована
mount | grep proc
# Тип файловой системы
cat /proc/filesystems | grep proc
Под капотом procfs реализована через механизм VFS (Virtual File System) ядра Linux. Каждый "файл" - это зарегистрированный обработчик с функцией чтения, которая вызывается при обращении. Запись в некоторые файлы тоже работает - и это уже не чтение состояния, а изменение поведения ядра прямо в рантайме.
Анатомия директории процесса и что там реально хранится
Для каждого запущенного процесса, включая потоки ядра, в /proc существует директория с именем, совпадающим с PID. Набор файлов внутри стандартен для всех процессов, и изучение хотя бы одной такой директории даёт понимание всей структуры.
# Посмотреть содержимое директории процесса
ls -la /proc/$$
# Чем запущен процесс
cat /proc/$$/cmdline | tr '\0' ' '
# Переменные окружения процесса
cat /proc/$$/environ | tr '\0' '\n'
# Текущий рабочий каталог
readlink /proc/$$/cwd
# Исполняемый файл
readlink /proc/$$/exe
Файл status даёт сводную картину состояния процесса в читаемом формате: имя, PID, PPID, состояние (R/S/D/Z), потребление памяти, UID/GID, ограничения и флаги возможностей (capabilities):
cat /proc/$$/status
Файл maps показывает полную карту виртуальной памяти процесса - все сегменты, их права доступа, смещения и источники (анонимные страницы, файлы, разделяемые библиотеки):
cat /proc/1/maps | head -20
Директория fd/ содержит символические ссылки на все открытые файловые дескрипторы процесса. Это прямая замена lsof для конкретного процесса без дополнительных инструментов:
# Все открытые файлы процесса
ls -la /proc/$$/fd
# Только сокеты
ls -la /proc/$$/fd | grep socket
Системные файлы верхнего уровня для мониторинга ресурсов
За пределами PID-директорий /proc содержит десятки файлов с общесистемной информацией. Это первичные источники данных, которые читают htop, vmstat, sar и большинство других инструментов мониторинга.
Память и нагрузка - самые частые запросы при диагностике:
# Подробная статистика памяти
cat /proc/meminfo
# Средняя нагрузка за 1, 5 и 15 минут и число задач
cat /proc/loadavg
# Статистика по всем CPU: user, nice, system, idle, iowait, irq, softirq
cat /proc/stat
# Дисковая статистика: число операций, секторов, миллисекунды ожидания
cat /proc/diskstats
Информация о процессоре и системе:
# Подробная информация о каждом ядре CPU
cat /proc/cpuinfo
# Время работы системы в секундах
cat /proc/uptime
# Параметры загрузки ядра
cat /proc/cmdline
# Версия ядра
cat /proc/version
Сетевая подсистема представлена целой директорией /proc/net/, которая содержит таблицы состояния сетевого стека:
# TCP-соединения с состоянием и адресами в hex
cat /proc/net/tcp
# UDP-сокеты
cat /proc/net/udp
# Статистика сетевых интерфейсов (байты, пакеты, ошибки)
cat /proc/net/dev
# Таблица маршрутизации
cat /proc/net/route
# ARP-таблица
cat /proc/net/arp
Адреса в /proc/net/tcp хранятся в шестнадцатеричном формате с обратным порядком байт - особенность, которая поначалу удивляет. ss и netstat делают обратное преобразование автоматически, но при написании скриптов это нужно учитывать.
Управление параметрами ядра через /proc/sys
Директория /proc/sys - это не просто источник информации, а двунаправленный интерфейс управления. Запись в файлы внутри этой директории меняет поведение ядра немедленно, без перезагрузки и без перекомпиляции. Именно на этом механизме основана утилита sysctl.
# Прочитать параметр максимального числа открытых файлов
cat /proc/sys/fs/file-max
# Изменить параметр напрямую
echo 2097152 > /proc/sys/fs/file-max
# Включить форвардинг IP-пакетов
echo 1 > /proc/sys/net/ipv4/ip_forward
# Размер буфера TCP
cat /proc/sys/net/core/rmem_max
# Ограничения на overcommit памяти
cat /proc/sys/vm/overcommit_memory
Изменения через /proc/sys не сохраняются после перезагрузки. Для постоянного применения параметры записывают в /etc/sysctl.conf или файлы в /etc/sysctl.d/, а применяют через sysctl -p. Но для экстренной настройки работающего сервера прямая запись в /proc/sys работает мгновенно - и это принципиальное отличие от большинства других механизмов конфигурации ядра, где изменение вступает в силу только после перезагрузки.
Каждый параметр в /proc/sys соответствует конкретной переменной в исходном коде ядра. Это означает, что параметры документированы в официальной документации ядра в директории Documentation/admin-guide/sysctl/, и их поведение предсказуемо.
Опции монтирования procfs и безопасность в многопользовательских средах
Procfs спроектирован с допущением, что чтение информации о чужих процессах - нормально. На рабочем сервере это не всегда желательно: любой локальный пользователь может прочитать переменные окружения чужих процессов, увидеть список открытых файлов и узнать командные строки запущенных демонов.
Опция монтирования hidepid контролирует видимость чужих процессов:
# hidepid=0 - поведение по умолчанию, все процессы видны всем
# hidepid=1 - чужие /proc/PID существуют, но stat() возвращает только PID
# hidepid=2 - чужие /proc/PID полностью скрыты для непривилегированных
# Применить немедленно
mount -o remount,hidepid=2 /proc
# Постоянно через /etc/fstab
# proc /proc proc defaults,hidepid=2 0 0
Если нужно предоставить доступ к информации о процессах отдельным сервисам (например, мониторинговому агенту), используется параметр gid=:
# Создать группу мониторинга и разрешить ей видеть все процессы
groupadd monitoring
mount -o remount,hidepid=2,gid=$(getent group monitoring | cut -d: -f3) /proc
В контейнерных средах каждое pid-пространство имён получает собственный экземпляр procfs. Это означает, что внутри контейнера /proc показывает только процессы этого контейнера - изоляция работает на уровне ядра, а не фильтрацией вывода.
Практические сценарии диагностики через прямое чтение /proc
Бывают ситуации, когда стандартные утилиты недоступны - минимальный образ, broken environment, ограниченный chroot. В таких случаях /proc становится единственным инструментом.
Найти процесс, удерживающий удалённый файл (классическая задача когда диск "занят" после rm):
# Найти все удалённые файлы, которые ещё открыты
find /proc/*/fd -ls 2>/dev/null | grep deleted
# Узнать PID процесса держащего конкретный файл
grep -l "myfile" /proc/*/maps 2>/dev/null
Проверить лимиты файловых дескрипторов для процесса:
# Текущие и максимальные лимиты
cat /proc/$$/limits
# Сколько дескрипторов реально открыто
ls /proc/$$/fd | wc -l
Посмотреть планировщик и приоритет процесса:
# Scheduling policy и nice-значение
cat /proc/$$/sched 2>/dev/null | head -5
grep ^prio /proc/$$/stat
Procfs - это один из тех инструментов, ценность которого растёт обратно пропорционально тому, сколько других инструментов доступно. На полностью оснащённой системе с htop, perf, bpftrace и strace он остаётся в тени. Но в момент, когда нужно понять, что происходит прямо сейчас, без установки дополнительных пакетов, без специальных прав и без изменения системы - /proc там, где он всегда был: смонтирован, актуален и открыт для чтения.