@ Карта сайта News Автора!

Bog BOS: Загрузка Linux

Linux Linux: дистрибутивы RPM yum Установщик Linux anaconda Загрузка Linux

Последние изменения:
2024.11.22: sysadmin: systemd-journald (централизованное хранение)
2024.11.11: sysadmin: Linux: пространства имён
2024.11.06: sysadmin: настройка TCP/IP в Linux: виртуальный интерфейс и виртуальный мост
2024.10.25: sysadmin: Linux VFS, атрибуты, расширенные атрибуты, ACL

Последнее изменение файла: 2024.10.04
Скопировано с www.bog.pp.ru: 2024.11.23

Bog BOS: Загрузка Linux

В статье описывается процесс загрузки Linux (x86, GRUB, SysV init): последовательность выполнения, настройка загрузчиков и /etc/inittab, systemctl.

Последовательность загрузки (x86 и x86_64) в режиме BIOS (полный PnP)

  1. инициализация контроллера RAM
  2. декомпрессия BIOS из флеш в RAM
  3. защита от записи захваченного куска и передача туда управления
  4. POST (Power On Self Test) - процедура идентификации, тестирования и конфигурации оборудования
  5. процедура IPL - Initial Program Load (по мотивам BBS, PnP BIOS, PCI Local Bus, PXE Specification)
  6. первоначальный загрузчик находит и загружает программу загрузки 2 этапа (stage 2) и передаёт ей управление (GRUB, LILO, SYSLINUX); используется BIOS API; обычное место загрузчика 2 этапа - /boot/
  7. загрузчик 2 этапа выбирает, находит и загружает ядро и RAM диск (initrd) в память; GRUB читает конфигурацию из /boot/grub/grub.conf; конфигурация для LILO хранится в MBR; GRUB и LILO позволяют вывести список возможных загружаемых систем на экран и выбрать нужную с помощью клавиатуры; GRUB позволяет изменить параметры загрузки (корневая файловая система, ядро, RAM диск, параметры ядра) с помощью текстового редактора; используется BIOS API; RAM диск содержит образ файловой системы с модулями (драйверами) устройств, необходимыми для монтирования корневой файловой системы; в случае со встроенным Linux RAM диск содержит всю систему
  8. ядро повторно обходит и инициализирует периферийные устройства, для которых есть встроенные драйвера
  9. ядро монтирует RAM диск (предварительно разжав) и загружает с него необходимые модули, инициализирует соответствующие устройства
  10. если необходимо, то ядро инициализирует LVM и программный RAID
  11. ядро размонтирует RAM диск и освобождает занимаемую им память
  12. ядро монтирует корневую файловую систему в режиме "только чтение"; в процессе дальнейшей работы ядро загружает дополнительные модули с корневой файловой системы
  13. запускается процесс /sbin/init (далее описывается загрузка в стиле System V)
  14. init разбирает конфигурационный файл /etc/inittab для определения дальнейших действий; если при загрузке указан уровень s (или S), то inittab не читается, а система переходит в однопользовательский режим (shell на /dev/console с правами root); строка с действием initdefault определяет "уровень выполнения" (run level) по умолчанию, т.е. режим работы системы (однопользовательская, многопользовательская, с доступом в сеть, с графическим окружением и т.д.); строка с действием sysinit (/etc/rc.d/rc.sysinit) определяет скрипт инициализации;
  15. init выполняет скрипт /etc/rc.d/rc.sysinit (проверка и монтирование остальных файловых систем, swap и т.д.)
  16. в "нормальном" /etc/inittab при переходе на любой уровень запускается скрипт /etc/rc.d/rc с указанием уровня в качестве параметра; данный скрипт запускает скрипты /etc/rcуровень.d/K* (в алфавитном порядке) с параметром stop и скрипты /etc/rcуровень.d/S* с параметром start; в конце запускается /etc/rc.d/rc.local; по традиции скрипты являются символьными ссылками на скрипты в директории /etc/init.d/; вместо /etc/init.d/ может использоваться /etc/rc.d/init.d/; вместо /etc/rcуровень.d/ может использоваться /etc/rc.d/rcуровень.d; реальность несколько сложнее

Последовательность загрузки (x86 и x86_64) в режиме UEFI и systemd

  1. инициализация платформы UEFI
  2. менеджер загрузки UEFI выбирает драйверы и приложения из списка
  3. загрузка ядра и RAM диска с помощью GRUB 2; RAM диск содержит образ файловой системы с модулями (драйверами) устройств, необходимыми для монтирования корневой файловой системы; в случае со встроенным Linux RAM диск содержит всю систему
  4. ядро повторно обходит и инициализирует периферийные устройства, для которых есть встроенные драйвера
  5. ядро монтирует RAM диск (предварительно разжав) и загружает с него необходимые модули, инициализирует соответствующие устройства - dracut
  6. ядро размонтирует RAM диск и освобождает занимаемую им память
  7. ядро монтирует корневую файловую систему в режиме "только чтение"; в процессе дальнейшей работы ядро загружает дополнительные модули с корневой файловой системы
  8. запускается процесс /usr/lib/systemd/systemd

