summaryrefslogtreecommitdiffstats
path: root/src/sleep
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2021-05-21 18:23:42 +0200
committerLennart Poettering <lennart@poettering.net>2021-05-22 11:00:00 +0200
commitc8cd8ca398608aabe510f24ab5187ceb643600bd (patch)
tree0b80c50fefe42bb61ce7f43ac9001474f27a9d81 /src/sleep
parentsleep: introduce high-level SleepOperation enum (diff)
downloadsystemd-c8cd8ca398608aabe510f24ab5187ceb643600bd.tar.xz
systemd-c8cd8ca398608aabe510f24ab5187ceb643600bd.zip
sleep: use SleepOperation enum everywhere and drop sleep_settings()
Instead of comparing strings everywhere, let's use the new enum. This allows us to drop sleep_settings(), since the operation enum can be directly used as index into the config settings. Some minor other refactoring is done, but mostly just shifting thing around a bit, no actual change in behaviour.
Diffstat (limited to 'src/sleep')
-rw-r--r--src/sleep/sleep.c79
1 files changed, 46 insertions, 33 deletions
diff --git a/src/sleep/sleep.c b/src/sleep/sleep.c
index 8aeaa1a543..86b155c9ea 100644
--- a/src/sleep/sleep.c
+++ b/src/sleep/sleep.c
@@ -35,9 +35,7 @@
#include "time-util.h"
#include "util.h"
-static char* arg_verb = NULL;
-
-STATIC_DESTRUCTOR_REGISTER(arg_verb, freep);
+static SleepOperation arg_operation = _SLEEP_OPERATION_INVALID;
static int write_hibernate_location_info(const HibernateLocation *hibernate_location) {
char offset_str[DECIMAL_STR_MAX(uint64_t)];
@@ -169,11 +167,17 @@ static int lock_all_homes(void) {
return 0;
}
-static int execute(char **modes, char **states, const char *action) {
+static int execute(
+ const SleepConfig *sleep_config,
+ SleepOperation operation,
+ const char *action) {
+
char *arguments[] = {
NULL,
(char*) "pre",
- arg_verb,
+ /* NB: we use 'arg_operation' instead of 'operation' here, as we want to communicate the overall
+ * operation here, not the specific one, in case of s2h. */
+ (char*) sleep_operation_to_string(arg_operation),
NULL
};
static const char* const dirs[] = {
@@ -181,10 +185,24 @@ static int execute(char **modes, char **states, const char *action) {
NULL
};
- _cleanup_fclose_ FILE *f = NULL;
_cleanup_(hibernate_location_freep) HibernateLocation *hibernate_location = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
+ char **modes, **states;
int r;
+ assert(sleep_config);
+ assert(operation >= 0);
+ assert(operation < _SLEEP_OPERATION_MAX);
+ assert(operation != SLEEP_SUSPEND_THEN_HIBERNATE); /* Handled by execute_s2h() instead */
+
+ states = sleep_config->states[operation];
+ modes = sleep_config->modes[operation];
+
+ if (strv_isempty(states))
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "No sleep states configured for sleep operation %s, can't sleep.",
+ sleep_operation_to_string(operation));
+
/* 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");
@@ -211,6 +229,11 @@ static int execute(char **modes, char **states, const char *action) {
return log_error_errno(r, "Failed to write mode to /sys/power/disk: %m");;
}
+ /* Pass an action string to the call-outs. This is mostly our operation string, except if the
+ * hibernate step of s-t-h fails, in which case we communicate that with a separate action. */
+ if (!action)
+ action = sleep_operation_to_string(operation);
+
r = setenv("SYSTEMD_SLEEP_ACTION", action, 1);
if (r != 0)
log_warning_errno(errno, "Error setting SYSTEMD_SLEEP_ACTION=%s: %m", action);
@@ -220,20 +243,20 @@ static int execute(char **modes, char **states, const char *action) {
log_struct(LOG_INFO,
"MESSAGE_ID=" SD_MESSAGE_SLEEP_START_STR,
- LOG_MESSAGE("Suspending system..."),
- "SLEEP=%s", arg_verb);
+ LOG_MESSAGE("Entering sleep state '%s'...", sleep_operation_to_string(operation)),
+ "SLEEP=%s", sleep_operation_to_string(arg_operation));
r = write_state(&f, states);
if (r < 0)
log_struct_errno(LOG_ERR, r,
"MESSAGE_ID=" SD_MESSAGE_SLEEP_STOP_STR,
- LOG_MESSAGE("Failed to suspend system. System resumed again: %m"),
- "SLEEP=%s", arg_verb);
+ LOG_MESSAGE("Failed to put system to sleep. System resumed again: %m"),
+ "SLEEP=%s", sleep_operation_to_string(arg_operation));
else
log_struct(LOG_INFO,
"MESSAGE_ID=" SD_MESSAGE_SLEEP_STOP_STR,
- LOG_MESSAGE("System resumed."),
- "SLEEP=%s", arg_verb);
+ LOG_MESSAGE("System returned from sleep state."),
+ "SLEEP=%s", sleep_operation_to_string(arg_operation));
arguments[1] = (char*) "post";
(void) execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL, NULL, arguments, NULL, EXEC_DIR_PARALLEL | EXEC_DIR_IGNORE_ERRORS);
@@ -262,7 +285,7 @@ static int execute_s2h(const SleepConfig *sleep_config) {
if (r < 0)
return log_error_errno(errno, "Error setting hibernate timer: %m");
- r = execute(sleep_config->suspend_modes, sleep_config->suspend_states, "suspend");
+ r = execute(sleep_config, SLEEP_SUSPEND, NULL);
if (r < 0)
return r;
@@ -278,11 +301,11 @@ static int execute_s2h(const SleepConfig *sleep_config) {
log_debug("Attempting to hibernate after waking from %s timer",
format_timespan(buf, sizeof(buf), sleep_config->hibernate_delay_sec, USEC_PER_SEC));
- r = execute(sleep_config->hibernate_modes, sleep_config->hibernate_states, "hibernate");
+ r = execute(sleep_config, SLEEP_HIBERNATE, NULL);
if (r < 0) {
log_notice_errno(r, "Couldn't hibernate, will try to suspend again: %m");
- r = execute(sleep_config->suspend_modes, sleep_config->suspend_states, "suspend-after-failed-hibernate");
+ r = execute(sleep_config, SLEEP_SUSPEND, "suspend-after-failed-hibernate");
if (r < 0)
return log_error_errno(r, "Could neither hibernate nor suspend, giving up: %m");
}
@@ -351,20 +374,14 @@ static int parse_argv(int argc, char *argv[]) {
"Usage: %s COMMAND",
program_invocation_short_name);
- arg_verb = strdup(argv[optind]);
- if (!arg_verb)
- return log_oom();
-
- if (!STR_IN_SET(arg_verb, "suspend", "hibernate", "hybrid-sleep", "suspend-then-hibernate"))
- return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
- "Unknown command '%s'.", arg_verb);
+ arg_operation = sleep_operation_from_string(argv[optind]);
+ if (arg_operation < 0)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown command '%s'.", argv[optind]);
return 1 /* work to do */;
}
static int run(int argc, char *argv[]) {
- bool allow;
- char **modes = NULL, **states = NULL;
_cleanup_(free_sleep_configp) SleepConfig *sleep_config = NULL;
int r;
@@ -378,19 +395,15 @@ static int run(int argc, char *argv[]) {
if (r < 0)
return r;
- r = sleep_settings(arg_verb, sleep_config, &allow, &modes, &states);
- if (r < 0)
- return r;
-
- if (!allow)
+ if (!sleep_config->allow[arg_operation])
return log_error_errno(SYNTHETIC_ERRNO(EACCES),
- "Sleep mode \"%s\" is disabled by configuration, refusing.",
- arg_verb);
+ "Sleep operation \"%s\" is disabled by configuration, refusing.",
+ sleep_operation_to_string(arg_operation));
- if (streq(arg_verb, "suspend-then-hibernate"))
+ if (arg_operation == SLEEP_SUSPEND_THEN_HIBERNATE)
return execute_s2h(sleep_config);
else
- return execute(modes, states, arg_verb);
+ return execute(sleep_config, arg_operation, NULL);
}
DEFINE_MAIN_FUNCTION(run);