Ich habe eine Reihe von LVM-Partitionen, die jeweils eine Ubuntu-Installation enthalten. Gelegentlich möchte ich eine apt-get dist-upgrade
, um eine Installation auf die neuesten Pakete zu aktualisieren. Ich mache das mit chroot - der Prozess ist normalerweise ungefähr so:
$ 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
[Nicht gezeigt: Ich ein- und aushängen auch /mnt/chroot-0/{dev,sys,proc}
als Bind-Mounts auf die reale /dev
, /sys
und /proc
, wie die dist-upgrade scheint diese zu erwarten anwesend sein]
Nach dem Upgrade auf "exact" funktioniert dieser Vorgang jedoch nicht mehr. Die endgültige Umount-Datei schlägt fehl, da noch Dateien im /mnt/chroot-0
Dateisystem geöffnet sind . lsof
Bestätigt, dass in der Chroot Prozesse mit geöffneten Dateien vorhanden sind. Diese Prozesse wurden während des dist-Upgrades gestartet. Dies liegt vermutlich daran, dass bestimmte Dienste in der Chroot neu gestartet werden müssen (z. B. durch service postgresql restart
), nachdem das Paket aktualisiert wurde.
Ich denke also, ich muss upstart mitteilen, dass alle Dienste, die in dieser Chroot ausgeführt werden, gestoppt werden sollen. Gibt es eine Möglichkeit, dies zuverlässig zu tun?
Ich habe es versucht:
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
Wo initctl list
scheint das Richtige zu tun und nur Prozesse aufzulisten, die in dieser bestimmten Wurzel gestartet wurden. Ich habe versucht, dies auch hinzuzufügen, wie von Tuminoid vorgeschlagen:
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
Diese scheinen jedoch nicht alles zu erfassen; Prozesse, die auf PID 1 zurückgesetzt wurden, werden nicht gestoppt. Ich habe auch versucht:
sudo chroot /mnt/chroot-0 telinit 0
In diesem Fall unterscheidet init jedoch nicht zwischen den einzelnen Roots und fährt die gesamte Maschine herunter.
Gibt es eine Möglichkeit, init anzuweisen, alle Prozesse in einer bestimmten Chroot zu stoppen, damit ich das Dateisystem sicher trennen kann? Verfügt upstart über eine Möglichkeit, alle untergeordneten Prozesse (wie beim regulären Herunterfahren) innerhalb einer Chroot SIGTERM / SIGKILL zuzuweisen?