LINUX.ORG.RU
ФорумTalks

Немного Марсианской Логики

 


3

2

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

Note that requirement dependencies do not influence the order in which services are started or stopped.

Именно так, для определения порядка нужно использовать After=. И вот я сижу и пытаюсь представить, какой извращенный use-case пришел этим людям в их гойловы и кто вообще выпустил разработчиков из зоопарка.

★☆

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

Я лично представлял себе, что в случае упоминания After= или Before= директива Requires= попросту не нужна, она подразумевается. И я весь топик пытаюсь понять, зачем она нужна в случае наличия After или Before.

Нет, как раз о том :)

kirk_johnson ★☆
() автор топика
Последнее исправление: kirk_johnson (всего исправлений: 1)
Ответ на: комментарий от Ivan_qrt

Тогда ему нужен After на интерфейс/network-online.

Об этом и речь. В случае с 0.0.0.0 и так работает, а вот с 10.10.10.1 нужен After. Отсюда и вывод — я не вижу действительно важного use-case, который бы оправдывал настолько свободную настройку юнитов.

kirk_johnson ★☆
() автор топика
Ответ на: комментарий от Ivan_qrt

Ну это уже бессмысленный разговор, а главное к делу совсем не относится.

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

kirk_johnson ★☆
() автор топика
Ответ на: комментарий от Ivan_qrt

По сути вопрос, зачем нужен after без requires. Я на него и ответил.

Ты сказал, как оно работает, но не зачем оно такое нужно.

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

Отсюда и вывод — я не вижу действительно важного use-case, который бы оправдывал настолько свободную настройку юнитов.

Ты привёл юзкейс где нужен after, и из этого сделал вывод, что нет юзкейсов, где достаточно requires?

Лёня захотел систему инициализации с минимумом блокировок. Он её и сделал. Логика requires и after такие для этого.

С каких пор у сторонников лапши на башетрадиционных инитов, гибкость - это недостаток? Что за фигня?

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

Ты сказал, как оно работает, но не зачем оно такое нужно.

Я привел в качестве примера, зачем такое может потребоваться, vpn и сбор статистики с различных источников. Чем тебе не «зачем оно такое нужно»?

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

Ты привёл юзкейс где нужен after, и из этого сделал вывод, что нет юзкейсов, где достаточно requires?

Нет. Я привел несколько примеров того, что Requires= без After= может сломать загрузку при определенных обстоятельствах, и не вижу профита от раздельного Requires= и After=.

С каких пор у сторонников лапши на башетрадиционных инитов, гибкость - это недостаток? Что за фигня?

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

kirk_johnson ★☆
() автор топика
Ответ на: комментарий от Ivan_qrt

Я привел в качестве примера, зачем такое может потребоваться, vpn

Это? Немного Марсианской Логики (комментарий)

VPN, запускаемая по After network-online и не останавливаемая при останове сети - так себе пример.

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

Нет. Я привел несколько примеров того, что Requires= без After= может сломать загрузку при определенных обстоятельствах, и не вижу профита от раздельного Requires= и After=.

Ну да, запускать всё, что хоть как-то связано последовательно безопаснее. Запускать вообще всё последовательно ещё безопаснее.

Но Лёня хочет параллелить по-максимуму. Я его в этом поддерживаю.

Да, бездумно ставить везде requires без after опасно. Но там, где безопасно надо ставить только requires.

Как пример, у тебя может быть httpd за nginx. Nginx без httpd не нужен. Httpd без nginx тоже. Но почему бы их не запускать параллельно?

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

Это? Немного Марсианской Логики (комментарий)

Это.

Допустим у тебя есть vpn. Его надо запускать только после networkmanager-online, systemd-networkd.service + resolved (емнип, online для него пока не поддерживается), network.service и т.п. Что именно у пользователя используется ты не знаешь, может даже что-то своё. Знаешь, что если кто-то из них запущен, то стартовать надо после него.

Ты пишешь After=networkmanager-online.service, After=network.service и т.п. Проблема решена. Если я хочу сменить network.service на systemd-networkd.service, я могу не вносить никаких изменений в сервис vpn.

Альтернатива, клепать ещё один таргет, чуть ниже network-online.target, на который ставить зависимость для vpn. Что лучше, вопрос спорный, но в systemd возможны оба варианта.


VPN, запускаемая по After network-online и не останавливаемая при останове сети - так себе пример.

