#!/bin/sh OPEN_SHELL_BEFORE_SHUTDOWN= movemount() { if mountpoint -q "$1"; then umount /root/"$1" else mkdir -p "$1" mount --move /root/"$1" "$1" fi } retry_n_delay() { local n="$1" delay="$2" shift 2 while [ "$n" -gt 0 ]; do "$@" && break; sleep $delay; n=$((n-1)); done } umount_all_novirtual() { # EQUIVALENT: umount -a -t norootfs,nosysfs,noproc,notmpfs,nodevpts,nodevtmpfs # busyboxy umount does not support -t, therefore: tac /proc/mounts | { errors=0 while read dev mp type opts _; do case $type in rootfs|sysfs|proc|tmpfs|devpts|devtmpfs) ;; *) umount "$mp" || errors=$((errors+1)) ;; esac done return $errors } } losetup_delete_all() { local f dev for f in /sys/dev/block/7:*/loop; do dev=${f#/sys/dev/block/7:} dev=/dev/loop${dev%%/*} losetup -d $dev done } mdadm_stop_all() { for md in /dev/md* /dev/md/*; do test -b "$md" && mdadm --stop "$md" done } lvm_deactivate() { lvm lvchange -v -an samizdat 11>&-; } killemdead() { force= pids="$(pidof "$@")" while [ "$pids" ]; do kill $force $pids living= for p in $pids; do if [ -e /proc/$p ]; then living=1 break fi done [ ! "$living" ] && break force=-9 done } specials= movemounts= umounts= while read dev mp type opts _; do # N.B. order is reversed in variables case $mp in /root/dev|/root/proc) specials="$mp $specials" ;; /root/sys|/root/cdrom|/root/mnt/*|/root/gpg|/root/overlay|/root/xino|/root/squashes/*) movemounts="$mp $movemounts" ;; /root/*) umounts="$mp $umounts" ;; esac done < /proc/mounts # Unmount mounts under /root that we didn't put there while true; do error=0; success=0 for m in $umounts; do if umount $m; then success=$((success+1)) else error=$((error+1)) fi done [ $error = 0 ] && break [ $success = 0 ] && break done # Move back mounts that we moved for m in $movemounts; do movemount "${m#/root}" # TODO: error handling done killemdead gpg-agent samizdat-pinentry umount /root/dev umount /root/proc ln -sf /proc/mounts /etc/mtab umount_all_novirtual mdadm_stop_all losetup_delete_all lvm_deactivate cryptsetup remove samizdatcrypt losetup_delete_all umount_all_novirtual if [ "$OPEN_SHELL_BEFORE_SHUTDOWN" ]; then read cmd < /halt echo echo "Remove cdrom and press ctrl-d to run '$cmd'." /bin/sh -i fi read cmd < /halt && $cmd sleep 1 echo "Error! Starting emergency shell with pid 1." exec /bin/sh -i