nixpkgs/upstart-jobs/halt.nix
Eelco Dolstra 2d20b19e5b * Don't get stuck in an infinite unmount loop on shutdown.
svn path=/nixos/trunk/; revision=7580
2007-01-09 09:52:16 +00:00

81 lines
1.9 KiB
Nix

{bash, event, utillinux}:
assert event == "reboot"
|| event == "halt"
|| event == "system-halt"
|| event == "power-off";
{
name = "sys-" + event;
job = "
start on ${event}
script
exec < /dev/tty1 > /dev/tty1 2>&1
echo \"\"
echo \"<<< SYSTEM SHUTDOWN >>>\"
echo \"\"
export PATH=${utillinux}/bin:${utillinux}/sbin:$PATH
# Do an initial sync just in case.
sync || true
getMountPoints() {
cat /proc/mounts \\
| grep -v '^rootfs' \\
| sed 's|^[^ ]\\+ \\+\\([^ ]\\+\\).*|\\1|' \\
| grep -v '/proc\\|/sys\\|/dev'
}
getDevice() {
local mountPoint=$1
cat /proc/mounts \\
| grep -v '^rootfs' \\
| grep \"^[^ ]\\+ \\+$mountPoint \\+\" \\
| sed 's|^\\([^ ]\\+\\).*|\\1|'
}
# Unmount file systems. We repeat this until no more file systems
# can be unmounted. This is to handle loopback devices, file
# systems mounted on other file systems and so on.
tryAgain=1
while test -n \"$tryAgain\"; do
tryAgain=
for mp in $(getMountPoints); do
device=$(getDevice $mp)
echo \"unmounting $mp...\"
if umount -n \"$mp\"; then
if test \"$mp\" != /; then tryAgain=1; fi
else
mount -n -o remount,ro \"$mp\"
fi
# Hack: work around a bug in mount (mount -o remount on a
# loop device forgets the loop=/dev/loopN entry in
# /etc/mtab).
if echo \"$device\" | grep -q '/dev/loop'; then
echo \"removing loop device $device...\"
losetup -d \"$device\" || true
fi
done
done
cat /proc/mounts
# Final sync.
sync || true
# Right now all events above power off the system.
if test ${event} = reboot; then
exec reboot -f
else
exec halt -f -p
fi
end script
";
}