Devuan: плод нелюбви к systemd

Автор: Евгений Голышев

Статья была опубликована в 237-м выпуске журнала Linux Format. По истечении полугода с момента публикации права на статью переходят ее автору, поэтому материал публикуется в нашем блоге.

Кена Томпсона [Ken Thompson] однажды спросили, что бы он изменил в UNIX, если бы проектировал систему заново, и он ответил: «Я бы написал creat с буквой e» (англ. I’d spell creat with an e). Эта шутка, на мой взгляд, как ничто другое подчеркивает, насколько бережно Unix хранит традиции: за 40 с лишним лет так никто и не добавил букву e к имени системного вызова, хотя количество опечаток, допущенных при написании кода, велико и с каждым днем продолжает расти. В конце концов, кто может осмелиться сказать, что архитектурные решения патриархов Томпсона и Ритчи ошибочны?

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

И однажды в этот мир вторгся человек по имени Леннарт Пёттеринг [Lennart Poettering], со своим видением дистрибутивостроения, которое, по мистическому совпадению, в корне отличалось от того, к которому все успели привыкнуть за пару десятков лет. Всё бы ничего, но Леннарт родился с редкой способностью изменять всё вокруг, поэтому он легко начал воплощать свои задумки, а через крупнейшие дистрибутивы (Debian, Ubuntu, Red Hat Enterprise Linux, SUSE Linux Enterprise и т. д.) они стали добираться до согласных и несогласных с ним пользователей.

Леннарт полон неоднозначных идей того, каким образом дистрибутивы GNU/Linux можно сделать лучше.

Данная статья посвящена Devuan (читается как DevOne). Devuan является производным от Debian GNU/Linux дистрибутивом, основная цель которого заключается в альтернативном развитии Debian, как если бы он никогда не встретился с известным детищем Леннарта под названием systemd. Я написал эту статью главным образом по двум причинам.

Во-первых, Debian-подобные дистрибутивы – моя страсть, а Devuan, один из ярких представителей этого семейства, упоминался на страницах LXF только вскользь, поэтому я чувствую своим долгом исправить это недоразумение.

Во-вторых, я хочу помочь читателям разобраться в ситуации, сложившейся вокруг проекта systemd, а также понять, что побудило разработчиков Devuan потратить два с половиной года на то, чтобы «вытравить» systemd из Debian Jessie, получив таким образом первую стабильную версию производного дистрибутива.

В конце концов, если человек в один прекрасный момент поймет, что ненавидит systemd, то пусть хотя бы будет способен объяснить, почему.

К счастью или сожалению, материал не содержит информации, которая могла бы оказаться полезной при

  • установке, настройке и администрировании серверов под управлением Devuan;
  • администрировании серверов на базе Linux-подобных операционных систем, использующих systemd (если вы интересуетесь практиче­ской стороной systemd, то рекомендую обратиться к LXF199).

Хочу сразу отметить, что я не являюсь пользователем Devuan, предпочитая ему Debian (рабочая станция) и Ubuntu (ноутбук), и стараюсь занимать нейтральную позицию в спорах, связанных с действиями Леннарта Пёттеринга в общем и с systemd в частности. Но разочаровываться не стоит – я регулярно имею дело с Devuan при решении различных задач, одной из которых является разработка сервиса для кастомизации образов операционных систем для одноплатных компьютеров.

А теперь предлагаю начать обсуждение заявленных тем… но обо всём по порядку.

В погоне за ускорением загрузки

В конце 2000‐х несколько крупных производителей операционных систем на базе ядра Linux пришли к выводу, что необходимо ускорять время загрузки своих систем. Так как за загрузку операционной системы отвечает система инициализации, стало очевидно, что начинать нужно именно с нее. В течении долгого времени дистрибутивы GNU/Linux использовали для этих целей SysVinit, созданную Микéлем ван Смооренбургом [Miquel van Smoorenburg] и основанную на идеях оригинальной System V init. SysVinit сейчас считается классиче­ской системой инициализации и в данной статье противопоставляется всем другим.

SysVinit представляет собой систему инициализации, основанную на уровнях запуска (runlevel-based). Уровни запуска – это состояния, в которых может находиться система; система переходит из одного состояние в другое. SysVinit выполняет скрипты, ассоциированные с определенным уровнем, когда система входит в (или покидает) этот уровень. К примеру, когда система входит в уровень запуска N, то SysVinit запускает скрипты из /etc/rcN.d, где N — число от 0 до 6. Однако со временем накопилось много потребностей, которые классиче­ская система инициализации не могла удовлетворить в силу своей архитектуры (к примеру, слежение за своими дочерними процессами и их перезапуск в случае необходимости).

Недостатки SysVinit мотивировали компанию Canonical, которая является основным разработчиком Ubuntu, начать работу над альтернативной системой инициализации под названием Upstart, а достоинства launchd из Mac OS X и SMF из Solaris послужили основным источником ценных идей, которые помогли в решении поставленной задачи. Новая система инициализации оказалась эффективнее, чем SysVinit благодаря событийно-ориентированной архитектуре (event-driven architecture). Системные сервисы стало возможным запускать и останавливать на основе событий, а не уровней запуска. Данный подход предполагал генерацию событий при запуске или остановке системных сервисов, что позволило организовать привязку к ним других сервисов.

Таким образом, для определения последовательности запуска сервисов и оценки возможности их выполнения в параллельном режиме был взят на вооружение метод учета зависимостей. Работа в тандеме с ядром, которое также стало развиваться в сторону событийно-ориентированной архитектуры, благодаря чему появилась возможность асинхронной загрузки драйверов, заметно сократила время от нажатия кнопки включения до полной готовности всей системы. И при всём при этом Upstart была разработана с оглядкой на обратную совместимость с SysVinit.

Upstart дебютировала в Ubuntu 6.10 «Edgy Eft» в конце 2006 г., заменив SysVinit (однако окочательно новая система инициализации была интегрирована в дистрибутив только к выходу Ubuntu 9.10 «Karmic Koala»). Затем на Upstart обратили внимание компании Google и Red Hat, интегрировав ее в свои продукты. Так Upstart нашла применение за пределами Ubuntu и начала использоваться в ChromeOS и Red Hat Enterprise Linux 6. На новую систему инициализации даже планировал перейти Debian.

При всех своих достоинствах, Upstart оказалась всего лишь трамплином для другой, более совершенной системы инициализации. Так, в апреле 2010 г. компания Red Hat, при участии разработчиков из Novell, IBM, Intel и Nokia, поставила перед собой цель создать систему инициализации, нацеленную на более интенсивную параллелизацию выполнения сервисов на этапе загрузки. Проект, получивший название systemd, возглавил Леннарт Пёттеринг. И уже в июле того же года была выпущена первая стабильная версия проекта.

