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

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

Последние изменения:
2024.05.03: sysadmin: От CentOS 7 к Rocky Linux 8

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

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 диска; RAM диск содержит образ файловой системы с модулями (драйверами) устройств, необходимыми для монтирования корневой файловой системы; в случае со встроенным Linux RAM диск содержит всю систему
  4. ядро повторно обходит и инициализирует периферийные устройства, для которых есть встроенные драйвера
  5. ядро монтирует RAM диск (предварительно разжав) и загружает с него необходимые модули, инициализирует соответствующие устройства - dracut
  6. ядро размонтирует RAM диск и освобождает занимаемую им память
  7. ядро монтирует корневую файловую систему в режиме "только чтение"; в процессе дальнейшей работы ядро загружает дополнительные модули с корневой файловой системы
  8. запускается процесс /usr/lib/systemd/systemd
  9. тут будет длинный рассказ после того как 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-сокеты для общения между процессами. Контролирует состояние юнитов и реагирует на их изменение, перезапускает юнит при аварийном завершении, собирает сообщения. Позволяет активировать сервисы по зависимостям, обращению к портам и сокетам (замена inetd, xinetd.service), обращению D-Bus, по расписанию (замена cron), по активации обрудования (udev), обращению к файлу или каталогу. Сервисы наследуют окружение процесса 1, а не от оболочки, в которой запускается скрипт service. Осуществляется проверка на зацикливание зависимостей с попыткой автоматического удаления желаемых (Wants), но не обязательных зависимостей. Аналогично inetd слушает требуемые сервисами сокеты (сетевые порты) используя специальные юниты (.socket) для их создания и передаёт их процессам юнитов при необходимости, это также позволяет не терять сообщения при перезапуске сервисов - сообщения встают в очередь к незакрываемому на время перезапуска сокету. Сервисы, зависимые от базовых сервисов (точнее от интерфейсных сокетов), могут быть запущены без ожидания завершения запуска базового сервиса. Для ожидания монтирования файловой системы или доступа к конкретному файл используется механизм autofs (.mount, .automount и .path).

При запуске головного процесса юнита помещает его в отдельную контрольную группу (cgroup), в которую попадают все его потомки, что позволяет аккуратно завершить все процессы юнита (в прошлой жизни использовались setsid, установление лидера группы процессов и т.д.). Посмотреть имена групп можно командой "ps xawf -eo pid,user,cgroup:80,args" или systemd-cgls, которые выводят дерево процессов.

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

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

Файлы настройки в /etc/systemd (пользовательские), /run/systemd/system/ (временные), /usr/lib/systemd/ (дистрибутивные). Основной файл - /etc/systemd/system.conf, описание юнитов в подкаталогах system/.

Сервисы systemd:

Подсистема 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 имя-скрипта|имя-файловой-системы". Описание юнита в "родном" формате имеет приоритет над результатом работы генератора. Генераторы:

Сохранён интерфейс /dev/initctl для работы старых программ (shutdown, poweroff?) - сервис транслирующий старые команды в обращение через D-Bus (systemd-initctl.socket, systemd-initctl.socket(8), systemd-initctl.service, systemd-initctl.service(8)).

Сохранена совместимость с 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.

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

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

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

Управление работой сервисов: systemctl {is-active|status|start|stop|reload|restart|mask|unmask|show} имя-юнита (show показывает все параметры юнита - 229 штук в версии 239!).

Управление запуском сервисов при загрузке, обращению к сокету и т.п.: systemctl {is-enabled|disable|enable|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=имя-режима. Сервис debug-shell обеспечивает оболочку во время загрузки (enable).

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

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

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

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

Привычный /etc/rc.local лежит в /etc/rc.d/rc.local, настройки systemd сервиса rc-local расположены в /usr/lib/systemd/system/rc-local.service, запускается в режиме multi-user.target после network.target, предварительно необходимо дать права на выполнение

chmod u+x /etc/rc.d/rc.local

Удалённое управление (ключ --hostname) производится через ssh (зачем это? почему нельзя просто использовать ssh? эадел для замены в будущем ssh?).

Юниты systemd

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

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

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

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

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

Пример своего сервиса (/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

Последние изменения:
2024.05.03: sysadmin: От CentOS 7 к Rocky Linux 8



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