LINUX.ORG.RU

Systemd 29

 , ,


0

1

16 июня, тихо и незаметно вышла 29-ая версия новой системы инициализации для Linux. Среди её возможностей основными являются:

  • событийно-ориентированная система параллельного запуска сервисов;
  • управление через dbus;
  • упразднение загрузочных bash-скриптов и замена схожим по функциональности кодом на C для управления консолью, установки локали, запуска fsck, монтирования файловых систем и др.;
  • возможность запуска сервисов по появлению данных в сокете, запуску или остановке других сервисов, наличию подключённых устройств или смонтированных файловых систем;
  • встроенное упреждающее чтение с диска;
  • интеграция с cgroups;
  • совместимость со старыми скриптами, предназначенных для использования с SysVinit.

Всё это даёт возможность загружать систему за время порядка 10 секунд и выключать за 1 секунду.

В новой версии были незначительно изменены Makefile-ы, и было добавлено 2 пункта в TODO:

  • посылать сигнал, когда загрузка завершена;
  • при неудачном запуске сервиса попытаться перезапустить его.

Будем надеяться, что в следующей 30 версии мы увидим эти новые фичи.

Исходники

О systemd и ссылки

>>> Подробности

★★★★★

Проверено: maxcom ()
Последнее исправление: gentoo_root (всего исправлений: 1)
Ответ на: комментарий от tailgunner

> Программа. Насчет «всех возможных», правда, я не понял - есть единый граф завизмостей, он и проверяется.

Граф нужно перестраивать после каждого изменения набора сервисов; на разных «ранлевелах» он будет разный. В конце-концов, данная программа будет просто иной реализацией того же systemd.

Я даже не спрашиваю, как ты реализуешь этот самый запуск on-demand без хотя бы каки-то явно указанных зависимостей.

А здесь зависимости не по программам, а по ресурсам, что гораздо умнее. Нужен доступ к разделу ЖД — просто ждем, когда он будет доступен. Вся синхронизация происходит в ядре, не нужно эвристик и sleep'ов.

unanimous ★★★★★
()
Ответ на: комментарий от unanimous

> Ну так и там глитчи случаются — про rpm (dll) hell не слышали?

Про dll hell - конечно слышали. Это такая штука, когда не понятно, где чей файл, кому он нужен и кто от него зависит. А вот про rpm hell - еще ни разу не слышали. Там всегда видно, какой файл кому принадлежит и кто от него зависит.

Просто в сфере управления файлами (пакетами) пока ничего лучше не придумали; systemd же предлагает проблему убрать

Он предлагает убрать что? Какую проблему? Ту, которую он же сам и придумал? До него проблемы не было.

anonymous
()
Ответ на: комментарий от unanimous

>> Программа. Насчет «всех возможных», правда, я не понял - есть единый граф завизмостей, он и проверяется.

Граф нужно перестраивать после каждого изменения набора сервисов; на разных «ранлевелах» он будет разный.

При большом желании можно сказать и так. На самом деле, ранлевел - это подграф единого графа.

данная программа будет просто иной реализацией того же systemd.

Глупости. systemd гораздо больше и сложнее (в этом одна из главных его проблем). Я уже приводил ссылку на реализацию только графа зависмостей для init.

Я даже не спрашиваю, как ты реализуешь этот самый запуск on-demand без хотя бы каки-то явно указанных зависимостей.

А здесь зависимости не по программам, а по ресурсам, что гораздо умнее.

Это не ответ. Повторю тебе твой же вопрос:

unanimous> нужно постоянно проверять, чтобы граф не имел циклических зависимостей. Кто это будет делать для всех возможных конфигураций сервисов и где гарантия, что случайно или по злому умыслу такая зависимость не будет пропущена?

От зависмостей ты не избавишься никак, кто будет проверять, удовлетворены ли они, нет ли циклов? Добавлю от себя: кто и как ты будешь отслеживать циклы и други проблемы, что делать при их возникновении?

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

> rpm hell - еще ни разу не слышали. Там всегда видно, какой файл кому принадлежит и кто от него зависит.

Ну так поздравляю, значит вы еще не пользовались линуксом серьезно.

Он предлагает убрать что? Какую проблему? Ту, которую он же сам и придумал? До него проблемы не было.