На тот момент systemd получала не больше негативной критики, чем любой другой проект, позиционирующий себя как альтернативная система инициализации. Всё шло относительно гладко, несмотря на то что systemd (почти) сразу обратила на себя внимание своим агрессивным подходом к делам, связанным с обратной совместимостью. (К примеру, если Upstart была совместима со скриптами инициализации SysVinit, то новейшая система инициализации не была завязана ни на Bash, ни на любую другую оболочку.) Ситуацию не сильно усугубил и тот факт, что именно Леннарт был тем самым разработчиком звукового сервера PulseAudio, который в начале своего пути не отличался стабильностью работы (в основном из-за аудиодрайверов, а не ошибок в коде PulseAudio).

Проекту серьезно досталось немного позднее, когда в один прекрасный день systemd перестал позиционироваться как альтернативная система инициализации, превратившись в системный менеджер, в котором система инициализации стала всего лишь одним из многочисленных компонентов. О двух таких компонентах — journald и logind — я хочу рассказать прямо сейчас.

logind представляет собой систему управления пользовательскими сеансами. До того, как за решение этой задачи взялись разработчики systemd, дистрибутивы GNU/Linux для этих целей использовали ConsoleKit. В свое время ConsoleKit поставил перед собой амбициозную цель – поддержку более одного независимого рабочего места (multi-seat), что предполагает одновременную работу на одной системе нескольких независимых графических сеансов для различных пользователей. (Функция редкая, но в некоторых случаях очень востребованная.) Тем не менее, архитектура ConsoleKit не способствовала достижению заветной цели и проект оказался в глубокой стагнации. Так, без переизобретения велосипеда непростая задача поддержки более одного независимого рабочего места была решена в рамках компонента logind. Другими словами, лучшей альтернативы в мире Linux еще не видели. Более того, решение оказалось настолько удачным, что Энди Винго (Andy Wingo), один из разработчиков дистрибутива Guix, реализовал возможность обособленного использования logind. Проект получил название elogind (по аналогии с eudev). На elogind даже перешел Devuan, который, напомню, принципиально не использует systemd; но об этом немного позже.

journald представляет собой сервис журналирования событий. Этот компонент, в свою очередь, является отличным примером того, как разработчики systemd не только решили задачу, которая давно не нуждалась в решении, но и решили ее по-своему. Двумя основными отличиями journald от различных реализация syslogd, которые много лет занимались задачами журналирования в Unix, являются использование криптографиче­ских средств для гарантирования неизменности и целостности накопленных логов и хранение этих логов в двоичном виде. Традиционно логи на Unix-серверах хранятся в текстовом виде, поэтому хранение логов в двоичном виде воспринимается как недостаток, который обесценивает любые достоинства journald, даже такие крутые, как гарантию неизменности и целостности логов. Подробнее о journald можно узнать из LXF191/192 и LXF199.

Появление Devuan

В конце 2013-го – начале 2014-го Debian в очередной раз вернулся к актуальной для себя задаче – переходу на более современную систему инициализации. В каче­стве кандидатов рассматривались Upstart и systemd, и по результатам голосования победила последняя. Следом за Debian пошла Ubuntu.

По итогам интеграции systemd в Debian дистрибутив не только перешел на новую систему инициализации, но и оказался сильно завязанным на системном менеджере, который был призван управлять всеми аспектами работы системы. В итоге, systemd был поставлен в один ряд с ядром и стандартной библиотекой языка C, для которых в дистрибутиве не предусмотрены альтернативы. Jessie стал первым выпуском Debian, который не мог функционировать без systemd. Таким образом, группа разработчиков Veteran Unix Admins, которые были не согласны с этой политикой, выпустили в рамках проекта Devuan свободную от systemd версию Jessie. Чтобы этого добиться, разработчикам потребовалось внести изменение в 381 пакет. Так появился первый выпуск Devuan, позволивший пользователям Debian использовать или не использовать systemd в зависимости от их желания.

Второй в истории лидер проекта Debian является пользователем Devaun.

В качестве системы инициализации в Devuan по умолчанию используется SysVinit, которая сейчас более-менее активно развивается. Дело в том, что версия 2.89, выпущенная 28‐го марта 2018-го года, была первой за 8 лет стагнации проекта, но с приходом Джесса Смита [Jesse Smith], который занял пустующее кресло сопровождающего проекта, ситуация резко изменилась.

Различные новостные ресурсы, освещающие достижения открытого и свободного программного обеспечения, позиционируют Devuan как борца за независимость от systemd (отчасти это объясняется тем, что самыми оперативными оказываются информационные источники, пополняемые сообществом, а профессиональные издания, как правило, чуть медленнее реагируют на события и потому постоянно догоняют первых по горячим следам). С одной стороны, это позволило быстро обратить на проект внимание, сделав Devuan звездой мира СПО. С другой стороны, это искажает оригинальные цели проекта – свободе выбора системы инициализации. Сейчас с полной уверенностью можно утверждать, что Devuan добился этой цели: во втором выпуске дистрибутива, известном под кодовым именем ASCII, который вышел 9 июня 2018 г., пользователям помимо SysVinit предлагается OpenRC, которая используется в Alpine Linux и Gentoo.

Заключение

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

Что касается фактов, то systemd является образцом отлично написанного системного программного обеспечения, а в сообществе разработчиков царят мир, гармония и взаимоуважение. Леннарт, в свою очередь, является примером отличного лидера, который, ко всему прочему, еще и невероятно креативен – пишет много и интересно, освещая различные особенности Unix в своем блоге. Но чутье подсказывает, что где-то здесь должен быть подвох. И он действительно есть. Когда в рамках systemd решаются какие-то задачи, то разработчики, как правило, подходят к их решению по-своему и без оглядки на обратную совместимость, посягая на святая святых – традиции Unix (к примеру, я почувствовал легкое недомогание, когда первый раз прочитал новость о том, что journald предлагает хранить логи в двоичном виде). Именно здесь и начинаются конфликты интересов. Но не все решения разработчиков systemd так уже плохи. Об этом свидетельствует тот факт, что некоторые компоненты systemd уже используются в дистрибутивах, которые сознательно отказываются от systemd как от системы инициализации.

Имена доверьте авторам

Есть иногда у некоторых проектов такие имена, глядя на которые, не сразу возможно угадать их правильное произношение (под «правильным» я в данном случае подразумеваю принятое в сообществе). Обычно в таких случаях необходимо обратиться к FAQ’у или истории этих проектов. В каче­стве примера на ум приходят web-сервер Lighttpd (читается как lighty) и Nginx (читается как engine-x). (Очень забавно, когда люди с серьезным выражением лица рассказывают о некоем web-сервере под названием Энгинкс.) Но история с именами на этом не заканчивается.

Есть и такие проекты, авторы которых настаивают на строгом написании названий своих детищ. Однако все мы привыкли к тому, что слова, с которых начинаются предложения, пишутся с большой буквы. А еще мы помним, что с заглавной буквы всегда пишутся все имена собственные. Но в школе обычно не учат тому, что всем этим правилам нужно следовать только в том случае, если они не противоречат правилу написания конкретного имени. В каче­стве примеров проектов, с которыми нужно считаться с этой точки зрения, хочу привести ownCloud и, конечно, systemd. Таким образом, в каком бы месте предложения ни стояли эти имена, после какого бы знака препинания не шли – они должны сохранять авторский вариант написания.

В заключение, думаю, что нужно сказать пару слов о том, почему следует писать systemd с маленькой буквы несмотря на то, что это имя собственное. Дело в том, что проект был назван по имени основного исполняемого файла, который запускается первым при загрузке системы, становясь процессом с номером 1 и родителем всех остальных процессов. Традиционно (и тут тоже традиции!) в UNIX и C, родного для этой ОС языка, использовался нижний регистр, поэтому одна из ключевых программ в Linux-подобной операционной системе могла быть названа только systemd, а не Systemd, SystemD или как-то еще.

Raspbian: сборка образа. Часть 2

Автор: Евгений Голышев

Статья была опубликована в 236-м выпуске журнала Linux Format. По истечении полугода с момента публикации права на статью переходят ее автору, поэтому материал публикуется в нашем блоге.

Тема сборки минимально функциональной версии Raspbian продолжается. Эту часть я хочу начать с обсуждения несправедливо забытого термина JeOS (читается как juice). Этот термин, который, кстати, расшифровывается как «just enough operating system», был очень популярен лет десять назад, когда производители коммерческих дистрибутивов GNU/Linux были увлечены разработкой инструментов для индивидуальной настройки [customization] операционных систем. JeOS – это подход, согласно которому для решения какой-то конкретной задачи достаточно взять минимально возможную версию операционной системы и установить поверх нее зависимости, необходимые для запуска одного конкретного приложения, решающего эту задачу. Таким образом, решение получается самодостаточным и максимально эффективным с точки зрения производительности. В зависимости от инструмента, помогающего кастомизировать операционные системы, конечный результат был пригоден для запуска как на реальной, так и в виртуальной машине. Самым ярким из этих инструментов был SUSE Studio, который неоднократно освещался на страницах Linux Format (к примеру, в LXF125 и LXF138). Он одним из первых начал широко использовать термин «виртуальное устройство [virtual appliance]», который означает операционную систему узкого назначения вкупе с целевым приложением, пригодную для запуска в виртуальной машине. Но времена меняются, и всё чаще для решении какой-то конкретной задачи выделяется целый Raspberry Pi или любой другой одноплатный компьютер. Терминология здесь еще недостаточно проработана, и необходимо это исправить. Назовем, к примеру, подготовленный в первой части этого руководства образ минимально функциональной версии Raspbian термином JeOSI (предлагаю произносить его как juicy). По аналогии с JeOS новый термин расшифровывается как «just enough operating system image». С переводом будет немного сложнее. Дело в том, что словосочетание «just enough» в данном случае является наречием, а не существительным, что делает эти термины больше похожими на слоганы, чем на что-то другое. После нескольких часов размышлений я не придумал ничего лучше, чем «достаточно просто операционной системы» [можно также перевести как «ОС в обрез», – прим. ред.] для JeOS и «достаточно просто образа операционной системы» для JeOSI (как рекламный слоган популярного в 1990-х растворимого напитка Invite – «просто добавь воды»). На самом деле куда важнее, что JeOSI может сбить с толку тем, что перекликается с сетевой моделью OSI или некоммерче­ской организацией Open Source Initiative, название которой также часто сокращается до OSI; но более удачного термина я пока предложить не могу.

Итак, пора определиться с целями второй части учебника.

Показанный в первой части подход позволяет собирать минимально функциональные образы для Raspberry Pi на основе Debian-подобных дистрибутивов. Прежде чем написать статью, я успел опробовать этот подход на Raspbian, Devuan и Ubuntu. Однако именно Raspbian использовался в качестве примера для демонстрации сборки образа на протяжении всей первой части руководства, т.к. он является «родным» для RPi. Таким образом, выбор в пользу этого дистрибутива был исключительно символическим, и нет никаких препятствий в использовании любого другого основанного на Debian дистрибутива. Экспериментируйте.

Особенность второй части учебника заключается в том, что она в основном состоит из набора не зависящих друг от друга рецептов, которые (каждый по-своему) предлагают сделать полученный в предыдущей части образ более полезным с практической точки зрения. Поэтому эту часть учебника можно читать как от начала до конца, так и выборочно, переходя только к тем рецептам, которые представляют наибольший интерес, без риска для понимания идущего за ними (или перед ними) материала. Вторая часть учебника предполагает наличие образа, который у вас должен был появиться после работы с первой частью. Создайте где-нибудь две директории – boot и rootfs – и смонтируйте в них загрузочный и корневой раздел соответственно.

$ sudo mkdir /mnt/boot /mnt/rootfs
$ LOOP_DEV=$(sudo losetup --partscan --show --find raspbian-stretch.img)
$ sudo mount ${LOOP_DEV}p1 /mnt/boot
$ sudo mount ${LOOP_DEV}p2 /mnt/rootfs

А теперь – вперед.

Поддержка сети

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

SUSE Studio был пионером и отличным примером решения в области кастомизации операционных систем.
SUSE Studio был пионером и отличным примером решения в области кастомизации операционных систем.

Raspbian использует системный менеджер systemd, который, помимо всего прочего, пытается решить проблему с именованием сетевых интерфейсов. Таким образом, в рамках systemd 197, который вышел 7 января 2013 г., в udev была добавлена поддержка т. н. «предсказуемых имен сетевых интерфейсов [Predictable Network Interface Names]». И первым делом я предлагаю отключить эту поддержку. Во-первых, по иронии судьбы предсказуемые имена не всегда предсказуемы. Во-вторых, в случае RPi и его единственного проводного сетевого интерфейса нет никакой проблемы с именованием. В-третьих, я хочу, чтобы этот учебник был применим ко всем производным от Debian дистрибутивам, которые могут по тем или иным причинам не использовать systemd.

Чтобы отключить поддержку предсказуемых имен сетевых интерфейсов, необходимо добавить два следующие параметра к командной строке ядра, которая содержится в cmdline.txt на загрузочном разделе.

net.ifnames=0 biosdevname=0

Для этого добавьте в самое начало файла cmdline.txt, который находится на загрузочном разделе, эти два параметра, отредактировав файл вручную или воспользовавшись следующей командой:

