ฉันมีพาร์ติชั่น 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
เป็นออัพเกรดดูเหมือนว่าจะคาดหวังเหล่านี้จะนำเสนอ]
อย่างไรก็ตามหลังจากอัปเกรดเป็นแม่นยำกระบวนการนี้จะไม่ทำงานอีกต่อไป - umount สุดท้ายจะล้มเหลวเนื่องจากยังคงมีไฟล์ที่เปิดอยู่ใน/mnt/chroot-0
ระบบไฟล์ lsof
ยืนยันว่ามีกระบวนการที่เปิดไฟล์ใน chroot กระบวนการเหล่านี้ได้รับการเริ่มต้นในระหว่างการอัพเกรด dist ฉันคิดว่านี่เป็นเพราะบริการบางอย่างใน chroot จำเป็นต้องเริ่มต้นใหม่ (เช่นผ่านservice postgresql restart
) หลังจากแพ็คเกจถูกอัพเกรด
ดังนั้นฉันคิดว่าฉันต้องบอกคนธรรมดาเพื่อหยุดบริการทั้งหมดที่กำลังทำงานอยู่ภายใน 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
อย่างไรก็ตามสิ่งเหล่านี้ดูเหมือนจะไม่ได้จับทุกอย่าง กระบวนการที่มีการ daemonised และรับการ reputed PID 1 จะไม่หยุด ฉันยังลอง:
sudo chroot /mnt/chroot-0 telinit 0
แต่ในกรณีนี้ init ไม่ได้แยกความแตกต่างระหว่างรูทที่แยกจากกันและปิดเครื่องทั้งหมด
ดังนั้นมีวิธีใดที่จะบอกให้ init หยุดกระบวนการทั้งหมดใน chroot นั้น ๆ เพื่อที่ฉันจะสามารถ unmount ระบบไฟล์ได้อย่างปลอดภัย? การพุ่งพรวดมีสิ่งอำนวยความสะดวกใด ๆ ในการ SIGTERM / SIGKILL กระบวนการลูกทั้งหมด (เช่นจะทำในระหว่างการปิดระบบปกติ) ภายใน chroot หรือไม่?