Загрузчики

В различных дистрибутивах и различных ситуациях могут использоваться следующие загрузчики:

LILO и GRUB работают через BIOS, а большинство BIOS позволяют доступ только к первым двум IDE-дискам (считая ATAPI CD-ROM) в пределах первых 1023 цилиндров. Так что каталог (или раздел) /boot, в котором хранятся как файлы самого загрузчика, так и загружаемые файлы (ядро, initrd) должен удовлетворять данным ограничениям.

Уровни выполнения и /etc/inittab

Формат файла /etc/inittab (комментарии начинаются с символа '#'):

идентификатор:перечень-уровней-выполнения:действие:процесс

где

При запуске процесса устанавливаются переменные окружения: PATH, INIT_VERSION, RUNLEVEL, PREVLEVEL, CONSOLE.

Уровни выполнения для Red Hat Linux:

Переход на другой уровень можно сделать с помощью программы telinit или прямо через /dev/initctl. telinit с указанием уровня q (Q) заставляет init перечитать /etc/inittab. Использование SIGPWR и /etc/powerstatus признано устаревшим.

Загрузчик может передать процессу init параметры

systemd

systemd (LGPL) - управление системой и сервисами. RHEL/CentOS 7.9 - версия 219. RHEL/RockyLinux 8.10 - версия 239. Запускается как PID 1 вместо процесса init (initd, SysV init), UpStart, OpenRC, runit, dinitq. Для совместимости поддерживает скрипты инициализации LSB (/etc/init.d). Управляет запуском модулей (unit) и отслеживает зависимость между модулями (юнитами). Предполагается, что в будущем заменит собой все системные сервисы Linux. Уже имеются замены следующим сервисам:

Кстати, Gnome 3.8 и выше не работает без systemd (используется для управления сессиями).

Использует D-Bus и Unix-сокеты для общения между процессами. Состояния юнитов: активный, неактивный, упавший. systemd контролирует состояние юнитов и реагирует на их изменение, перезапускает юнит при аварийном завершении, собирает сообщения. Позволяет активировать сервисы по зависимостям, обращению к портам и сокетам (замена inetd, xinetd.service), обращению D-Bus, по расписанию (замена cron), по активации обрудования (udev), обращению к файлу или каталогу. Зависимости (положительные Requires и отрицательные Conflicts) отделены от требований к порядку загрузки (After и Before), т.е. можно задать порядок, но не требовать активизации упомянутых юнитов (не будут запущены, если не затребовано в другом месте), и наоборот (будут запущены параллельно). Сервисы наследуют окружение процесса 1, а не от оболочки, в которой запускается скрипт service. Юниты могут запросить изменение состояний других юнитов, такие запросы называются заданиями (job) и ставятся в очередь заданий. Осуществляется проверка добавляемых в очередь заданий на зацикливание зависимостей с попыткой автоматического удаления желаемых (Wants), но не обязательных зависимостей. systemd аналогично inetd слушает требуемые сервисами сокеты (сетевые порты) используя специальные юниты (.socket) для их создания и передаёт соединение очередному процессу юнита, возможно вместе со слушающим сокетом, это также позволяет не терять сообщения при перезапуске сервисов - сообщения встают в очередь к незакрываемому на время перезапуска сокету. Сервисы, зависимые от базовых сервисов (точнее от интерфейсных сокетов), могут быть запущены без ожидания завершения запуска базового сервиса. Для ожидания монтирования файловой системы или доступа к конкретному файл используется механизм autofs (.mount, .automount и .path).

При запуске головного процесса юнита помещает его в отдельную контрольную группу (cgroup), в которую попадают все его потомки, что позволяет аккуратно завершить все процессы юнита (в прошлой жизни использовались setsid, установление лидера группы процессов и т.д.), а также контролировать потребление ресурсов всем сервисом. Иерарахия cgroup в /sys/fs/cgroup/systemd/. При монтировании указывается (иерархия без контроллеров): "-t cgroup -o none,name=systemd,release_agent=/usr/lib/systemd/systemd-cgroups-agent] cgroup /sys/fs/cgroup/systemd". Лимиты в /etc/security/limits.conf действуют на сеансы через PAM, но не на сервисы systemd. В cgroups v1 (до systemd 232, RHEL7) для каждого контроллера (cpu, memory, blkio) создаётся отдельная иерархия. В cgroups v2 (после systemd 232, в RHEL8 не используется?) общая иерархия для контроллеров ? и отдельная cgroup v1 для device, memory, pids. Посмотреть имена групп можно командой "ps xawf -eo pid,user,cgroup:80,args" или systemd-cgls, которые выводят дерево процессов.

