Get rid of the Upstart shutdown job

The only thing that Upstart's shutdown job did that systemd doesn't do
natively is update the hardware clock.  So added a service for that.
wip/yesman
Eelco Dolstra 12 years ago
parent ca2bd17f54
commit c3fb248bcb
  1. 3
      modules/module-list.nix
  2. 25
      modules/system/boot/shutdown.nix
  3. 162
      modules/system/upstart-events/shutdown.nix

@ -194,8 +194,9 @@
./system/boot/kernel.nix
./system/boot/luksroot.nix
./system/boot/modprobe.nix
./system/boot/stage-1.nix
./system/boot/shutdown.nix
./system/boot/stage-1-extratools.nix
./system/boot/stage-1.nix
./system/boot/stage-2.nix
./system/boot/systemd.nix
./system/etc/etc.nix

@ -0,0 +1,25 @@
{ config, pkgs, ... }:
with pkgs.lib;
{
# This unit saves the value of the system clock to the hardware
# clock on shutdown.
boot.systemd.units."save-hwclock.service" =
{ wantedBy = [ "shutdown.target" ];
text =
''
[Unit]
Description=Save Hardware Clock
DefaultDependencies=no
Before=shutdown.target
[Service]
Type=oneshot
ExecStart=${pkgs.utillinux}/sbin/hwclock --systohc --utc
'';
};
}

@ -1,162 +0,0 @@
{ config, pkgs, ... }:
with pkgs.lib;
{
jobs.shutdown =
{ name = "shutdown";
task = true;
stopOn = ""; # must override the default ("starting shutdown")
environment = { MODE = "poweroff"; };
extraConfig = "console owner";
script =
''
set +e # continue in case of errors
${pkgs.kbd}/bin/chvt 1
exec < /dev/console > /dev/console 2>&1
echo ""
if test "$MODE" = maintenance; then
echo "<<< Entering maintenance mode >>>"
else
echo "<<< System shutdown >>>"
fi
echo ""
${config.powerManagement.powerDownCommands}
export PATH=${pkgs.utillinux}/bin:${pkgs.utillinux}/sbin:$PATH
# Do an initial sync just in case.
sync
# Kill all remaining processes except init, this one and any
# Upstart jobs that don't stop on the "starting shutdown"
# event, as these are necessary to complete the shutdown.
omittedPids=$(initctl list | sed -e 's/.*process \([0-9]\+\)/-o \1/;t;d')
#echo "saved PIDs: $omittedPids"
echo "sending the TERM signal to all processes..."
${pkgs.sysvtools}/bin/killall5 -15 $job $omittedPids
sleep 1 # wait briefly
echo "sending the KILL signal to all processes..."
${pkgs.sysvtools}/bin/killall5 -9 $job $omittedPids
# If maintenance mode is requested, start a root shell, and
# afterwards emit the "startup" event to bring everything
# back up.
if test "$MODE" = maintenance; then
echo ""
echo "<<< Maintenance shell >>>"
echo ""
${pkgs.shadow}/bin/login root
initctl emit -n startup
exit 0
fi
# Write a shutdown record to wtmp while /var/log is still writable.
reboot --wtmp-only
# Set the hardware clock to the system time.
echo "setting the hardware clock..."
hwclock --systohc --utc
# Stop all swap devices.
swapoff -a
# 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=
failed= # list of mount points that couldn't be unmounted/remounted
# Get rid of loopback devices.
loDevices=$(losetup -a | sed 's#^\(/dev/loop[0-9]\+\).*#\1#')
if [ -n "$loDevices" ]; then
echo "removing loopback devices $loDevices..."
losetup -d $loDevices
fi
cp /proc/mounts /dev/.mounts # don't read /proc/mounts while it's changing
exec 4< /dev/.mounts
while read -u 4 device mp fstype options rest; do
# Skip various special filesystems. Non-existent
# mount points are typically tmpfs/aufs mounts from
# the initrd.
if [ "$mp" = /proc -o "$mp" = /sys -o "$mp" = /dev -o "$device" = "rootfs" -o "$mp" = /run -o "$mp" = /var/run -o "$mp" = /var/lock -o ! -e "$mp" ]; then continue; fi
echo "unmounting $mp..."
# We need to remount,ro before attempting any
# umount, or bind mounts may get confused, with
# the fs not being properly flushed at the end.
# `-i' is to workaround a bug in mount.cifs (it
# doesn't recognise the `remount' option, and
# instead mounts the FS again).
success=
if mount -t "$fstype" -n -i -o remount,ro "device" "$mp"; then success=1; fi
# Note: don't use `umount -f'; it's very buggy.
# (For instance, when applied to a bind-mount it
# unmounts the target of the bind-mount.) !!! But
# we should use `-f' for NFS.
if [ "$mp" != / -a "$mp" != /nix -a "$mp" != /nix/store ]; then
if umount -n "$mp"; then success=1; tryAgain=1; fi
fi
if [ -z "$success" ]; then failed="$failed $mp"; fi
done
done
# Warn about filesystems that could not be unmounted or
# remounted read-only.
if [ -n "$failed" ]; then
echo "warning: the following filesystems could not be unmounted:"
for mp in $failed; do echo " $mp"; done
echo Enter 'i' to launch a shell, or wait 10 seconds to continue.
read -t 10 A
if [ "$A" == "i" ]; then
${pkgs.bashInteractive}/bin/bash -i < /dev/console &> /dev/console
fi
sleep 5
fi
# Final sync.
sync
# Either reboot or power-off the system.
if test "$MODE" = reboot; then
echo "rebooting..."
sleep 1
exec reboot -f
else
echo "powering off..."
sleep 1
exec halt -f -p
fi
'';
};
}
Loading…
Cancel
Save