如何删除丢失的 systemd 单元?

如何删除丢失的 systemd 单元?

我不知道如何删除不再包含文件的 systemd 单元。它们似乎仍然以某种方式存在于系统中。

我正在尝试移除的旧的损坏单元:

core@ip-172-16-32-83 ~ $ systemctl list-units --all firehose-router*
  UNIT                       LOAD      ACTIVE SUB    DESCRIPTION
<E2><97><8F> [email protected] not-found failed failed [email protected]
<E2><97><8F> [email protected] not-found failed failed [email protected]

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

2 loaded units listed.
To show all installed unit files use 'systemctl list-unit-files'.

这些文件不存在,但重新加载后这些单元仍然保留:

core@ip-172-16-32-83 ~ $ systemctl list-unit-files [email protected]
core@ip-172-16-32-83 ~ $ sudo systemctl daemon-reload
core@ip-172-16-32-83 ~ $ systemctl list-units --all firehose-router*
  UNIT                       LOAD      ACTIVE SUB    DESCRIPTION
<E2><97><8F> [email protected] not-found failed failed [email protected]
<E2><97><8F> [email protected] not-found failed failed [email protected]

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

2 loaded units listed.
To show all installed unit files use 'systemctl list-unit-files'.

我找不到与它们相关的文件:

core@ip-172-16-32-83 ~ $ sudo find /var/run/systemd -name "*firehose-router*"
core@ip-172-16-32-83 ~ $ find /etc/systemd/ -name "*firehose-router*"
core@ip-172-16-32-83 ~ $ find /usr/lib/systemd/ -name "*firehose-router*"
core@ip-172-16-32-83 ~ $

那么我该如何摆脱这些呢?

答案1

你要执行的命令是systemctl reset-failed

答案2

当 systemd 分析单元定义文件时,它会注意文件中调用的任何其他相关单元 - 无论这些其他单元是否存在。

$ systemctl --state=not-found --all
> ( ...prints list of 'not-found' units )

$ grep -r "<missing-unit>" /usr/lib/systemd/system
> ( returns files with references to <missing-unit> )

当一个单元显示为“未找到”时,这并不一定是错误 - 我们只知道,本地单元定义声称与它有某种关系。这种关系可能不是我们关心的。例如,它可能是"Before:"其他单元,但我们不使用该其他单元。