Запускаемая после любого из After=NetworkManager-online и т.п., но не стартующая их сама. И запускаемая до network-online.target. Как она будет запускаться/останавливаться зависит от секции install и Before=. Я про это вообще ничего не говорил.

Второй пример устраивает?

Ivan_qrt ★★★★★
()
Последнее исправление: Ivan_qrt (всего исправлений: 1)
Ответ на: комментарий от Deleted

(Как я понимаю, Wants= и Requires= взаимоисключающие. Могут ли быть After (Before) совместно с Wants ?)

Конечно, могут быть.

Я лично представлял себе, что в случае упоминания After= или Before= директива Requires= попросту не нужна, она подразумевается. И я весь топик пытаюсь понять, зачем она нужна в случае наличия After или Before. В доке написано: ортогонально.

Нет, не подразумевается, о чём и сказано в доке.

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

Нет. Ты привел пример UB.

Что ты называешь UB?

Он неверный.

В каком месте?

Они взаимоопределяющие и одновременно использоваться не могут.

Взаимоисключающие? Взаимоопределяющие? Протрезвей, потом приходи.

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

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

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

Вот это довольно мерзкая хрень, потому что:

«Вот это» — это что? Постгрес мерзкая хрень?

Порождает чудесный race condition (который в случае с postgres не особо важен, конечно)

Какой?

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

Как?

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

При чём тут OpenRC? И там, и там модель зависимостей. Если в OpenRC два слова заменили одним, от этого ничего особо не поменялось.

Тем более что на самом деле ( Ivan_qrt) пример с VPN плохой, потому что в systemd тоже есть «абстрактные» таргеты (типа твоих net и dns), и достаточно просто притянуть их.

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от kirk_johnson

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

Вот тебе ещё один пример: есть у нас сервер и клиент. Сервер «сокет-активируемый» в терминологии systemd (что это такое, надеюсь, объяснять не надо). В этом случае мы всё равно хотим положить клиента при падении сервера, но упорядочивать их запуск уже необязательно. Поэтому в клиенте мы напишем Requires=$SERVER без всяких After=.

Так лучше?

Пример After= без Wants=/Requires= привёл Ivan_qrt.

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 2)
Ответ на: комментарий от intelfx

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

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

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

В доках написано, что совсем обязательно.

Эммм.. ну тогда я перестал понимать смысл этой конструкции

selivan ★★★
()

По треду сложилось впечатление, что это просто ещё один костыль для «быстрой загрузки». Если сервис Y зависит от сервиса X, но может подождать его самостоятельно, то мы не делаем нормальное дерево с After, а просто прописываем Requires и экономим доли секунд на времени загрузки системы. Победа ёпт.

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

раздельного Requires= и After=.

А профит в двух ключевых словах (Before/After) для одного и того же ты видишь?

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

А профит в двух ключевых словах (Before/After) для одного и того же ты видишь?

Ага. Before= — до. After= — после. Нет кейворда — плевать как.

kirk_johnson ★☆
() автор топика
Ответ на: комментарий от intelfx

Какой?

Ну вот твой пример с vacuum и postgres. Тебе необходимо регулярно запускать vacuum, шоп данные не потерять. У тебя окно в несколько недель, на самом деле. А теперь представь, что у тебя окно не в несколько недель, а в несколько секунд. А порядок загрузки не определен :)

kirk_johnson ★☆
() автор топика
Последнее исправление: kirk_johnson (всего исправлений: 1)
Ответ на: комментарий от Ivan_qrt

Второй пример устраивает?

Нет. Это то же самое. After не прописывает зависимость, и VPN не останавливается при остановке с сети - это надо как-то прописывать отдельно. Если бы директива Requires была реализована нормально, ее бы одной хватило и для корректного старта, и для корректного завершения.

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

P_P

Ну вот есть у тебя пакет foo, предоставляющий foo.service. И есть пакет bar, предоставляющий bar.service. Ты хочешь запустить bar.service после foo.service. У тебя два варианта: модифицировать пакет foo (Before=bar.service) или добавить в свой пакет bar нужную опцию (After=foo.service). Преимущества второго подхода становятся видны при добавлении сервисов baz, azb и zab, стартующих после foo.

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

Вроде понял о чем ты. Имеется ввиду, что если сетка работает, например, через nm, то при останоке nm, vpn не остановится, а при последующем запуске не запустится.

