删除 Debian 软件包会自动屏蔽 systemd 服务 - 导致 systemd 警告

sou*_*edi 4 debian systemd

我启动了一个 Debian 不稳定容器。早期,容器内的 systemd 显示rsync.service: Cannot add dependency job, ignoring: Unit rsync.service is masked.

我确定 rsync.service 被自动屏蔽,因为 rsync 包被删除。重新安装该软件包会再次揭开它的面纱。

  1. 是否有这种行为的文档?
  2. 当面对Debian的这种行为时,导致systemd发出警告的冲突是什么?
  3. 我惊喜地看到这种行为以某种方式检测我是否在安装时屏蔽了 rsync,并避免在我删除并重新安装 rsync 时自动取消屏蔽。这是如何实施的??它还有更微妙的限制吗?

发现包装去除时的自动掩蔽

我知道 rsync 最初已安装,但现在已删除。我取下面具,留下了这个:

$ sudo systemctl status rsync
? rsync.service - LSB: fast remote file copy program daemon
   Loaded: loaded (/etc/init.d/rsync; generated; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:systemd-sysv-generator(8)

$ # reset status of all systemd services
$ # DO NOT TRY THIS COMMAND INSIDE A REAL, NON-CONTAINER SYSTEM...
$ # IT DOES NOT GO WELL.
$ sudo systemctl isolate default.target

$ sudo systemctl status rsync
? rsync.service - LSB: fast remote file copy program daemon
   Loaded: loaded (/etc/init.d/rsync; generated; vendor preset: enabled)
   Active: active (exited) since Wed 2017-06-07 11:35:27 BST; 1s ago
     Docs: man:systemd-sysv-generator(8)
  Process: 432 ExecStart=/etc/init.d/rsync start (code=exited, status=0/SUCCESS)
   CGroup: /machine.slice/machine-unstable.scope/system.slice/rsync.service

Jun 07 11:35:27 unstable systemd[1]: Starting LSB: fast remote file copy program daemon...
Jun 07 11:35:27 unstable systemd[1]: Started LSB: fast remote file copy program daemon.
Run Code Online (Sandbox Code Playgroud)

此输出具有误导性。Debian的/etc/init.d/rsync没有首发rsync --daemon,因为我并没有改变默认RSYNC_ENABLE=false/etc/default/rsync。(在这种情况下,init 脚本本身会静默退出;但是我相信 systemd 启动会为其显示一条启动消息,类似于上面显示的日志消息)。因此,掩蔽在这里起到了有用的作用。

(/etc/init.d/rsync 在包被删除时仍然存在的原因是 initscripts 被认为是用户可编辑的配置文件)

事实证明,如果我再次安装 rsync, rsync.service 将被取消屏蔽。如果我删除它, rsync.service 会再次被屏蔽。

我很高兴地说,如果我安装 rsync,屏蔽它,然后删除并重新安装 rsync,rsync 仍然被屏蔽。

如果我用apt-get remove --purge rsync它来完全删除它,包括残留的配置文件,那么这个掩码就被删除了。

由于我安装了 etckeeper,我注意到完全删除也会删除 /etc/systemd/system/multi-user.target.wants/rsync.service,以及删除掩码(/etc/systemd/system/rsync.service-> /dev/null)。这些文件都不属于包 ( dpkg-query -L rsync),因此看起来这些删除是由包脚本引起的。

软件版本

最新的 Debian 不稳定容器。这个问题是在发布拉伸之前不久被问到的。

主机使用 systemd-container 版本 231-15.fc25。

systemd 消息“忽略:单元 rsync.service 被屏蔽”的更多上下文

$ sudo systemd-nspawn -b -D unstable
Spawning container unstable on /home/nspawn/unstable.
Press ^] three times within 1s to kill container.
systemd 232 running in system mode. (+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN)
Detected virtualization systemd-nspawn.
Detected architecture x86-64.

Welcome to Debian GNU/Linux 9 (stretch)!

Set hostname to <unstable>.
Failed to install release agent, ignoring: File exists
rsync.service: Cannot add dependency job, ignoring: Unit rsync.service is masked
[  OK  ] Started Dispatch Password Requests to Console Directory Watch.
Run Code Online (Sandbox Code Playgroud)

sou*_*edi 6

是否有这种行为的文档?

它被写下来。关于为什么要实现这一点的指针可以在提交消息中找到,该文件已移至其他地方...

我惊喜地看到这种行为以某种方式检测我是否在安装时屏蔽了 rsync,并避免在我删除并重新安装 rsync 时自动取消屏蔽。这是如何实施的??它还有更微妙的限制吗?

仔细一看,还是能找到源码历史的。它链接到一个问题,该问题确认屏蔽用于在 systemd 下尽可能好地处理 system V initscripts。

切线:有一个未实施的提案将消除对此的需求,#749400 - dh_installinit: 在删除 package 时禁用 init 脚本。并不是说这是一个明确的好主意。IIUC,它无法跟踪用户是否启用了脚本。(注意这是每个运行级别的单独设置,在系统 V init 中)。

对此的线索在包脚本中,我在/var/lib/dpkg/info/rsync.postrm.

## from /usr/share/debhelper/autoscripts/postrm-systemd :

if [ "$1" = "remove" ]; then
    if [ -x "/usr/bin/deb-systemd-helper" ]; then
        deb-systemd-helper mask rsync.service >/dev/null
    fi
fi
Run Code Online (Sandbox Code Playgroud)

这样做的内容记录在man deb-systemd-helper. '“屏蔽”操作将保持关于该服务之前是否启用/禁用的状态,并将在“取消屏蔽”时正确返回到该状态。它也被评论在 rsync.postinst

## from /usr/share/debhelper/autoscripts/postinst-systemd-enable :

# This will only remove masks created by d-s-h on package removal.
deb-systemd-helper unmask rsync.service >/dev/null || true
Run Code Online (Sandbox Code Playgroud)

Fedora Linux(版本 25)没有实现这种行为。可以说是因为他们不支持系统 V init 并且有一个策略来完全删除旧式的 init 脚本。我不知道他们在过渡期间是如何处理这个问题的……但他们本可以忽略它而不会造成任何功能问题。

当面对Debian的这种行为时,导致systemd发出警告的冲突是什么?

在一般情况下,屏蔽已启用的服务似乎有点可疑,也许吧?

看起来基于 rpm 的发行版没有/没有尝试保留 initscripts 的启用状态。因为它们checkconf --del在移除时运行。 https://www.cyberciti.biz/faq/centos-rhel-suse-rpm-see-installation-uninstallation-scripts/


现代 Fedora rpms 有类似的代码

$ rpm -q --scripts rsync
...
    # Package removal, not upgrade 
    systemctl --no-reload disable --now avahi-daemon.socket avahi-daemon.service > /dev/null 2>&1 || :
...
Run Code Online (Sandbox Code Playgroud)

我看着这个,因为我注意到删除 rsync-daemon 不会删除 /etc/systemd/system/multi-user.target.wants/rsyncd.service. 因为systemctl disable如果符号链接指向已删除的文件,则当前不会删除它们。 这是 rsync 包特有的错误:服务文件在 package 中rsync,但引用服务的 rpm 脚本在 package 中rsync-daemon