I have a number of LVM partitions, each containing an Ubuntu installation. Occasionally, I want to do an apt-get dist-upgrade
, to update an installation to the most recent packages. I do this with chroot - the process is usually something like:
$ 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
[ not shown: I also mount and unmount /mnt/chroot-0/{dev,sys,proc}
as bind-mounts to the real /dev
, /sys
and /proc
, as the dist-upgrade seems to expect these to be present ]
However, after upgrading to precise, this process no longer works - the final umount will fail because there are still open files on the /mnt/chroot-0
filesystem. lsof
confirms that there are processes with open files in the chroot. These processes have been started during the dist-upgrade, I'm assuming this is because certain services in the chroot need to be restarted (eg, through service postgresql restart
) after the package is upgraded.
So, I figure I need to tell upstart to stop all the services that are running within this chroot. Is there a way to reliably do this?
I've tried:
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
Where initctl list
seems to do the right thing and only list processes that have been started in this particular root. I've tried adding this too, as suggested by 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
However, these doesn't seem to catch everything; processes that have daemonised and been reparented to PID 1 don't get stopped. I've also tried:
sudo chroot /mnt/chroot-0 telinit 0
But in this case, init doesn't distinguish between the separate roots and shuts down the entire machine.
So, is there any way to tell init to stop all processes in a particular chroot, so that I can safely unmount the filesystem? Does upstart have any facility to SIGTERM/SIGKILL all child processes (as would be done during regular shutdown) within a chroot?