summaryrefslogtreecommitdiffstats
path: root/hooks/resume
blob: 8ff84dd8db21e37bd3b784f0000f36541971c7c8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/bin/sh

PREREQ=""

prereqs()
{
	echo "$PREREQ"
}

case $1 in
# get pre-requisites
prereqs)
	prereqs
	exit 0
	;;
esac

. /usr/share/initramfs-tools/scripts/functions

# First check if a location is set and is a valid swap partition.
# If so, the config file will be copied in and there is nothing to do.
if [ -n "$RESUME" ] && [ "$RESUME" != auto ]; then
	if [ "$RESUME" = none ]; then
		exit 0
	fi
	if resume_dev_node="$(resolve_device "$RESUME")" && \
	   blkid -p -n swap "$resume_dev_node" >/dev/null 2>&1; then
		exit 0
	fi

	echo >&2 "W: initramfs-tools configuration sets RESUME=$RESUME"
	echo >&2 "W: but no matching swap device is available."
fi

# If we were not explicitly requested to select a device, or the -v
# option is used, report that we are doing so
report_auto()
{
	test "${verbose?}" != y && test "$RESUME" = auto || echo "I: $*"
}

# Report in excruciating detail if the -v option is used
report_verbose()
{
	test "${verbose?}" != y || echo "I: $*"
}

report_verbose "Configuration sets RESUME=$RESUME"

# Try to autodetect the RESUME partition, using biggest swap device that
# is not ephemeral.  We need to be able to read the listed swap partitions.
resume_auto=
if ! ischroot && [ -r /proc/swaps ]; then
	# shellcheck disable=SC2013
	for resume_auto in $(grep ^/dev/ /proc/swaps | sort -rnk3 | cut -d " " -f 1); do
		report_verbose "Checking swap device $resume_auto"
		ephemeral=false
		dm_name="$(dmsetup info -c --noheadings -o name "$resume_auto" 2>/dev/null)"

		# dm-crypt is ephemeral if the key file is /dev/urandom
		if [ -n "$dm_name" ] && [ -e /etc/crypttab ]; then
			report_verbose "$resume_auto has device-mapper name $dm_name; checking crypttab"
			# shellcheck disable=SC2034
			while read -r cryptdev srcdev keyfile junk; do
				report_verbose "Found cryptdev=$cryptdev keyfile=$keyfile"
				if [ "$cryptdev" = "$dm_name" ] && [ "$keyfile" = /dev/urandom ]; then
					report_verbose "Rejecting $resume_auto since it has no permanent key"
					ephemeral=true
				fi
			done < /etc/crypttab
		fi

		# zram is ephemeral
		case "$resume_auto" in
		/dev/zram*)
			report_verbose "Rejecting $resume_auto since it is zram"
			ephemeral=true
			;;

		/dev/zd[0-9]*)
			report_verbose "Rejecting $resume_auto since it is zvol"
			ephemeral=true
			;;
		esac

		$ephemeral || break
	done

	if $ephemeral; then
		resume_auto=
	fi
	if [ -n "$resume_auto" ]; then
		if [ -n "$dm_name" ]; then
			resume_auto_canon="/dev/mapper/$dm_name"
		elif UUID=$(blkid -s UUID -o value "$resume_auto"); then
			resume_auto_canon="UUID=$UUID"
		else
			resume_auto_canon=
		fi
		report_auto "The initramfs will attempt to resume from $resume_auto"
		if [ -n "$resume_auto_canon" ]; then
			report_auto "($resume_auto_canon)"
			resume_auto="$resume_auto_canon"
		fi
		report_auto "Set the RESUME variable to override this."
	fi
fi

# Write selected resume device to intramfs conf.d
if [ "$RESUME" = auto ] || [ -n "$resume_auto" ]; then
	# If we were explicitly requested to select a device, and we failed,
	# report that
	if [ -z "$resume_auto" ]; then
		echo >&2 "W: initramfs-tools failed to select a resume device"
	fi
	echo "RESUME=${resume_auto}" > "${DESTDIR}/conf/conf.d/zz-resume-auto"
fi