diff options
author | Lennart Poettering <lennart@poettering.net> | 2012-05-05 02:06:58 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2012-05-08 13:54:23 +0200 |
commit | 6edd7d0a09171ea5ae8e01b7b1cbcb0bdfbfeb16 (patch) | |
tree | 85a09e06fd5dfc98cb198fafb9a33b70e79a4c63 | |
parent | 4943c1c94ba751c98763f4232b4350481b22c90a (diff) |
sleep: implement suspend/hibernate as first class targets
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile.am | 18 | ||||
-rw-r--r-- | TODO | 5 | ||||
-rw-r--r-- | man/systemctl.xml | 10 | ||||
-rw-r--r-- | man/systemd.special.xml | 34 | ||||
-rw-r--r-- | src/core/shutdown.c | 6 | ||||
-rw-r--r-- | src/core/special.h | 2 | ||||
-rw-r--r-- | src/shared/util.c | 3 | ||||
l--------- | src/sleep/Makefile | 1 | ||||
-rw-r--r-- | src/sleep/sleep.c | 83 | ||||
-rw-r--r-- | src/systemctl/systemctl.c | 16 | ||||
-rw-r--r-- | units/.gitignore | 2 | ||||
-rw-r--r-- | units/hibernate.service.in | 16 | ||||
-rw-r--r-- | units/hibernate.target | 14 | ||||
-rw-r--r-- | units/sleep.target | 13 | ||||
-rw-r--r-- | units/suspend.service.in | 16 | ||||
-rw-r--r-- | units/suspend.target | 14 |
17 files changed, 243 insertions, 11 deletions
diff --git a/.gitignore b/.gitignore index 7f22255c52..e61f1cdbad 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/systemd-sleep /systemd-inhibit /systemd-remount-fs /build-aux diff --git a/Makefile.am b/Makefile.am index dbcfeb384f..002a86aeba 100644 --- a/Makefile.am +++ b/Makefile.am @@ -67,6 +67,7 @@ usergeneratordir=$(pkglibexecdir)/user-generators pkgincludedir=$(includedir)/systemd systemgeneratordir=$(rootlibexecdir)/system-generators systemshutdowndir=$(rootlibexecdir)/system-shutdown +systemsleepdir=$(rootlibexecdir)/system-sleep systemunitdir=$(rootprefix)/lib/systemd/system udevlibexecdir=$(rootprefix)/lib/udev udevhomedir = $(libexecdir)/udev @@ -117,6 +118,7 @@ AM_CPPFLAGS = \ -DSYSTEMD_CGROUP_AGENT_PATH=\"$(rootlibexecdir)/systemd-cgroups-agent\" \ -DSYSTEMD_BINARY_PATH=\"$(rootlibexecdir)/systemd\" \ -DSYSTEMD_SHUTDOWN_BINARY_PATH=\"$(rootlibexecdir)/systemd-shutdown\" \ + -DSYSTEMD_SLEEP_BINARY_PATH=\"$(rootlibexecdir)/systemd-sleep\" \ -DSYSTEMCTL_BINARY_PATH=\"$(rootbindir)/systemctl\" \ -DSYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH=\"$(rootbindir)/systemd-tty-ask-password-agent\" \ -DSYSTEMD_STDIO_BRIDGE_BINARY_PATH=\"$(bindir)/systemd-stdio-bridge\" \ @@ -230,7 +232,8 @@ rootlibexec_PROGRAMS = \ systemd-fsck \ systemd-timestamp \ systemd-ac-power \ - systemd-sysctl + systemd-sysctl \ + systemd-sleep systemgenerator_PROGRAMS = \ systemd-getty-generator @@ -266,6 +269,7 @@ dist_systemunit_DATA = \ units/nss-lookup.target \ units/nss-user-lookup.target \ units/mail-transfer-agent.target \ + units/hibernate.target \ units/http-daemon.target \ units/poweroff.target \ units/reboot.target \ @@ -276,7 +280,9 @@ dist_systemunit_DATA = \ units/final.target \ units/umount.target \ units/sigpwr.target \ + units/sleep.target \ units/sockets.target \ + units/suspend.target \ units/swap.target \ units/systemd-initctl.socket \ units/systemd-shutdownd.socket \ @@ -318,12 +324,14 @@ nodist_systemunit_DATA = \ units/systemd-sysctl.service \ units/halt.service \ units/emergency.service \ + units/hibernate.service \ units/poweroff.service \ units/reboot.service \ units/kexec.service \ units/fsck@.service \ units/fsck-root.service \ units/rescue.service \ + units/suspend.service \ units/user@.service \ units/systemd-udev.service \ units/systemd-udev-trigger.service \ @@ -1063,6 +1071,13 @@ systemd_sysctl_LDADD = \ libsystemd-shared.la # ------------------------------------------------------------------------------ +systemd_sleep_SOURCES = \ + src/sleep/sleep.c + +systemd_sleep_LDADD = \ + libsystemd-shared.la + +# ------------------------------------------------------------------------------ systemd_fsck_SOURCES = \ src/fsck/fsck.c @@ -3027,6 +3042,7 @@ systemd-install-data-hook: $(DESTDIR)$(prefix)/lib/sysctl.d \ $(DESTDIR)$(sysconfdir)/sysctl.d \ $(DESTDIR)$(systemshutdowndir) \ + $(DESTDIR)$(systemsleepdir) \ $(DESTDIR)$(systemgeneratordir) \ $(DESTDIR)$(usergeneratordir) $(MKDIR_P) -m 0755 \ @@ -53,9 +53,6 @@ Features: * ExecOnFailure=/usr/bin/foo -* logind: add "mode" flag to poweroff/suspend inhibit logic so that we can - support both "inhibit" and "delay" mode. - * fedora: make sshd and pam_loginuid work in nspawn containers * fix utmp for console logins in containers @@ -72,8 +69,6 @@ Features: * journald: allow forwarding of log data to specific TTY instea dof console -* suspend/hibernate/hybrid support, auto-suspend logic with idle hint - * add RequiredBy to [Install] * udev: move to LGPL diff --git a/man/systemctl.xml b/man/systemctl.xml index dd0ff786ec..9e113eb0fe 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -1149,6 +1149,16 @@ <option>--user</option> option) and will fail otherwise.</para></listitem> </varlistentry> + <varlistentry> + <term><command>suspend</command></term> + + <listitem><para>Suspend the system.</para></listitem> + </varlistentry> + <varlistentry> + <term><command>hibernate</command></term> + + <listitem><para>Hibernate the system.</para></listitem> + </varlistentry> </variablelist> </refsect1> diff --git a/man/systemd.special.xml b/man/systemd.special.xml index 39c3802210..984e998aba 100644 --- a/man/systemd.special.xml +++ b/man/systemd.special.xml @@ -58,6 +58,7 @@ <filename>exit.service</filename>, <filename>final.service</filename>, <filename>graphical.target</filename>, + <filename>hibernate.target</filename>, <filename>http-daemon.target</filename>, <filename>halt.target</filename>, <filename>kbrequest.target</filename>, @@ -80,7 +81,9 @@ <filename>runlevel5.target</filename>, <filename>shutdown.target</filename>, <filename>sigpwr.target</filename>, + <filename>sleep.target</filename>, <filename>sockets.target</filename>, + <filename>suspend.target</filename>, <filename>swap.target</filename>, <filename>sysinit.target</filename>, <filename>syslog.service</filename>, @@ -240,6 +243,15 @@ </listitem> </varlistentry> <varlistentry> + <term><filename>hibernate.target</filename></term> + <listitem> + <para>A special target unit + for hibernating the + system. This pulls in + <filename>sleep.target</filename>.</para> + </listitem> + </varlistentry> + <varlistentry> <term><filename>http-daemon.target</filename></term> <listitem> <para>A target for pulling in @@ -591,6 +603,19 @@ </listitem> </varlistentry> <varlistentry> + <term><filename>sleep.target</filename></term> + <listitem> + <para>A special target unit + that is pulled in by + <filename>suspend.target</filename> + and + <filename>hibernate.target</filename> + and may be used to hook units + into the sleep state + logic.</para> + </listitem> + </varlistentry> + <varlistentry> <term><filename>sockets.target</filename></term> <listitem> <para>A special target unit @@ -605,6 +630,15 @@ </listitem> </varlistentry> <varlistentry> + <term><filename>suspend.target</filename></term> + <listitem> + <para>A special target unit + for suspending the + system. This pulls in + <filename>sleep.target</filename>.</para> + </listitem> + </varlistentry> + <varlistentry> <term><filename>swap.target</filename></term> <listitem> <para>Similar to diff --git a/src/core/shutdown.c b/src/core/shutdown.c index 2494bb86a1..a8dfe2614f 100644 --- a/src/core/shutdown.c +++ b/src/core/shutdown.c @@ -309,6 +309,7 @@ int main(int argc, char *argv[]) { unsigned retries; bool need_umount = true, need_swapoff = true, need_loop_detach = true, need_dm_detach = true; bool killed_everbody = false, in_container, use_watchdog = false; + char *arguments[3]; log_parse_environment(); log_set_target(LOG_TARGET_CONSOLE); /* syslog will die if not gone yet */ @@ -442,7 +443,10 @@ int main(int argc, char *argv[]) { if (retries >= FINALIZE_ATTEMPTS) log_error("Too many iterations, giving up."); - execute_directory(SYSTEM_SHUTDOWN_PATH, NULL, NULL); + arguments[0] = NULL; + arguments[1] = argv[1]; + arguments[2] = NULL; + execute_directory(SYSTEM_SHUTDOWN_PATH, NULL, arguments); /* If we are in a container, just exit, this will kill our * container for good. */ diff --git a/src/core/special.h b/src/core/special.h index 2db4711c2e..bc9b330ffb 100644 --- a/src/core/special.h +++ b/src/core/special.h @@ -36,6 +36,8 @@ #define SPECIAL_REBOOT_TARGET "reboot.target" #define SPECIAL_KEXEC_TARGET "kexec.target" #define SPECIAL_EXIT_TARGET "exit.target" +#define SPECIAL_SUSPEND_TARGET "suspend.target" +#define SPECIAL_HIBERNATE_TARGET "hibernate.target" /* Special boot targets */ #define SPECIAL_RESCUE_TARGET "rescue.target" diff --git a/src/shared/util.c b/src/shared/util.c index 8a0b2a1b46..d8d3f1a16d 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -4106,8 +4106,7 @@ void execute_directory(const char *directory, DIR *d, char *argv[]) { _argv[1] = NULL; argv = _argv; } else - if (!argv[0]) - argv[0] = path; + argv[0] = path; execv(path, argv); diff --git a/src/sleep/Makefile b/src/sleep/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/sleep/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/sleep/sleep.c b/src/sleep/sleep.c new file mode 100644 index 0000000000..7062dc242f --- /dev/null +++ b/src/sleep/sleep.c @@ -0,0 +1,83 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 Lennart Poettering + + 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 <http://www.gnu.org/licenses/>. +***/ + +#include <stdio.h> +#include <errno.h> +#include <string.h> + +#include "log.h" +#include "util.h" + +int main(int argc, char *argv[]) { + const char *verb; + char* arguments[4]; + int r; + FILE *f; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + if (argc != 2) { + log_error("Invalid number of arguments."); + r = -EINVAL; + goto finish; + } + + if (streq(argv[1], "suspend")) + verb = "mem"; + else if (streq(argv[1], "hibernate")) + verb = "disk"; + else { + log_error("Unknown action '%s'.", argv[1]); + r = -EINVAL; + goto finish; + } + + 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]; + arguments[3] = NULL; + execute_directory(SYSTEMD_SLEEP_BINARY_PATH, NULL, arguments); + + fputs(verb, f); + fputc('\n', f); + fflush(f); + + r = ferror(f) ? -errno : 0; + + arguments[1] = (char*) "post"; + execute_directory(SYSTEMD_SLEEP_BINARY_PATH, NULL, arguments); + + fclose(f); + +finish: + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + +} diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index acede4e765..762b5be346 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -97,6 +97,8 @@ static enum action { ACTION_REBOOT, ACTION_KEXEC, ACTION_EXIT, + ACTION_SUSPEND, + ACTION_HIBERNATE, ACTION_RUNLEVEL2, ACTION_RUNLEVEL3, ACTION_RUNLEVEL4, @@ -1605,6 +1607,10 @@ static enum action verb_to_action(const char *verb) { return ACTION_DEFAULT; else if (streq(verb, "exit")) return ACTION_EXIT; + else if (streq(verb, "suspend")) + return ACTION_SUSPEND; + else if (streq(verb, "hibernate")) + return ACTION_HIBERNATE; else return ACTION_INVALID; } @@ -1623,7 +1629,9 @@ static int start_unit(DBusConnection *bus, char **args) { [ACTION_RESCUE] = SPECIAL_RESCUE_TARGET, [ACTION_EMERGENCY] = SPECIAL_EMERGENCY_TARGET, [ACTION_DEFAULT] = SPECIAL_DEFAULT_TARGET, - [ACTION_EXIT] = SPECIAL_EXIT_TARGET + [ACTION_EXIT] = SPECIAL_EXIT_TARGET, + [ACTION_SUSPEND] = SPECIAL_SUSPEND_TARGET, + [ACTION_HIBERNATE] = SPECIAL_HIBERNATE_TARGET }; int r, ret = 0; @@ -4201,7 +4209,9 @@ static int systemctl_help(void) { " poweroff Shut down and power-off the system\n" " reboot Shut down and reboot the system\n" " kexec Shut down and reboot the system with kexec\n" - " exit Ask for user instance termination\n", + " exit Request user instance exit\n" + " suspend Suspend the system\n" + " hibernate Hibernate the system\n", program_invocation_short_name); return 0; @@ -5135,6 +5145,8 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError { "poweroff", EQUAL, 1, start_special }, { "reboot", EQUAL, 1, start_special }, { "kexec", EQUAL, 1, start_special }, + { "suspend", EQUAL, 1, start_special }, + { "hibernate", EQUAL, 1, start_special }, { "default", EQUAL, 1, start_special }, { "rescue", EQUAL, 1, start_special }, { "emergency", EQUAL, 1, start_special }, diff --git a/units/.gitignore b/units/.gitignore index 68c174f1f5..dc5e1d47d3 100644 --- a/units/.gitignore +++ b/units/.gitignore @@ -1,3 +1,5 @@ +/hibernate.service +/suspend.service /console-getty.service /systemd-journald.service user@.service diff --git a/units/hibernate.service.in b/units/hibernate.service.in new file mode 100644 index 0000000000..6dba653d37 --- /dev/null +++ b/units/hibernate.service.in @@ -0,0 +1,16 @@ +# 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 +DefaultDependencies=no +Requires=sleep.target +After=sleep.target + +[Service] +Type=oneshot +ExecStart=@rootlibexecdir@/systemd-sleep hibernate diff --git a/units/hibernate.target b/units/hibernate.target new file mode 100644 index 0000000000..05238a7cbf --- /dev/null +++ b/units/hibernate.target @@ -0,0 +1,14 @@ +# 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. + +# See systemd.special(7) for details + +[Unit] +Description=Hibernate +DefaultDependencies=no +BindTo=hibernate.service +After=hibernate.service diff --git a/units/sleep.target b/units/sleep.target new file mode 100644 index 0000000000..9f4b247eb5 --- /dev/null +++ b/units/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. + +# See systemd.special(7) for details + +[Unit] +Description=Sleep +DefaultDependencies=no +RefuseManualStart=yes diff --git a/units/suspend.service.in b/units/suspend.service.in new file mode 100644 index 0000000000..3cf819e476 --- /dev/null +++ b/units/suspend.service.in @@ -0,0 +1,16 @@ +# 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 +DefaultDependencies=no +Requires=sleep.target +After=sleep.target + +[Service] +Type=oneshot +ExecStart=@rootlibexecdir@/systemd-sleep suspend diff --git a/units/suspend.target b/units/suspend.target new file mode 100644 index 0000000000..3ddb44975d --- /dev/null +++ b/units/suspend.target @@ -0,0 +1,14 @@ +# 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. + +# See systemd.special(7) for details + +[Unit] +Description=Suspend +DefaultDependencies=no +BindTo=suspend.service +After=suspend.service |