machine: rework machine_gc()

Let's check the leader alive state, and let's log about dbus errors.
This mimics (but is not quite identical to) what we do these days in
logind for GC'ing user sessions.
This commit is contained in:
Lennart Poettering
2025-05-27 10:27:37 +02:00
parent 0c38bc6227
commit ca02f658e0
3 changed files with 33 additions and 10 deletions
+27 -6
View File
@@ -609,22 +609,43 @@ int machine_finalize(Machine *m) {
}
bool machine_may_gc(Machine *m, bool drop_not_started) {
int r;
assert(m);
if (m->class == MACHINE_HOST)
return false;
if (!pidref_is_set(&m->leader))
return true;
if (drop_not_started && !m->started)
return true;
if (m->scope_job && manager_job_is_active(m->manager, m->scope_job))
r = pidref_is_alive(&m->leader);
if (r == -ESRCH)
return true;
if (r < 0)
log_debug_errno(r, "Unable to determine if leader PID " PID_FMT " is still alive, assuming not: %m", m->leader.pid);
if (r > 0)
return false;
if (m->unit && manager_unit_is_active(m->manager, m->unit))
return false;
if (m->scope_job) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
r = manager_job_is_active(m->manager, m->scope_job, &error);
if (r < 0)
log_debug_errno(r, "Failed to determine whether job '%s' is active, assuming it is: %s", m->scope_job, bus_error_message(&error, r));
if (r != 0)
return false;
}
if (m->unit) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
r = manager_unit_is_active(m->manager, m->unit, &error);
if (r < 0)
log_debug_errno(r, "Failed to determine whether unit '%s' is active, assuming it is: %s", m->unit, bus_error_message(&error, r));
if (r != 0)
return false;
}
return true;
}
+4 -2
View File
@@ -1262,7 +1262,7 @@ int manager_kill_unit(Manager *manager, const char *unit, int signo, sd_bus_erro
return bus_call_method(manager->bus, bus_systemd_mgr, "KillUnit", error, NULL, "ssi", unit, "all", signo);
}
int manager_unit_is_active(Manager *manager, const char *unit) {
int manager_unit_is_active(Manager *manager, const char *unit, sd_bus_error *reterr_error) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_free_ char *path = NULL;
@@ -1294,6 +1294,7 @@ int manager_unit_is_active(Manager *manager, const char *unit) {
BUS_ERROR_LOAD_FAILED))
return false;
sd_bus_error_move(reterr_error, &error);
return r;
}
@@ -1304,7 +1305,7 @@ int manager_unit_is_active(Manager *manager, const char *unit) {
return !STR_IN_SET(state, "inactive", "failed");
}
int manager_job_is_active(Manager *manager, const char *path) {
int manager_job_is_active(Manager *manager, const char *path, sd_bus_error *reterr_error) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
int r;
@@ -1329,6 +1330,7 @@ int manager_job_is_active(Manager *manager, const char *path) {
if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
return false;
sd_bus_error_move(reterr_error, &error);
return r;
}
+2 -2
View File
@@ -46,8 +46,8 @@ int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *err
int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
int manager_kill_unit(Manager *manager, const char *unit, int signo, sd_bus_error *error);
int manager_unref_unit(Manager *m, const char *unit, sd_bus_error *error);
int manager_unit_is_active(Manager *manager, const char *unit);
int manager_job_is_active(Manager *manager, const char *path);
int manager_unit_is_active(Manager *manager, const char *unit, sd_bus_error *reterr_errno);
int manager_job_is_active(Manager *manager, const char *path, sd_bus_error *reterr_errno);
int manager_find_machine_for_uid(Manager *m, uid_t host_uid, Machine **ret_machine, uid_t *ret_internal_uid);
int manager_find_machine_for_gid(Manager *m, gid_t host_gid, Machine **ret_machine, gid_t *ret_internal_gid);