This solves the problem of the major:minor of devices changing between hibernation. It also makes initialization lazy, as we no longer need to explicitly wait on the device to show up (this will be taken care of by udevadm settle). Note that this patch drops support for tux-on-ice. As upstream developerment of TOI seems stalled and forever relegated to being maintained out of tree, I'm okay with this. Signed-off-by: Dave Reisner <dreisner@archlinux.org> --- So, I tested this as far as ensuring that the udev rule is generated correctly and triggers, writing the correct values into /sys/power/resume, but I can't actually hibernate/resume my desktop to test this (mobo firmware bug). If anyone who uses this hook wants to test this, please do and report back. hooks/resume | 71 +++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 25 deletions(-) diff --git a/hooks/resume b/hooks/resume index 04ca1aa..ce02dfa 100644 --- a/hooks/resume +++ b/hooks/resume @@ -1,41 +1,62 @@ #!/usr/bin/ash -run_hook () { - local resumedev +generate_resume_udev_rule() { + local resume=$1 case $resume in '') - err "resume: no device specified for hibernation" - return 1; + # no resume parameter specified + return 0; ;; - swap:*|file:*) - # tux-on-ice syntax: swap:/dev/sda2 or file:/dev/sda2:0xdeadbeef - if [ -d /sys/power/tuxonice ]; then - echo "$resume" >/sys/power/tuxonice/resume - echo >/sys/power/tuxonice/do_resume - return 0 - else - err "resume: tux-on-ice syntax detected, but no support found" - return 1 - fi + PARTUUID=*) + attrmatch="ENV{ID_PART_ENTRY_NAME}==\"${resume#*=}\"" + ;; + PARTLABEL=*) + attrmatch="ENV{ID_PART_ENTRY_UUID}==\"${resume#*=}\"" + ;; + UUID=*|LABEL=*) + attrmatch="ENV{ID_FS_${resume%%=*}}==\"${resume#*=}\"" + ;; + /dev/*) + attrmatch="KERNEL==\"${resume#/dev/}\"" ;; - *) - # standard hibernation - if resumedev=$(resolve_device "$resume" "$rootdelay"); then - if [ -e /sys/power/resume ]; then - printf "%d:%d" $(stat -Lc "0x%t 0x%T" "$resumedev") >/sys/power/resume - return 0 - else - err "resume: no hibernation support found" - return 1 - fi - fi + err "resume: hibernation device '$resume' not found" + return 1 ;; esac + mkdir -p /run/udev/rules.d + printf >/run/udev/rules.d/99-initramfs-resume.rules \ + "ACTION==\"add|change\", %s, RUN+=\"/bin/sh -c 'echo %%M:%%m >/sys/power/resume'\"\n" \ + "$attrmatch" +} + +set_resume_device() { + local resumedev resume=$1 + + if resumedev=$(resolve_device "$resume" "$rootdelay"); then + printf "%d:%d" $(stat -Lc "0x%t 0x%T" "$resumedev") >/sys/power/resume + return 0 + fi + err "resume: hibernation device '$resume' not found" return 1 } +run_earlyhook () { + [ -z "$resume" ] && return 0; + + if [ ! -e /sys/power/resume ]; then + err "resume: no hibernation support found" + return 1 + fi + + if [ -n "$udev_running" ]; then + generate_resume_udev_rule "$resume" + else + set_resume_device "$resume" + fi +} + # vim: set ft=sh ts=4 sw=4 et: -- 1.8.4.2