Хорошо, попробуем аналогию, раз по-нормальному не доходит. Раньше, когда процессоры были преимущественно одноядерными, а ОС — однозадачными, не существовало проблем разделения ресурсов. Один ресурс — один пользователь. sysV из того времени, и запустить в данный момент оно может только одну службу, собственно, эти S# и K# этому и предназначается. Но теперь есть возможность запускать службы параллельно; однако возникают всякого рода конфликты, схожие с race conditions в многопоточном программировании. Очевидно, что их надо решать, однако подход построения «граф очередности исполнения» почему-то в многопоточном программировании распространения не получил, а используются средства синхронизации, вроде семафоров, критических секций и блокировок. Здесь все то же самое: сервис запрашивает у systemd необходимые ему ресурсы, а само планирование и очередность исполнения определяется «на лету» по доступности этих самых ресурсов.

unanimous ★★★★★
()
Ответ на: комментарий от unanimous

> Раньше, когда процессоры были преимущественно одноядерными, а ОС — однозадачными, не существовало проблем разделения ресурсов. Один ресурс — один пользователь. sysV из того времени, и запустить в данный момент оно может только одну службу

Ты лжешь.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

> От зависмостей ты не избавишься никак, кто будет проверять, удовлетворены ли они, нет ли циклов? Добавлю от себя: кто и как ты будешь отслеживать циклы и други проблемы, что делать при их возникновении?

Почитай мой ответ выше и скажи: почему не строят «графа очередности исполнения» в многопоточном программировании?

unanimous ★★★★★
()
Ответ на: комментарий от tailgunner

> Ты лжешь.

А на что указываюе S# и K# в линках на скрипты, пускающие сервисы как не на порядок запуска? Или я что-то пропустил?

Конечно, ускорить добавлением амперсандов пытались и в sysV, но это все костыли и ad hoc решения.

unanimous ★★★★★
()
Ответ на: комментарий от unanimous

> Почитай мой ответ выше и скажи: почему не строят «графа очередности исполнения» в многопоточном программировании?

Кто не строит? И причем тут многопоточное программирование? Почему не make -j100500?

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

>Если он не должен запускаться при загрузке, то он вообще никак не связан с загрузкой и не имеет отношения к init-демону. Init запускает то, что нужно запустить при ЗАГРУЗКЕ системы. То, что нужно запустить в ответ на соединение, запускает xinetd. То, что запускается по времени, запускает крон. То, что запускается по клику мышкой на иконке - запускает файловый менеджер. То, что запускается по появлению устройст, запускает udev.

Все анонимусы, блин, такие умные, а никто до сих пор не ответил на вопрос:

А если надо, чтобы зависело от устройства и активировалось по сокету - как это сделать без systemd, с помощью udev и xinetd?

Он отсюда:

http://www.linux.org.ru/jump-message.jsp?msgid=6395201&cid=6405429

Вот как такое сделать без systemd?

gentoo_root ★★★★★
() автор топика
Ответ на: комментарий от unanimous

> А на что указываюе S# и K# в линках на скрипты, пускающие сервисы как не на порядок запуска? Или я что-то пропустил?

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

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

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

unanimous ★★★★★
()
Ответ на: комментарий от tailgunner

> Ты пропустил то, что система многозадачная, пользователь использует кучу ресурсов и одновременно запущено куча служб.

Погоди-погоди, мы говорим о системе инициализации, так? О том, как правильно распараллеливать запуск служб. Управление уже запущеными службами и работа этих служб — это уже другой вопрос.

unanimous ★★★★★
()
Ответ на: комментарий от unanimous

> Да, зависимости нужны в момент написания программы, однако их почему-то пытаются минимизировать,

Ну так минимизируй граф зависмостей.

используя примитивы синхронизации.

Господи, да причем тут примитивы синхронизации.

Так ты ответишь на свой же вопрос (да и на мои тоже)?

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

> Так ты ответишь на свой же вопрос (да и на мои тоже)?

Я тебе ответил, просто ты не хочешь осознать. Еще раз, идея systemd, как я ее понимаю, это отказаться от явного построения графа зависимостей в пользу запуска про доступности соответствующих ресурсов. Я вижу аналогию такого подхода в использовании примитивов синхронизации при доступе к разделяемым ресурсам в программировании: ты запрашиваешь ресурс и просто ждешь, когда система тебе его предоставит; нет необходимости знать о _других_ процессах, выполняющихся в системе. Так же и в systemd — сервис просто ждет нужных ему ресурсов, он не обязан знать о том, какие сервисы еще запущены в системе (тот самый «граф зависимостей»)

unanimous ★★★★★
()
Ответ на: комментарий от unanimous

>> Так ты ответишь на свой же вопрос (да и на мои тоже)?

