logind: make sure when we are explicitly asked to terminate session/user/seat to use "replace" job mode

Otherwise our request will possibly fail if something else is already
enqeued, but given this is an explicit user request, let's not allow
things to fail.

Fixes: #16702
This commit is contained in:
Lennart Poettering 2020-09-11 18:06:59 +02:00
parent bda625730d
commit 1a42ce0920
4 changed files with 10 additions and 10 deletions

View File

@ -4072,13 +4072,13 @@ int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error,
return strdup_job(reply, job);
}
int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
int manager_stop_unit(Manager *manager, const char *unit, const char *job_mode, sd_bus_error *error, char **ret_job) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
int r;
assert(manager);
assert(unit);
assert(job);
assert(ret_job);
r = bus_call_method(
manager->bus,
@ -4086,12 +4086,12 @@ int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, c
"StopUnit",
error,
&reply,
"ss", unit, "fail");
"ss", unit, job_mode ?: "fail");
if (r < 0) {
if (sd_bus_error_has_names(error, BUS_ERROR_NO_SUCH_UNIT,
BUS_ERROR_LOAD_FAILED)) {
*job = NULL;
*ret_job = NULL;
sd_bus_error_free(error);
return 0;
}
@ -4099,7 +4099,7 @@ int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, c
return r;
}
return strdup_job(reply, job);
return strdup_job(reply, ret_job);
}
int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *ret_error) {

View File

@ -25,7 +25,7 @@ int manager_send_changed(Manager *manager, const char *property, ...) _sentinel_
int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, char **wants, char **after, const char *requires_mounts_for, sd_bus_message *more_properties, sd_bus_error *error, char **job);
int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
int manager_stop_unit(Manager *manager, const char *unit, const char *job_mode, sd_bus_error *error, char **job);
int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error);
int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error);
int manager_unit_is_active(Manager *manager, const char *unit, sd_bus_error *error);

View File

@ -768,7 +768,7 @@ static int session_stop_scope(Session *s, bool force) {
(s->user->user_record->kill_processes > 0 ||
manager_shall_kill(s->manager, s->user->user_record->user_name)))) {
r = manager_stop_unit(s->manager, s->scope, &error, &s->scope_job);
r = manager_stop_unit(s->manager, s->scope, force ? "replace" : "fail", &error, &s->scope_job);
if (r < 0) {
if (force)
return log_error_errno(r, "Failed to stop session scope: %s", bus_error_message(&error, r));

View File

@ -475,7 +475,7 @@ int user_start(User *u) {
return 0;
}
static void user_stop_service(User *u) {
static void user_stop_service(User *u, bool force) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
int r;
@ -487,7 +487,7 @@ static void user_stop_service(User *u) {
u->service_job = mfree(u->service_job);
r = manager_stop_unit(u->manager, u->service, &error, &u->service_job);
r = manager_stop_unit(u->manager, u->service, force ? "replace" : "fail", &error, &u->service_job);
if (r < 0)
log_warning_errno(r, "Failed to stop user service '%s', ignoring: %s", u->service, bus_error_message(&error, r));
}
@ -518,7 +518,7 @@ int user_stop(User *u, bool force) {
r = k;
}
user_stop_service(u);
user_stop_service(u, force);
u->stopping = true;