Обещана, но не гарантирована стабильность формата юнитов, документированные ключи systemd, systemctl, loginctl, journalctl и т.п..

Типы юнитов (имя юнита определяется именем файла с его описанием):

Цели (.target, режим работы; цель по умолчанию задаётся командой "systemctl set-default ..." или при загрузке ключом ядра systemd.default=, systemd.unit=):

Файлы настройки в /etc/systemd/ (администраторские, наибольший приоритет), /run/systemd/ (временные), /usr/lib/systemd/ (дистрибутивные, наименьший приоритет). Основные настройки systemd в system.conf в этих каталогах. Описание юнитов в подкаталогах system/ (общесистемные) и user/ (пользовательские, управление сеансами пользователей). В дополнение к описанию юнита в файле имя.тип можно использовать каталог имя.тип.d/, в который поместить отличия от менее приоритетного описания (с указанием секций, новые значения переменных замещают значения из менее приоритетных источников).

Сервисы systemd:

Получить больше информации в журнал можно указав ключи ядра при загрузке: systemd.log_level=debug systemd.log_target=kmsg log_buf_len=1M printk.devkmsg=on, debug, rd.debug (смотреть: journalctl -ab). Для запуска отладочной оболочки (tty9, CTRL+ALT+F9) надо использовать ключ ядра systemd.debug_shell=1.

Подсистема systemd.generator позволяет преобразовать на ходу посторонние файлы настройки в юниты при загрузке и перечтении (reload) настройки systemd. Генераторы ищутся в /run/systemd/system-generators/, /etc/systemd/system-generators/, /usr/local/lib/systemd/system-generators/, /usr/lib/systemd/system-generators/, /run/systemd/user-generators/, /etc/systemd/user-generators/, /usr/local/lib/systemd/user-generators/ и /usr/lib/systemd/user-generators/. Генераторы запускаются в самом начале загрузки до syslog, systemd и монтирования дополнительных файловых систем. Получившийся юнит можно посмотреть в каталогах /run/systemd/generator{.early,,.late} и $XDG_RUNTIME_DIR/generator{early,,late} или с помощью "systemctl show имя-скрипта|имя-файловой-системы". Описание юнита в "родном" формате имеет приоритет над результатом работы генератора. Генераторы:

Сохранена совместимость с utmp/wtmp - systemd-update-utmp.service, ystemd-update-utmp-runlevel.service (systemd-update-utmp.service(8), systemd-update-utmp-runlevel.service(8), systemd-update-utmp(8)).

Кроме инициализации (init.scope) и управления системой (system.slice) systemd используется для управления сессиями пользователей (user.slice)

Утилиты:

systemctl

systemctl - основная управляющая утилита systemd. Файл настройки - /etc/systemd/system.conf.

Параметры system.conf:

Общие ключи:

Вывести документацию по юниту: systemctl help имя-юнита.

Получить список {активных | всех | несгенерированных} юнитов: systemctl [--all] [--type тип-юнита] [--state={active|failed}] {list-units|list-unit-files} [режим-работы].

Повторное чтение описаний юнитов: systemctl daemon-reload. Необходимо, например, при добавлении сервиса.

Перезапуск systemd: systemctl daemon-rexec.

Управление работой сервисов: systemctl {start|stop|reload|reload-or-restart|reload-or-try-restar|restart|try-restart} имя-юнита. При запуске сервиса все конфликтующие сервисы (и их зависимые?) останавливаются без запроса и извещения.

Узнать состояние юнита: systemctl {is-active|is-enabled|status [-n число-сообщений|-f]} имя-юнита.

Послать сигнал всем процессам сервиса: systemctl kill [-s имя-сигнала] [--kill-who=main] имя-юнита.

Управление запуском сервисов при загрузке, обращению к сокету и т.п.: systemctl {disable|enable|reenable|preset} имя-юнита.

Маскировка сервиса (сервис останавливается, ручной и автоматический запуск блокируется): systemctl {mask|unmak} имя-юнита (делается ссылка /etc/systemd/system/имя-юнита на /dev/null и "systemctl daemon-reload").

Управление режимом работы (аналог уровня в inittab): systemctl set-default {graphical.target|multi-user.target|rescue.target}. Ключ ядра systemd.unit=имя-режима при загрузке.

Узнать режим работы по умолчанию: systemctl get-default.

