我启动了一个 Debian 不稳定的容器。早期,容器内的 systemd 显示rsync.service: Cannot add dependency job, ignoring: Unit rsync.service is masked
.
我确定 rsync.service 被自动屏蔽,因为 rsync 包已被删除。重新安装该软件包再次揭开了它的面纱。
- 有关于此行为的文档吗?
- 当面对 Debian 的这种行为时,是什么冲突导致 systemd 发出警告?
- 我惊喜地发现,这种行为以某种方式检测到我在安装 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.
此输出具有误导性。 Debian/etc/init.d/rsync
没有启动,rsync --daemon
因为我没有更改. (在这种情况下,init 脚本本身会默默退出;但是我相信 systemd 启动时会显示一条启动消息,类似于上面显示的日志消息)。所以掩蔽在这里起到了有用的作用。RSYNC_ENABLE=false
/etc/default/rsync
(删除包后 /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 不稳定容器。在stretch发布之前不久就有人提出这个问题。
主机使用 systemd-container 版本 231-15.fc25。
systemd 消息“忽略:Unit 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.
答案1
有关于此行为的文档吗?
它被写下来了。指针至为什么这是在文件的提交消息中找到的,该文件后来被移动到其他地方......
我惊喜地发现,这种行为以某种方式检测到我在安装 rsync 时是否屏蔽了它,并且在删除并重新安装 rsync 时避免自动取消屏蔽。这是如何实现的??它还有其他微妙的限制吗?
仔细找,还是可以找到的来源历史。它链接到一个问题,这证实了在 systemd 下使用屏蔽来尽可能最好地处理系统 V 初始化脚本。
切线:有一个未实施的提案可以消除对此的需要,#749400 - dh_installinit:在删除软件包时禁用初始化脚本。这并不是说这是一个明确的好主意。 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
它的作用记录在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
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 rpm 具有类似的代码
$ rpm -q --scripts rsync
...
# Package removal, not upgrade
systemctl --no-reload disable --now avahi-daemon.socket avahi-daemon.service > /dev/null 2>&1 || :
...
我看了这个,因为我注意到删除 rsync-daemon 并没有删除 /etc/systemd/system/multi-user.target.wants/rsyncd.service
. 因为 这是 rsync 包特有的错误:服务文件位于 package 中systemctl disable
如果符号链接指向已被删除的文件,则当前不会删除它们。rsync
,但引用该服务的 rpm 脚本位于 package 中rsync-daemon
。