Я тебе ответил

Где? Если что, я не спрашивал о твоем понимании идей systemd. Мне интересно, как и когда обнаруживаются, и как обрабатываются циклы в зависимостях служб.

Еще раз, идея systemd, как я ее понимаю, это отказаться от явного построения графа зависимостей

Поцеринг будет удивлен.

<Ъ>

«systemd supports several kinds of dependencies between units. After/Before can be used to fix the ordering how units are activated. It is completely orthogonal to Requires and Wants, which express a positive requirement dependency, either mandatory, or optional. Then, there is Conflicts which expresses a negative requirement dependency. Finally, there are three further, less used dependency types».

</Ъ>

/me .oO( кроме меня, кто-нибудь вообще читал дизайн документы systemd? )

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Я читал, но сейчас я обсуждаю свое понимание зачем оно нужно. Кроме того, очередность все равно нужна — невозможно все пускать в параллель, но, как я понимаю, идея заключается в сведении к минимуму знания отдельно взятого сервиса о всей системе в целом.

unanimous ★★★★★
()
Ответ на: комментарий от unanimous

> Тем, что нужно постоянно проверять, чтобы граф не имел циклических зависимостей. Кто это будет делать для всех возможных конфигураций сервисов и где гарантия, что случайно или по злому умыслу такая зависимость не будет пропущена?

Вообще-то systemd этого не гарантирует. И в нем легко получить циклическую зависимость.

Но описать структуру, которая будет это гарантировать, несложно.

Договоримся, что сервисы будут заданы в sysvinit-совместимом режиме. То есть - набор симлинков в rc.d на скрипты, у каждой из которых есть в начала номер от 00 до 99.
Чтобы загрузиться runlevel X мы запускаем все скрипты /etc/rcX.d/S* в лексикографическом порядке с параметром start.
Чтобы перейти из runlevel X в runlevel Y мы запускаем скрипты /etc/rcY.d/K* с параметром stop (если они запускались в runlevel X), а затем запускаем скрипты /etc/rcY.d/S* с параметром start. Тоже в лексикографическом порядке.

Так работает sysvinit. Так он работал всегда. И тут нет и не может быть циклических зависимостей. Все проблемы решены? Еще нет.

В чем недостаток такого подхода? В том, что скрипты запускаются последовательно - за один проход по всем номерам от 00 до 99. Следующий скрипт запускается только после того, как закончится предыдущий. А ведь многие могли бы стартовать параллельно, сэкономив на этом время загрузки. Как решить эту проблему? Очень просто.

В каждый скрипт в начале в комментариях записываются два поля: Provides и Requires. Затем init-демон (это даже может быть не демон, а скрипт на баше) когда пробегается по скриптам, не ждет окончания предыдущего скрипта, а сразу смотрит следующий, и проверяет, если его Requires есть среди Provides-ов скриптов, которые еще выполняются, то этот скрипт ставится в очередь, иначе - запускается сразу. Так для всех скриптов.

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

PS: эти Provides и Requires называются LSB Header.

anonymous
()
Ответ на: комментарий от unanimous

> Я читал

То есть для тебя явное указание зависимостей - это «отказ от явного построения графа»? Если так, то вопросов больше нет.

tailgunner ★★★★★
()
Ответ на: комментарий от gentoo_root

> А если надо, чтобы зависело от устройства и активировалось по сокету - как это сделать без systemd, с помощью udev и xinetd?

Оно не запускается при старте системы? Значит к init-у оно отношения не имеет. Приведи реальный пример такого демона, и я скажу, как он должен запускаться.

anonymous
()
Ответ на: комментарий от tailgunner

> То есть для тебя явное указание зависимостей - это «отказ от явного построения графа»? Если так, то вопросов больше нет.

Нет, не так. Я понимаю, в systemd явного прописывания зависимостей можно избежать, когда они не нужны, в то время как в твоем варианте они основа всей системы.

unanimous ★★★★★
()
Ответ на: комментарий от unanimous

> А здесь зависимости не по программам, а по ресурсам, что гораздо умнее. Нужен доступ к разделу ЖД — просто ждем, когда он будет доступен. Вся синхронизация происходит в ядре, не нужно эвристик и sleep'ов.

О, да, это гораздо умнее. Но зачем это надо в init-демоне? И причем тут вообще ядро?

anonymous
()
Ответ на: комментарий от anonymous

>Приведи реальный пример такого демона, и я скажу, как он должен запускаться.