Согласен, плохо. Не завязываясь на конкретный сервис предоставления сети, ты по-другому и не сделаешь. Только если заводить промежуточный таргет, и в [Install] WantedBy на RequiredBy менять, а vpn'у Require на этот таргет прописывать.

Но к вопросу After без Require это уже отношения не имеет, так же как и нужность не завязывания на конкретный сервис.

Ещё вариант. Вот тебе дефолтный юнит mariadb из fedora 24:

[Unit]
Description=MariaDB 10.1 database server
After=syslog.target
After=network.target

[Service]
Type=notify
User=mysql
Group=mysql

ExecStartPre=/usr/libexec/mysql-check-socket
ExecStartPre=/usr/libexec/mysql-prepare-db-dir %n
# MYSQLD_OPTS here is for users to set in /etc/systemd/system/mariadb@.service.d/MY_SPECIAL.conf
# Note: we set --basedir to prevent probes that might trigger SELinux alarms,
# per bug #547485
ExecStart=/usr/libexec/mysqld --basedir=/usr $MYSQLD_OPTS $_WSREP_NEW_CLUSTER
ExecStartPost=/usr/libexec/mysql-check-upgrade
ExecStopPost=/usr/libexec/mysql-wait-stop

# Setting this to true can break replication and the Type=notify settings
# See also bind-address mysqld option.
PrivateNetwork=false

KillMode=process
KillSignal=SIGTERM

# Don't want to see an automated SIGKILL ever
SendSIGKILL=no

# Restart crashed server only, on-failure would also restart, for example, when
# my.cnf contains unknown option
Restart=on-abort
RestartSec=5s

UMask=007

# Give a reasonable amount of time for the server to start up/shut down
TimeoutSec=300

# Place temp files in a secure directory, not /tmp
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Поясняю: она может работать как без системного логгера, так и без сети. Но, если сетка и логгер всё таки есть, то стартовать надо после них.

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

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

Не завязываясь на конкретный сервис предоставления сети, ты по-другому и не сделаешь.

Почему не сделаю? Если бы Requires дожидался старта указанной службы, всё бы работало автоматически.

Ещё вариант. Вот тебе дефолтный юнит mariadb из fedora 24:

Отличный результат борьбы с шелл-портянками.

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

Если бы Requires дожидался старта указанной службы, всё бы работало автоматически.

Не завязываясь на конкретный сервис предоставления сети

В requires придётся прописывать конкретный сервис. Либо заводить промежуточный таргет и прописывать его.

Отличный результат борьбы с шелл-портянками.

Вполне отличный. И я без сарказма и т.п. Попробуй, сделай полный аналог на баше, уместив их в 24 значимых строки.

Про пример есть что сказать?

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

В requires придётся прописывать конкретный сервис

Или каждый сервис provides некую capability (как упомянуто для openrc).

Попробуй, сделай полный аналог на баше, уместив их в 24 значимых строки.

Тут плохо не то, что без шелла всё равно обойтись невозможно, а что проектировщик делал вид, что сможет.

Про пример есть что сказать?

Пример с Maria? Можно еще добавить, что это тошнотворный песец, но это аргумент только для тех, кто вырос не в венде.

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

Или каждый сервис provides некую capability (как упомянуто для openrc).

Это и есть промежуточный таргет, вид в профиль. За исключением косяков, если для одной capability нужно несколько сервисов.

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

Понятно. Хвостострел завилял хвостом. Вполне ожидаемо. Я так понимаю, что полезного тебе сказать больше нечего, и дискуссию можно прекращать?

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

Или каждый сервис provides некую capability (как упомянуто для openrc).

Это и есть промежуточный таргет, вид в профиль

Нет. Это достигает той же цели более простым и эффективным способом.

Хвостострел завилял хвостом

Системд-фанбой всегда найдет возможность продемонстрировать свой уровень.

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

Можно по дефолту запрещать все соединения, кроме специального, а в ExecStartPost= условного автовакуума пинать контрольный сокет и разрешать всё.

Если бы в реальном постгресе (вне нашего мысленного эксперимента) действительно стояла такая проблема, там наверняка было бы сделано именно так. Только хардкодом в управляющем процессе.

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 2)
Ответ на: комментарий от Stil

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

