Система инициализации Systemd. Часть I

Наверное, все уже слышали о новой системе инициализации systemd, которая разрабатывается под опекой Red Hat и Novell. Я решил перевести описание работы этой системы от ее автора из его же блога. Сама статья оказалась слишком большой, поэтому выкладываю пока только ее первую часть. Вторую часть я выложу в течение пары дней. Ссылка на оригинал традиционно приведена в конце поста. Также традиционно, мои комментарии по тексту приведены курсивом.

Если вы в теме и умеете хорошо читать между строк, то уже знаете, о чем пойдет речь. Но, думаю, все равно вам будет интересна эта статья. Поэтому налейте себе чашечку кофе, садитесь и читайте о том, что грядет.

История долгая, а для тех, кто не хочет читать целиком, скажу вкратце: мы экспериментируем с новой системой инициализации, и это весело!

Здесь код. А вот сама история:

 

Роль процесса с PID 1

Каждая Unix-система имеет процесс со своим специальным идентификатором, равным 1. Этот процесс запускается ядром прежде всех остальных и является родительским процессом для всех процессов, которые не имеют собственного родителя. Благодаря этому он может делать много чего такого, что не могут остальные процессы. Например отвечает за такие вещи, как инициализация и поддержка работы пользовательского пространства в процессе загрузки системы.

Исторически на Linux в качестве такого процесса выступает старый добрый sysvinit, преклонный возраст которого сказывается все чаще и чаще. Многие пытались предложить ему замену, но реально прижился только Upstart (что интересно, один из вариантов перевода слова «upstart» — «выскочка» — прим. перев.), который уже нашел свое место во всех основных дистрибутивах.

Как уже отмечалось выше, главная обязанность init’а — максимально быстро инициализировать и сделать доступным пользовательское пространство. К сожалению, традиционная схема инициализации SysV делает это не так быстро, как хотелось бы.

Для организации быстрого и эффективного процесса загрузки системы решающее значение имеет следующее:

  • Запустить минимум необходимого.
  • Попытаться запустить параллельно всё остальное.

Что это означает на практике?

Запустить минимум необходимого означает запустить лишь самые необходимые сервисы либо отложить запуск каких-либо из них до тех пор, пока они реально не понадобятся. Иногда мы заранее знаем, какие сервисы нам понадобятся (syslog, системная шина D-Bus и т.п.), но так бывает не всегда. К примеру, демон bluetoothd не должен быть запущен то тех пор, пока не будет подключен Bluetooth-адаптер либо пока какое-то из приложений не захочет установить с ним соединение через интерфейс D-Bus. Аналогично для системы печати: если машина физически не подключена к принтеру, и/или никакие приложения не пытаются напечатать что-нибудь, то необходимости запускать демон печати, такой как CUPS, нет. Так же и для Avahi: если машина не подключена к сети, или пока никакое из приложений не захочет использовать его API, его также нет необходимости запускать. Это справедливо даже для SSH: пока кто-либо не захочет зайти на машину — в нем нет необходимости, его нужно запустить лишь тогда, когда кто-то захочет установить первое соединение (и это же относится ко многим машинам, где может быть запущен ssh, в тех случаях, когда к нему присоединяются раз месяц или реже).

Параллельный запуск всего остального означает, что если нужно что-либо запустить, то мы должны делать это не последовательно, а пытаться запустить все одновременно, чтобы максимально нагрузить имеющиеся ресурсы системы, сократив время ее запуска.

Динамическое изменение аппаратного и программного обеспечения

Современные системы (в частности операционные системы общего назначения) являются весьма динамичными в плане своей конфигурации и использования: они мобильны, запускают и останавливают различные приложения, к