мета-данные страницы
Глава 6: Запуск пользовательского пространства
Пользовательское пространство запускается в следующем порядке:
- Процесс init.
- Основные службы низшего уровня, такие как udevd и syslogd.
- Конфигурация сети.
- Службы среднего и высокого уровня (cron, print и т.д.).
- Приглашения для входа в систему, графические интерфейсы и приложения высокого уровня, такие как веб-серверы.
6.1 Основные сведения об init
init (инициализация) - программа пользовательского пространства, расположенная в /sbin. Её основная цель - запускать и останавливать основные служебные процессы системы.
Во всех актуальных версиях основных дистрибутивов Linux стандартной реализацией init является systemd.
Альтернативные системы init
В старых системах встречаются другие реализации:
| Система | Описание | Использование |
|---|---|---|
| System V init | Традиционная последовательная инициализация (Sys V из Unix System V) | RHEL до 7.0, Debian 8 |
| Upstart | Реализация для дистрибутивов Ubuntu | Ubuntu до 15.04 |
| runit | Облегченная система инициализации | Встроенные платформы и облегченные системы |
| Android init | Собственная система инициализации | Android |
| BSD init | Версия для BSD | Редко встречается в современных Linux системах |
Проблемы System V init
Система инициализации System V работает как последовательная серия сценариев, где каждый сценарий запускает одну службу или настраивает отдельную часть системы. Обычно зависимости разбираются просто, и система достаточно гибка для необычных задач.
Однако существуют существенные ограничения:
Производительность:
- Две части последовательной загрузки не могут выполняться одновременно
Управление системой:
- Сложность поиска PID демона службы (требуется ps или механизм, специфичный для службы)
- Полустандартная система записи PID (/var/run/myservice.pid)
- Много стандартного шаблонного кода в сценариях
Конфигурация:
- Мало информации о службах и конфигурации по требованию
- Большинство служб запускается только при загрузке
- Конфигурация устанавливается в основном при загрузке
- Традиционный демон inetd (для сетевых служб по требованию) уже не используется
Современные системы инициализации (такие как systemd) решают эти проблемы путём изменения способа запуска служб, порядка их контроля и настройки зависимостей.
6.2 Определение системы инициализации
Определить версию инициализации можно, проверив наличие определённых файлов и каталогов:
systemd:
- Наличие каталогов /usr/lib/systemd и /etc/systemd
Upstart:
- Наличие каталога /etc/init с несколько файлами .conf
- (Исключение: Debian 7 и старше используют System V init, несмотря на /etc/init)
System V init:
- Отсутствие вышеуказанных каталогов
- Наличие файла /etc/inittab
Информацию также можно получить из страницы руководства init(1).
6.3 systemd
systemd - современная реализация init в Linux, интегрирующая функциональность Unix-служб (cron, inetd). Вдохновлена launchd от Apple.
Основные отличия от традиционной init:
- Расширенное управление службами
- Отслеживание демонов после запуска
- Группировка процессов службы
- Ориентирована на выполнение задач и целей
Система использует юниты (units) для задач, содержит инструкции запуска и зависимости. Активирует юниты по мере готовности, не придерживаясь жесткой последовательности. Реагирует на системные события (uevents).
6.3.1 Юниты и типы юнитов
systemd управляет не только процессами/службами, но и монтированием ФС, запросами подключения сети, таймерами.
| Тип юнита | Описание |
|---|---|
| Service units | Управление служебными демонами Unix |
| Target units | Управление другими юнитами, группировка |
| Socket units | Местоположение запросов входящих сетевых подключений |
| Mount units | Контроль присоединения файловых систем |
Примечание: полный список типов см. systemd(1)
6.3.2 Графики загрузки и зависимостей юнитов
При загрузке активируется целевой юнит default.target, объединяющий юниты служб и монтирования как зависимости. Зависимости образуют граф (не дерево). Юниты могут зависеть от нескольких предыдущих.
Визуализировать граф: `systemd-analyze dot` (требует фильтрации для сложных систем).
Примечание: В большинстве систем default.target → целевой юнит высокого уровня (графический интерфейс и т.д.)
6.3.3 Конфигурация systemd
Основные каталоги:
| Каталог | Назначение |
|---|---|
| /lib/systemd/system или /usr/lib/systemd/system | Системные юниты (глобальная конфигурация) |
| /etc/systemd/system | Локальная конфигурация |
Правило: не изменяйте системные юниты (сохраняет дистрибутив), вносите изменения в /etc/systemd/system.
Проверка пути поиска:
systemctl -p UnitPath show pkg-config systemd --variable=systemdsystemunitdir pkg-config systemd --variable=systemdsystemconfdir
Юнит-файлы
Формат из спецификации XDG Desktop Entries (.ini подобный) с секциями в квадратных скобках и переменными.
Пример dbus-daemon.service:
[Unit] Description=D-Bus System Message Bus Documentation=man:dbus-daemon(1) Requires=dbus.socket RefuseManualStart=yes [Service] ExecStart=/usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only ExecReload=/usr/bin/dbus-send --print-reply --system --type=method_call --dest=org.freedesktop.DBus / org.freedesktop.DBus.ReloadConfig
[Unit] - описание, информация о зависимостях [Service] - подготовка, запуск, перезагрузка службы
Переменные
Синтаксис: `$ПЕРЕМЕННАЯ`
Пример (sshd.service):
[Service] EnvironmentFile=/etc/sysconfig/sshd ExecStartPre=/usr/sbin/sshd-keygen ExecStart=/usr/sbin/sshd -D $OPTIONS $CRYPTO_POLICY ExecReload=/bin/kill -HUP $MAINPID
- $OPTIONS, $CRYPTO_POLICY - из EnvironmentFile
- $MAINPID - PID отслеживаемого процесса
Спецификаторы
Синтаксис: `%спецификатор`
- %n - имя текущего юнита
- %H - имя хоста
- %I, %i - имя экземпляра (для юнитов с @)
Пример: getty@.service → getty@tty1, getty@tty2 (динамическое создание).
Полный список см. systemd.unit(5)
6.3.4 Процесс работы systemd
systemctl - основная команда для управления systemd юнитами.
Основные команды
| Операция | Команда | Описание |
|---|---|---|
| Список активных юнитов | systemctl list-units | Вывод сокращен; используйте –full для полных имен |
| Все юниты | systemctl list-units –all | Включает неактивные юниты |
| Статус юнита | systemctl status <unit> | Показывает статус, PID, cgroup, журнал |
| Запуск | systemctl start <unit> | Активация юнита |
| Остановка | systemctl stop <unit> | Деактивация юнита |
| Перезапуск | systemctl restart <unit> | Перезапуск юнита |
| Перезагрузка конфига | systemctl reload <unit> | Перезагрузка только для данного юнита |
| Перезагрузка всех | systemctl daemon-reload | Перезагрузка всех конфигураций |
| Текущие задания | systemctl list-jobs | Список активных заданий (изменений состояния) |
| Журнал юнита | journalctl –unit=<unit> | Все сообщения журнала |
Пример просмотра статуса
$ systemctl status sshd.service
Вывод содержит: статус загрузки, состояние (active/inactive), основной процесс (Main PID), контрольную группу (cgroup) и сообщения журнала.
Добавление юнита
Размещайте юнит-файлы в /etc/systemd/system (не перезаписываются при обновлении дистрибутива).
# Создать файл /etc/systemd/system/test1.target [Unit] Description=test 1 # Создать файл /etc/systemd/system/test2.target с зависимостью [Unit] Description=test 2 Wants=test1.target # Активировать systemctl start test2.target # Если есть секция [Install], включить перед активацией systemctl enable test2.target
Удаление юнита
# 1. Деактивировать systemctl stop <unit> # 2. Отключить (если есть [Install]) systemctl disable <unit> # 3. Удалить юнит-файл
Примечание: Задания (jobs) - это изменения состояния юнитов, не путать с заданиями оболочки. Требуются права суперпользователя для некоторых операций.
6.3.5 Отслеживание и синхронизация процессов systemd
systemd использует cgroups (группы управления ядра Linux) для отслеживания иерархии процессов. Параметр Type в юнит-файле указывает поведение службы при запуске.
| Type | Описание |
|---|---|
| simple | Процесс не разветвляется, остается основным процессом |
| forking | Процесс разветвляется; systemd ждет завершения исходного процесса |
| notify | Служба отправляет уведомление systemd, когда готова |
| dbus | Служба регистрируется на D-Bus, когда готова |
| oneshot | Процесс полностью завершается после запуска; RemainAfterExit=yes по умолчанию |
| idle | Как simple, но запуск отложен до завершения всех активных заданий |
Примечание: Type=simple не известен время запуска; используйте Type=notify, Type=dbus или отложенный запуск (раздел 6.3.7) для синхронизации зависимых юнитов.
6.3.6 Зависимости systemd
Гибкая система зависимостей требует баланса между строгостью и отказоустойчивостью. Слишком строгие правила могут заблокировать доступ при сбое некритичного сервиса. systemd предлагает несколько типов зависимостей для гибкого управления:
| Тип | Описание |
|---|---|
| Requires | Строгие зависимости. При сбое зависимости юнит также отключается. |
| Wants | Зависимости только для активации. Сбой зависимости не влияет на юнит. Рекомендуется использовать по возможности. |
| Requisite | Юниты, которые уже должны быть активны. Если не активны, юнит не запустится. |
| Conflicts | Отрицательные зависимости. При активации юнита противоположная зависимость деактивируется. |
Просмотр зависимостей:
systemctl show -p type unit
Порядок выполнения юнитов
По умолчанию юниты с Requires и Wants запускаются одновременно. Для упорядочивания используйте:
- Before - текущий юнит активируется раньше перечисленных
- After - текущий юнит активируется после перечисленных
systemd ждет активного статуса юнита перед активацией зависимостей.
Зависимости по умолчанию
systemd автоматически добавляет зависимость After к Wants-зависимостям. Эти неявные зависимости вычисляются во время загрузки и не сохраняются в файлах конфигурации.
Отключить зависимости по умолчанию:
DefaultDependencies=no
Условные зависимости
Для проверки состояния системы:
- ConditionPathExists=p - путь существует
- ConditionPathIsDirectory=p - путь является каталогом
- ConditionFileNotEmpty=p - файл существует и не пуст
При ложном условии юнит не активируется, но другие зависимости активируются независимо от условия.
Секция [Install] и включение юнитов
Раздел [Install] позволяет указывать зависимости в обратном порядке без изменения дополнительных файлов. Используйте WantedBy или RequiredBy.
Пример:
test1.target:
[Unit] Description=test 1 [Install] WantedBy=test2.target
test2.target:
[Unit] Description=test 2
Включение юнита:
systemctl enable test1.target # Создаст: /etc/systemd/system/test2.target.wants/test1.target
Отключение юнита:
systemctl disable test1.target
Важно: включение юнита не активирует его. Юнит с разделом [Install] считается отключенным по умолчанию и включается после перезагрузки.
Каталоги .wants и .require в /etc/systemd/system обычно управляются разделом [Install], но можно добавлять символические ссылки вручную для временных зависимостей без редактирования системных файлов юнитов.
6.3.7 Запуск по запросу и параллелизация ресурсов в systemd
systemd позволяет откладывать запуск юнита до момента, когда на него поступит запрос. Процесс:
1. Создается юнит systemd для сервиса (Unit A) 2. Определяется ресурс (сокет, файл, устройство) 3. Создается юнит ресурса (Unit R): .socket, .path или .device 4. systemd мониторит ресурс и активирует Unit A при обращении
При обращении к ресурсу:
1. systemd блокирует ресурс и буферизует входные данные 2. Активирует Unit A 3. Unit A берет управление ресурсом и обрабатывает буферизованные данные
Важные замечания:
- Юнит ресурсов должен охватывать все точки доступа сервиса
- Связь между юнитами может быть неявной (по имени) или явной (параметр Socket=)
- Не все серверы поддерживают взаимодействие с юнитами ресурсов
Пример: сокет-юнит и служебный юнит
Echo-сервис на TCP-порту 22222.
echo.socket:
[Unit] Description=echo socket [Socket] ListenStream=22222 Accept=true
echo@.service:
[Unit] Description=echo service [Service] ExecStart=/bin/cat StandardInput=socket
Запуск:
systemctl start echo.socket
telnet localhost 22222
Остановка:
systemctl stop echo.socket
Экземпляры и передача управления
Символ @ в имени echo@.service означает параллельные экземпляры. При Accept=true в сокет-юните systemd принимает входящие соединения и создает отдельный экземпляр для каждого. Каждый экземпляр считывает данные как стандартный ввод.
Если сервис может самостоятельно принимать соединения, исключите @ из имени и не устанавливайте Accept=true. Сервис получит полный контроль над сокетом.
Документация: systemd.socket(5), systemd.path(5), systemd.device(5), systemd.exec(5)
Оптимизация загрузки с помощью юнитов ресурсов
Юниты ресурсов ускоряют загрузку путем параллельной активации:
| Последовательный запуск | Параллельный запуск с юнитом ресурса |
|---|---|
| Служба E (ресурс R) запускается | Юнит R активируется немедленно |
| Службы A, B, C ждут E | Службы A, B, C, E стартуют параллельно |
| Долгое время загрузки | Быстрая загрузка, E берет управление когда готова |
systemd предоставляет интерфейс юнита ресурса (R) еще до полной активации служебного юнита (E). Это позволяет зависимым юнитам (A, B, C) стартовать параллельно, а не ждать E.
Побочный эффект: Одновременный запуск многих юнитов может временно замедлить систему.
Пример: journald и D-Bus обычно загружаются параллельно этим способом.
6.3.8 Вспомогательные компоненты systemd
systemd включает поддержку задач управления системой, помимо запуска и управления сервисами. Исполняемые файлы расположены в /lib/systemd и имеют префикс systemd-.
| Служба | Назначение |
|---|---|
| udevd | Управление устройствами (см. Глава 3) |
| journald | Служба логирования; обрабатывает различные механизмы, включая syslog (см. Глава 7) |
| resolved | Демон кэширования DNS (см. Глава 9) |
Примеры программ:
- systemd-udevd (интегрированный в systemd demон udevd)
- systemd-fsck (простая обертка для стандартных системных утилит)
Некоторые программы в /lib/systemd - обычные обертки, запускающие стандартные утилиты и уведомляющие systemd о результатах.
Справка: Неизвестную программу в /lib/systemd можно найти в man-страницах, где описаны и утилита, и соответствующий ей тип юнита.
6.4. Уровни выполнения в System V
System V init использует уровни выполнения (runlevel) для определения состояния машины - число от 0 до 6. Проверить текущий уровень:
who -r
Выход: run-level 5 2019-01-27 16:43
Уровни выполнения различают состояния: запуск, выключение, однопользовательский режим, консоль. Например, 2–4 - текстовая консоль, 5 - графический интерфейс.
Примечание: systemd поддерживает уровни выполнения как устаревшие, предпочитая им целевые юниты.
6.5. System V init
System V init - одна из старейших систем инициализации Linux. Устанавливается редко (встречается в RHEL < 7.0, встроенных системах), но пакеты могут содержать её сценарии, совместимые с systemd.
Состоит из:
- Конфигурационный файл:
/etc/inittab - Сценарии загрузки и символические ссылки
| Файл | Содержимое |
|---|---|
| /etc/inittab | Четыре поля: идентификатор : уровни выполнения : действие : команда |
| /etc/rc.d/rc | Запускает программы из rc*.d в числовом порядке |
| /etc/rc*.d | Каталоги со сценариями (rc1.d, rc2.d и т.д.) |
Пример строки inittab:
id:5:initdefault: l5:5:wait:/etc/rc.d/rc 5
| Действие | Назначение |
|---|---|
| initdefault | Уровень выполнения по умолчанию |
| wait | Выполнить команду один раз при входе на уровень, ждать завершения |
| respawn | Перезапустить команду при выходе (например, getty для виртуальных консолей) |
| ctrlaltdel | Действие при нажатии Ctrl+Alt+Del (обычно shutdown) |
| sysinit | Первое действие при запуске, до всех уровней выполнения |
6.5.1. System V init: последовательность команд при запуске
Команда rc 5 запускает сценарии из /etc/rc5.d:
- S (Start) - выполнить с аргументом
start - K (Kill) - выполнить с аргументом
stop - Числа 00–99 - порядок выполнения
Пример каталога rc5.d:
S10sysklogd S20ppp S99gpm S12kerneld S25netstd_nfs S99httpd S15netstd_init S30netstd_misc S99rmnologin
Команда rc выполняет их последовательно:
S10sysklogd start S12kerneld start S15netstd_init start ... S99sshd start
Сценарии оболочки запускают программы из /sbin или /usr/sbin. Для редактирования используйте less или аналогичные программы.
6.5.2. Ферма ссылок System V init
Содержимое rc*.d - символические ссылки на файлы в /etc/init.d:
lrwxrwxrwx . . . S10sysklogd -> ../init.d/sysklogd lrwxrwxrwx . . . S12kerneld -> ../init.d/kerneld lrwxrwxrwx . . . S99httpd -> ../init.d/httpd
Дистрибутивы используют эту ферму ссылок (link farm) для переиспользования одних сценариев на всех уровнях выполнения.
Запуск и остановка служб
/etc/init.d/httpd start # Запустить /etc/init.d/httpd stop # Остановить
Изменение последовательности загрузки
Отключить службу без удаления:
mv S99httpd _S99httpd
Префикс _ заставит rc игнорировать ссылку.
Добавить службу: скопируйте сценарий в init.d, создайте символическую ссылку в rc*.d. Несущественные службы - номера 90+, после основных систем.
6.5.3. Команда run-parts
Утилита run-parts запускает все исполняемые программы в каталоге в определённом порядке.
| Дистрибутив | Функции |
|---|---|
| Fedora | Простая версия - запускает всё подряд |
| Debian/Ubuntu | Сложная - фильтр по регулярным выражениям, передача аргументов |
Используется в сценариях для массового запуска программ. Большинству пользователей детали неважны.
6.5.4. Управление System V init
telinit - команда управления уровнями выполнения:
| Команда | Действие |
|---|---|
telinit 3 | Переключиться на уровень выполнения 3 |
telinit q | Перечитать /etc/inittab |
telinit s | Однопользовательский режим |
Предупреждение: init завершит процессы, отсутствующие в inittab для нового уровня.
6.5.5. Совместимость systemd и System V
systemd отслеживает System V сценарии:
1. Активирует ''<N>.target'' (N - уровень выполнения)
2. Идентифицирует скрипты в ''/etc/rc<N>.d''
3. Связывает скрипт со служебным юнитом (''foo.service'')
4. Активирует юнит, запускает с аргументом start/stop
5. Связывает процессы со служебным юнитом
Результат: можно использовать systemctl для управления, но режим совместимости всё равно запускает сценарии последовательно.
6.6 Завершение работы системы
Используйте shutdown для корректного завершения:
shutdown -h now # Остановить сейчас shutdown -r +10 # Перезагрузить через 10 минут
| Параметр | Действие |
|---|---|
| -h | Halt - остановка и отключение питания |
| -r | Reboot - перезагрузка |
| now | Немедленно |
| +n | Через n минут |
Перед завершением: shutdown создаёт /etc/nologin (запрет входа), уведомляет пользователей.
Процедура завершения
1. init просит каждый процесс завершиться 2. Через время применяет сигнал TERM 3. Если не помогает - KILL для оставшихся процессов 4. Блокирует системные файлы 5. Демонтирует все FS кроме корневой 6. Ремонтирует корневую FS в режиме read-only 7. Синхронизирует буфер (sync) 8. Указывает ядру перезагрузиться/остановиться (reboot(2))
halt/reboot: вызывают shutdown, или если система уже на уровне выключения - сигналят ядру напрямую. Флаг -f (force) - быстрое выключение без проверок.
6.7 Начальная файловая система оперативной памяти
initramfs - временное пользовательское пространство перед основной загрузкой. Решает проблему: ядру нужны драйверы в виде модулей, но модули - это файлы, а FS не смонтирована.
Как это работает
1. Загрузчик загружает архив с модулями ядра в оперативную память 2. Ядро распаковывает архив во временную RAM-FS 3. Утилиты в initramfs загружают необходимые драйверы 4. Монтируют реальную корневую FS 5. Запускают полноценный init
| Дистрибутив | Реализация |
|---|---|
| Простые системы | Shell-скрипт, udev, монтирование корня |
| systemd системы | Полная systemd без модулей, minimal udev config |
Отключение initramfs
Если все драйверы встроены в ядро - можно пропустить initramfs. Удалите строку initrd в GRUB (лучше через редактор меню, чем файл конфига).
Примечание: современные ядра требуют initramfs для UUID-монтирования и других функций.
Содержимое initramfs
Распакуйте архив:
unmkinitramfs /boot/initramfs-*.img .
Старые системы использовали cpio архивы (см. cpio(1)).
Создание initramfs
Обычно создаётся автоматически дистрибутивом. Основные утилиты:
- mkinitramfs - простая, распространённая
- dracut - более мощная
Примечание: термин initrd (initial RAM disk) - устаревший, использовал образ диска. Сейчас initramfs (cpio-архив) стандарт. Файлы конфига ещё содержат имя initrd.
6.8 Аварийная загрузка системы и однопользовательский режим
При проблемах с системой используйте live-образ дистрибутива или SystemRescueCD на съёмном носителе. Live-образ - полная Linux, загружающаяся без установки.
Задачи после сбоя
- Проверка файловых систем
- Сброс забытого пароля
- Исправление критичных файлов (
/etc/fstab,/etc/passwd) - Восстановление резервных копий
Однопользовательский режим
Быстрая загрузка в root-оболочку без служб.
| Init система | Режим |
|---|---|
| System V | Уровень выполнения 1 |
| systemd | rescue.target |
| Параметр загрузчика | -s |
Недостатки: сеть часто недоступна, нет GUI, терминал может работать некорректно. Live-образ более предпочтителен.
Требует: пароль суперпользователя для входа.