mirror of
https://github.com/systemd/systemd
synced 2024-07-21 10:17:21 +00:00
Merge pull request #30055 from YHNdnzj/logind-handle-action
logind-action: several cleanups
This commit is contained in:
commit
905dd9d6e6
15
TODO
15
TODO
|
@ -1454,21 +1454,6 @@ Features:
|
|||
|
||||
* teach parse_timestamp() timezones like the calendar spec already knows it
|
||||
|
||||
* beef up s2h to implement a battery watch loop: instead of entering
|
||||
hibernation unconditionally after coming back from resume make a decision
|
||||
based on the battery load level: if battery level is above a specific
|
||||
threshold, go to suspend again, only hibernate if below it. This means we'd
|
||||
stick to suspend usually, but fall back to hibernation only when battery runs
|
||||
empty (well, subject to our sampling interval). Related to this, check if we
|
||||
can make ACPI _BTP (i.e. /sys/class/power_supply/*/alarm) work for us too,
|
||||
i.e. see if it can wake up machines from suspend, so that we could resume
|
||||
automatically when the system is low on power and move automatically to
|
||||
hibernation mode. (see
|
||||
https://uefi.org/sites/default/files/resources/ACPI%206_2_A_Sept29.pdf
|
||||
section 10.2.2.8 and
|
||||
https://docs.microsoft.com/en-us/windows-hardware/design/device-experiences/modern-standby-wake-sources
|
||||
at the end).
|
||||
|
||||
* We should probably replace /etc/rc.d/README with a symlink to doc
|
||||
content. After all it is constant vendor data.
|
||||
|
||||
|
|
|
@ -133,9 +133,8 @@ const HandleActionData* handle_action_lookup(HandleAction action) {
|
|||
return &handle_action_data_table[action];
|
||||
}
|
||||
|
||||
int manager_handle_action(
|
||||
static int handle_action_execute(
|
||||
Manager *m,
|
||||
InhibitWhat inhibit_key,
|
||||
HandleAction handle,
|
||||
bool ignore_inhibited,
|
||||
bool is_edge) {
|
||||
|
@ -156,73 +155,11 @@ int manager_handle_action(
|
|||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
InhibitWhat inhibit_operation;
|
||||
Inhibitor *offending = NULL;
|
||||
bool supported;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
|
||||
/* If the key handling is turned off, don't do anything */
|
||||
if (handle == HANDLE_IGNORE) {
|
||||
log_debug("Handling of %s (%s) is disabled, taking no action.",
|
||||
inhibit_key == 0 ? "idle timeout" : inhibit_what_to_string(inhibit_key),
|
||||
is_edge ? "edge" : "level");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (inhibit_key == INHIBIT_HANDLE_LID_SWITCH) {
|
||||
/* If the last system suspend or startup is too close,
|
||||
* let's not suspend for now, to give USB docking
|
||||
* stations some time to settle so that we can
|
||||
* properly watch its displays. */
|
||||
if (m->lid_switch_ignore_event_source) {
|
||||
log_debug("Ignoring lid switch request, system startup or resume too close.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the key handling is inhibited, don't do anything */
|
||||
if (inhibit_key > 0) {
|
||||
if (manager_is_inhibited(m, inhibit_key, INHIBIT_BLOCK, NULL, true, false, 0, NULL)) {
|
||||
log_debug("Refusing %s operation, %s is inhibited.",
|
||||
handle_action_to_string(handle),
|
||||
inhibit_what_to_string(inhibit_key));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Locking is handled differently from the rest. */
|
||||
if (handle == HANDLE_LOCK) {
|
||||
if (!is_edge)
|
||||
return 0;
|
||||
|
||||
log_info("Locking sessions...");
|
||||
session_send_lock_all(m, true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (handle == HANDLE_SUSPEND)
|
||||
supported = sleep_supported(SLEEP_SUSPEND) > 0;
|
||||
else if (handle == HANDLE_HIBERNATE)
|
||||
supported = sleep_supported(SLEEP_HIBERNATE) > 0;
|
||||
else if (handle == HANDLE_HYBRID_SLEEP)
|
||||
supported = sleep_supported(SLEEP_HYBRID_SLEEP) > 0;
|
||||
else if (handle == HANDLE_SUSPEND_THEN_HIBERNATE)
|
||||
supported = sleep_supported(SLEEP_SUSPEND_THEN_HIBERNATE) > 0;
|
||||
else if (handle == HANDLE_KEXEC)
|
||||
supported = access(KEXEC, X_OK) >= 0;
|
||||
else
|
||||
supported = true;
|
||||
|
||||
if (!supported && HANDLE_ACTION_IS_SLEEP(handle) && handle != HANDLE_SUSPEND) {
|
||||
supported = sleep_supported(SLEEP_SUSPEND) > 0;
|
||||
if (supported) {
|
||||
log_notice("Requested %s operation is not supported, using regular suspend instead.",
|
||||
handle_action_to_string(handle));
|
||||
handle = HANDLE_SUSPEND;
|
||||
}
|
||||
}
|
||||
|
||||
if (!supported)
|
||||
if (handle == HANDLE_KEXEC && access(KEXEC, X_OK) < 0)
|
||||
return log_warning_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"Requested %s operation not supported, ignoring.", handle_action_to_string(handle));
|
||||
|
||||
|
@ -235,7 +172,8 @@ int manager_handle_action(
|
|||
inhibit_operation = handle_action_lookup(handle)->inhibit_what;
|
||||
|
||||
/* If the actual operation is inhibited, warn and fail */
|
||||
if (!ignore_inhibited &&
|
||||
if (inhibit_what_is_valid(inhibit_operation) &&
|
||||
!ignore_inhibited &&
|
||||
manager_is_inhibited(m, inhibit_operation, INHIBIT_BLOCK, NULL, false, false, 0, &offending)) {
|
||||
_cleanup_free_ char *comm = NULL, *u = NULL;
|
||||
|
||||
|
@ -264,6 +202,97 @@ int manager_handle_action(
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int handle_action_sleep_execute(
|
||||
Manager *m,
|
||||
HandleAction handle,
|
||||
bool ignore_inhibited,
|
||||
bool is_edge) {
|
||||
|
||||
bool supported;
|
||||
|
||||
assert(m);
|
||||
assert(HANDLE_ACTION_IS_SLEEP(handle));
|
||||
|
||||
if (handle == HANDLE_SUSPEND)
|
||||
supported = sleep_supported(SLEEP_SUSPEND) > 0;
|
||||
else if (handle == HANDLE_HIBERNATE)
|
||||
supported = sleep_supported(SLEEP_HIBERNATE) > 0;
|
||||
else if (handle == HANDLE_HYBRID_SLEEP)
|
||||
supported = sleep_supported(SLEEP_HYBRID_SLEEP) > 0;
|
||||
else if (handle == HANDLE_SUSPEND_THEN_HIBERNATE)
|
||||
supported = sleep_supported(SLEEP_SUSPEND_THEN_HIBERNATE) > 0;
|
||||
else
|
||||
assert_not_reached();
|
||||
|
||||
if (!supported && handle != HANDLE_SUSPEND) {
|
||||
supported = sleep_supported(SLEEP_SUSPEND) > 0;
|
||||
if (supported) {
|
||||
log_notice("Requested %s operation is not supported, using regular suspend instead.",
|
||||
handle_action_to_string(handle));
|
||||
handle = HANDLE_SUSPEND;
|
||||
}
|
||||
}
|
||||
|
||||
if (!supported)
|
||||
return log_warning_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"Requested %s operation not supported, ignoring.", handle_action_to_string(handle));
|
||||
|
||||
return handle_action_execute(m, handle, ignore_inhibited, is_edge);
|
||||
}
|
||||
|
||||
int manager_handle_action(
|
||||
Manager *m,
|
||||
InhibitWhat inhibit_key,
|
||||
HandleAction handle,
|
||||
bool ignore_inhibited,
|
||||
bool is_edge) {
|
||||
|
||||
assert(m);
|
||||
assert(handle_action_valid(handle));
|
||||
|
||||
/* If the key handling is turned off, don't do anything */
|
||||
if (handle == HANDLE_IGNORE) {
|
||||
log_debug("Handling of %s (%s) is disabled, taking no action.",
|
||||
inhibit_key == 0 ? "idle timeout" : inhibit_what_to_string(inhibit_key),
|
||||
is_edge ? "edge" : "level");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (inhibit_key == INHIBIT_HANDLE_LID_SWITCH) {
|
||||
/* If the last system suspend or startup is too close, let's not suspend for now, to give
|
||||
* USB docking stations some time to settle so that we can properly watch its displays. */
|
||||
if (m->lid_switch_ignore_event_source) {
|
||||
log_debug("Ignoring lid switch request, system startup or resume too close.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the key handling is inhibited, don't do anything */
|
||||
if (inhibit_key > 0) {
|
||||
if (manager_is_inhibited(m, inhibit_key, INHIBIT_BLOCK, NULL, true, false, 0, NULL)) {
|
||||
log_debug("Refusing %s operation, %s is inhibited.",
|
||||
handle_action_to_string(handle),
|
||||
inhibit_what_to_string(inhibit_key));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Locking is handled differently from the rest. */
|
||||
if (handle == HANDLE_LOCK) {
|
||||
if (!is_edge)
|
||||
return 0;
|
||||
|
||||
log_info("Locking sessions...");
|
||||
session_send_lock_all(m, true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (HANDLE_ACTION_IS_SLEEP(handle))
|
||||
return handle_action_sleep_execute(m, handle, ignore_inhibited, is_edge);
|
||||
|
||||
return handle_action_execute(m, handle, ignore_inhibited, is_edge);
|
||||
}
|
||||
|
||||
static const char* const handle_action_verb_table[_HANDLE_ACTION_MAX] = {
|
||||
[HANDLE_IGNORE] = "do nothing",
|
||||
[HANDLE_POWEROFF] = "power off",
|
||||
|
|
|
@ -2543,11 +2543,13 @@ static int method_can_shutdown_or_sleep(
|
|||
assert(a);
|
||||
|
||||
if (a->sleep_operation >= 0) {
|
||||
r = sleep_supported(a->sleep_operation);
|
||||
SleepSupport support;
|
||||
|
||||
r = sleep_supported_full(a->sleep_operation, &support);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return sd_bus_reply_method_return(message, "s", "na");
|
||||
return sd_bus_reply_method_return(message, "s", support == SLEEP_DISABLED ? "no" : "na");
|
||||
}
|
||||
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
|
||||
|
|
|
@ -411,7 +411,8 @@ bool manager_is_inhibited(
|
|||
bool inhibited = false;
|
||||
|
||||
assert(m);
|
||||
assert(w > 0 && w < _INHIBIT_WHAT_MAX);
|
||||
assert(w > 0);
|
||||
assert(w < _INHIBIT_WHAT_MAX);
|
||||
|
||||
HASHMAP_FOREACH(i, m->inhibitors) {
|
||||
if (!i->started)
|
||||
|
@ -457,7 +458,7 @@ const char *inhibit_what_to_string(InhibitWhat w) {
|
|||
"handle-reboot-key")+1];
|
||||
char *p;
|
||||
|
||||
if (w < 0 || w >= _INHIBIT_WHAT_MAX)
|
||||
if (!inhibit_what_is_valid(w))
|
||||
return NULL;
|
||||
|
||||
p = buffer;
|
||||
|
|
|
@ -68,6 +68,10 @@ bool inhibitor_is_orphan(Inhibitor *i);
|
|||
InhibitWhat manager_inhibit_what(Manager *m, InhibitMode mm);
|
||||
bool manager_is_inhibited(Manager *m, InhibitWhat w, InhibitMode mm, dual_timestamp *since, bool ignore_inactive, bool ignore_uid, uid_t uid, Inhibitor **offending);
|
||||
|
||||
static inline bool inhibit_what_is_valid(InhibitWhat w) {
|
||||
return w > 0 && w < _INHIBIT_WHAT_MAX;
|
||||
}
|
||||
|
||||
const char *inhibit_what_to_string(InhibitWhat k);
|
||||
int inhibit_what_from_string(const char *s);
|
||||
|
||||
|
|
Loading…
Reference in a new issue