Merge pull request #22445 from lnussel/logind

logind: post review fixes
This commit is contained in:
Luca Boccassi
2022-02-14 16:16:39 +00:00
committed by GitHub
5 changed files with 145 additions and 145 deletions
+90 -98
View File
@@ -20,101 +20,99 @@
static const ActionTableItem action_table[_HANDLE_ACTION_MAX] = {
[HANDLE_POWEROFF] = {
SPECIAL_POWEROFF_TARGET,
INHIBIT_SHUTDOWN,
"org.freedesktop.login1.power-off",
"org.freedesktop.login1.power-off-multiple-sessions",
"org.freedesktop.login1.power-off-ignore-inhibit",
_SLEEP_OPERATION_INVALID,
SD_MESSAGE_SHUTDOWN_STR,
"System is powering down",
"power-off",
},
.handle = HANDLE_POWEROFF,
.target = SPECIAL_POWEROFF_TARGET,
.inhibit_what = INHIBIT_SHUTDOWN,
.polkit_action = "org.freedesktop.login1.power-off",
.polkit_action_multiple_sessions = "org.freedesktop.login1.power-off-multiple-sessions",
.polkit_action_ignore_inhibit = "org.freedesktop.login1.power-off-ignore-inhibit",
.sleep_operation = _SLEEP_OPERATION_INVALID,
.message_id = SD_MESSAGE_SHUTDOWN_STR,
.message = "System is powering down",
.log_message = "power-off",
},
[HANDLE_REBOOT] = {
SPECIAL_REBOOT_TARGET,
INHIBIT_SHUTDOWN,
"org.freedesktop.login1.reboot",
"org.freedesktop.login1.reboot-multiple-sessions",
"org.freedesktop.login1.reboot-ignore-inhibit",
_SLEEP_OPERATION_INVALID,
SD_MESSAGE_SHUTDOWN_STR,
"System is rebooting",
"reboot",
},
[HANDLE_HALT] = {
SPECIAL_HALT_TARGET,
INHIBIT_SHUTDOWN,
"org.freedesktop.login1.halt",
"org.freedesktop.login1.halt-multiple-sessions",
"org.freedesktop.login1.halt-ignore-inhibit",
_SLEEP_OPERATION_INVALID,
SD_MESSAGE_SHUTDOWN_STR,
"System is halting",
"halt",
},
[HANDLE_KEXEC] = {
SPECIAL_KEXEC_TARGET,
INHIBIT_SHUTDOWN,
"org.freedesktop.login1.reboot",
"org.freedesktop.login1.reboot-multiple-sessions",
"org.freedesktop.login1.reboot-ignore-inhibit",
_SLEEP_OPERATION_INVALID,
SD_MESSAGE_SHUTDOWN_STR,
"System is rebooting with kexec",
"kexec",
},
[HANDLE_SUSPEND] = {
SPECIAL_SUSPEND_TARGET,
INHIBIT_SLEEP,
"org.freedesktop.login1.suspend",
"org.freedesktop.login1.suspend-multiple-sessions",
"org.freedesktop.login1.suspend-ignore-inhibit",
SLEEP_SUSPEND,
},
[HANDLE_HIBERNATE] = {
SPECIAL_HIBERNATE_TARGET,
INHIBIT_SLEEP,
"org.freedesktop.login1.hibernate",
"org.freedesktop.login1.hibernate-multiple-sessions",
"org.freedesktop.login1.hibernate-ignore-inhibit",
SLEEP_HIBERNATE,
},
[HANDLE_HYBRID_SLEEP] = {
SPECIAL_HYBRID_SLEEP_TARGET,
INHIBIT_SLEEP,
"org.freedesktop.login1.hibernate",
"org.freedesktop.login1.hibernate-multiple-sessions",
"org.freedesktop.login1.hibernate-ignore-inhibit",
SLEEP_HYBRID_SLEEP,
},
[HANDLE_SUSPEND_THEN_HIBERNATE] = {
SPECIAL_SUSPEND_THEN_HIBERNATE_TARGET,
INHIBIT_SLEEP,
"org.freedesktop.login1.hibernate",
"org.freedesktop.login1.hibernate-multiple-sessions",
"org.freedesktop.login1.hibernate-ignore-inhibit",
SLEEP_SUSPEND_THEN_HIBERNATE,
},
[HANDLE_FACTORY_RESET] = {
SPECIAL_FACTORY_RESET_TARGET,
_INHIBIT_WHAT_INVALID,
NULL,
NULL,
NULL,
_SLEEP_OPERATION_INVALID,
SD_MESSAGE_FACTORY_RESET_STR,
"System is performing factory reset",
NULL
},
.handle = HANDLE_REBOOT,
.target = SPECIAL_REBOOT_TARGET,
.inhibit_what = INHIBIT_SHUTDOWN,
.polkit_action = "org.freedesktop.login1.reboot",
.polkit_action_multiple_sessions = "org.freedesktop.login1.reboot-multiple-sessions",
.polkit_action_ignore_inhibit = "org.freedesktop.login1.reboot-ignore-inhibit",
.sleep_operation = _SLEEP_OPERATION_INVALID,
.message_id = SD_MESSAGE_SHUTDOWN_STR,
.message = "System is rebooting",
.log_message = "reboot",
},
[HANDLE_HALT] = {
.handle = HANDLE_HALT,
.target = SPECIAL_HALT_TARGET,
.inhibit_what = INHIBIT_SHUTDOWN,
.polkit_action = "org.freedesktop.login1.halt",
.polkit_action_multiple_sessions = "org.freedesktop.login1.halt-multiple-sessions",
.polkit_action_ignore_inhibit = "org.freedesktop.login1.halt-ignore-inhibit",
.sleep_operation = _SLEEP_OPERATION_INVALID,
.message_id = SD_MESSAGE_SHUTDOWN_STR,
.message = "System is halting",
.log_message = "halt",
},
[HANDLE_KEXEC] = {
.handle = HANDLE_KEXEC,
.target = SPECIAL_KEXEC_TARGET,
.inhibit_what = INHIBIT_SHUTDOWN,
.polkit_action = "org.freedesktop.login1.reboot",
.polkit_action_multiple_sessions = "org.freedesktop.login1.reboot-multiple-sessions",
.polkit_action_ignore_inhibit = "org.freedesktop.login1.reboot-ignore-inhibit",
.sleep_operation = _SLEEP_OPERATION_INVALID,
.message_id = SD_MESSAGE_SHUTDOWN_STR,
.message = "System is rebooting with kexec",
.log_message = "kexec",
},
[HANDLE_SUSPEND] = {
.handle = HANDLE_SUSPEND,
.target = SPECIAL_SUSPEND_TARGET,
.inhibit_what = INHIBIT_SLEEP,
.polkit_action = "org.freedesktop.login1.suspend",
.polkit_action_multiple_sessions = "org.freedesktop.login1.suspend-multiple-sessions",
.polkit_action_ignore_inhibit = "org.freedesktop.login1.suspend-ignore-inhibit",
.sleep_operation = SLEEP_SUSPEND,
},
[HANDLE_HIBERNATE] = {
.handle = HANDLE_HIBERNATE,
.target = SPECIAL_HIBERNATE_TARGET,
.inhibit_what = INHIBIT_SLEEP,
.polkit_action = "org.freedesktop.login1.hibernate",
.polkit_action_multiple_sessions = "org.freedesktop.login1.hibernate-multiple-sessions",
.polkit_action_ignore_inhibit = "org.freedesktop.login1.hibernate-ignore-inhibit",
.sleep_operation = SLEEP_HIBERNATE,
},
[HANDLE_HYBRID_SLEEP] = {
.handle = HANDLE_HYBRID_SLEEP,
.target = SPECIAL_HYBRID_SLEEP_TARGET,
.inhibit_what = INHIBIT_SLEEP,
.polkit_action = "org.freedesktop.login1.hibernate",
.polkit_action_multiple_sessions = "org.freedesktop.login1.hibernate-multiple-sessions",
.polkit_action_ignore_inhibit = "org.freedesktop.login1.hibernate-ignore-inhibit",
.sleep_operation = SLEEP_HYBRID_SLEEP,
},
[HANDLE_SUSPEND_THEN_HIBERNATE] = {
.handle = HANDLE_SUSPEND_THEN_HIBERNATE,
.target = SPECIAL_SUSPEND_THEN_HIBERNATE_TARGET,
.inhibit_what = INHIBIT_SLEEP,
.polkit_action = "org.freedesktop.login1.hibernate",
.polkit_action_multiple_sessions = "org.freedesktop.login1.hibernate-multiple-sessions",
.polkit_action_ignore_inhibit = "org.freedesktop.login1.hibernate-ignore-inhibit",
.sleep_operation = SLEEP_SUSPEND_THEN_HIBERNATE,
},
[HANDLE_FACTORY_RESET] = {
.handle = HANDLE_FACTORY_RESET,
.target = SPECIAL_FACTORY_RESET_TARGET,
.inhibit_what = _INHIBIT_WHAT_INVALID,
.sleep_operation = _SLEEP_OPERATION_INVALID,
.message_id = SD_MESSAGE_FACTORY_RESET_STR,
.message = "System is performing factory reset",
},
};
const char* manager_target_for_action(HandleAction handle) {
assert(handle >= 0);
assert(handle < (ssize_t) ELEMENTSOF(action_table));
return action_table[handle].target;
}
const ActionTableItem* manager_item_for_handle(HandleAction handle) {
assert(handle >= 0);
assert(handle < (ssize_t) ELEMENTSOF(action_table));
@@ -122,12 +120,6 @@ const ActionTableItem* manager_item_for_handle(HandleAction handle) {
return &action_table[handle];
}
HandleAction manager_handle_for_item(const ActionTableItem* a) {
if (a && a < action_table + ELEMENTSOF(action_table))
return a - action_table;
return _HANDLE_ACTION_INVALID;
}
int manager_handle_action(
Manager *m,
InhibitWhat inhibit_key,
+2 -3
View File
@@ -28,6 +28,7 @@ typedef struct ActionTableItem ActionTableItem;
#include "sleep-config.h"
struct ActionTableItem {
HandleAction handle;
const char *target;
InhibitWhat inhibit_what;
const char *polkit_action;
@@ -36,8 +37,7 @@ struct ActionTableItem {
SleepOperation sleep_operation;
const char* message_id;
const char* message;
const char* log_str;
const char* log_message;
};
int manager_handle_action(
@@ -50,7 +50,6 @@ int manager_handle_action(
const char* handle_action_to_string(HandleAction h) _const_;
HandleAction handle_action_from_string(const char *s) _pure_;
const char* manager_target_for_action(HandleAction handle);
const ActionTableItem* manager_item_for_handle(HandleAction handle);
HandleAction manager_handle_for_item(const ActionTableItem* a);
+27 -21
View File
@@ -54,6 +54,15 @@
#include "utmp-wtmp.h"
#include "virt.h"
/* As a random fun fact sysvinit had a 252 (256-(strlen(" \r\n")+1))
* character limit for the wall message.
* https://git.savannah.nongnu.org/cgit/sysvinit.git/tree/src/shutdown.c#n72
* There is no real technical need for that but doesn't make sense
* to store arbitrary amounts either. As we are not stingy here, we
* allow 4k.
*/
#define WALL_MESSAGE_MAX 4096
static void reset_scheduled_shutdown(Manager *m);
static int get_sender_session(
@@ -349,7 +358,7 @@ static int property_get_scheduled_shutdown(
return r;
r = sd_bus_message_append(reply, "st",
handle_action_to_string(manager_handle_for_item(m->scheduled_shutdown_type)),
m->scheduled_shutdown_type ? handle_action_to_string(m->scheduled_shutdown_type->handle) : NULL,
m->scheduled_shutdown_timeout);
if (r < 0)
return r;
@@ -1499,13 +1508,13 @@ static int bus_manager_log_shutdown(
Manager *m,
const ActionTableItem *a) {
const char *message, *log_str;
const char *message, *log_message;
assert(m);
assert(a);
message = a->message;
log_str = a->log_str;
log_message = a->log_message;
if (message)
message = strjoina("MESSAGE=", message);
@@ -1517,13 +1526,13 @@ static int bus_manager_log_shutdown(
else
message = strjoina(message, " (", m->wall_message, ").");
if (log_str)
log_str = strjoina("SHUTDOWN=", log_str);
if (log_message)
log_message = strjoina("SHUTDOWN=", log_message);
return log_struct(LOG_NOTICE,
"MESSAGE_ID=%s", a->message_id ? a->message_id : SD_MESSAGE_SHUTDOWN_STR,
message,
log_str);
log_message);
}
static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
@@ -1884,7 +1893,7 @@ static int method_do_shutdown_or_sleep(
return r;
if ((flags & ~SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_PUBLIC) != 0)
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter");
if (manager_handle_for_item(a) != HANDLE_REBOOT && (flags & SD_LOGIND_REBOOT_VIA_KEXEC))
if (a->handle != HANDLE_REBOOT && (flags & SD_LOGIND_REBOOT_VIA_KEXEC))
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Reboot via kexec is only applicable with reboot operations");
} else {
/* Old style method: no flags parameter, but interactive bool passed as boolean in
@@ -2035,6 +2044,7 @@ static int update_schedule_file(Manager *m) {
int r;
assert(m);
assert(m->scheduled_shutdown_type);
r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0, MKDIR_WARN_MODE);
if (r < 0)
@@ -2052,7 +2062,7 @@ static int update_schedule_file(Manager *m) {
"MODE=%s\n",
m->scheduled_shutdown_timeout,
m->enable_wall_messages,
handle_action_to_string(manager_handle_for_item(m->scheduled_shutdown_type)));
handle_action_to_string(m->scheduled_shutdown_type->handle));
if (!isempty(m->wall_message)) {
_cleanup_free_ char *t = NULL;
@@ -2240,9 +2250,10 @@ static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userd
assert(m);
assert(message);
cancelled = !IN_SET(manager_handle_for_item(m->scheduled_shutdown_type), HANDLE_IGNORE, _HANDLE_ACTION_INVALID);
cancelled = m->scheduled_shutdown_type
&& !IN_SET(m->scheduled_shutdown_type->handle, HANDLE_IGNORE, _HANDLE_ACTION_INVALID);
if (!cancelled)
goto done;
return sd_bus_reply_method_return(message, "b", false);
a = m->scheduled_shutdown_type;
if (!a->polkit_action)
@@ -2281,8 +2292,7 @@ static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userd
username, tty, logind_wall_tty_filter, m);
}
done:
return sd_bus_reply_method_return(message, "b", cancelled);
return sd_bus_reply_method_return(message, "b", true);
}
static int method_can_shutdown_or_sleep(
@@ -2328,7 +2338,7 @@ static int method_can_shutdown_or_sleep(
if (handle >= 0) {
const char *target;
target = manager_target_for_action(handle);
target = manager_item_for_handle(handle)->target;
if (target) {
_cleanup_free_ char *load_state = NULL;
@@ -3115,14 +3125,10 @@ static int method_set_wall_message(
if (r < 0)
return r;
/* sysvinit has a 252 (256-(strlen(" \r\n")+1)) character
* limit for the wall message. There is no real technical
* need for that but doesn't make sense to store arbitrary
* amounts either.
* https://git.savannah.nongnu.org/cgit/sysvinit.git/tree/src/shutdown.c#n72)
*/
if (strlen(wall_message) > 252)
return -EMSGSIZE;
if (strlen(wall_message) > WALL_MESSAGE_MAX)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
"Wall message too long, maximum permitted length is %u characters.",
WALL_MESSAGE_MAX);
/* Short-circuit the operation if the desired state is already in place, to
* avoid an unnecessary polkit permission check. */
+2 -2
View File
@@ -64,7 +64,7 @@ static int warn_wall(Manager *m, usec_t n) {
assert(m);
if (!m->enable_wall_messages)
if (!m->enable_wall_messages || !m->scheduled_shutdown_type)
return 0;
left = m->scheduled_shutdown_timeout > n;
@@ -72,7 +72,7 @@ static int warn_wall(Manager *m, usec_t n) {
r = asprintf(&l, "%s%sThe system is going down for %s %s%s!",
strempty(m->wall_message),
isempty(m->wall_message) ? "" : "\n",
handle_action_to_string(manager_handle_for_item(m->scheduled_shutdown_type)),
handle_action_to_string(m->scheduled_shutdown_type->handle),
left ? "at " : "NOW",
left ? FORMAT_TIMESTAMP(m->scheduled_shutdown_timeout) : "");
if (r < 0) {
+24 -21
View File
@@ -12,6 +12,7 @@
#include "systemctl-compat-halt.h"
#include "systemctl-compat-telinit.h"
#include "systemctl-logind.h"
#include "systemctl-start-unit.h"
#include "systemctl-util.h"
#include "systemctl.h"
#include "terminal-util.h"
@@ -144,30 +145,32 @@ int halt_parse_argv(int argc, char *argv[]) {
int halt_main(void) {
int r;
/* always try logind first */
if (arg_when > 0)
r = logind_schedule_shutdown();
else {
r = logind_check_inhibitors(arg_action);
if (r < 0)
if (arg_force == 0) {
/* always try logind first */
if (arg_when > 0)
r = logind_schedule_shutdown();
else {
r = logind_check_inhibitors(arg_action);
if (r < 0)
return r;
r = logind_reboot(arg_action);
}
if (r >= 0)
return r;
if (IN_SET(r, -EACCES, -EOPNOTSUPP, -EINPROGRESS))
/* Requested operation requires auth, is not supported on the local system or already in
* progress */
return r;
/* on all other errors, try low-level operation */
r = logind_reboot(arg_action);
/* In order to minimize the difference between operation with and without logind, we explicitly
* enable non-blocking mode for this, as logind's shutdown operations are always non-blocking. */
arg_no_block = true;
if (!arg_dry_run)
return start_with_fallback();
}
if (r >= 0)
return r;
if (IN_SET(r, -EACCES, -EOPNOTSUPP, -EINPROGRESS))
/* Requested operation requires auth, is not supported on the local system or already in
* progress */
return r;
/* on all other errors, try low-level operation */
/* In order to minimize the difference between operation with and without logind, we explicitly
* enable non-blocking mode for this, as logind's shutdown operations are always non-blocking. */
arg_no_block = true;
if (!arg_dry_run && !arg_force)
return start_with_fallback();
if (geteuid() != 0) {
(void) must_be_root();