Внутреннее устройство Linux
Шрифт:
У команды systemd так много функций, что довольно трудно понять, с чего начать изучение основ. В общих чертах опишу, что происходит, когда во время загрузки системы запускается команда systemd.
1. Команда systemd загружает свою конфигурацию.
2. Команда systemd определяет цель загрузки, которая обычно называется default.target.
3. Команда systemd определяет все зависимости для цели загрузки по умолчанию, зависимости зависимостей и т. д.
4. Команда systemd активизирует зависимые процессы и цель загрузки.
5. После загрузки команда systemd может реагировать на системные события (такие как uevents) и активизировать дополнительные компоненты.
При запуске служб команда systemd
6.4.1. Модули и типы модулей
Одним из самых интересных свойств команды systemd является то, что она не только управляет процессами и службами, но способна также монтировать файловые системы, отслеживать сетевые сокеты, запускать таймеры и многое другое. Каждый тип таких возможностей называется типом модуля, а каждая конкретная способность — модулем. Когда вы задействуете какой-либо модуль, вы активизируете его.
Вместо того чтобы описывать все типы модулей (вы найдете их на странице руководства systemd(1)), рассмотрим лишь некоторые из них, которые выполняют задачи запуска в любой системе Unix.
• Модули служб. Контролируют традиционные демоны служб в системе Unix.
• Модули монтирования. Контролируют присоединение файловых систем.
• Целевые модули. Контролируют другие модули, как правило группируя их.
По умолчанию целью загрузки обычно является целевой модуль, который группирует несколько служб и монтирует модули в качестве зависимостей. В результате довольно легко получить частичное представление о том, что происходит при загрузке системы. Можно даже составить дерево зависимостей с помощью команды systemctl dot. Вы обнаружите, что это дерево достаточно обширное, поскольку многие модули не запускаются по умолчанию.
На рис. 6.1 приведена часть дерева зависимостей для модуля default.target, который можно найти в системе Fedora. При активизации этого модуля все расположенные под ним модули также активизируются.
Рис. 6.1. Дерево зависимостей модуля
6.4.2. Зависимости команды systemd
Зависимости при загрузке системы и ее работе гораздо сложнее, чем могут показаться на первый взгляд, поскольку жесткие зависимости не допускают изменений. Например, вы решили, что приглашение ко входу в систему будет отображаться после запуска сервера базы данных, поэтому вы определяете зависимость приглашения от сервера базы данных. Однако если с сервером базы данных случится сбой, то в результате указанной зависимости приглашение ко входу в систему также не появится, и вы не сможете даже войти в систему, чтобы исправить ошибку.
Задачи запуска системы Unix довольно терпимо относятся к ошибкам и зачастую сбои в задачах не вызывают серьезных проблем в стандартных службах. Например, если диск с данными для системы будет удален, но запись о нем в таблице /etc/fstab останется, то начальное монтирование файловой системы не осуществится. Однако такой сбой обычно не вызовет серьезных последствий в стандартной работе системы.
Чтобы приспособиться к требованиям гибкости и устойчивости к сбоям, команда systemd предлагает огромное
количество типов и стилей зависимостей. Обозначим их по ключевым словам синтаксиса, но подробно этот синтаксис будет рассмотрен в подразделе 6.4.3. Посмотрим сначала на главные типы.• Requires. Жесткие зависимости. При активизации модуля с зависимостью Requires команда systemd пытается активизировать модуль зависимости. Если модуль зависимости дает сбой, то команда systemd деактивизирует зависимый модуль.
• Wants. Зависимости, предназначенные только для активизации. Во время активизации какого-либо модуля команда systemd активизирует его Wants-зависимости, но не обращает внимания, если они дают сбой.
• Requisite. Модули, которые уже должны быть активными. Перед активизацией модуля с зависимостью Requisite команда systemd сначала проверяет состояние зависимости. Если такая зависимость еще не была активизирована, команда systemd дает сбой при активизации модуля с этой зависимостью.
• Conflicts. Противоположные зависимости. При активизации модуля с зависимостью Conflict команда systemd автоматически деактивизирует такую зависимость, если она активна. Одновременная активизация двух конфликтующих модулей вызовет сбой.
примечание
Тип зависимостей Wants особенно важен, поскольку он не распространяет ошибки на другие модули. В документации к команде systemd заявлено, что именно таким образом следует по возможности определять зависимости. Это позволит создать гораздо более устойчивую систему, подобную той, которая применяет традиционную команду init.
Зависимости могут быть также подключены «реверсивно». Например, чтобы добавить модуль А в качестве Wants-зависимости для модуля Б, не обязательно добавлять зависимость Wants в конфигурацию модуля Б. Вместо этого можно указать его как WantedBy-зависимость в конфигурации модуля А. То же самое верно и для зависимости RequiredBy. Конфигурация (а также результат) зависимости “By” немного сложнее, чем простое редактирование файла с настройками (см. пункт «Подключение модулей и секция [Install]» в подразделе 6.4.3).
Увидеть зависимости какого-либо модуля можно с помощью команды systemctl. С ее помощью можно также указать тип зависимости, например Wants или Requires:
# systemctl show -p type unit
Порядок следования
Ни один из вариантов синтаксиса, который вы видели, не определяет явным образом порядок следования модулей. По умолчанию активизация модуля с зависимостью Requires или Wants ведет к тому, что команда systemd активизирует одновременно все такие зависимости в качестве первого модуля. Это оптимально, поскольку необходимо запустить по возможности максимальное количество служб, причем максимально быстро, чтобы сократить время загрузки системы. Однако бывают ситуации, когда один модуль должен быть запущен после другого. Например, в системе, которая изображена на рис. 6.1, настроен запуск модуля default.target после модуля multi-user.service (этот порядок следования не отображен на иллюстрации).
Чтобы активизировать модули в определенном порядке, можно использовать следующие модификаторы зависимостей.
• Before. Текущий модуль будет активизирован до указанного модуля или модулей. Например, если в модуле foo.target будет инструкция Before=bar.target, команда systemd активизирует модуль foo.target перед модулем bar.target.
• After. Текущий модуль будет активизирован после перечисленного модуля или модулей.
Условные зависимости