82 lines
2.8 KiB
Bash
82 lines
2.8 KiB
Bash
#!/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 <http://www.linux-live.org/>
|
|
#
|
|
|
|
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
|