Какие сервисы запускаются в указанном режиме: systemctl show --no-pager -p "Wants" имя-режима (systemctl list-dependencies имя-юнита).

Зависимости юнитов: systemctl list-dependencies [{--before|--after} имя-юнита].

Узнать состояние текущих целей (режимов работы): systemctl list-units --type=target.

Выбрать режим работы прямо сейчас: systemctl isolate {graphical.target|multi-user.target|rescue.target}.

Посмотреть содержимое файла с описанием юнита: systemctl cat имя-юнита.

Посмотреть свойства юнита: systemctl show имя-юнита (229 штук в версии 239!).

Изменение свойств юнитов: systemctl set-property имя-юнита имя-свойства=значение.

Состояние системы (дерево системных сервисов и их процессов, а также пользовательских сеансов): systemctl status.

Перезагрузка: systemctl [--no-wall] {reboot|poweroff|halt|suspend|hibernate|hybrid-sleep|rescue|emergency} [--firmware-setup]. 7 Ctrl-Alt-Del в течении 2 секунд - немедленная перезагрузка.

Создание снимка текущего состояния юнитов и откатка к снимку: systemctl {snapshot|isolate}.

Показать юниты, которые не удалось запустить: systemctl --failed.

Сброс ошибок: systemctl reset-failed.

Зависшие задачи: systemctl list-jobs.

Вывести список виртуальных машин и контейнеров, совестимых с systemd; указывается состояние и число ошибок: systemctl list-machines.

Ключи /usr/lib/systemd/systemd:

Юниты systemd

Юнит имеет имя, зависимости, описание требуемых ресурсов и прочее. Описание юнита содержится в файлах подкаталогов system/ каталогов настройки systemd: /etc/systemd/{system,user}/ (локальные), /run/systemd/{system,user}/ (временные), /usr/lib/systemd/{system,user}/ (дистрибутивные). Имя и тип юнита определяются именем файла с описанием. Дополнения к настройкам могут быть помещены в каталог имя-юнита.тип.d в файлах с суффиксом .conf. Дополнительно в каталогах имя-юнита.тип.wants и имя-юнита.тип.requires могут быть символьные ссылки на описания юнитов, которые желательно или требуется активировать. Формат был выбран похожим на формат .ini файлов MS Windows, текстовый файл делится на секции, имя секции на отдельной строке в квадратных скобках, имя параметра и значение разделены символом "=" на отдельной строке. Несколько значений разделяются пробелами.

Сервисы могут присутствовать в нескольких экземлярах - имя-сервиса@идентификатор-экземпляра.service, например, getty@tty1.service. В этом случае systemd сначала пытается найти описание сервиса с таким именем, а при неудаче отбрасывает идентификатор-экземпляра и использует найденный файл как шаблон описания юнита.

Макросы в описании юнитов:

Секция Unit описывает юнит, параметры:

Секция Service описывает поведение юнита сервиса:

Секция Socket описывает поведение юнита сокета:

Секция Install (обрабатывается командами enable и disable) описывает когда должен запуститься сервис:

Пример своего сервиса (/usr/lib/systemd/system/имя-сервиса.service):

[Unit]
Description=Confluence
After=network.target nss-lookup.target

[Service]
Type=forking
WorkingDirectory=/home/confluence/atlassian-confluence-5.9.7
ExecStart=/home/confluence/atlassian-confluence-5.9.7/bin/start-confluence.sh
PIDFile=/home/confluence/atlassian-confluence-5.9.7/work/catalina.pid
ExecStop=/home/confluence/atlassian-confluence-5.9.7/bin/stop-confluence.sh
ExecReload=/home/confluence/atlassian-confluence-5.9.7/bin/stop-confluence.sh | sleep 60 | /home/confluence/atlassian-confluence-5.9.7/bin/start-confluence.sh
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=Confluence
SyslogFacility=daemon
IOSchedulingClass=best-effort
Restart=on-failure

[Install]
WantedBy=multi-user.target

systemd-logind и loginctl

systemd-hostnamed, systemd-resolved

Ссылки

@ Карта сайта News Автора!

Bog BOS: Загрузка Linux

Linux Linux: дистрибутивы RPM yum Установщик Linux anaconda Загрузка Linux

Последние изменения:
2024.11.22: sysadmin: systemd-journald (централизованное хранение)
2024.11.11: sysadmin: Linux: пространства имён
2024.11.06: sysadmin: настройка TCP/IP в Linux: виртуальный интерфейс и виртуальный мост
2024.10.25: sysadmin: Linux VFS, атрибуты, расширенные атрибуты, ACL



Copyright © 1996-2024 Sergey E. Bogomolov; www.bog.pp.ru