我有多个LVM分区,每个分区都包含Ubuntu安装。有时,我想执行apt-get dist-upgrade
,将安装更新为最新的软件包。我使用chroot进行此操作-该过程通常是这样的:
$ sudo mount /dev/local/chroot-0 /mnt/chroot-0
$ sudo chroot /mnt/chroot-0 sh -c 'apt-get update && apt-get dist-upgrade'
$ sudo umount /mnt/chroot-0
[未显示:我还装载和卸载/mnt/chroot-0/{dev,sys,proc}
的绑定坐骑到真正的/dev
,/sys
并且/proc
,作为距离-升级似乎希望这些在场]
但是,升级到精确版本后,该过程将不再起作用-最终的卸载将失败,因为文件/mnt/chroot-0
系统上仍然有打开的文件。lsof
确认chroot中有打开文件的进程。这些过程已在dist升级期间启动,我认为这是因为chroot中的某些服务在service postgresql restart
软件包升级后需要重新启动(例如,通过)。
因此,我认为我需要告诉upstart停止在此chroot中运行的所有服务。有没有办法可靠地做到这一点?
我试过了:
cat <<EOF | sudo chroot /mnt/chroot-0 /bin/sh
# stop 'initctl' services
initctl list | awk '/start\/running/ {print \$1}' | xargs -n1 -r initctl stop
EOF
凡initctl list
看来,做正确的事情,只有在这个特定的根已经启动列表的过程。正如Tuminoid的建议,我也尝试添加此内容:
cat <<EOF | sudo chroot /mnt/chroot-0 /bin/sh
# stop 'service' services
service --status-all 2>/dev/null |
awk '/^ \[ \+ \]/ { print \$4}' |
while read s; do service \$s stop; done
EOF
但是,这些似乎并不能解决所有问题。已守护进程并重新绑定到PID 1的进程不会停止。我也尝试过:
sudo chroot /mnt/chroot-0 telinit 0
但是在这种情况下,init 不会区分单独的根,而是关闭了整个计算机。
因此,是否有任何方法可以告诉init停止特定chroot中的所有进程,以便我可以安全地卸载文件系统?新贵公司是否有任何设施可以对chroot中的所有子进程执行SIGTERM / SIGKILL操作(如在常规关机过程中一样)?