better shutdown handling
parent
ee75cbc8cc
commit
3ccd071367
|
|
@ -1,117 +0,0 @@
|
||||||
#!/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 /run/initramfs/lib/cleanup --start poweroff
|
|
||||||
# or
|
|
||||||
# exec /run/initramfs/lib/cleanup --start shutdown
|
|
||||||
#
|
|
||||||
# on Slackware, add this to rc.0:
|
|
||||||
# exec /run/initramfs/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 $(/run/initramfs/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 the part which is to be called from shutdown script.
|
|
||||||
# We will assume init is running as process 1 and re-executes itself after 'telinit u'
|
|
||||||
# So we're going to force init to stop and start this script instead as PID 1
|
|
||||||
# If your init works differently, you may need to slightly modify few lines below
|
|
||||||
# - without this, init would be blocking union and it couldn't be unmounted later.
|
|
||||||
cd /run/initramfs
|
|
||||||
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.
|
|
||||||
# We know that init binary reexecutes itself with --init parameter
|
|
||||||
# All other processes are already killed
|
|
||||||
# so our goal now is just to unmount everything and reboot/shutdown
|
|
||||||
|
|
||||||
# First, mount proc and sys again since it will be needed and it was already unmounted
|
|
||||||
mount -t proc proc /proc >/dev/console 2>&1
|
|
||||||
mount -t sysfs sysfs /sys >/dev/console 2>&1
|
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
# Update devs so we are aware of all active /dev/loop* files.
|
|
||||||
# Detach loop devices which are no longer used
|
|
||||||
mdev -s
|
|
||||||
losetup | cut -d : -f 1 | xargs -n 1 losetup -d
|
|
||||||
|
|
||||||
# next, unmount everything from union, backwards
|
|
||||||
tac /proc/mounts | grep union | cut -d " " -f 2 | while read LINE; do
|
|
||||||
umount $LINE >/dev/console 2>&1
|
|
||||||
umount -l $LINE
|
|
||||||
done
|
|
||||||
|
|
||||||
# then free up loop mounts, backwards
|
|
||||||
tac /proc/mounts | grep loop | cut -d " " -f 2 | while read LINE; do
|
|
||||||
umount $LINE >/dev/console 2>&1 || \
|
|
||||||
umount -l $LINE
|
|
||||||
done
|
|
||||||
|
|
||||||
# remember from which device we are started, do it now before we lose it
|
|
||||||
DEVICE="$(cat /proc/mounts | grep /memory/data | grep /dev/ | cut -d " " -f 1)"
|
|
||||||
|
|
||||||
# free up memory mounts, backwards
|
|
||||||
tac /proc/mounts | grep memory | cut -d " " -f 2 | while read LINE; do
|
|
||||||
umount $LINE >/dev/console 2>&1
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
mount -o remount,ro $LINE >/dev/console 2>&1
|
|
||||||
umount -l $LINE
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# eject cdrom device if we were running from it
|
|
||||||
for i in $(cat /proc/sys/dev/cdrom/info | grep name); do
|
|
||||||
if [ "$DEVICE" = "/dev/$i" ]; then
|
|
||||||
echo "Attemptiong to eject /dev/$i..." >/dev/console
|
|
||||||
eject /dev/$i
|
|
||||||
echo "CD/DVD tray will close in 6 seconds..." >/dev/console
|
|
||||||
sleep 6
|
|
||||||
eject -t /dev/$i
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# and finally, last chance to run some commands by hand
|
|
||||||
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 /lib/command >/dev/console
|
|
||||||
$(cat /lib/command 2>/dev/null)
|
|
||||||
reboot -f
|
|
||||||
fi
|
|
||||||
|
|
@ -45,8 +45,12 @@ rm -Rf $INITRAMFS
|
||||||
mkdir -p $INITRAMFS/{bin,dev,etc,lib,lib64,mnt,proc,root,run,sys,tmp,usr,var/log}
|
mkdir -p $INITRAMFS/{bin,dev,etc,lib,lib64,mnt,proc,root,run,sys,tmp,usr,var/log}
|
||||||
ln -s bin $INITRAMFS/sbin
|
ln -s bin $INITRAMFS/sbin
|
||||||
|
|
||||||
cp static/{busybox,mount.*,eject} $INITRAMFS/bin
|
cp static/busybox $INITRAMFS/bin
|
||||||
chmod a+x $INITRAMFS/bin/{busybox,mount.*,eject}
|
cp static/eject $INITRAMFS/bin
|
||||||
|
cp static/mount.dynfilefs $INITRAMFS/bin/@mount.dynfilefs
|
||||||
|
cp static/mount.httpfs2 $INITRAMFS/bin/@mount.httpfs2
|
||||||
|
cp static/mount.ntfs-3g $INITRAMFS/bin/@mount.ntfs-3g
|
||||||
|
chmod a+x $INITRAMFS/bin/*
|
||||||
|
|
||||||
$INITRAMFS/bin/busybox | grep , | grep -v Copyright | tr "," " " | while read LINE; do
|
$INITRAMFS/bin/busybox | grep , | grep -v Copyright | tr "," " " | while read LINE; do
|
||||||
for TOOL in $LINE; do
|
for TOOL in $LINE; do
|
||||||
|
|
@ -128,8 +132,8 @@ touch $INITRAMFS/etc/{m,fs}tab
|
||||||
|
|
||||||
cp init $INITRAMFS
|
cp init $INITRAMFS
|
||||||
chmod a+x $INITRAMFS/init
|
chmod a+x $INITRAMFS/init
|
||||||
cp cleanup $INITRAMFS/lib
|
cp shutdown $INITRAMFS
|
||||||
chmod a+x $INITRAMFS/lib/cleanup
|
chmod a+x $INITRAMFS/shutdown
|
||||||
ln -s ../init $INITRAMFS/bin/init
|
ln -s ../init $INITRAMFS/bin/init
|
||||||
cp ../livekitlib $INITRAMFS/lib/
|
cp ../livekitlib $INITRAMFS/lib/
|
||||||
cp ../config $INITRAMFS/lib/
|
cp ../config $INITRAMFS/lib/
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Shutdown script for initramfs. It's automatically started by
|
||||||
|
# systemd (if you use it) on shutdown, no need for any tweaks.
|
||||||
|
# Purpose of this script is to unmount everything cleanly.
|
||||||
|
#
|
||||||
|
# Author: Tomas M <http://www.linux-live.org/>
|
||||||
|
#
|
||||||
|
|
||||||
|
. /lib/config
|
||||||
|
. /lib/livekitlib
|
||||||
|
|
||||||
|
debug_start
|
||||||
|
|
||||||
|
debug_log "Entering shutdown procedures of Linux Live Kit"
|
||||||
|
debug_log "Called with arguments: " "$*"
|
||||||
|
|
||||||
|
# if debug is enabled, run shell now
|
||||||
|
debug_shell
|
||||||
|
|
||||||
|
detach_free_loops()
|
||||||
|
{
|
||||||
|
losetup | cut -d : -f 1 | xargs -r -n 1 losetup -d
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1=dir
|
||||||
|
umount_all()
|
||||||
|
{
|
||||||
|
tac /proc/mounts | cut -d " " -f 2 | grep ^$1 | while read LINE; do
|
||||||
|
umount $LINE 2>/dev/null
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Update devs so we are aware of all active /dev/loop* files.
|
||||||
|
# Detach loop devices which are no longer used
|
||||||
|
mdev -s
|
||||||
|
detach_free_loops
|
||||||
|
|
||||||
|
# do it the dirty way, simply try to umount everything to get rid of most mounts
|
||||||
|
umount_all /oldroot
|
||||||
|
|
||||||
|
# free aufs of /run mount, and umount aufs
|
||||||
|
mkdir /run2
|
||||||
|
mount --move /oldroot/run /run2
|
||||||
|
umount /oldroot
|
||||||
|
|
||||||
|
# remember from which device we are started, so we can eject it later
|
||||||
|
DEVICE="$(cat /proc/mounts | grep /memory/data | grep /dev/ | cut -d " " -f 1)"
|
||||||
|
|
||||||
|
umount_all /run2
|
||||||
|
detach_free_loops
|
||||||
|
umount_all /run2
|
||||||
|
detach_free_loops
|
||||||
|
umount_all /run2
|
||||||
|
|
||||||
|
/bin/bash
|
||||||
|
|
||||||
|
# eject cdrom device if we were running from it
|
||||||
|
for i in $(cat /proc/sys/dev/cdrom/info | grep name); do
|
||||||
|
if [ "$DEVICE" = "/dev/$i" ]; then
|
||||||
|
echo "Attemptiong to eject /dev/$i..." >/dev/console
|
||||||
|
eject /dev/$i
|
||||||
|
echo "CD/DVD tray will close in 6 seconds..." >/dev/console
|
||||||
|
sleep 6
|
||||||
|
eject -t /dev/$i
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
debug_shell
|
||||||
|
|
||||||
|
$1 -f
|
||||||
|
|
||||||
|
reboot -f
|
||||||
|
|
@ -404,7 +404,7 @@ mount_data_http()
|
||||||
if [ "$(network_device)" != "" ]; then
|
if [ "$(network_device)" != "" ]; then
|
||||||
echo "* Mounting remote file..." >&2
|
echo "* Mounting remote file..." >&2
|
||||||
mkdir -p "$2"
|
mkdir -p "$2"
|
||||||
mount.httpfs2 -r 9999 -t 5 $CACHE -c /dev/null "$1" "$2" >/dev/null 2>/dev/null
|
@mount.httpfs2 -r 9999 -t 5 $CACHE -c /dev/null "$1" "$2" -o ro >/dev/null 2>/dev/null
|
||||||
mount -o loop "$2"/* "$2" # self mount
|
mount -o loop "$2"/* "$2" # self mount
|
||||||
echo "$2/$LIVEKITNAME"
|
echo "$2/$LIVEKITNAME"
|
||||||
fi
|
fi
|
||||||
|
|
@ -595,7 +595,7 @@ persistent_changes()
|
||||||
echo "* Activating dynamic sized storage for persistent changes"
|
echo "* Activating dynamic sized storage for persistent changes"
|
||||||
rm "$T1" "$T2" 2>/dev/null
|
rm "$T1" "$T2" 2>/dev/null
|
||||||
|
|
||||||
mount.dynfilefs "$CHANGES/changes.dat" 4000 "$2"
|
@mount.dynfilefs "$CHANGES/changes.dat" 4000 "$2"
|
||||||
if [ "$(device_bestfs "$2/loop.fs" | tr -d " ")" = "-t" ]; then
|
if [ "$(device_bestfs "$2/loop.fs" | tr -d " ")" = "-t" ]; then
|
||||||
mke2fs -F "$2/loop.fs" >/dev/null
|
mke2fs -F "$2/loop.fs" >/dev/null
|
||||||
fi
|
fi
|
||||||
|
|
@ -709,7 +709,7 @@ union_append_bundles()
|
||||||
echo "* $BUNDLE"
|
echo "* $BUNDLE"
|
||||||
BUN="$(basename "$BUNDLE")"
|
BUN="$(basename "$BUNDLE")"
|
||||||
mkdir -p "$2/$BUN"
|
mkdir -p "$2/$BUN"
|
||||||
mount -o loop -t squashfs "$1/$BUNDLE" "$2/$BUN"
|
mount -o loop,ro -t squashfs "$1/$BUNDLE" "$2/$BUN"
|
||||||
mount -o remount,add:1:"$2/$BUN" aufs "$3"
|
mount -o remount,add:1:"$2/$BUN" aufs "$3"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue