Eu tenho várias partições LVM, cada uma contendo uma instalação do Ubuntu. Ocasionalmente, quero fazer um apt-get dist-upgrade
, para atualizar uma instalação para os pacotes mais recentes. Eu faço isso com chroot - o processo geralmente é algo como:
$ 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
[Não apresentados: Eu também montar e desmontar /mnt/chroot-0/{dev,sys,proc}
como Bind-montagens para o real /dev
, /sys
e /proc
, como o dist-upgrade parece esperar que eles estejam presentes]
No entanto, após a atualização precisa, esse processo não funciona mais - a quantia final falhará porque ainda existem arquivos abertos no /mnt/chroot-0
sistema de arquivos. lsof
confirma que existem processos com arquivos abertos no chroot. Esses processos foram iniciados durante a dist-upgrade, presumo que isso ocorra porque certos serviços no chroot precisam ser reiniciados (por exemplo, através service postgresql restart
) após a atualização do pacote.
Então, acho que preciso dizer ao iniciante para interromper todos os serviços que estão sendo executados neste chroot. Existe uma maneira de fazer isso de maneira confiável?
Eu tentei:
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
Onde initctl list
parece fazer a coisa certa e listar apenas os processos que foram iniciados nessa raiz específica. Eu tentei adicionar isso também, como sugerido por 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
No entanto, isso não parece pegar tudo; processos que foram daemonizados e reparados no PID 1 não são interrompidos. Eu também tentei:
sudo chroot /mnt/chroot-0 telinit 0
Mas, neste caso, o init não faz distinção entre as raízes separadas e desliga a máquina inteira.
Então, existe alguma maneira de dizer ao init para parar todos os processos em um chroot específico, para que eu possa desmontar com segurança o sistema de arquivos? O iniciante tem algum recurso para SIGTERM / SIGKILL todos os processos filhos (como seria feito durante o desligamento regular) dentro de um chroot?