Index: systemd-195/src/sleep/sleep.c =================================================================== --- systemd-195.orig/src/sleep/sleep.c +++ systemd-195/src/sleep/sleep.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "log.h" #include "util.h" @@ -31,6 +32,9 @@ int main(int argc, char *argv[]) { const char *verb; char* arguments[4]; + const char *pmtools; + bool delegate_to_pmutils = false; + struct stat buf; int r; FILE *f; @@ -44,17 +48,27 @@ int main(int argc, char *argv[]) { goto finish; } - if (streq(argv[1], "suspend")) + if (streq(argv[1], "suspend")) { verb = "mem"; - else if (streq(argv[1], "hibernate") || streq(argv[1], "hybrid-sleep")) + pmtools = "/usr/sbin/pm-suspend"; + } + else if (streq(argv[1], "hibernate") || streq(argv[1], "hybrid-sleep")) { verb = "disk"; + if (streq(argv[1], "hibernate")) + pmtools = "/usr/sbin/pm-hibernate"; + else + pmtools = "/usr/sbin/pm-suspend-hybrid"; + } else { log_error("Unknown action '%s'.", argv[1]); r = -EINVAL; goto finish; } + delegate_to_pmutils = (stat(pmtools, &buf) >= 0 && S_ISREG(buf.st_mode) && (buf.st_mode & 0111)); + /* Configure the hibernation mode */ + if (!delegate_to_pmutils) { if (streq(argv[1], "hibernate")) { if (write_one_line_file("/sys/power/disk", "platform") < 0) write_one_line_file("/sys/power/disk", "shutdown"); @@ -64,13 +78,14 @@ int main(int argc, char *argv[]) { write_one_line_file("/sys/power/disk", "shutdown"); } + f = fopen("/sys/power/state", "we"); if (!f) { log_error("Failed to open /sys/power/state: %m"); r = -errno; goto finish; } - + } arguments[0] = NULL; arguments[1] = (char*) "pre"; arguments[2] = argv[1]; @@ -96,11 +111,16 @@ int main(int argc, char *argv[]) { "SLEEP=hybrid-sleep", NULL); + if (delegate_to_pmutils) { + r = -system(pmtools); + } + else { fputs(verb, f); fputc('\n', f); fflush(f); r = ferror(f) ? -errno : 0; + } if (streq(argv[1], "suspend")) log_struct(LOG_INFO, @@ -118,6 +138,7 @@ int main(int argc, char *argv[]) { arguments[1] = (char*) "post"; execute_directory(SYSTEM_SLEEP_PATH, NULL, arguments); + if (!delegate_to_pmutils) fclose(f); finish: