diff options
author | Lennart Poettering <lennart@poettering.net> | 2021-05-21 18:23:42 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2021-05-22 11:00:00 +0200 |
commit | c8cd8ca398608aabe510f24ab5187ceb643600bd (patch) | |
tree | 0b80c50fefe42bb61ce7f43ac9001474f27a9d81 /src/sleep | |
parent | sleep: introduce high-level SleepOperation enum (diff) | |
download | systemd-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.c | 79 |
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); |