$ sudo sh -c "echo 'net.ifnames=0 biosdevname=0 $(cat /mnt/cmdline.txt)' > /mnt/boot/cmdline.txt"

Если на данном этапе вы запишете образ на SD-карту, загрузите с нее устройство и выполните

$ ip link show

то увидите в списке всем хорошо знакомый eth0.

Следующим шагом необходимо разобраться с «именем хоста [hostname]». Дело в том, что debootstrap (см. первую часть учебника) назвал chroot-окружение именем системы, в которой оно собиралось, поэтому две ваши машины – RPi и та, на которой происходила сборка окружения – сейчас имеют одинаковые имена. Это необходимо исправить. Для этого придумайте новое имя для RPi и добавьте его в /etc/hostname и /etc/hosts, к примеру, следующим образом:

$ sudo sh -c "echo raspbian-jeosi > /mnt/rootfs/etc/hostname"
$ sudo sed -i '2i 127.0.0.1\traspbian-jeosi' /mnt/rootfs/etc/hosts

В данном случае в качес тве имени использовалось raspbian-jeosi. Назовите машину с учетом ваших личных вкусов и предпочтений, но помните, что согласно RFC 952 имена хостов не должны превышать 24-х символов; в качестве символов, из которых разрешается составлять имена – буквы латинского алфавита в верхнем и нижнем регистре, цифры, знак минуса (-) и точка (.).

В заключение необходимо установить пакеты, которые содержат DHCP-клиент, ряд вспомогательных утилит типа ping, всё необходимое для взаимодействия устройства с другими устройствами в сети (на базе стека протокола TCP/IP, разумеется) и SSH-сервер, ради которого всё это затевалось

$ sudo chroot /mnt/rootfs apt-get update
$ sudo chroot /mnt/rootfs apt-get install netbase net-tools iscdhcp-client inetutils-ping openssh-server

а также отредактировать конфигурационный файл /etc/network/interfaces, добавив в него следующее содержимое:

auto lo
iface lo inet loopback
auto eth0
allow-hotplug eth0
iface eth0 inet dhcp

И хотя после всех этих манипуляций образ наконец имеет всё необходимое, чтобы работать в Сети, остается одна небольшая про­блема с подключением к SSH-серверу. Дело в том, что OpenSSH, который достался дистрибутиву от Debian, сконфигурирован таким образом, чтобы не разрешать вход от имени root с парольной аутентификацией. Решить эту проблему можно одним из двух способов: либо измените в /etc/ssh/sshd_config текущее значение PermitRootLogin на yes, включив тем самым возможность входа как root по паролю (что настоятельно не рекомендуется), либо перейдите к следующему разделу и заведите еще одного пользователя в системе, на которого не будет накладываться это ограничение.

Пользователи

На данный момент в системе есть только один пользователь – root. Этого было достаточно, чтобы, не отвлекаясь на лишние детали, убедиться, что новоиспеченная система находится в рабочем состоянии. Теперь настало время обратить внимание на опущенные ранее детали.

В настоящее время разработчики дистрибутивов делятся на два лагеря, когда речь заходит о пользователе root (напомню, что по отношению к нему часто используется термин «суперполь­зователь»). Более консервативные следуют практике наличия по крайней мере двух учетных записей в системе: root’а для административных задач и непривилегированного пользователя для всех остальных. Этот канонический подход дошел до нас в почти неизменном виде с самых первых версий UNIX; но он не лишен недостатков. На мой взгляд, наиболее ярким из них является необходимость постоянного контроля за тем, чтобы сессия root’а была вовремя закрыта. Таким образом, всегда есть риск забыться и продолжить решение своих повседневных задач от лица суперпользователя, что может привести к серьезным негативным последствиям – ведь безграничные возможности, скрытые в учетной записи root’а, обладают поистине разрушительной силой, которую не каждый способен держать под контролем.

Debian является примером одного из консервативных с этой точки зрения дистрибутивов. Ubuntu, в свою очередь, это один из первых дистрибутивов, который взял на вооружение подход, при котором все административные задачи решаются посредством sudo. Суть этого подхода заключается в том, чтобы

  • не устанавливать пароль для суперпользователя, оставляя его учетную запись заблокированной, или заблокировать учетную запись явно, указав вместо пароля (или перед паролем) восклицательный знак (!);
  • установить программу sudo;
  • добавить первого пользователя (т. е. того, который был создан во время установки системы) в группу sudo, дав ему тем самым неограниченные права при выполнении любых операций в системе.
Получив дополнительные права через sudo, не забывайте, что с великой силой приходит великая ответственность.
Получив дополнительные права через sudo, не забывайте, что с великой силой приходит великая ответственность.

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

В официальном образе Raspbian используется именно этот подход. Какой подход будет использоваться в вашем образе – решать вам, но для начала необходимо завести в системе еще одного пользователя, от имени которого будет осуществляться вход, в том числе и через SSH.

Итак, чтобы создать пользователя с именем pi, выполните

$ sudo chroot /mnt/rootfs useradd -m -s /bin/bash pi

Заметьте, что useradd и другие смежные с ней программы, в том виде, в котором они используются в этом разделе, специфичны для всех систем, в которых используется shadow для управления пользователями и группами. В отличие от coreutils, интерфейс программ (и даже название самих программ) для управления пользователями и группами сильно варьируется от реализации к реализации, поэтому всё описанное здесь может отличаться от того, что принято в других Unix-подобных операционных системах и даже других дистрибутивах GNU/Linux.

Опция -m позволяет указать, что в /home необходимо создать домашнюю директорию пользователя с его именем, а опция -s говорит, что оболочкой по умолчанию должна стать Bash. Можно было бы посредством опции -p указать пароль, но это небезопасно. Во-первых, вышеприведенная команда останется в истории, к которой может получить доступ администратор или злоумышленник, если пользователь, от имени которого она выполнялась, будет скомпрометирован. Во-вторых, процесс создания пользователя будет фигурировать в списке процессов, из которого администратор может получить все переданные useradd параметры. В-третьих, пароль на экране может быть просто подсмотрен из-за плеча. Даже если эта и другие приведенные в данной статье команды выполняются на персональной машине в пустом и запертом помещении, я всё равно предлагаю пойти правильным путем и установить пароль пользователя отдельно. В конце концов, чтобы стать настоящим хакером, нужно быть немного шизофреником.

$ sudo chroot /mnt/rootfs passwd pi

На данном этапе образ имеет всё необходимое, чтобы считаться приверженцем консервативного подхода. Чтобы заставить его следовать подходу, при котором все административные задачи решаются через sudo, сначала установим саму программу, а затем добавим пользователя в соответствующую группу.

$ sudo chroot /mnt/rootfs apt-get update
$ sudo chroot /mnt/rootfs apt-get install sudo
$ sudo chroot /mnt/rootfs usermod -aG sudo pi

