У меня установлено и запущено несколько модулей systemd. Допустим, я вручную удалил foo.service
по
Я могу бегать systemctl daemon-reload
, а потом вижу:
# systemctl status foo.service
foo.service
Loaded: error (Reason: No such file or directory)
Active: active (running) since Mon 2013-07-08 13:50:29 EST; 48s ago
Main PID: 1642 (node)
Итак, systemd знает, что он не установлен и что он работает. Есть ли какая-нибудь команда, которую я могу использовать, чтобы остановить все запущенные службы, у которых больше нет файла модуля?
То, что я уже рассмотрел:
systemctl isolate <current-target>
Побочным эффектом этого будет остановка других запускаемых вручную служб, которые не требуются текущей цели.
Использовать systemctl disable
вместо удаления файлов вручную
Я бы хотел, но этот скрипт может быть запущен с хост-машины с доступом к файловой системе работающего контейнера - он не может вызывать systemd
прямо.
Использовать systemctl stop foo.service
Это означает, что я знаю, какие службы были удалены. Я не хочу разбираться в этом (или запоминать это), мне нужна общая команда, которую можно запустить в любое время, чтобы остановить любые устаревшие службы.
Я спросил список рассылки, и Леннарт Поеттеринг ответил следующим советом:
http://lists.freedesktop.org/archives/systemd-devel/2013-July/012083.html
Цитата для потомков:
Итак, правильный способ справиться с этим - убедиться, что рассматриваемые пакеты содержат правильные скрипты, завершающие все модули, которые они включают, перед деинсталляцией. Конечно, я боюсь, что всегда будут такие сломанные пакеты, поэтому я могу полностью увидеть ваш вариант использования.
В настоящее время нет хорошего способа справиться с этим, но вы можете сделать следующее:
$ systemctl --all --type=not-found --type=error
Здесь будут перечислены все блоки, в которых состояние загрузки - «ошибка» или «не найден» (обратите внимание, что «не найден» доступен только в самых последних версиях, а в более старых версиях systemd это был лишь частный случай ошибки Командная строка выше работает для всех версий). Переключатель --type = используется для фильтрации типов модулей, но на самом деле также может использоваться для фильтрации состояния загрузки.
Затем отфильтруйте первый столбец:
$ systemctl --no-legend --all --type=not-found --type=error | awk '{ print $1 }'
Это даст вам список файлов модулей, на которые есть ссылки или которые были запущены, но не имеют установленного файла модуля. Затем используйте это, чтобы остановить блоки:
$ systemctl stop `systemctl --no-legend -all --type=not-found --type=error | awk '{ print $1}'`