Например, я хочу, чтобы cupsd не занимал мою память, а запускался только тогда, когда вставлен мой принтер и к демону обратились по сокету, т.е. хотят что-то напечатать. Как это делается без systemd?

gentoo_root ★★★★★
() автор топика
Ответ на: комментарий от unanimous

> в systemd явного прописывания зависимостей можно избежать, когда они не нужны,

И в каких же это случаях? В тех, когда достаточно xinetd?

в то время как в твоем варианте они основа всей системы.

Они _всегда_ являются основой. Что в upstart, что в systemd. Потому что зависмости реально существуют.

tailgunner ★★★★★
()
Ответ на: комментарий от unanimous

> Я понимаю, в systemd явного прописывания зависимостей можно избежать, когда они не нужны, в то время как в твоем варианте они основа всей системы.

Хрен там. Зависимости в systemd прописываются тремя разными способами (Before, After, Wanted) и дополняются симлинками в файловой системе. При этом все могут зависеть от всех. Сокеты от маунтов, маунты от сервисов, а сервисы от сокетов. Зависимости в systemd такие, что dllhell покажется праздником.

anonymous
()
Ответ на: комментарий от anonymous

>С другой стороны она позволяет реализовать параллельный запуск сервисов,

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

anonymous
()
Ответ на: комментарий от gentoo_root

>Этого:

Ты предположение от фактов отличаешь? Вижу, что нет.

anonymous
()
Ответ на: комментарий от gentoo_root

> я хочу, чтобы cupsd не занимал мою память

Предоставь это менеджеру VM. Или пускай от udev.

tailgunner ★★★★★
()
Ответ на: комментарий от gentoo_root

> Например, я хочу, чтобы cupsd не занимал мою память, а запускался только тогда, когда вставлен мой принтер и к демону обратились по сокету, т.е. хотят что-то напечатать. Как это делается без systemd?

Зачем тебе нужен cups при вставке принтера. Что он будет делать с этим принтером, если cups-ом никто не пользуется? Зря занимать память? Значит просто при вставке принтера cups запускаться не должен. Это во-первых.

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

Итого, имеем, cups нужно запускать тогда, когда его кто-то пытается использовать. Как это сделать? Ответ - xinetd.

anonymous
()
Ответ на: комментарий от gentoo_root

> Все анонимусы, блин, такие умные, а никто до сих пор не ответил на вопрос:

А если надо, чтобы зависело от устройства и активировалось по сокету - как это сделать без systemd, с помощью udev и xinetd?


Прописать в xinetd скрипт, который будет активизироваться и первым делом парсить статус устройства, при благоприятных условиях запускать обработчик? Или в чем проблема?

Neksys ★★★
()
Ответ на: комментарий от anonymous

>Зачем тебе нужен cups при вставке принтера. Что он будет делать с этим принтером, если cups-ом никто не пользуется? Зря занимать память? Значит просто при вставке принтера cups запускаться не должен.

Вообще-то, я это и написал. Условие такое: вставлен принтер И к cupsd обратились. Читай внимательнее:

вставлен мой принтер и к демону обратились по сокету

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

Не может. Нет сетевых принтеров. В cups настроен один usb-принтер. Или с таким условием можно только с systemd?

gentoo_root ★★★★★
() автор топика
Ответ на: комментарий от Neksys

>Прописать в xinetd скрипт, который будет активизироваться и первым делом парсить статус устройства, при благоприятных условиях запускать обработчик?

Ага, вот и прилетели костыли. Лишние скрипты ещё нужны.

gentoo_root ★★★★★
() автор топика
Ответ на: комментарий от anonymous

> Но описать структуру, которая будет это гарантировать, несложно.
[...]

PS: эти Provides и Requires называются LSB Header.


Какой init-демон поддерживает обработку и параллельный запуск с учетом LSB Header? Если никакой, то вот она - новая идея, которая не хуже systemd, и достойна реализации.

anonymous
()
Ответ на: комментарий от anonymous

> Ничего она не позволяет - первый попавшийся долгозапускающийся процесс и все остальные дружно встают в очередь

Такой процесс поставит в очередь только тех, кто от него зависит. Для этого и нужны Provides/Requires. Остальные будут выполняться параллельно с ним.

кстати а очередь потом кто будет разруливать ?

init-демон. Хотя, вероятно, обработать такую очередь можно и на баше, подменив скрипт /etc/rc.d/rc на вариант, который умеет запускать их параллельно.

anonymous
()
Ответ на: комментарий от anonymous

>вот она - новая идея, которая не хуже systemd, и достойна реализации.

Идея - говно, вместо того чтобы запускать процессы инит будет в цикле список обходить и зависнет нахер при любой маломалькой оплошности в зависимостях

anonymous
()
Ответ на: комментарий от anonymous

> Идея - говно, вместо того чтобы запускать процессы инит будет в цикле список обходить и зависнет нахер при любой маломалькой оплошности в зависимостях.

Прочитай внимательнее. Цикла нет. Выполняется 1 (прописью ОДИН) проход по всем скриптам в лексикографическом порядке. Зависнуть негде.

anonymous
()
Ответ на: комментарий от gentoo_root

> Ага, вот и прилетели костыли. Лишние скрипты ещё нужны.

Таки не понял, почему этот скрипт лишний?
Вроде, как логика прозрачна и проста, и покрывает твою задачу как бык овцу...

Neksys ★★★
()
Ответ на: комментарий от anonymous

>Такой процесс поставит в очередь только тех, кто от него зависит.

Тоесть от поднятия интерфейса ethernet по твоему будет зависеть только один процесс или почти все на сервере, при этом у них еще могут быть куча взаимных зависимостей ?

anonymous
()
Ответ на: комментарий от anonymous

>> Такой процесс поставит в очередь только тех, кто от него зависит.

Тоесть от поднятия интерфейса ethernet по твоему будет зависеть только один процесс или почти все на сервере

Если от поднятого ethernet зависят все службы, то они станут в очередь до поднятия ethernet. И да, это единственно правильное поведение.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>И да, это единственно правильное поведение.

И как ты представляешь при таком раскладе за один проход запустить паралльно процессы с взависимостями ?

anonymous
()
Ответ на: комментарий от gentoo_root

> Не может. Нет сетевых принтеров. В cups настроен один usb-принтер. Или с таким условием можно только с systemd?

Ок. То есть «я так хочу», не потому что это нужно, а это - лично для себя. Ладно, хочу так хочу:

== /etc/xinetd.d/megacups ==
service megacups
{
[...]
        server = /bin/bash
        server_args = /usr/local/bin/megacups-init.sh
}
== /usr/local/bin/megacups-init.sh ==
#!/bin/sh
if [ -e /sys/bus/usb/devices/... ]; then
  exec /.../cups
fi

anonymous
()
Ответ на: комментарий от anonymous

И как ты представляешь при таком раскладе за один проход запустить паралльно процессы с взависимостями ?

А что ты называешь «запустить паралльно процессы с взависимостями»? Вот есть у нас 4 службы: local_fs, network, serv1, serv2. При этом network зависит от local_fs, serv1 и serv2 зависят от network. Тогда работа initd выглядит так:

SEQ
  local_fs
  network
  PAR
    serv1
    serv2

local_fs и network запускаются последовательно, serv1 и serv2 - в параллель.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>local_fs и network запускаются последовательно, serv1 и serv2 - в параллель.

При таком куцем списке сервисов этот огород с зависимостями просто не нужен. Запусти последовательно все и получишь тоже самое.

anonymous
()
Ответ на: комментарий от anonymous

> При таком куцем списке сервисов

Куцый список - это пример, чтобы тебе было проще понять.

Запусти последовательно все и получишь тоже самое.

А теперь представь, что serv1 и serv2 запускаются по 5 минут.

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

> Тоесть от поднятия интерфейса ethernet по твоему будет зависеть только один процесс или почти все на сервере

От поднятия интерфейса ethernet будут зависеть те сервисы, у которых в Requires написано $network. Все остальные от него не зависят.

при этом у них еще могут быть куча взаимных зависимостей?

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

anonymous
()
Ответ на: комментарий от tailgunner

>А теперь представь, что serv1 и serv2 запускаются по 5 минут.

А теперь представь - что твой скрипт уже давно обошел список за время пока поднимался net и оба serv1 и 2 оказались в очереди, как они оттуда параллельно запустятся при одном проходе ?

anonymous
()
Ответ на: комментарий от anonymous

> А теперь представь - что твой скрипт уже давно обошел список

Насчет прохода по списку - это тебе к анонимусу, я о нем ничего не говорил,

erv1 и 2 оказались в очереди, как они оттуда параллельно запустятся при одном проходе ?

Гипотетический проход по списку останавливается до окончания запуска local_fs, потом - до окончания запуска network, потом пускает в параллель serv1 и serv2,

tailgunner ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.