Каждый системный администратор рано или поздно сталкивается с необходимостью настройки параметров ядра "на лету". Заводские настройки хороши для среднего пользователя, но когда речь заходит о высоконагруженных серверах или системах реального времени, начинается настоящая работа. Именно здесь на сцену выходят две виртуальные файловые системы, которые превращают глубокие настройки ядра в простое чтение и запись файлов.
Два окна в мир ядра
Procfs и sysfs появились в разное время и с разными целями, но оба решают одну задачу: дают пользовательским программам доступ к внутренностям ядра без сложных системных вызовов. Представьте себе огромную библиотеку знаний о системе, где каждая книга - это файл, который можно просто открыть обычным текстовым редактором.
Procfs монтируется в /proc и изначально создавался для экспорта информации о процессах. Каждый запущенный процесс получает свою папку с идентификатором PID, внутри которой лежат файлы с детальной статистикой: используемая память, открытые дескрипторы, карта адресного пространства. Со временем /proc обросла подкаталогами с системной информацией: /proc/cpuinfo показывает характеристики процессора, /proc/meminfo выдает статистику по памяти, /proc/interrupts отображает счетчики прерываний. Разработчики Linux даже добавили специальный каталог /proc/sys, содержащий изменяемые параметры ядра.
Sysfs появилась позже, в ядре версии 2.6, когда стало ясно, что procfs превратилась в свалку разнородной информации. Задача sysfs более узкая и структурированная - представлять дерево устройств и объектов ядра в виде иерархии каталогов. Монтируется она в /sys, и внутри царит порядок: /sys/devices содержит все устройства системы, /sys/class группирует их по классам, /sys/kernel экспортирует настройки самого ядра.
Архитектура доступа к параметрам
Механизм работы обеих файловых систем построен на одном принципе: когда программа читает или записывает в файл, ядро вызывает специальную функцию-обработчик. Никакого реального хранения на диске не происходит - все данные формируются динамически из структур ядра.
В случае sysfs за каждым файлом стоит kobject - базовый объект ядра с набором атрибутов. Когда приложение открывает файл /sys/kernel/mm/transparent_hugepage/enabled, ядро вызывает функцию show(), которая читает текущее значение из памяти ядра и форматирует его в текст. Запись работает аналогично: новое значение передается в функцию store(), которая валидирует данные и обновляет внутренние структуры.
Procfs использует похожий механизм через структуру proc_dir_entry. Каждая запись в /proc/sys связана с конкретной переменной ядра через механизм sysctl. Например, файл /proc/sys/net/ipv4/ip_forward напрямую отображается на переменную ядра, управляющую перенаправлением IP-пакетов. Чтение cat /proc/sys/net/ipv4/ip_forward возвращает 0 или 1, а команда echo 1 > /proc/sys/net/ipv4/ip_forward мгновенно включает маршрутизацию.
Практический тюнинг производительности
Грамотная настройка параметров ядра может драматически изменить поведение системы. Возьмем задачу оптимизации сетевого стека для высоконагруженного веб-сервера. Сколько времени можно держать соединение в состоянии TIME_WAIT? Стандартные 60 секунд могут быстро исчерпать доступные порты при тысячах соединений в секунду.
echo 5 > /proc/sys/net/ipv4/tcp_fin_timeout
cat /proc/sys/net/ipv4/tcp_tw_reuse
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
Первая команда сокращает время ожидания закрытия соединения до 5 секунд. Вторая разрешает повторное использование портов из TIME_WAIT для новых исходящих соединений. Для проверки текущих настроек служит утилита sysctl -a, выдающая список всех доступных параметров.
Настройка виртуальной памяти не менее критична. Параметр vm.dirty_ratio определяет процент оперативной памяти, который можно заполнить "грязными" (несохраненными) страницами перед принудительной записью на диск. По умолчанию это 20%, но на серверах с большим объемом RAM это может привести к огромным задержкам при сбросе кэша.
sysctl -w vm.dirty_ratio=10
sysctl -w vm.dirty_background_ratio=5
Теперь фоновая запись начнется при заполнении 5% памяти, а принудительная - при 10%. Система станет писать на диск чаще, но маленькими порциями, избегая длительных блокировок.
Системы реального времени и изоляция CPU
В мире систем реального времени каждая микросекунда на счету. Промышленные контроллеры, торговые роботы на биржах, аудио/видео обработка - везде нужна предсказуемая латентность без джиттера. Linux справляется с такими задачами через механизм изоляции процессорных ядер.
Параметр загрузки isolcpus выводит указанные CPU из-под управления планировщика. Задачи больше не мигрируют на изолированные ядра автоматически - туда можно поместить только критичный процесс реального времени, привязав его командой taskset. Дополнительно применяется nohz_full, который отключает периодические прерывания таймера на изолированных ядрах, когда там выполняется всего один поток.
# В GRUB: isolcpus=2-7 nohz_full=2-7 rcu_nocbs=2-7
cat /proc/cmdline | grep isolcpus
cat /proc/interrupts
Но изолировать CPU от планировщика недостаточно. Аппаратные прерывания продолжают прилетать на все ядра. Решение - через /proc/irq настроить affinity каждого прерывания на "хозяйственные" ядра:
for irq in $(ls /proc/irq); do
if [ -d "/proc/irq/$irq" ]; then
echo 0-1 > /proc/irq/$irq/smp_affinity_list 2>/dev/null
fi
done
Эта команда перенаправляет все IRQ на первые два ядра, оставляя остальные свободными для критичных задач. Проверка эффективности ведется через cyclictest - утилиту, измеряющую латентность в реальном времени. На правильно настроенной системе максимальная задержка падает с сотен микросекунд до единиц.
Динамическая настройка через sysfs
Sysfs открывает доступ к устройствам и подсистемам ядра через структурированную иерархию. Каждое устройство представлено каталогом в /sys/devices, а симлинки в /sys/class группируют устройства по типам. Хотите изменить политику энергосбережения для конкретного диска?
ls /sys/class/block/sda/queue/
cat /sys/class/block/sda/queue/scheduler
echo noop > /sys/class/block/sda/queue/scheduler
Планировщик ввода-вывода noop просто передает запросы устройству в порядке поступления, что идеально для SSD. Для вращающихся дисков лучше deadline или cfq, сортирующие запросы для минимизации перемещений головок.
Управление частотой процессора тоже ведется через sysfs. Каталог /sys/devices/system/cpu/cpuN/cpufreq содержит файлы для каждого ядра:
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
Губернатор performance фиксирует частоту на максимуме, игнорируя энергосбережение. Для серверов это стандартная практика, исключающая задержки при разгоне частоты под нагрузкой.
Постоянные настройки и их применение
Записывать значения напрямую в /proc и /sys удобно для экспериментов, но после перезагрузки все сбросится. Для сохранения параметров служит файл /etc/sysctl.conf. Синтаксис прост: вместо косых черт из пути /proc/sys используются точки:
net.ipv4.ip_forward = 1
net.ipv4.tcp_fin_timeout = 5
vm.swappiness = 10
kernel.sched_min_granularity_ns = 2000000
После добавления строк в конфигурацию применяем изменения командой sysctl -p. Некоторые дистрибутивы используют каталог /etc/sysctl.d/ для модульного управления настройками - каждое приложение может добавить свой файл .conf с нужными параметрами.
Для sysfs постоянных настроек стандартными средствами не предусмотрено, но systemd позволяет создать unit-файл типа oneshot, который выполнит нужные команды echo при загрузке. Альтернатива - скрипты инициализации или использование udev rules для настройки устройств в момент их появления.
Мониторинг и диагностика через виртуальные ФС
Помимо настройки, procfs и sysfs незаменимы для диагностики. Файл /proc/meminfo показывает детальную статистику памяти: сколько занято, свободно, в кэше, в буферах. Утилиты типа free, top, vmstat черпают данные именно отсюда. /proc/slabinfo раскрывает использование внутренних кэшей ядра - полезно при поиске утечек памяти в драйверах.
Сетевая статистика доступна в /proc/net: таблица маршрутизации в /proc/net/route, список сокетов в /proc/net/tcp и /proc/net/udp, счетчики протоколов в /proc/net/snmp. Для траблшутинга сети эти файлы дают исчерпывающую картину без установки дополнительных утилит.
В sysfs живет информация об устройствах: температура процессора читается из /sys/class/thermal/thermal_zoneN/temp, состояние батареи - из /sys/class/power_supply/BATN/. Команда lspci -k использует sysfs для определения загруженных драйверов устройств PCI.
Опытные администраторы строят мониторинг, периодически читая нужные файлы и отправляя метрики в системы сбора данных. Это эффективнее, чем вызовы специализированных утилит, каждая из которых парсит те же виртуальные файлы.