From c0e9d9913b66649783a4fac05a0da4db1b79faec Mon Sep 17 00:00:00 2001 From: Mark H Weaver Date: Sun, 14 Aug 2016 04:45:06 -0400 Subject: [PATCH] PRELIMINARY: Add support for hibernation. * gnu/build/linux-boot.scm (boot-system): Look for a resume= argument on the linux command line, and if present, attempt to resume from hibernation. * gnu/services/desktop.scm (): Change the default value of the 'handle-hibernate-key' key to 'hibernate'. --- gnu/build/linux-boot.scm | 50 +++++++++++++++++++++++++++++++++++++--- gnu/services/desktop.scm | 6 +---- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scm index f273957d78..767a424e72 100644 --- a/gnu/build/linux-boot.scm +++ b/gnu/build/linux-boot.scm @@ -477,9 +477,10 @@ upon error." (call-with-error-handling (lambda () (mount-essential-file-systems) - (let* ((args (linux-command-line)) - (to-load (find-long-option "--load" args)) - (root (find-long-option "--root" args))) + (let* ((args (linux-command-line)) + (to-load (find-long-option "--load" args)) + (root (find-long-option "--root" args)) + (resume-device (find-long-option "resume" args))) (when (member "--repl" args) (start-repl)) @@ -512,6 +513,49 @@ upon error." (unless (pre-mount) (error "pre-mount actions failed"))) + ;; + ;; Attempt to resume from hibernation. + ;; + ;; IMPORTANT: This *must* happen before we mount any filesystems on + ;; disk. Quoting linux-libre/Documentation/swsusp.txt: + ;; + ;; * BIG FAT WARNING ************************************************** + ;; * + ;; * If you touch anything on disk between suspend and resume... + ;; * ...kiss your data goodbye. + ;; * + ;; * If you do resume from initrd after your filesystems are mounted... + ;; * ...bye bye root partition. + ;; * [this is actually same case as above] + ;; * + (when (and resume-device + (file-exists? resume-device) + (file-exists? "/sys/power/resume")) + (false-if-exception + (let* ((device-base-name + ;; The base name of the device file, after resolving + ;; symlinks. + (let loop ((file resume-device)) + (match (stat:type (lstat file)) + ('symlink + (let ((target (readlink file))) + (if (string-prefix? "/" target) + (loop target) + (loop (string-append (dirname file) "/" target))))) + (_ (basename file))))) + (major+minor + ;; The major:minor string (e.g. "8:2") corresponding + ;; to the resume device. + (call-with-input-file (string-append "/sys/class/block/" + device-base-name + "/dev") + read-line))) + ;; Write the major:minor string to /sys/power/resume + ;; to attempt resume from hibernation. + (when major+minor + (call-with-output-file "/sys/power/resume" + (cut display major+minor <>)))))) + (setenv "EXT2FS_NO_MTAB_OK" "1") (if root diff --git a/gnu/services/desktop.scm b/gnu/services/desktop.scm index a32756e040..93ad9cbc82 100644 --- a/gnu/services/desktop.scm +++ b/gnu/services/desktop.scm @@ -595,11 +595,7 @@ include the @command{udisksctl} command, part of UDisks, and GNOME Disks." (handle-suspend-key elogind-handle-suspend-key (default 'suspend)) (handle-hibernate-key elogind-handle-hibernate-key - ;; (default 'hibernate) - ;; XXX Ignore it for now, since we don't - ;; yet handle resume-from-hibernation in - ;; our initrd. - (default 'ignore)) + (default 'hibernate)) (handle-lid-switch elogind-handle-lid-switch (default 'suspend)) (handle-lid-switch-docked elogind-handle-lid-switch-docked -- 2.23.0