udev-watchdog-wrapper 3.21 KB
Newer Older
T(A)ILS developers's avatar
T(A)ILS developers committed
1
#!/bin/sh
2

3 4
set -e

5
### Helper functions
6

7 8 9
# For whatever reason, the initscript that calls us sets a pretty scarse $PATH
PATH="/usr/bin:${PATH}"

Tails developers's avatar
Tails developers committed
10 11 12 13
### Helper functions

using_fromiso() {
	grep -qs -w -E '(fromiso|isofrom)=' /proc/cmdline
14 15
}

Tails developers's avatar
Tails developers committed
16 17 18 19 20
# Returns the boot device's path in a form that can be passed to the
# eject command, e.g. /dev/scd0 or /dev/block/NN:MM.
boot_device() {
	if using_fromiso ; then
	# When booting with e.g. fromiso=/dev/sdx3/tails-XXX.iso, a loop device
21
	# is mounted onto /lib/live/mount/medium => we cannot get the boot device from there.
Tails developers's avatar
Tails developers committed
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
	# This loop device's backing file is seen by the system as
	# /isofrom/XXX.iso, which is not available presumably because pivotroot
	# was run => we cannot get the boot device from there either.
	# Instead, we parse fromiso='s argument the same way live-boot does
	# in order to extract the device path (/dev/sdx3)
		for ARGUMENT in $(cat /proc/cmdline) ; do
			case "${ARGUMENT}" in
				isofrom=*|fromiso=*)
					FROMISO="${ARGUMENT#*=}"
					;;
			esac
		done
		echo $(dirname "$FROMISO")
	else
	# Refactorer, beware: the rest of this script depends on the fact that
	# the path returned in this case is suitable to be passed as an argument
	# to --path in "udevadm info --query" commands... which is not the case
	# of paths in the /dev/sdxN form.
40
		DEV_NUMBER="$(udevadm info --device-id-of-file=/lib/live/mount/medium)"
Tails developers's avatar
Tails developers committed
41 42
		echo "/dev/block/$DEV_NUMBER"
	fi
43
}
44 45 46

# First clean the screen, then brutally shutdown the machine.
do_stop() {
47 48 49 50 51 52
	# Kill everything run by amnesia or Debian-gdm, otherwise emergency
	# shutdown fails for some reason. Incidentally, this also allows
	# the test suite to look for a known message ("Happy dumping!")
	# on the screen.
	/bin/loginctl --signal=9 kill-user amnesia || true
	/bin/systemctl stop gdm.service || true
intrigeri's avatar
intrigeri committed
53
	/bin/systemctl --signal=9 kill gdm.service || true
54 55 56
	/bin/loginctl --signal=9 kill-user Debian-gdm || true

	# Finally, return to the initramfs and poweroff the system
57
	/bin/systemctl --force poweroff
58 59
}

60 61 62

### Main

Tails developers's avatar
Tails developers committed
63
BOOT_DEVICE=$(boot_device)
64

65 66 67 68 69 70 71
# If the boot_device is not present, shutdown immediately
# This typically happens when the boot device is removed _during_ a suspend
if test -z "$BOOT_DEVICE" || ! test -e "$BOOT_DEVICE"; then
    do_stop
fi


Tails developers's avatar
Tails developers committed
72 73 74 75 76
# Assign to QUERY_SELECTOR an option that can be passed as a query selector
# to udevadm info --query commands.
if using_fromiso ; then
	DEV_NAME=$(basename "$BOOT_DEVICE")
	QUERY_SELECTOR="--name $DEV_NAME"
77
else
Tails developers's avatar
Tails developers committed
78
	QUERY_SELECTOR="--path $BOOT_DEVICE"
79 80
fi

Tails developers's avatar
Tails developers committed
81
DEV_UDEV_PATH=$(udevadm info --query path     $QUERY_SELECTOR)
82 83 84
# SD in SDIO has no ID_TYPE, let's pretend it's a disk just like USB sticks
DEV_TYPE_LINE=$(udevadm info --query property $QUERY_SELECTOR | grep -w '^ID_TYPE') \
	|| DEV_TYPE_LINE='ID_TYPE=disk'
Tails developers's avatar
Tails developers committed
85
DEV_TYPE="${DEV_TYPE_LINE#*=}"
86

87 88 89
# If the world was sane we'd want to *disable* the eject lock, but it turns out
# that blocks the block events so udev-watchdog never receives the "change"
# event. See [[bugs/sdmem_on_eject_broken_for_CD]].
90
# FIXME: we might be able to do the more sane "-i off" with future kernel/udev
91
if [ "$DEV_TYPE" = "cd" ]; then
92
	eject -i on "${BOOT_DEVICE}" >/dev/null
93 94 95
fi

# Start udev-watchdog and stop on clean exit.
Tails developers's avatar
Tails developers committed
96
/usr/local/sbin/udev-watchdog "$DEV_UDEV_PATH" "$DEV_TYPE" && do_stop