Теперь пользователь pi может временно заимствовать права суперпользователя для тех вещей, которые выполняются через sudo.

Финальный штрих – блокировка учетной записи root. Для этого выполните

$ sudo chroot /mnt/rootfs passwd -l root

Данная команда поставит восклицательный знак (!) перед хэшем пароля, и это обозначит, что учетная запись заблокирована.

Загляните в «теневой файл паролей [shadowed password file]» /etc/shadow, чтобы в этом убедиться.

На этом тему можно было бы считать закрытой, но остается еще одна вещь, которая не дает мне покоя. Дело в том, что за полтора десятка лет существования Ubuntu успело подрасти целое поколение линуксоидов, которые убеждены, что sudo – это не более чем просто способ временного получения прав суперпользователя, и если оставить всё как есть, то наш учебник только поддержит это распространенное заблуждение. Я хочу внести свой посильный вклад в то, чтобы исправить сложившуюся ситуацию. Для этого я предлагаю решить одну простую, но очень актуальную для RPi задачу, суть которой заключается в том, чтобы дать пользователю возможность выключать или перезагружать свое устройство через Android-приложение нажатием одной кнопки. Таким образом, потребуется посредством sudo дать пользователю право выполнять команды systemctl poweroff и systemctl reboot. Более того, необходимо не только дать пользователю право выполнения этих команд, но и при этом не спрашивать его пароль. Дело в том, что Android-приложение SSH Button, которое я предлагаю использовать для создания кнопок выключения и перезагрузки устройства, как и любое подобное приложение, очень примитивно. Оно подключается к SSH-серверу, выполняет указанную программу и анализирует код завершения [exit status]. Если в результате своей работы программа переходит в режим, в котором она ожидает каких-то действий от пользователя (к примеру, ввода пароля), то SSH Button считает выполнение программы неудачным. Всё это создает идеальные условия для того, чтобы копнуть чуть глубже возможности, предлагаемые sudo, чем я и предлагаю заняться прямо сейчас.

Правила, согласно которым sudo принимает решение, кто и что в праве делать, находятся в /etc/sudoers. Однако, вместо того чтобы редактировать этот файл напрямую, я предлагаю добавить новое правило в виде отдельного файла через подключаемую директорию /etc/sudoers.d. Создайте файл, к примеру, с именем shutdown со следующим содержимым.

pi raspbian-jeosi =NOPASSWD: /usr/bin/systemctl halt,/usr/bin/systemctl reboot

Все файлы в этой директории должны иметь права 0440 (-r–r—–).

$ sudo chmod 0440 /mnt/rootfs/etc/sudoers.d/shutdown

Теперь установите SSH Button на любое устройство под управлением Android. Затем создайте в нем кнопку и укажите в ее настройках адрес вашего RPi, логин и пароль пользователя pi и одну из разрешенных этому пользователю команд — systemctl poweroff или systemctl reboot.

Удобный способ выполнить любую команду на RPi с мобильного устройства.
Удобный способ выполнить любую команду на RPi с мобильного устройства.

Этот подход особенно удобен, когда вам нужно подключиться к RPi только для того, чтобы корректно завершить все процессы на нем перед его выключением. Читайте следующий раздел, в котором пойдет речь о том, как сделать корневую файловую систему доступной только на чтение и, таким образом, избавиться от необходимости т.н. корректного завершения работы.

Доступный только на чтение корень

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

Доступный только на чтение корень – это умышленное ограничение функциональности системы для повышения ее живучести. Но основная проблема здесь не в том, как этого добиться, а в том, как минимизировать последствия от этого ограничения: ведь будет очень обидно, если демон, предназначенный для решения той самой единственной задачи, потеряет способность вести журнал… Тому, как сделать корень доступным только на чтение и не терять логи в этих условиях, посвящена большая часть этого раздела. (В силу того, что материал руководства выходит далеко за пределы журналирования, разговор на эту тему не будет исчерпывающим, поэтому я настоятельно рекомендую обратиться к статье «Записки демонов» из LXF91 за более детальными подробностями по этому вопросу.)

Традиционно в Unix-подобных операционных системах журналированием занимается демон syslogd. В Debian, к примеру, используется одна из его реализаций под названием rsyslog. Когда сообщение доходит до syslogd, возможен один из пяти вариантов развития событий:

  • сообщение может быть добавлено в файл;
  • сообщение может быть выдано на терминал любого указанного пользователя;
  • сообщение может быть записано в FIFO (именованный канал);
  • сообщение может быть перенаправлено syslogd, находящемуся на другой машине;
  • сообщение может быть проигнорировано.

Самый распространенный первый вариант не подходит, т.к. корневая файловая система доступна только на чтение. Можно, конечно, передавать логи на другую машину, но в некоторых случаях наличие еще одной машины может оказаться избыточным. К счастью, другая реализация syslogd, разработанная в рамках проекта Busybox, поддерживает использование так называемого «кольцевого буфера [circular buffer]» для хранения логов. Таким образом, создается иллюзия того, что логи пишутся в обычном режиме так, как если бы корневая файловая система не была доступна только на чтение.

В Raspbian (и других дистрибутивах, основанных на Debian) реализация syslogd от проекта Busybox находится в пакете busybox-syslogd.

$ sudo chroot /mnt/rootfs apt-get install busybox-syslogd

Если в системе уже был установлен rsyslog, то установка busybox-syslogd приведет к его удалению, т. к. busybox-syslogd возьмет на себя функции rsyslog.

Теперь логи подавляющего большинства демонов в вашей системе будут сохраняться в памяти. busybox-syslogd сконфигурирован в Raspbian таким образом, чтобы использовать для этих целей буфер размером 64 КБ. Однако, если произойдет внезапное отключение питания, то все логи вылетят в трубу. Конечно, самым надежным во всех случаях подходом является хранение логов на отдельной машине, и busybox-syslogd это тоже умеет.

Несмотря на то, что подавляющее большинство демонов используют syslogd для журналирования, есть демоны, которые занимаются этим вопросом самостоятельно. К примеру, Nginx ведет два типа журналов: журнал доступа [access log] и журнал ошибок [error log], и по умолчанию не пользуется услугами syslogd для этих целей. Тем не менее, модуль Nginx ngx_http_log_module, который занимается журналированием, поддерживает использование syslogd. В Debian и его производных Nginx сконфигурирован так, чтобы журнал доступа сохранялся в /var/log/nginx/access. log, а журнал ошибок – в /var/log/nginx/error.log. Очевидно, что в файловой системе, доступной только на чтение, Nginx не сможет писать в access.log и error.log, поэтому необходимо попросить web-сервер регистрировать события через syslogd. Для этого отредактируйте /etc/nginx/nginx.conf так, чтобы директивы access_log и error_log выглядели следующим образом.

access_log syslog:server=unix:/dev/log,nohostname;
error_log syslog:server=unix:/dev/log,nohostname;

И в заключение, необходимо сделать корневой раздел доступным только на чтение. Для этого добавьте параметр ro к командной строке ядра, которая находится в файле cmdline.txt на загрузочном разделе.

Сборка ядра

Сейчас система основана на Raspbian’овском ядре, которое латается и пакетируется самими разработчиками одноплатников, поэтому оно, как ни что другое, отлично поддерживает RPi. Пакет raspberrypi-kernel, установка которого обсуждалась в первой части этого руководства, содержит ядро, предназначенное для решения широкого круга задач, что открывает огромные возможности для оптимизаций. Таким образом, в данном разделе речь пойдет о том, как самостоятельно собрать ядро – для того, чтобы получить возможность подогнать его под решение конкретной задачи.

Теперь осталось определиться, у кого мы возьмем ядро, которое будем здесь собирать: у Линуса, разработчиков RPi или у когото еще. Предлагаю собирать именно «ванильное» ядро, т. к. этот подход является наиболее дистрибутивонезависимым. Базовая поддержка RPi появилась в upstream’е достаточно давно. К примеру, RPi 2 поддерживается Linux’ом, начиная с версии 4.5, которая вышла 13-го марта 2016 г., а RPi 3 – начиная с версии 4.8, которая вышла 2 октября того же года. Безусловно, RPi поддерживается «ванильным», т. е. стандартным, ядром не настолько хорошо, как Raspbian’овским, но для решения некоторых задач этим можно пренебречь.

В качестве примера я возьму Linux 4.14 — последний на момент написания статьи выпуск с длительным сроком поддержки. Так, этот раздел не потеряет своей актуальности ни на грамм, пока не закончится жизненный цикл выпуска 4.14, которое при участии Google будет сопровождаться до 2023 г. Тем не менее, я призываю вас брать самую последнюю на момент чтения этого руководства версию ядра и применять к ней описанные здесь рецепты.

А теперь к делу. Загрузите с kernel.org архив с интересующей вас версией ядра Linux. К примеру, им оказался linux-4.14.52.tar.xz. Распакуйте его.

$ tar xJvf linux-4.14.52.tar.xz

Затем установите необходимые для конфигурации и сборки ядра пакеты (в Debian и производных от него это build-essential, libncurses5-dev и gcc-arm-linux-gnueabihf). После этого выполните следующие команды, чтобы приступить к конфигурации целевого ядра, ради которой мы здесь все собрались.

$ ARCH=arm make bcm2835_defconfig
$ ARCH=arm make menuconfig
menuconfig поможет сконфигурировать ядро для решения конкретной задачи.
menuconfig поможет сконфигурировать ядро для решения конкретной задачи.

На этом этапе, как правило, из ядра выкидывается всё, что не способствует выполнению поставленной задачи, и добавляется всё, чего не хватает. Руководство не предлагает в каче­стве примера какую-то конкретную задачу, поэтому здесь всё зависит от вас. Я настоятельно рекомендую не зацикливаться на этом шаге, двинуться дальше, а потом еще раз вернуться к этому разделу после просмотра доклада «Tuning Linux For Embedded Systems: When Less is More» Даррена Гарта [Darren Hart], где он ставит перед собой цель собрать минимально возможное ядро для встраиваемого устройства.

После того как с конфигурацией будет покончено, можно начинать сборку:

$ ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- chrt -i 0 make -j4 deb-pkg

В результате получится несколько Deb-пакетов. Сейчас нас интересует linux-image, полное название у которого в моем случае – linux-image-4.14.52_4.14.52-1_armhf.deb. Установите его, предварительно удалив пакет с Raspbian’овским ядром:

$ sudo chroot /mnt/rootfs apt-get purge raspberrypi-kernel
$ sudo cp linux-image-4.14.52_4.14.52-1_armhf.deb /mnt/rootfs
$ sudo chroot /mnt/rootfs dpkg -i linux-image-4.14.52_4.14.52-1_armhf.deb
$ sudo rm /mnt/rootfs/linux-image-4.14.52_4.14.52-1_armhf.deb

Затем удалите с загрузочного раздела всё, что относилось к Raspbian’овскому ядру и загрузите на него новое ядро и dtb-файлы:

$ sudo rm /mnt/boot/{cmdline.txt,bcm283*,kernel7.img}
$ sudo cp /mnt/rootfs/boot/vmlinuz-4.14.52 /mnt/boot/zImage
$ sudo cp /mnt/rootfs/usr/lib/linux-image-4.14.52/bcm283* /mnt/boot

Для загрузки «ванильного» ядра потребуется загрузчик, в качестве которого я предлагаю использовать Das U-Boot. Последней стабильной версией U-Boot на момент написания статьи является 2018.05. Загрузите архив с исходниками U-Boot, укажите файл конфигурации, которая соответствует вашему устройству, и запустите сборку.

Что касается файла конфигурации, то в моем случае это rpi_3_32b_defconfig, т. к. я хочу запустить на Raspberry Pi 3 Model B собранное под ARMv7 ядро Linux, поскольку мы имеем дело с 32-битной пакетной базой Raspbian. Подсмотрите в директории configs все возможные варианты.

$ curl -O ftp://ftp.denx.de/pub/u-boot/u-boot-2018.05.tar.bz2
$ tar xjvf u-boot-2018.05.tar.bz2
$ cd u-boot-2018.05
$ ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- chrt -i 0 make rpi_3_32b_defconfig
$ ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- chrt -i 0 make -j4

Теперь подготовьте файл boot.scr со следующим содержимым:

mmc dev 0
setenv fdtfile bcm2837-rpi-3-b.dtb
setenv bootargs earlyprintk console=tty0 console=ttyAMA0
root=/dev/mmcblk0p2 rootwait init=/bin/systemd
fatload mmc 0:1 ${kernel_addr_r} zImage
fatload mmc 0:1 ${fdt_addr_r} ${fdtfile}
bootz ${kernel_addr_r} - ${fdt_addr_r}

Этот файл содержит список команд, которые U-Boot должен выполнить. Такой способ конфигурации U-Boot делает загрузчик очень гибким.

Есть три места, на которые в этом пункте стоит обратить пристальное внимание.

  • 2-я строка содержит имя DTB-файла, соответствующего устройству, на котором планируется загрузка ядра. Указанный в этой строке файл, в числе прочих DTB-файлов, был получен при сборке ядра и уже находится на корневом и загрузочном разделах. Укажите здесь DTB-файл, соответствующий вашему устройству.
  • 3-я строка содержит командную строку ядра.
  • 4-я строка содержит имя двоичного файла ядра (zImage).

