#!/bin/sh # This script must be executed with parameter "--start" at the end of distro shutdown # What it does is it executes as init (process 1) and unmounts all filesystems # including union and the USB device (if any), so it can be cleanly removed # # Simply add the following as the last command executed by init on your distro # instead of the actual poweroff or shutdown command: # # exec /mnt/live/lib/cleanup --start poweroff # or # exec /mnt/live/lib/cleanup --start shutdown # # on Slackware, add this to rc.0: # exec /mnt/live/lib/cleanup --start /sbin/$command # # It may be needed to call this script also with --killall5 from your shutdown scripts # instead of calling regular killall5, to prevent fuse filesystems from being killed # # Author: Tomas M # if [ "$1" = "--killall5" ]; then # kill all unneeded processes, which have smaller ID then the ID of # current shell's parent process. We can't use killall5, as it would kill some # processes which may be currently needed, for example fuse filesystems (ntfs-3g). for pid in $(/mnt/live/bin/ps | grep -v "PID" | grep -E -v "\[.*\]" | grep -E -v "mount|posixovl|fuse" | sed -r "s/^ +//" | cut -d " " -f 1); do if [ $pid -lt $PPID ]; then LIST="$LIST $pid" fi done kill -15 $LIST 2>/dev/null # SIGTERM sleep 2 # give processes some time to end properly kill -9 $LIST 2>/dev/null # SIGKILL fi if [ "$1" = "--start" ]; then # this is our first call. We will setup everything so the actual init actually # reloads, but calls this script again instead of itself cd /mnt/live cp "$0" sbin/init pivot_root . memory/union echo "$2 -f" > /lib/command chroot /memory/union /sbin/telinit u fi if [ "$1" = "--init" ]; then # now we're called from init to replace the process nr 1. # All other processes are already killed # so our goal is just to unmount everything # First, mount proc again since it will be beeded mount -t proc proc /proc >/dev/console 2>&1 # next, unmount everything tac /proc/mounts | grep union | cut -d " " -f 2 | while read LINE; do umount $LINE umount -l $LINE 2>/dev/null done tac /proc/mounts | grep memory | cut -d " " -f 2 | while read LINE; do umount $LINE umount -l $LINE 2>/dev/null done # make sure the data directory is at least remounted read-only, # if the previous unmount failed due to some busy err mount -o remount,ro /memory/data 2>/dev/null # if debug is requested, start commandline prompt here if grep -q debug /proc/cmdline; then echo "Starting shell for debug" >/dev/console setsid sh -c 'exec sh < /dev/tty1 >/dev/tty1 2>&1' fi cat /proc/mounts >/dev/console 2>&1 $(cat /lib/command 2>/dev/null) reboot -f fi