当我的进程(及其子进程)收到 aSIGTERM
并且发送者是systemd
(PID == 1)时,您好,有一个非常奇怪的情况。我的设置如下:
- 两个“simmetric”分区安装在
/opt/a
和 上/mnt/a
,分别为一个主分区和一个辅助分区; - 一个正在运行的
systemd
服务单元(可在 中执行/opt/a/bin/my_exe
),在特定条件下,它会下载一些.deb
档案并启动 bash 脚本来安装它们; - 由于包中的文件层次结构引用
/opt/a
,因此该脚本启动一个实例,执行onunshare
的绑定安装并调用以安装包:/mnt/a
/opt/a
dpkg
#!/bin/bash
DEB_PKG="$1"
unshare -m /bin/bash <<-EOF
mount --bind /mnt/a /opt/a
dpkg -i --admindir=/opt/a/var/lib/dpkg "\$DEB_PKG"
EOF
好吧,我验证了当为安装可执行文件的 .deb 包调用脚本时/opt/a/bin/my_exe
,systemd
将 a 发送SIGTERM
到脚本和正在运行的my_exe
.对于所有其他软件包,安装完成时不会出现错误。此外,如果手动启动/opt/a/bin/my_exe
一切都很好。我怀疑,由于某些原因,systemd
不喜欢postinst
产生问题的包中的某些步骤,但是:
- 我不知道它是如何拦截它们的;
- 安装是在另一个分区中执行的。
所有包的脚本postinst
都是相同的:
while IFS=' ' read -r f
do
if [[ -e "$f" && "$f" == /opt/a/* ]]; then
chown -h obs.obs $f
fi
done < "$DPKG_ADMINDIR"/info/$DPKG_MAINTSCRIPT_PACKAGE.list
编辑:这是 systemd.service
文件(非常简单):
[Unit]
Description=Extensible and configurable updater manager.
[Service]
ExecStart=/opt/a/bin/my_exe -c /opt/a/etc/config.ini
User=obs
Group=obs
Restart=on-failure
RestartSec=30
[Install]
WantedBy=multi-user.target
EDIT2:经过其他调查后,我发现正在运行的服务的可执行文件被.deb
软件包安装替换,也被SIGTERM
.因此,systemd 似乎认为被替换的可执行文件是正在运行的进程的可执行文件,而不是其他分区中的可执行文件。这怎么可能?绑定挂载是在专用挂载命名空间中完成的,并且在其内部/opt/a
应该引用/mnt/a
.我验证了在我的 shell 中我没有看到绑定安装:
$ findmnt | grep "/opt/a"
|-/opt/a /dev/sda6 ext4 rw,relatime,sync,data=ordered
当我看到由以下命令创建的挂载命名空间内的绑定挂载时unshare
:
# nsenter -m -t $(pidof update_script.sh) /bin/bash
# findmnt | grep "/opt/a"
|-/opt/a /dev/sda6 ext4 rw,relatime,sync,data=ordered
| `-/opt/a /dev/sda5 ext4 rw,relatime,sync,data=ordered