run: Ref() the unit again after reconnecting to the bus
Follow-up for c8f59296bf
Currently, the unit is only reffed in transient_unit_set_properties()
via AddRef(), which however would be dropped if a reconnection
is attempted. Make sure to explicitly re-add reference in that case.
This commit is contained in:
+46
-17
@@ -1646,32 +1646,42 @@ static int on_retry_timer(sd_event_source *s, uint64_t usec, void *userdata) {
|
||||
}
|
||||
|
||||
static int run_context_reconnect(RunContext *c) {
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
|
||||
int r;
|
||||
|
||||
assert(c);
|
||||
|
||||
run_context_detach_bus(c);
|
||||
|
||||
_cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
|
||||
r = connect_bus(&bus);
|
||||
if (r < 0)
|
||||
goto retry_timer;
|
||||
|
||||
r = sd_bus_call_method(bus,
|
||||
"org.freedesktop.systemd1",
|
||||
c->bus_path,
|
||||
"org.freedesktop.systemd1.Unit",
|
||||
"Ref",
|
||||
&error,
|
||||
/* reply = */ NULL, NULL);
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Failed to reconnect, retrying in 2s: %m");
|
||||
/* Hmm, the service manager probably hasn't finished reexecution just yet? Try again later. */
|
||||
if (sd_bus_error_has_names(&error,
|
||||
SD_BUS_ERROR_NO_REPLY,
|
||||
SD_BUS_ERROR_DISCONNECTED,
|
||||
SD_BUS_ERROR_TIMED_OUT,
|
||||
SD_BUS_ERROR_SERVICE_UNKNOWN,
|
||||
SD_BUS_ERROR_NAME_HAS_NO_OWNER))
|
||||
goto retry_timer;
|
||||
|
||||
r = event_reset_time_relative(
|
||||
c->event,
|
||||
&c->retry_timer,
|
||||
CLOCK_MONOTONIC,
|
||||
2 * USEC_PER_SEC, /* accuracy= */ 0,
|
||||
on_retry_timer, c,
|
||||
SD_EVENT_PRIORITY_NORMAL,
|
||||
"retry-timeout",
|
||||
/* force_reset= */ false);
|
||||
if (r < 0) {
|
||||
(void) sd_event_exit(c->event, EXIT_FAILURE);
|
||||
return log_error_errno(r, "Failed to install retry timer: %m");
|
||||
}
|
||||
if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
|
||||
log_warning_errno(r, "Unit deactivated during reconnection to the bus, exiting.");
|
||||
else
|
||||
log_error_errno(r, "Failed to re-add reference to unit: %s", bus_error_message(&error, r));
|
||||
|
||||
return 0;
|
||||
(void) sd_event_exit(c->event, EXIT_FAILURE);
|
||||
return r;
|
||||
}
|
||||
|
||||
r = run_context_attach_bus(c, bus);
|
||||
@@ -1683,6 +1693,25 @@ static int run_context_reconnect(RunContext *c) {
|
||||
log_info("Reconnected to bus.");
|
||||
|
||||
return run_context_update(c);
|
||||
|
||||
retry_timer:
|
||||
log_warning_errno(r, "Failed to reconnect, retrying in 2s: %m");
|
||||
|
||||
r = event_reset_time_relative(
|
||||
c->event,
|
||||
&c->retry_timer,
|
||||
CLOCK_MONOTONIC,
|
||||
2 * USEC_PER_SEC, /* accuracy= */ 0,
|
||||
on_retry_timer, c,
|
||||
SD_EVENT_PRIORITY_NORMAL,
|
||||
"retry-timeout",
|
||||
/* force_reset= */ false);
|
||||
if (r < 0) {
|
||||
(void) sd_event_exit(c->event, EXIT_FAILURE);
|
||||
return log_error_errno(r, "Failed to install retry timer: %m");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int run_context_check_started(RunContext *c) {
|
||||
@@ -1792,7 +1821,7 @@ static int run_context_update(RunContext *c) {
|
||||
SD_BUS_ERROR_SERVICE_UNKNOWN,
|
||||
SD_BUS_ERROR_NAME_HAS_NO_OWNER)) {
|
||||
|
||||
log_info("Bus call failed due to connection problems. Trying to reconnect...");
|
||||
log_info_errno(r, "Bus call failed due to connection problems. Trying to reconnect...");
|
||||
/* Not propagating error, because we handled it already, by reconnecting. */
|
||||
return run_context_reconnect(c);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user