答案3

  • failed- 当一个单元进入故障状态并可以使用命令重置时systemctl reset-failed发生
  • not-found- 当你删除了一个单元,但 systemd 仍然引用它时,例如当启用了一个单元,并在 中放置了一个符号链接时/etc/systemd/system,可以通过在 中删除对该单元的引用,然后/etc/systemd/system/*.wants/运行 ​​来解决这个问题systemctl daemon-reload

例如,假设以下 bash 脚本:

#!/bin/bash
# script.sh
while true
do
    sleep 1
done

以及三个 systemd 单元:example-foo.serviceexample-bar.serviceexample-baz.service

$ sudo systemctl cat example-{foo,bar,baz}.service
# /etc/systemd/system/example-foo.service
[Service]
ExecStart=/home/vagrant/script.sh
[Install]
WantedBy=multi-user.target

# /etc/systemd/system/example-bar.service
[Service]
ExecStart=/home/vagrant/script.sh
[Install]
WantedBy=multi-user.target

# /etc/systemd/system/example-baz.service
[Service]
ExecStart=/home/vagrant/script.sh
[Install]
WantedBy=multi-user.target

现在,让我们启动并启用这些单元。观察符号链接是如何创建的。

$ sudo systemctl start example-{foo,bar,baz}.service
$ sudo systemctl enable example-{foo,bar,baz}.service
Created symlink from /etc/systemd/system/multi-user.target.wants/example-foo.service to /etc/systemd/system/example-foo.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/example-bar.service to /etc/systemd/system/example-bar.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/example-baz.service to /etc/systemd/system/example-baz.service.

确认我们的三个单位确实有六个文件。

$ find /etc/systemd/system -name 'example*.service'
/etc/systemd/system/multi-user.target.wants/example-bar.service
/etc/systemd/system/multi-user.target.wants/example-foo.service
/etc/systemd/system/multi-user.target.wants/example-baz.service
/etc/systemd/system/example-bar.service
/etc/systemd/system/example-foo.service
/etc/systemd/system/example-baz.service

现在,检查所有三个单元的状态,它们正在运行。

$ systemctl list-units example*
UNIT                LOAD   ACTIVE SUB     DESCRIPTION
example-bar.service loaded active running example-bar.service
example-baz.service loaded active running example-baz.service
example-foo.service loaded active running example-foo.service

现在,通过向 发送 SIGKILL 来模拟故障example-foo.service。观察单元如何处于故障状态。

$ sudo systemctl kill -s KILL example-foo.service
$ systemctl list-units example*
  UNIT                LOAD   ACTIVE SUB     DESCRIPTION
  example-bar.service loaded active running example-bar.service
  example-baz.service loaded active running example-baz.service
● example-foo.service loaded failed failed  example-foo.service

要重置处于故障状态的单元,请使用该systemctl reset-failed命令。观察单元现在如何处于非活动状态。

$ sudo systemctl reset-failed
$ systemctl list-units example*
UNIT                LOAD   ACTIVE SUB     DESCRIPTION
example-bar.service loaded active running example-bar.service
example-baz.service loaded active running example-baz.service

...
$ systemctl list-units --all example*
UNIT                LOAD   ACTIVE   SUB     DESCRIPTION
example-bar.service loaded active   running example-bar.service
example-baz.service loaded active   running example-baz.service
example-foo.service loaded inactive dead    example-foo.service

好的,现在让我们删除 example-bar.service 单元。观察该单元如何处于未找到状态;但是,example-bar.service 损坏的符号链接仍然在 /etc/systemd/system/multi-user.target.wants 中

$ sudo rm /etc/systemd/system/example-bar.service
$ sudo systemctl daemon-reload
$ sudo systemctl stop example-bar.service
Failed to stop example-bar.service: Unit example-bar.service not loaded.
$ systemctl list-units --all example*
  UNIT                LOAD      ACTIVE   SUB     DESCRIPTION
● example-bar.service not-found inactive dead    example-bar.service
  example-baz.service loaded    active   running example-baz.service
  example-foo.service loaded    inactive dead    example-foo.service
$ find /etc/systemd/system -name 'example*.service'
/etc/systemd/system/multi-user.target.wants/example-bar.service
/etc/systemd/system/multi-user.target.wants/example-foo.service
/etc/systemd/system/multi-user.target.wants/example-baz.service
/etc/systemd/system/example-foo.service
/etc/systemd/system/example-baz.service

删除损坏的符号链接并确认 example-bar.service 单元已消失。

$ sudo rm /etc/systemd/system/multi-user.target.wants/example-bar.service
$ sudo systemctl daemon-reload
$ systemctl list-units --all example*
UNIT                LOAD   ACTIVE   SUB     DESCRIPTION
example-baz.service loaded active   running example-baz.service
example-foo.service loaded inactive dead    example-foo.service

答案4

看起来 systemd 维护着链接,但是当您删除单元文件时不知道如何处理它们。

您可以尝试手动删除它们,/etc/systemd/system/suspend.target.wants/但当然systemctl reset-failed从之前的答案来看,这听起来是一个更好的选择。

$ cd /etc/systemd/system
$ sudo mv lock.service /tmp 
$ sudo systemctl disable lock.service
Failed to disable unit: No such file or directory
$ sudo mv /tmp/lock.service .
$ sudo systemctl disable lock.service
Removed /etc/systemd/system/suspend.target.wants/lock.service.

相关内容