Теперь необходимо скомпилировать boot.scr в boot.scr.uimg. Для этого потребуется программа mkimage, которую можно найти в пакете u-boot-tools во всех Debian-подобных дистрибутивах или в uboot-tools в Fedora.

$ mkimage -A arm -O linux -T script -C none -n boot.scr -d boot.scr boot.scr.uimg

Наконец, нужно перекинуть двоичный файл загрузчика, который был получен после сборки U-Boot, и boot.scr.uimg на загрузочный раздел:

$ sudo u-boot.bin /mnt/boot/kernel7.img
$ sudo boot.scr.uimg /mnt/boot

Очистка образа

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

Существует идиома, которая решает эту проблему. Она стала популярной за счет повсеместного использования в Dockerfile’ах, т.к. Docker-образы, как и образы для одноплатников, тоже нуждаются в очистке от «строительного мусора». Выглядит эта идиома следующим образом.

$ sudo apt-get clean
$ sudo rm -rf /var/lib/apt/lists/*

Первая команда удаляет кэшированные двоичные пакеты, а вторая – индексные файлы. В нашем случае эти команды будут выглядеть так:

$ sudo chroot /mnt/rootfs apt-get clean
$ sudo rm -rf /mnt/rootfs/var/lib/apt/lists/*

Заключение

Несмотря на то, что есть достаточно большое количество скриптов, автоматизирующих весь описанный в этом руководстве процесс, я убежден в большой пользе понимания, что у них под капотом. Во-первых, эти скрипты нуждаются в контрибьюторах – и где как не здесь их выращивать. Во-вторых, спускаясь на уровень сборки своей системы, хоть и на основе двоичных пакетов, есть возможность лучше понять GNU/Linux, а где как не здесь этим заниматься. Я старался выжимать максимум из каждого раздела этой части руководства, выстраивая как можно более длинные цепочки из смежных тем для того, чтобы сделать материал как можно более энциклопедическим. Теперь ваша очередь – сдуйте пыль со своего одноплатника и выжмите из него максимум. Удачного хакинга.

OS DAY 2018

В июне 2017 я впервые узнал о ежегодной конференции разработчиков операционных систем OS DAY. В марте 2018 обновилась информация на официальной странице мероприятия https://osday.ru и стартовал приём заявок на доклады по вопросам обеспечения надёжности программно-аппаратных систем на этапах проектирования, разработки, эксплуатации и сопровождения. Мы с Женей зарегистрировались в качестве участников, решили поехать поучиться у коллег. Конечно хотелось заявиться с презентацией и рассказать о CusDeb, но, сказать по правде, я постеснялся.

Зато Женя не постеснялся написать разработчикам Debian, поинтересовался не собирается ли кто из них посетить OS DAY 2018, предложил бух…..поговорить о разработке Debian и подписать ключи. На предложение откликнулись Сергей и Дмитрий. Сергей, сказал, что у него не будет времени на конференцию, но он готов встретиться, чтобы подписать ключи. Дмитрий, ознакомившись с программой конференции, зарегистрировался.

17 мая в 9 утра мы были в главном здании академии наук в Москве. Вход по паспортам, нас проверяли по спискам, всё строго. Докладчики выступали в зелёном зале на третьем этаже, свободных мест не было, собралось более 200 участников. В перерывах мы рассматривали стенды разработчиков отечественных операционных систем. На мой взгляд, самый живой стенд получился у ребят из Базальт СПО. Несколько железяк под управлением base ALT отлично транслировали месседж — “Платформа base ALT работает на отечественном железе”.

На обеде познакомились с Дмитрием Шечневым, и я впервые в жизни увидел, как происходит подписание GnuPG ключей у разработчиков Debian. Согласно правилам Женя передал Диме отпечаток (fingerprint) ключа и длину ключа, распечатанные на бумаге, затем показал паспорт. Дима проверил паспорт и убедившись, что Женя является тем, за кого себя выдаёт, загрузил ключ по отпечатку с сервера публичных ключей, подписал его и отправил на этот же сервер.

Дмитрий Шечнев и Евгений Голышев
Дмитрий Шечнев и Евгений Голышев

После обеда подошли к Дмитрию Завалишину, чтобы сфотографироваться с легендой. Рассказали ему коротко о нашем конструкторе операционных систем для одноплатных компьютеров, сказали, что постеснялись отправить заявку на доклад. Оказалось, у него дома валяется Raspberry Pi, и он посоветовал нам прислать заявку на доклад через год на OS DAY 2019.

Евгений Голышев, Дмитрий Завалишин, Денис Мосолов
Евгений Голышев, Дмитрий Завалишин и Денис Мосолов

А вот цитаты из докладов первого дня, которые я записал в блокнот:

Не нужно распространять ПО в контейнерах, это небезопасно. Просто задумайтесь, кто будет обновлять операционную систему внутри изолированного окружения?
Дмитрий Державин, о том, кто отвечает за обновление ОС внутри Docker-контейнера.

Представьте, что когда вы утром выходите из дома, вы всю мебель дома разбираете, пакуете и тащите с собой, а когда возвращаетесь, то всё опять собираете.
Дмитрий Завалишин, о сохранении состояния программы в ОС.

Второй день конференции получился более дискуссионным, чем первый. Я узнал, что в России есть федеральная служба по техническому и экспортному контролю (ФСТЭК России). Эта служба утвердила требования безопасности информации к операционным системам. Требования применяются к операционным системам, используемым в целях обеспечения защиты информации, содержащей сведения, составляющие государственную тайну, и иной информации ограниченного доступа при ее обработке в информационных системах. В соответствии с требованиями выделяются три типа операционных систем: операционная система общего назначения (тип «А»), встраиваемая операционная система (тип «Б»), операционная система реального времени (тип «В»). Для дифференциации требований к функциям безопасности операционных систем выделяются шесть классов защиты операционных систем. Самый низкий класс – шестой, самый высокий – первый. Из доклада Петра Девянина я узнал, что Astra Linux Special Edition является операционной системой типа «А» и второго класса защиты. Astra Linux Special Edition стала первой операционной системой, сертифицированной по новым требованиям ФСТЭК России.

После обеда речь зашла об образовании. Георгий Курячий, Вартан Падарян и Роман Симаков рассказали каждый о своём опыте подготовки системных программистов, после чего конференция плавно перетекла в самое обыкновенное обсуждение образования в нашей стране. Высказались почти все, кто был на тот момент в зале. В какой-то момент микрофон взял Алексей Мандрыкин из компании Fast Reports и немного рассказал, как решается проблема подготовки будущих специалистов в Ростове-на-Дону.

Цитата из докладов второго дня конференции:

Если рассказывать студенту только об одной архитектуре, то через некоторое время он может даже не представлять, что существуют другие архитектуры.
Георгий Курячий, о синдроме утёнка.

Внутри системника живут магические человечки, которые каким-то образом выполняют всю работу.
О магическом мышлении.

В заключении, поделюсь выводом, который я сделал для себя после OS DAY 2018. Пора прекращать верить в магических человечков, которые магическим образом выполняют работу системы, а брать и изучать, как всё работает на различных уровнях абстракции, вплоть до транзисторов.

Денис Мосолов

Debian vs. Devuan

Devuan (читается как DevOne) является производным от Debian GNU/Linux дистрибутивом. Принципиальное отличие между Debian и Devuan заключается в отсутствии привязки к systemd у последнего. Несмотря на то, что дистрибутиву уже три года, все еще остается много вопросов относительно его появления и назначения. После того как наша команда добавила возможность кастомизации Devuan сначала в Pieman, а затем в CusDeb, я наконец хочу немного рассказать об этом дистрибутиве в нашем блоге. Основным источником разногласий, которые вылились в работу над Devuan, является переход Debian и Ubuntu на использование системы инициализации systemd. Но обо всем по порядку.

Ускорение загрузки

В конце 2000-х несколько крупных производителей операционных систем на базе ядра Linux пришли к выводу, что необходимо ускорять время загрузки своих систем и, как следствие, брать на вооружение альтернативную систему инициализации. Так как именно система инициализации отвечает за загрузку операционной системы, то стало очевидно, что начинать нужно именно с нее. В течении долгого времени дистрибутивы GNU/Linux использовали для этих целей SysVinit, которая сейчас считается классической системой инициализации и в данной статье противопоставляется всем другим.

Компания Canonical, которая является основным разработчиком дистрибутива Ubuntu, начала работу над альтернативной системой инициализации под названием Upstart в середине 2000-х. Upstart дебютировала в Ubuntu 6.10 «Edgy Eft», заменив SysVinit, но окочательно новая система иницализации была интегрирована в дистрибутив только к выходу Ubuntu 9.10 «Karmic Koala». Затем на Upstart обратили внимание компании Google и Red Hat, интегрировав ее в свои продукты. Так, Upstart начала использоваться в ChromeOS и Red Hat Enterprise Linux 6. На новую систему инициализации даже планировал перейти Debian.

Upstart оказалась эффективней чем SysVinit благодаря событийно-ориентированной архитектуре. Системные сервисы стало возможным запускать и останавливать на основе событий, а не уровней запуска (runlevels), указанных в скриптах инициализации. Данный подход предполагал генерацию событий при запуске или остановке системных сервисов, что позволило организовать привязку к ним других сервисов. Таким образом, для определения последовательности запуска сервисов и оценки возможности их выполнения в параллельном режиме был взят на вооружение метод учета зависимостей. Работа в тандеме с ядром, которое также стало развиваться в сторону событийно-ориентированной архитектуры, благодаря чему появилась возможность асинхронной загрузки драйверов, заметно сократила время от нажатия кнопки включения до полной готовности всей системы.

Недостатки SysVinit мотивировали разработчиков Upstart приступить к созданию альтернативной системы инициализации, а достоинства launchd из Mac OS X и SMF из Solaris послужили основным источником ценных идей, которые помогли в решении поставленной задачи. Однако, по воле судьбы или случайному стечению обстоятельств, Upstart оказалась всего лишь трамплином для другой, более совершенной системы инициализации. Так, компания Red Hat, при участии разработчиков из Novell, IBM, Intel и Nokia, поставила перед собой цель создать систему инициализации, нацеленную на более интенсивную параллелизацию выполнения сервисов на этапе загрузки. Проект получил название systemd и отличался более радикальным подходом к решению некоторых задач. К примеру, если Upstart была совместима со скриптами инициализации SysVinit, то systemd предлагала для этих целей новый синтаксис и, таким образом, не была завязана ни на Bash, ни на любую другую оболочку. Тем не менее, на этам этапе все было хорошо. Волна критики накатила на проект немного позднее, когда стало очевидно, что акцент разработчиков немного сместился в сторону, отличную от первоначальных целей. Так, в один прекрасный момент проект под названием systemd стал позиционироваться не как «альтернативная система инициализации», а как «системный менеджер». Система инициализации в этом проекте стала одним из многочисленных компонентов, а весь проект стал нацелен на управление различными аспектами работы системы. Также стоит заметить, что немалая доля критики свалилась на systemd из-за того, что лидером проекта является не кто иной, как сам Леннарт Поттеринг (Lennart Poettering), в прошлом разработчик звукового сервера PulseAudio, который в начале своего пути не отличался стабильностью работы (в основном из-за аудиодрайверов, а не ошибок в коде PulseAudio), что и является причиной ненависти как к проекту, так и к его автору.

Появление Devuan

Наконец, я подобрался к основным мотивам, которые заставили разработчиков Devuan форкнуть Debian с целью его альтернативного развития. В конце 2013-го – начале 2014-го Debian в очередной раз вернулся к актуальной для себя задаче – переходу на более современную систему инициализации. В качестве кандидатов рассматривались Upstart и systemd, и по результатам голосования победила последняя. Следом за Debian пошла Ubuntu. Стоит заметить, что выбор стоял между системой инициализации и системным менеджером, одним из компонентов которого являлась система инициализации. По итогам интеграции systemd в Debian дистрибутив не только перешел на новую систему инициализации, но и оказался сильно завязанным на системном менеджере, который был призван управлять всеми аспектами работы системы. В итоге, systemd был поставлен в один ряд с ядром и стандартной библиотекой языка C, для которых в дистрибутиве не предусмотрены альтернативы. Jessie стал первым выпуском Debian, который не мог функционировать без systemd. Поэтом группа разработчиков Veteran Unix Admins, несогласная с этой политикой, выпустила в рамках проекта Devuan свободную от systemd версию Jessie. Для того чтобы этого добиться, разработчикам потребовалось внести изменение в 381 пакет. Так появился первый выпуск Devuan, позволивший пользователям Debian использовать или не использовать systemd в зависимости от их желания.

Заключение

Я написал эту статью в первую очередь для того, чтобы помочь нашим пользователям разобраться в причинах появления еще одного производного от Debian дистрибутива. При этом я не являюсь противником ни systemd, ни Леннарта Поттеринга, и остаюсь пользователем Debian (рабочая станция) и Ubuntu (ноутбук). Тем не менее, я считаю, что безальтернативная поставка systemd в крупнейших дистрибутивах является крайностью. В связи со всем этим я попытался сделать статью как можно более беспристрастной. Но теперь наконец я могу сказать, что я восхищаюсь разработчиками Devuan и ценю проделанную ими работу, и рад заявить, что CusDeb поддерживает этот дистрибутив.