From ce31ec116f9bf4ad45952b6a200f4181fac311a3 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Tue, 13 Sep 2016 21:24:07 -0400 Subject: ./tools/notsd-move --- src/grp-initprogs/grp-sleep/Makefile | 30 +++ .../systemd-hibernate-resume-generator/Makefile | 38 ++++ .../hibernate-resume-generator.c | 99 ++++++++++ .../systemd-hibernate-resume-generator.xml | 93 +++++++++ .../grp-sleep/systemd-hibernate-resume/Makefile | 45 +++++ .../systemd-hibernate-resume/hibernate-resume.c | 82 ++++++++ .../systemd-hibernate-resume@.service.in | 20 ++ .../systemd-hibernate-resume@.service.xml | 81 ++++++++ src/grp-initprogs/grp-sleep/systemd-sleep/Makefile | 49 +++++ .../grp-sleep/systemd-sleep/hibernate.target | 13 ++ .../grp-sleep/systemd-sleep/hybrid-sleep.target | 13 ++ src/grp-initprogs/grp-sleep/systemd-sleep/sleep.c | 215 +++++++++++++++++++++ .../grp-sleep/systemd-sleep/sleep.target | 13 ++ .../grp-sleep/systemd-sleep/suspend.target | 13 ++ .../systemd-sleep/systemd-hibernate.service.in | 17 ++ .../systemd-sleep/systemd-hybrid-sleep.service.in | 17 ++ .../grp-sleep/systemd-sleep/systemd-sleep.conf.xml | 186 ++++++++++++++++++ .../grp-sleep/systemd-sleep/systemd-sleep.xml | 146 ++++++++++++++ .../systemd-sleep/systemd-suspend.service.in | 17 ++ 19 files changed, 1187 insertions(+) create mode 100644 src/grp-initprogs/grp-sleep/Makefile create mode 100644 src/grp-initprogs/grp-sleep/systemd-hibernate-resume-generator/Makefile create mode 100644 src/grp-initprogs/grp-sleep/systemd-hibernate-resume-generator/hibernate-resume-generator.c create mode 100644 src/grp-initprogs/grp-sleep/systemd-hibernate-resume-generator/systemd-hibernate-resume-generator.xml create mode 100644 src/grp-initprogs/grp-sleep/systemd-hibernate-resume/Makefile create mode 100644 src/grp-initprogs/grp-sleep/systemd-hibernate-resume/hibernate-resume.c create mode 100644 src/grp-initprogs/grp-sleep/systemd-hibernate-resume/systemd-hibernate-resume@.service.in create mode 100644 src/grp-initprogs/grp-sleep/systemd-hibernate-resume/systemd-hibernate-resume@.service.xml create mode 100644 src/grp-initprogs/grp-sleep/systemd-sleep/Makefile create mode 100644 src/grp-initprogs/grp-sleep/systemd-sleep/hibernate.target create mode 100644 src/grp-initprogs/grp-sleep/systemd-sleep/hybrid-sleep.target create mode 100644 src/grp-initprogs/grp-sleep/systemd-sleep/sleep.c create mode 100644 src/grp-initprogs/grp-sleep/systemd-sleep/sleep.target create mode 100644 src/grp-initprogs/grp-sleep/systemd-sleep/suspend.target create mode 100644 src/grp-initprogs/grp-sleep/systemd-sleep/systemd-hibernate.service.in create mode 100644 src/grp-initprogs/grp-sleep/systemd-sleep/systemd-hybrid-sleep.service.in create mode 100644 src/grp-initprogs/grp-sleep/systemd-sleep/systemd-sleep.conf.xml create mode 100644 src/grp-initprogs/grp-sleep/systemd-sleep/systemd-sleep.xml create mode 100644 src/grp-initprogs/grp-sleep/systemd-sleep/systemd-suspend.service.in (limited to 'src/grp-initprogs/grp-sleep') diff --git a/src/grp-initprogs/grp-sleep/Makefile b/src/grp-initprogs/grp-sleep/Makefile new file mode 100644 index 0000000000..5a3a87d2bf --- /dev/null +++ b/src/grp-initprogs/grp-sleep/Makefile @@ -0,0 +1,30 @@ +# -*- Mode: makefile; indent-tabs-mode: t -*- +# +# This file is part of systemd. +# +# Copyright 2010-2012 Lennart Poettering +# Copyright 2010-2012 Kay Sievers +# Copyright 2013 Zbigniew Jędrzejewski-Szmek +# Copyright 2013 David Strauss +# Copyright 2016 Luke Shumaker +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. +# +# systemd is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with systemd; If not, see . +include $(dir $(lastword $(MAKEFILE_LIST)))/../../../config.mk +include $(topsrcdir)/build-aux/Makefile.head.mk + +nested.subdirs += systemd-hibernate-resume +nested.subdirs += systemd-hibernate-resume-generator +nested.subdirs += systemd-sleep + +include $(topsrcdir)/build-aux/Makefile.tail.mk diff --git a/src/grp-initprogs/grp-sleep/systemd-hibernate-resume-generator/Makefile b/src/grp-initprogs/grp-sleep/systemd-hibernate-resume-generator/Makefile new file mode 100644 index 0000000000..835f2a37b2 --- /dev/null +++ b/src/grp-initprogs/grp-sleep/systemd-hibernate-resume-generator/Makefile @@ -0,0 +1,38 @@ +# -*- Mode: makefile; indent-tabs-mode: t -*- +# +# This file is part of systemd. +# +# Copyright 2010-2012 Lennart Poettering +# Copyright 2010-2012 Kay Sievers +# Copyright 2013 Zbigniew Jędrzejewski-Szmek +# Copyright 2013 David Strauss +# Copyright 2016 Luke Shumaker +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. +# +# systemd is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with systemd; If not, see . +include $(dir $(lastword $(MAKEFILE_LIST)))/../../../../config.mk +include $(topsrcdir)/build-aux/Makefile.head.mk + +ifneq ($(ENABLE_HIBERNATE),) +systemgenerator_PROGRAMS += \ + systemd-hibernate-resume-generator + +systemd_hibernate_resume_generator_SOURCES = \ + src/hibernate-resume/hibernate-resume-generator.c + +systemd_hibernate_resume_generator_LDADD = \ + libsystemd-shared.la + +endif # ENABLE_HIBERNATE + +include $(topsrcdir)/build-aux/Makefile.tail.mk diff --git a/src/grp-initprogs/grp-sleep/systemd-hibernate-resume-generator/hibernate-resume-generator.c b/src/grp-initprogs/grp-sleep/systemd-hibernate-resume-generator/hibernate-resume-generator.c new file mode 100644 index 0000000000..6380c297c2 --- /dev/null +++ b/src/grp-initprogs/grp-sleep/systemd-hibernate-resume-generator/hibernate-resume-generator.c @@ -0,0 +1,99 @@ +/*** + This file is part of systemd. + + Copyright 2014 Ivan Shapovalov + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "basic/alloc-util.h" +#include "basic/log.h" +#include "basic/mkdir.h" +#include "basic/proc-cmdline.h" +#include "basic/special.h" +#include "basic/string-util.h" +#include "basic/unit-name.h" +#include "basic/util.h" +#include "shared/fstab-util.h" + +static const char *arg_dest = "/tmp"; +static char *arg_resume_dev = NULL; + +static int parse_proc_cmdline_item(const char *key, const char *value) { + + if (streq(key, "resume") && value) { + free(arg_resume_dev); + arg_resume_dev = fstab_node_to_udev_node(value); + if (!arg_resume_dev) + return log_oom(); + } + + return 0; +} + +static int process_resume(void) { + _cleanup_free_ char *name = NULL, *lnk = NULL; + int r; + + if (!arg_resume_dev) + return 0; + + r = unit_name_from_path_instance("systemd-hibernate-resume", arg_resume_dev, ".service", &name); + if (r < 0) + return log_error_errno(r, "Failed to generate unit name: %m"); + + lnk = strjoin(arg_dest, "/" SPECIAL_SYSINIT_TARGET ".wants/", name, NULL); + if (!lnk) + return log_oom(); + + mkdir_parents_label(lnk, 0755); + if (symlink(SYSTEM_DATA_UNIT_PATH "/systemd-hibernate-resume@.service", lnk) < 0) + return log_error_errno(errno, "Failed to create symlink %s: %m", lnk); + + return 0; +} + +int main(int argc, char *argv[]) { + int r = 0; + + if (argc > 1 && argc != 4) { + log_error("This program takes three or no arguments."); + return EXIT_FAILURE; + } + + if (argc > 1) + arg_dest = argv[1]; + + log_set_target(LOG_TARGET_SAFE); + log_parse_environment(); + log_open(); + + umask(0022); + + /* Don't even consider resuming outside of initramfs. */ + if (!in_initrd()) + return EXIT_SUCCESS; + + r = parse_proc_cmdline(parse_proc_cmdline_item); + if (r < 0) + log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m"); + + r = process_resume(); + free(arg_resume_dev); + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/grp-initprogs/grp-sleep/systemd-hibernate-resume-generator/systemd-hibernate-resume-generator.xml b/src/grp-initprogs/grp-sleep/systemd-hibernate-resume-generator/systemd-hibernate-resume-generator.xml new file mode 100644 index 0000000000..d811b9b551 --- /dev/null +++ b/src/grp-initprogs/grp-sleep/systemd-hibernate-resume-generator/systemd-hibernate-resume-generator.xml @@ -0,0 +1,93 @@ + + + + + + + + systemd-hibernate-resume-generator + systemd + + + + Developer + Ivan + Shapovalov + intelfx100@gmail.com + + + + + + systemd-hibernate-resume-generator + 8 + + + + systemd-hibernate-resume-generator + Unit generator for resume= kernel parameter + + + + /usr/lib/systemd/system-generators/systemd-hibernate-resume-generator + + + + Description + + systemd-hibernate-resume-generator is a + generator that instantiates + systemd-hibernate-resume@.service8 + unit according to the value of parameter + specified on the kernel command line. + + + + Kernel Command Line + + systemd-hibernate-resume-generator + understands the following kernel command line parameters: + + + + + resume= + + Takes a path to the resume device. Both + persistent block device paths like + /dev/disk/by-foo/bar and + fstab5-style + specifiers like FOO=bar are + supported. + + + + + + + See Also + + systemd1, + systemd-hibernate-resume@.service8, + kernel-command-line7 + + + + diff --git a/src/grp-initprogs/grp-sleep/systemd-hibernate-resume/Makefile b/src/grp-initprogs/grp-sleep/systemd-hibernate-resume/Makefile new file mode 100644 index 0000000000..95f44744a2 --- /dev/null +++ b/src/grp-initprogs/grp-sleep/systemd-hibernate-resume/Makefile @@ -0,0 +1,45 @@ +# -*- Mode: makefile; indent-tabs-mode: t -*- +# +# This file is part of systemd. +# +# Copyright 2010-2012 Lennart Poettering +# Copyright 2010-2012 Kay Sievers +# Copyright 2013 Zbigniew Jędrzejewski-Szmek +# Copyright 2013 David Strauss +# Copyright 2016 Luke Shumaker +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. +# +# systemd is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with systemd; If not, see . +include $(dir $(lastword $(MAKEFILE_LIST)))/../../../../config.mk +include $(topsrcdir)/build-aux/Makefile.head.mk + +ifneq ($(ENABLE_HIBERNATE),) + +rootlibexec_PROGRAMS += \ + systemd-hibernate-resume + +systemd_hibernate_resume_SOURCES = \ + src/hibernate-resume/hibernate-resume.c + +systemd_hibernate_resume_LDADD = \ + libsystemd-shared.la + +nodist_systemunit_DATA += \ + units/systemd-hibernate-resume@.service + +endif # ENABLE_HIBERNATE + +EXTRA_DIST += \ + units/systemd-hibernate-resume@.service.in + +include $(topsrcdir)/build-aux/Makefile.tail.mk diff --git a/src/grp-initprogs/grp-sleep/systemd-hibernate-resume/hibernate-resume.c b/src/grp-initprogs/grp-sleep/systemd-hibernate-resume/hibernate-resume.c new file mode 100644 index 0000000000..64d14bf64b --- /dev/null +++ b/src/grp-initprogs/grp-sleep/systemd-hibernate-resume/hibernate-resume.c @@ -0,0 +1,82 @@ +/*** + This file is part of systemd. + + Copyright 2014 Ivan Shapovalov + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include "basic/alloc-util.h" +#include "basic/fileio.h" +#include "basic/log.h" +#include "basic/util.h" + +int main(int argc, char *argv[]) { + struct stat st; + const char *device; + _cleanup_free_ char *major_minor = NULL; + int r; + + if (argc != 2) { + log_error("This program expects one argument."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + /* Refuse to run unless we are in an initrd() */ + if (!in_initrd()) + return EXIT_SUCCESS; + + device = argv[1]; + + if (stat(device, &st) < 0) { + log_error_errno(errno, "Failed to stat '%s': %m", device); + return EXIT_FAILURE; + } + + if (!S_ISBLK(st.st_mode)) { + log_error("Resume device '%s' is not a block device.", device); + return EXIT_FAILURE; + } + + if (asprintf(&major_minor, "%d:%d", major(st.st_rdev), minor(st.st_rdev)) < 0) { + log_oom(); + return EXIT_FAILURE; + } + + r = write_string_file("/sys/power/resume", major_minor, WRITE_STRING_FILE_CREATE); + if (r < 0) { + log_error_errno(r, "Failed to write '%s' to /sys/power/resume: %m", major_minor); + return EXIT_FAILURE; + } + + /* + * The write above shall not return. + * + * However, failed resume is a normal condition (may mean that there is + * no hibernation image). + */ + + log_info("Could not resume from '%s' (%s).", device, major_minor); + return EXIT_SUCCESS; +} diff --git a/src/grp-initprogs/grp-sleep/systemd-hibernate-resume/systemd-hibernate-resume@.service.in b/src/grp-initprogs/grp-sleep/systemd-hibernate-resume/systemd-hibernate-resume@.service.in new file mode 100644 index 0000000000..65e8eb83f1 --- /dev/null +++ b/src/grp-initprogs/grp-sleep/systemd-hibernate-resume/systemd-hibernate-resume@.service.in @@ -0,0 +1,20 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Resume from hibernation using device %f +Documentation=man:systemd-hibernate-resume@.service(8) +DefaultDependencies=no +BindsTo=%i.device +Wants=local-fs-pre.target +After=%i.device +Before=local-fs-pre.target +ConditionPathExists=/etc/initrd-release + +[Service] +Type=oneshot +ExecStart=@rootlibexecdir@/systemd-hibernate-resume %f diff --git a/src/grp-initprogs/grp-sleep/systemd-hibernate-resume/systemd-hibernate-resume@.service.xml b/src/grp-initprogs/grp-sleep/systemd-hibernate-resume/systemd-hibernate-resume@.service.xml new file mode 100644 index 0000000000..7d00827447 --- /dev/null +++ b/src/grp-initprogs/grp-sleep/systemd-hibernate-resume/systemd-hibernate-resume@.service.xml @@ -0,0 +1,81 @@ + + + + + + + + systemd-hibernate-resume@.service + systemd + + + + Developer + Ivan + Shapovalov + intelfx100@gmail.com + + + + + + systemd-hibernate-resume@.service + 8 + + + + systemd-hibernate-resume@.service + systemd-hibernate-resume + Resume from hibernation + + + + systemd-hibernate-resume@.service + /usr/lib/systemd/systemd-hibernate-resume + + + + Description + + systemd-hibernate-resume@.service + initiates the resume from hibernation. It is instantiated with the + device to resume from as the template argument. + + systemd-hibernate-resume only supports + the in-kernel hibernation implementation, known as + swsusp. + Internally, it works by writing the major:minor of specified + device node to /sys/power/resume. + + Failing to initiate a resume is not an error condition. It + may mean that there was no resume image (e. g. if the system has + been simply powered off and not hibernated). In such case, the + boot is ordinarily continued. + + + + See Also + + systemd1, + systemd-hibernate-resume-generator8 + + + + diff --git a/src/grp-initprogs/grp-sleep/systemd-sleep/Makefile b/src/grp-initprogs/grp-sleep/systemd-sleep/Makefile new file mode 100644 index 0000000000..45c0beaf9d --- /dev/null +++ b/src/grp-initprogs/grp-sleep/systemd-sleep/Makefile @@ -0,0 +1,49 @@ +# -*- Mode: makefile; indent-tabs-mode: t -*- +# +# This file is part of systemd. +# +# Copyright 2010-2012 Lennart Poettering +# Copyright 2010-2012 Kay Sievers +# Copyright 2013 Zbigniew Jędrzejewski-Szmek +# Copyright 2013 David Strauss +# Copyright 2016 Luke Shumaker +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. +# +# systemd is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with systemd; If not, see . +include $(dir $(lastword $(MAKEFILE_LIST)))/../../../../config.mk +include $(topsrcdir)/build-aux/Makefile.head.mk + +rootlibexec_PROGRAMS += systemd-sleep +systemd_sleep_SOURCES = \ + src/sleep/sleep.c + +systemd_sleep_LDADD = \ + libsystemd-shared.la + +ifneq ($(ENABLE_HIBERNATE),) + +dist_systemunit_DATA += \ + units/hibernate.target \ + units/hybrid-sleep.target + +nodist_systemunit_DATA += \ + units/systemd-hibernate.service \ + units/systemd-hybrid-sleep.service + +endif # ENABLE_HIBERNATE + +EXTRA_DIST += \ + units/systemd-hibernate.service.in \ + units/systemd-hybrid-sleep.service.in + +include $(topsrcdir)/build-aux/Makefile.tail.mk diff --git a/src/grp-initprogs/grp-sleep/systemd-sleep/hibernate.target b/src/grp-initprogs/grp-sleep/systemd-sleep/hibernate.target new file mode 100644 index 0000000000..143eb59230 --- /dev/null +++ b/src/grp-initprogs/grp-sleep/systemd-sleep/hibernate.target @@ -0,0 +1,13 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Hibernate +Documentation=man:systemd.special(7) +DefaultDependencies=no +BindsTo=systemd-hibernate.service +After=systemd-hibernate.service diff --git a/src/grp-initprogs/grp-sleep/systemd-sleep/hybrid-sleep.target b/src/grp-initprogs/grp-sleep/systemd-sleep/hybrid-sleep.target new file mode 100644 index 0000000000..d2d3409225 --- /dev/null +++ b/src/grp-initprogs/grp-sleep/systemd-sleep/hybrid-sleep.target @@ -0,0 +1,13 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Hybrid Suspend+Hibernate +Documentation=man:systemd.special(7) +DefaultDependencies=no +BindsTo=systemd-hybrid-sleep.service +After=systemd-hybrid-sleep.service diff --git a/src/grp-initprogs/grp-sleep/systemd-sleep/sleep.c b/src/grp-initprogs/grp-sleep/systemd-sleep/sleep.c new file mode 100644 index 0000000000..e9e84bc893 --- /dev/null +++ b/src/grp-initprogs/grp-sleep/systemd-sleep/sleep.c @@ -0,0 +1,215 @@ +/*** + This file is part of systemd. + + Copyright 2012 Lennart Poettering + Copyright 2013 Zbigniew Jędrzejewski-Szmek + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include + +#include "basic/def.h" +#include "basic/fd-util.h" +#include "basic/fileio.h" +#include "basic/log.h" +#include "basic/string-util.h" +#include "basic/strv.h" +#include "basic/util.h" +#include "shared/sleep-config.h" + +static char* arg_verb = NULL; + +static int write_mode(char **modes) { + int r = 0; + char **mode; + + STRV_FOREACH(mode, modes) { + int k; + + k = write_string_file("/sys/power/disk", *mode, 0); + if (k == 0) + return 0; + + log_debug_errno(k, "Failed to write '%s' to /sys/power/disk: %m", + *mode); + if (r == 0) + r = k; + } + + if (r < 0) + log_error_errno(r, "Failed to write mode to /sys/power/disk: %m"); + + return r; +} + +static int write_state(FILE **f, char **states) { + char **state; + int r = 0; + + STRV_FOREACH(state, states) { + int k; + + k = write_string_stream(*f, *state, true); + if (k == 0) + return 0; + log_debug_errno(k, "Failed to write '%s' to /sys/power/state: %m", + *state); + if (r == 0) + r = k; + + fclose(*f); + *f = fopen("/sys/power/state", "we"); + if (!*f) + return log_error_errno(errno, "Failed to open /sys/power/state: %m"); + } + + return r; +} + +static int execute(char **modes, char **states) { + + char *arguments[] = { + NULL, + (char*) "pre", + arg_verb, + NULL + }; + static const char* const dirs[] = {SYSTEM_SLEEP_PATH, NULL}; + + int r; + _cleanup_fclose_ FILE *f = NULL; + + /* This file is opened first, so that if we hit an error, + * we can abort before modifying any state. */ + f = fopen("/sys/power/state", "we"); + if (!f) + return log_error_errno(errno, "Failed to open /sys/power/state: %m"); + + /* Configure the hibernation mode */ + r = write_mode(modes); + if (r < 0) + return r; + + execute_directories(dirs, DEFAULT_TIMEOUT_USEC, arguments); + + log_struct(LOG_INFO, + LOG_MESSAGE_ID(SD_MESSAGE_SLEEP_START), + LOG_MESSAGE("Suspending system..."), + "SLEEP=%s", arg_verb, + NULL); + + r = write_state(&f, states); + if (r < 0) + return r; + + log_struct(LOG_INFO, + LOG_MESSAGE_ID(SD_MESSAGE_SLEEP_STOP), + LOG_MESSAGE("System resumed."), + "SLEEP=%s", arg_verb, + NULL); + + arguments[1] = (char*) "post"; + execute_directories(dirs, DEFAULT_TIMEOUT_USEC, arguments); + + return r; +} + +static void help(void) { + printf("%s COMMAND\n\n" + "Suspend the system, hibernate the system, or both.\n\n" + "Commands:\n" + " -h --help Show this help and exit\n" + " --version Print version string and exit\n" + " suspend Suspend the system\n" + " hibernate Hibernate the system\n" + " hybrid-sleep Both hibernate and suspend the system\n" + , program_invocation_short_name); +} + +static int parse_argv(int argc, char *argv[]) { + enum { + ARG_VERSION = 0x100, + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + {} + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) + switch(c) { + case 'h': + help(); + return 0; /* done */ + + case ARG_VERSION: + return version(); + + case '?': + return -EINVAL; + + default: + assert_not_reached("Unhandled option"); + } + + if (argc - optind != 1) { + log_error("Usage: %s COMMAND", + program_invocation_short_name); + return -EINVAL; + } + + arg_verb = argv[optind]; + + if (!streq(arg_verb, "suspend") && + !streq(arg_verb, "hibernate") && + !streq(arg_verb, "hybrid-sleep")) { + log_error("Unknown command '%s'.", arg_verb); + return -EINVAL; + } + + return 1 /* work to do */; +} + +int main(int argc, char *argv[]) { + _cleanup_strv_free_ char **modes = NULL, **states = NULL; + int r; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + r = parse_argv(argc, argv); + if (r <= 0) + goto finish; + + r = parse_sleep_config(arg_verb, &modes, &states); + if (r < 0) + goto finish; + + r = execute(modes, states); + +finish: + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/grp-initprogs/grp-sleep/systemd-sleep/sleep.target b/src/grp-initprogs/grp-sleep/systemd-sleep/sleep.target new file mode 100644 index 0000000000..10c7c8d594 --- /dev/null +++ b/src/grp-initprogs/grp-sleep/systemd-sleep/sleep.target @@ -0,0 +1,13 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Sleep +Documentation=man:systemd.special(7) +DefaultDependencies=no +RefuseManualStart=yes +StopWhenUnneeded=yes diff --git a/src/grp-initprogs/grp-sleep/systemd-sleep/suspend.target b/src/grp-initprogs/grp-sleep/systemd-sleep/suspend.target new file mode 100644 index 0000000000..f50cb2264f --- /dev/null +++ b/src/grp-initprogs/grp-sleep/systemd-sleep/suspend.target @@ -0,0 +1,13 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Suspend +Documentation=man:systemd.special(7) +DefaultDependencies=no +BindsTo=systemd-suspend.service +After=systemd-suspend.service diff --git a/src/grp-initprogs/grp-sleep/systemd-sleep/systemd-hibernate.service.in b/src/grp-initprogs/grp-sleep/systemd-sleep/systemd-hibernate.service.in new file mode 100644 index 0000000000..29d9b696a8 --- /dev/null +++ b/src/grp-initprogs/grp-sleep/systemd-sleep/systemd-hibernate.service.in @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Hibernate +Documentation=man:systemd-suspend.service(8) +DefaultDependencies=no +Requires=sleep.target +After=sleep.target + +[Service] +Type=oneshot +ExecStart=@rootlibexecdir@/systemd-sleep hibernate diff --git a/src/grp-initprogs/grp-sleep/systemd-sleep/systemd-hybrid-sleep.service.in b/src/grp-initprogs/grp-sleep/systemd-sleep/systemd-hybrid-sleep.service.in new file mode 100644 index 0000000000..914b686c36 --- /dev/null +++ b/src/grp-initprogs/grp-sleep/systemd-sleep/systemd-hybrid-sleep.service.in @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Hybrid Suspend+Hibernate +Documentation=man:systemd-suspend.service(8) +DefaultDependencies=no +Requires=sleep.target +After=sleep.target + +[Service] +Type=oneshot +ExecStart=@rootlibexecdir@/systemd-sleep hybrid-sleep diff --git a/src/grp-initprogs/grp-sleep/systemd-sleep/systemd-sleep.conf.xml b/src/grp-initprogs/grp-sleep/systemd-sleep/systemd-sleep.conf.xml new file mode 100644 index 0000000000..9a379ecb94 --- /dev/null +++ b/src/grp-initprogs/grp-sleep/systemd-sleep/systemd-sleep.conf.xml @@ -0,0 +1,186 @@ + + + + + + + + systemd-sleep.conf + systemd + + + + Developer + Zbigniew + Jędrzejewski-Szmek + zbyszek@in.waw.pl + + + + + + systemd-sleep.conf + 5 + + + + systemd-sleep.conf + sleep.conf.d + Suspend and hibernation configuration file + + + + /etc/systemd/sleep.conf + /etc/systemd/sleep.conf.d/*.conf + /run/systemd/sleep.conf.d/*.conf + /usr/lib/systemd/sleep.conf.d/*.conf + + + + Description + + systemd supports three general + power-saving modes: + + + + suspend + + a low-power state + where execution of the OS is paused, + and complete power loss might result + in lost data, and which is fast to + enter and exit. This corresponds to + suspend, standby, or freeze states as + understood by the kernel. + + + + + hibernate + + a low-power state + where execution of the OS is paused, + and complete power loss does not + result in lost data, and which might + be slow to enter and exit. This + corresponds to the hibernation as + understood by the kernel. + + + + + hybrid-sleep + + a low-power state + where execution of the OS is paused, + which might be slow to enter, and on + complete power loss does not result in + lost data but might be slower to exit + in that case. This mode is called + suspend-to-both by the kernel. + + + + + Settings in these files determine what strings + will be written to + /sys/power/disk and + /sys/power/state by + systemd-sleep8 + when + systemd1 + attempts to suspend or hibernate the machine. + + + + + + Options + + The following options can be configured in the + [Sleep] section of + /etc/systemd/sleep.conf or a + sleep.conf.d file: + + + + SuspendMode= + HibernateMode= + HybridSleepMode= + + The string to be written to + /sys/power/disk by, + respectively, + systemd-suspend.service8, + systemd-hibernate.service8, or + systemd-hybrid-sleep.service8. + More than one value can be specified by separating + multiple values with whitespace. They will be tried + in turn, until one is written without error. If + neither succeeds, the operation will be aborted. + + + + + SuspendState= + HibernateState= + HybridSleepState= + + The string to be written to + /sys/power/state by, + respectively, + systemd-suspend.service8, + systemd-hibernate.service8, or + systemd-hybrid-sleep.service8. + More than one value can be specified by separating + multiple values with whitespace. They will be tried + in turn, until one is written without error. If + neither succeeds, the operation will be aborted. + + + + + + + Example: freeze + + Example: to exploit the freeze mode added + in Linux 3.9, one can use systemctl suspend + with + [Sleep] +SuspendState=freeze + + + + See Also + + systemd-sleep8, + systemd-suspend.service8, + systemd-hibernate.service8, + systemd-hybrid-sleep.service8, + systemd1, + systemd.directives7 + + + + diff --git a/src/grp-initprogs/grp-sleep/systemd-sleep/systemd-sleep.xml b/src/grp-initprogs/grp-sleep/systemd-sleep/systemd-sleep.xml new file mode 100644 index 0000000000..a8beb86f4d --- /dev/null +++ b/src/grp-initprogs/grp-sleep/systemd-sleep/systemd-sleep.xml @@ -0,0 +1,146 @@ + + + + + + + + + systemd-suspend.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-suspend.service + 8 + + + + systemd-suspend.service + systemd-hibernate.service + systemd-hybrid-sleep.service + systemd-sleep + System sleep state logic + + + + systemd-suspend.service + systemd-hibernate.service + systemd-hybrid-sleep.service + /usr/lib/systemd/system-sleep + + + + Description + + systemd-suspend.service is a system + service that is pulled in by suspend.target + and is responsible for the actual system suspend. Similarly, + systemd-hibernate.service is pulled in by + hibernate.target to execute the actual + hibernation. Finally, + systemd-hybrid-sleep.service is pulled in by + hybrid-sleep.target to execute hybrid + hibernation with system suspend. + + Immediately before entering system suspend and/or + hibernation systemd-suspend.service (and the + other mentioned units, respectively) will run all executables in + /usr/lib/systemd/system-sleep/ and pass two + arguments to them. The first argument will be + pre, the second either + suspend, hibernate, or + hybrid-sleep depending on the chosen action. + Immediately after leaving system suspend and/or hibernation the + same executables are run, but the first argument is now + post. All executables in this directory are + executed in parallel, and execution of the action is not continued + until all executables have finished. + + Note that scripts or binaries dropped in + /usr/lib/systemd/system-sleep/ are intended + for local use only and should be considered hacks. If applications + want to be notified of system suspend/hibernation and resume, + there are much nicer interfaces available. + + Note that + systemd-suspend.service, + systemd-hibernate.service, and + systemd-hybrid-sleep.service + should never be executed directly. Instead, trigger system sleep + states with a command such as systemctl suspend + or similar. + + Internally, this service will echo a string like + mem into /sys/power/state, + to trigger the actual system suspend. What exactly is written + where can be configured in the [Sleep] section + of /etc/systemd/sleep.conf or a + sleep.conf.d file. See + systemd-sleep.conf5. + + + + + Options + + systemd-sleep understands the + following commands: + + + + + + + + + + + Suspend, hibernate, or put the system to + hybrid sleep. + + + + + + + See Also + + systemd-sleep.conf5, + systemd1, + systemctl1, + systemd.special7, + systemd-halt.service8 + + + + diff --git a/src/grp-initprogs/grp-sleep/systemd-sleep/systemd-suspend.service.in b/src/grp-initprogs/grp-sleep/systemd-sleep/systemd-suspend.service.in new file mode 100644 index 0000000000..3a702d2e22 --- /dev/null +++ b/src/grp-initprogs/grp-sleep/systemd-sleep/systemd-suspend.service.in @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Suspend +Documentation=man:systemd-suspend.service(8) +DefaultDependencies=no +Requires=sleep.target +After=sleep.target + +[Service] +Type=oneshot +ExecStart=@rootlibexecdir@/systemd-sleep suspend -- cgit v1.2.3