Впечатление неправильное. Before=/After= без Wants=/Requires= не используют для ускорения чего-либо, т. к. Wants= между двумя сервисами вообще не используют, а Requires= создаёт ещё и зависимость при остановке, которая в любом случае нужна (упал сервер — положи и клиента).

Напротив, мы тут в основном обсуждаем случаи, когда нужно использовать Requires= без After=. Я вот привёл два примера.

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

Что ты называешь UB?

Учи матчасть.

Взаимоисключающие? Взаимоопределяющие? Протрезвей, потом приходи.

Если это тебе не понятно, то иди учись, тупица.

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

Какой ты дерзкий. Определись хотя бы, взаимоисключающие у тебя параметры или взаимоопределяющие, лол :D А потом уже что-то кукарекай.

Хотя это всё равно не важно, потому что на самом деле они независимые, о чём прямо сказано в доке.

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

kirk_johnson> Да я бы с радостью, но в новом доебане (на котором основан proxmox) systemd.

apt-get purge systemd apt-get install sysvinit openrc

Вот только часть пакетов там намертво привязали к systemd без адекватных причин, о чём уже предупреждал Ян Джексон, когда выдвигал требование не привязывать пакеты к конкретному иниту, если они сами по себе могут без него работать, но предложение и голосование саботировали, так как заговор systemd-филищ существует. И некоторые из них даже на ЛОР пробрались (их не мешало бы забанить).

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

Документация ясно даёт понять, что разработчики systemd - психически ненормальные. И тот самый отрывок, который ты привёл, это подтверждает. Потому, что requires у всех нормальных людей означает обязательность, но у разработчиков systemd и подсосков поцеринга нет логического мышления в принципе, поэтому для них слово «требование» означает нечто необязательное к выполнению.

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

subwoofer> Увожаемый, когда поссышь тогда и приходи, пообщаемся нормально. А свои сортирные темы оставь при себе.

Сортирная тема - в systemd.

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

Ivan_qrt> Философия системд в том, что все сервисы должны запускаться паралельно, с минимальным кол-вом блокировок.

Это чистейшая ложь. Философия systemd заключается в том, чтобы инит был максимально сложным и непонятным дабы дать возможность сопровождать систему только специально обученным обезьянам с сертификатом от врага свободного ПО - RedHat. Специально обученным обезьянам логика не нужна, им достаточно только вызубрить, что подразумевал Поцеринг. Поэтому помойка в systemd начинается с PID 1. И поэтому Поцеринг старается заменить по возможности всю базовую систему монолитным набором systemd. А запуск сервисов - это уже дело десятое. Судя по шатанию основ в сторону неадекватности, заказчика техническая сторона вопроса не интересует - RedHat хочет просто подмять под себя всех и протолкнуть свою монополию в ущерб сообществу и экосистеме.

Quasar ★★★★★
()
Последнее исправление: Quasar (всего исправлений: 1)
Ответ на: комментарий от Ivan_qrt

Ivan_qrt> Если сервису А нужен Б, но он может подождать его запуска, то должно быть просто Requires.

Нет - если сервису А нужен сервис Б, но подождать можно, то должно быть не Requires, а Runlater ли что-то вроде этого. Requires означает, что надо запустить сервис ещё до запуска указанного.

Ivan_qrt> Если сервис А должен запускаться строго после Б (не умеет ждать), но сам Б для него необязателен, то либо просто After, либо After + Wants, по ситуации.

В этом случае не After или Wants, а Recommended. Потому, что само слово After подразумевает, что сервис надо обязательно запустить после заданного. А Wants - это вообще какое-то нечто.

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

intelfx> Если в OpenRC два слова заменили одним, от этого ничего особо не поменялось.

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

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

Нет. Это достигает той же цели более простым и эффективным способом.

Более простой, т.к. не надо создавать файл для таргета в /etc/systemd/system? И вместо RequiredBy/WantedBy писать provides?

Ну да, разница огромна. В чём эффективность?

Вы все вендузятники, а я дартаньян вырос на юниксе.
Фанбои, фанбои, фанбои

Ясненько.

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

Вы все вендузятники, а я дартаньян вырос на юниксе.

Ты опять всё выдумал. Я вырос на ОС ЕС.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)

Я просто добавляю Restart=always, и он через десяток попыток таки запускается успешно :D

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

А вот и квазарчик пожаловал со своим вечным баттхёртом. Проходи мимо, не задерживайся.

Да, чувак фееричен.

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