logind: add PrepareForShutdownWithMetadata signal
The existing signal doesn't say which type of shutdown is going to happen.
With the introduction of soft-reboot, it is useful to have this information
broadcasted, so that clients can choose to do different things based on the
reboot type.
Add a{sv} as the payload so that more metadata can be added later if
needed, without needing to add yet another signal.
Send both old and new signal for backward compatibility, and send the new
one first so that clients can just wait for the first one on both old and
new systems.
This commit is contained in:
committed by
Luca Boccassi
parent
fd0a804271
commit
e4aab5cf1a
@@ -281,6 +281,8 @@ static const char* const handle_action_verb_table[_HANDLE_ACTION_MAX] = {
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP_TO_STRING(handle_action_verb, HandleAction);
|
||||
|
||||
/* These strings are sent out by PrepareForShutdownWithMetadata signals as metadata, so the values cannot
|
||||
* change as they are public APIs. */
|
||||
static const char* const handle_action_table[_HANDLE_ACTION_MAX] = {
|
||||
[HANDLE_IGNORE] = "ignore",
|
||||
[HANDLE_POWEROFF] = "poweroff",
|
||||
|
||||
+40
-12
@@ -1548,18 +1548,43 @@ int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
|
||||
return r;
|
||||
}
|
||||
|
||||
static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
|
||||
int active = _active;
|
||||
static int send_prepare_for(Manager *m, const HandleActionData *a, bool _active) {
|
||||
int k = 0, r, active = _active;
|
||||
|
||||
assert(m);
|
||||
assert(IN_SET(w, INHIBIT_SHUTDOWN, INHIBIT_SLEEP));
|
||||
assert(a);
|
||||
assert(IN_SET(a->inhibit_what, INHIBIT_SHUTDOWN, INHIBIT_SLEEP));
|
||||
|
||||
return sd_bus_emit_signal(m->bus,
|
||||
"/org/freedesktop/login1",
|
||||
"org.freedesktop.login1.Manager",
|
||||
w == INHIBIT_SHUTDOWN ? "PrepareForShutdown" : "PrepareForSleep",
|
||||
"b",
|
||||
active);
|
||||
/* We need to send both old and new signal for backward compatibility. The newer one allows clients
|
||||
* to know which type of reboot is going to happen, as they might be doing different actions (e.g.:
|
||||
* on soft-reboot), and it is sent first, so that clients know that if they receive the old one
|
||||
* first then they don't have to wait for the new one, as it means it's not supported. So, do not
|
||||
* change the order here, as it is an API. */
|
||||
if (a->inhibit_what == INHIBIT_SHUTDOWN) {
|
||||
k = sd_bus_emit_signal(m->bus,
|
||||
"/org/freedesktop/login1",
|
||||
"org.freedesktop.login1.Manager",
|
||||
"PrepareForShutdownWithMetadata",
|
||||
"ba{sv}",
|
||||
active,
|
||||
1,
|
||||
"type",
|
||||
"s",
|
||||
handle_action_to_string(a->handle));
|
||||
if (k < 0)
|
||||
log_debug_errno(k, "Failed to emit PrepareForShutdownWithMetadata(): %m");
|
||||
}
|
||||
|
||||
r = sd_bus_emit_signal(m->bus,
|
||||
"/org/freedesktop/login1",
|
||||
"org.freedesktop.login1.Manager",
|
||||
a->inhibit_what == INHIBIT_SHUTDOWN ? "PrepareForShutdown" : "PrepareForSleep",
|
||||
"b",
|
||||
active);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to emit PrepareForShutdown(): %m");
|
||||
|
||||
return RET_GATHER(k, r);
|
||||
}
|
||||
|
||||
static int execute_shutdown_or_sleep(
|
||||
@@ -1604,7 +1629,7 @@ static int execute_shutdown_or_sleep(
|
||||
|
||||
error:
|
||||
/* Tell people that they now may take a lock again */
|
||||
(void) send_prepare_for(m, a->inhibit_what, false);
|
||||
(void) send_prepare_for(m, a, false);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -1712,7 +1737,7 @@ int bus_manager_shutdown_or_sleep_now_or_later(
|
||||
a->target, load_state);
|
||||
|
||||
/* Tell everybody to prepare for shutdown/sleep */
|
||||
(void) send_prepare_for(m, a->inhibit_what, true);
|
||||
(void) send_prepare_for(m, a, true);
|
||||
|
||||
delayed =
|
||||
m->inhibit_delay_max > 0 &&
|
||||
@@ -3708,6 +3733,9 @@ static const sd_bus_vtable manager_vtable[] = {
|
||||
SD_BUS_SIGNAL_WITH_ARGS("PrepareForShutdown",
|
||||
SD_BUS_ARGS("b", start),
|
||||
0),
|
||||
SD_BUS_SIGNAL_WITH_ARGS("PrepareForShutdownWithMetadata",
|
||||
SD_BUS_ARGS("b", start, "a{sv}", metadata),
|
||||
0),
|
||||
SD_BUS_SIGNAL_WITH_ARGS("PrepareForSleep",
|
||||
SD_BUS_ARGS("b", start),
|
||||
0),
|
||||
@@ -3763,7 +3791,7 @@ int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *err
|
||||
log_info("Operation '%s' finished.", inhibit_what_to_string(m->delayed_action->inhibit_what));
|
||||
|
||||
/* Tell people that they now may take a lock again */
|
||||
(void) send_prepare_for(m, m->delayed_action->inhibit_what, false);
|
||||
(void) send_prepare_for(m, m->delayed_action, false);
|
||||
|
||||
m->action_job = mfree(m->action_job);
|
||||
m->delayed_action = NULL;
|
||||
|
||||
Reference in New Issue
Block a user