diff options
Diffstat (limited to 'modules.d/95resume')
-rwxr-xr-x | modules.d/95resume/module-setup.sh | 68 | ||||
-rwxr-xr-x | modules.d/95resume/parse-resume.sh | 81 | ||||
-rwxr-xr-x | modules.d/95resume/resume.sh | 18 |
3 files changed, 167 insertions, 0 deletions
diff --git a/modules.d/95resume/module-setup.sh b/modules.d/95resume/module-setup.sh new file mode 100755 index 0000000..d255103 --- /dev/null +++ b/modules.d/95resume/module-setup.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +# called by dracut +check() { + swap_on_netdevice() { + local _dev + for _dev in "${swap_devs[@]}"; do + block_is_netdevice "$(get_maj_min "$_dev")" && return 0 + done + return 1 + } + + # Only support resume if hibernation is currently on + # and no swap is mounted on a net device + [[ $hostonly ]] || [[ $mount_needs ]] && { + swap_on_netdevice || [[ -f /sys/power/resume && "$(< /sys/power/resume)" == "0:0" ]] || grep -rq '^\|[[:space:]]resume=' /proc/cmdline /etc/cmdline /etc/cmdline.d /etc/kernel/cmdline /usr/lib/kernel/cmdline 2> /dev/null && return 255 + } + + return 0 +} + +# called by dracut +cmdline() { + local _resume + + for dev in "${!host_fs_types[@]}"; do + [[ ${host_fs_types[$dev]} =~ ^(swap|swsuspend|swsupend)$ ]] || continue + _resume=$(shorten_persistent_dev "$(get_persistent_dev "$dev")") + [[ -n ${_resume} ]] && printf " resume=%s" "${_resume}" + done +} + +# called by dracut +install() { + local _bin + local _resumeconf + + if [[ $hostonly_cmdline == "yes" ]]; then + _resumeconf=$(cmdline) + [[ $_resumeconf ]] && printf "%s\n" "$_resumeconf" >> "${initdir}/etc/cmdline.d/95resume.conf" + fi + + # if systemd is included and has the hibernate-resume tool, use it and nothing else + if dracut_module_included "systemd" && [[ -x $dracutsysrootdir$systemdutildir/systemd-hibernate-resume ]]; then + inst_multiple -o \ + "$systemdutildir"/system-generators/systemd-hibernate-resume-generator \ + "$systemdsystemunitdir"/systemd-hibernate-resume@.service \ + "$systemdutildir"/systemd-hibernate-resume + return 0 + fi + + # Optional uswsusp support + for _bin in /usr/sbin/resume /usr/lib/suspend/resume /usr/lib64/suspend/resume /usr/lib/uswsusp/resume /usr/lib64/uswsusp/resume; do + [[ -x $dracutsysrootdir${_bin} ]] && { + inst "${_bin}" /usr/sbin/resume + [[ $hostonly ]] && [[ -f $dracutsysrootdir/etc/suspend.conf ]] && inst -H /etc/suspend.conf + break + } + done + + if ! dracut_module_included "systemd"; then + inst_hook cmdline 10 "$moddir/parse-resume.sh" + else + inst_script "$moddir/parse-resume.sh" /lib/dracut/parse-resume.sh + fi + + inst_script "$moddir/resume.sh" /lib/dracut/resume.sh +} diff --git a/modules.d/95resume/parse-resume.sh b/modules.d/95resume/parse-resume.sh new file mode 100755 index 0000000..75a905d --- /dev/null +++ b/modules.d/95resume/parse-resume.sh @@ -0,0 +1,81 @@ +#!/bin/sh + +if resume=$(getarg resume=) && ! getarg noresume; then + export resume + echo "$resume" > /.resume +else + unset resume +fi + +resume="$(label_uuid_to_dev "$resume")" + +if splash=$(getarg splash=); then + export splash +else + unset splash +fi + +case "$splash" in + quiet) + a_splash="-P splash=y" + ;; + *) + a_splash="-P splash=n" + ;; +esac + +if ! getarg noresume; then + if [ -n "$resume" ]; then + wait_for_dev /dev/resume + + { + printf "KERNEL==\"%s\", ACTION==\"add|change\", SYMLINK+=\"resume\"\n" \ + "${resume#/dev/}" + printf "SYMLINK==\"%s\", ACTION==\"add|change\", SYMLINK+=\"resume\"\n" \ + "${resume#/dev/}" + } >> /etc/udev/rules.d/99-resume-link.rules + + { + if [ -x /usr/sbin/resume ]; then + printf -- 'KERNEL=="%s", ' "${resume#/dev/}" + printf -- '%s' 'ACTION=="add|change", ENV{ID_FS_TYPE}=="suspend|swsuspend|swsupend",' + printf -- " RUN+=\"/sbin/initqueue --finished --unique --name 00resume /usr/sbin/resume %s \'%s\'\"\n" \ + "$a_splash" "$resume" + printf -- 'SYMLINK=="%s", ' "${resume#/dev/}" + printf -- '%s' 'ACTION=="add|change", ENV{ID_FS_TYPE}=="suspend|swsuspend|swsupend",' + printf -- " RUN+=\"/sbin/initqueue --finished --unique --name 00resume /usr/sbin/resume %s \'%s\'\"\n" \ + "$a_splash" "$resume" + fi + + printf -- 'KERNEL=="%s", ' "${resume#/dev/}" + printf -- '%s' 'ACTION=="add|change", ENV{ID_FS_TYPE}=="suspend|swsuspend|swsupend",' + printf -- '%s\n' ' RUN+="/sbin/initqueue --finished --unique --name 00resume echo %M:%m > /sys/power/resume"' + + printf -- 'SYMLINK=="%s", ' "${resume#/dev/}" + printf -- '%s' 'ACTION=="add|change", ENV{ID_FS_TYPE}=="suspend|swsuspend|swsupend",' + printf -- '%s\n' ' RUN+="/sbin/initqueue --finished --unique --name 00resume echo %M:%m > /sys/power/resume"' + } >> /etc/udev/rules.d/99-resume.rules + + # shellcheck disable=SC2016 + printf '[ -e "%s" ] && { ln -fs "%s" /dev/resume 2> /dev/null; rm -f -- "$job" "%s/initqueue/timeout/resume.sh"; }\n' \ + "$resume" "$resume" "$hookdir" >> "$hookdir"/initqueue/settled/resume.sh + + { + printf -- "%s" 'warn "Cancelling resume operation. Device not found.";' + # shellcheck disable=SC2016 + printf -- ' cancel_wait_for_dev /dev/resume; rm -f -- "$job" "%s/initqueue/settled/resume.sh";\n' "$hookdir" + } >> "$hookdir"/initqueue/timeout/resume.sh + + mv /lib/dracut/resume.sh /lib/dracut/hooks/pre-mount/10-resume.sh + else + { + if [ -x /usr/sbin/resume ]; then + printf -- '%s' 'SUBSYSTEM=="block", ACTION=="add|change", ENV{ID_FS_TYPE}=="suspend|swsuspend|swsupend",' + # shellcheck disable=SC2016 + printf -- ' RUN+="/sbin/initqueue --finished --unique --name 00resume /usr/sbin/resume %s $tempnode"\n' "$a_splash" + fi + printf -- '%s' 'SUBSYSTEM=="block", ACTION=="add|change", ENV{ID_FS_TYPE}=="suspend|swsuspend|swsupend",' + printf -- '%s\n' ' RUN+="/sbin/initqueue --finished --unique --name 00resume echo %M:%m > /sys/power/resume"' + } >> /etc/udev/rules.d/99-resume.rules + fi +fi diff --git a/modules.d/95resume/resume.sh b/modules.d/95resume/resume.sh new file mode 100755 index 0000000..c808880 --- /dev/null +++ b/modules.d/95resume/resume.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +PATH=/usr/sbin:/usr/bin:/sbin:/bin + +[ -s /.resume -a -b "$resume" ] && { + # First try user level resume; it offers splash etc + case "$splash" in + quiet) + a_splash="-P splash=y" + ;; + *) + a_splash="-P splash=n" + ;; + esac + [ -x "$(command -v resume)" ] && command resume "$a_splash" "$resume" + + (readlink -fn "$resume" > /sys/power/resume) > /.resume +} |