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.
}
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;
}
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;
BUS_ERROR_LOAD_FAILED))
return false;
+ sd_bus_error_move(reterr_error, &error);
return r;
}
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;
if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
return false;
+ sd_bus_error_move(reterr_error, &error);
return r;
}
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);