s->timer_event_source = sd_event_source_disable_unref(s->timer_event_source);
s->exec_fd_event_source = sd_event_source_disable_unref(s->exec_fd_event_source);
+ s->bus_name_pid_lookup_slot = sd_bus_slot_unref(s->bus_name_pid_lookup_slot);
+
service_release_resources(u);
}
return 1;
}
+static bool pick_up_pid_from_bus_name(Service *s) {
+ assert(s);
+
+ /* If the service is running but we have no main PID yet, get it from the owner of the D-Bus name */
+
+ return !pid_is_valid(s->main_pid) &&
+ IN_SET(s->state,
+ SERVICE_START,
+ SERVICE_START_POST,
+ SERVICE_RUNNING,
+ SERVICE_RELOAD);
+}
+
+static int bus_name_pid_lookup_callback(sd_bus_message *reply, void *userdata, sd_bus_error *ret_error) {
+ const sd_bus_error *e;
+ Unit *u = userdata;
+ uint32_t pid;
+ Service *s;
+ int r;
+
+ assert(reply);
+ assert(u);
+
+ s = SERVICE(u);
+ s->bus_name_pid_lookup_slot = sd_bus_slot_unref(s->bus_name_pid_lookup_slot);
+
+ if (!s->bus_name || !pick_up_pid_from_bus_name(s))
+ return 1;
+
+ e = sd_bus_message_get_error(reply);
+ if (e) {
+ r = sd_bus_error_get_errno(e);
+ log_warning_errno(r, "GetConnectionUnixProcessID() failed: %s", bus_error_message(e, r));
+ return 1;
+ }
+
+ r = sd_bus_message_read(reply, "u", &pid);
+ if (r < 0) {
+ bus_log_parse_error(r);
+ return 1;
+ }
+
+ if (!pid_is_valid(pid)) {
+ log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "GetConnectionUnixProcessID() returned invalid PID");
+ return 1;
+ }
+
+ log_unit_debug(u, "D-Bus name %s is now owned by process " PID_FMT, s->bus_name, (pid_t) pid);
+
+ service_set_main_pid(s, pid);
+ unit_watch_pid(UNIT(s), pid, false);
+ return 1;
+}
+
static void service_bus_name_owner_change(Unit *u, const char *new_owner) {
Service *s = SERVICE(u);
else if (s->state == SERVICE_START && new_owner)
service_enter_start_post(s);
- } else if (new_owner &&
- s->main_pid <= 0 &&
- IN_SET(s->state,
- SERVICE_START,
- SERVICE_START_POST,
- SERVICE_RUNNING,
- SERVICE_RELOAD)) {
-
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
- pid_t pid;
+ } else if (new_owner && pick_up_pid_from_bus_name(s)) {
/* Try to acquire PID from bus service */
- r = sd_bus_get_name_creds(u->manager->api_bus, s->bus_name, SD_BUS_CREDS_PID, &creds);
- if (r >= 0)
- r = sd_bus_creds_get_pid(creds, &pid);
- if (r >= 0) {
- log_unit_debug(u, "D-Bus name %s is now owned by process " PID_FMT, s->bus_name, pid);
-
- service_set_main_pid(s, pid);
- unit_watch_pid(UNIT(s), pid, false);
- }
+ s->bus_name_pid_lookup_slot = sd_bus_slot_unref(s->bus_name_pid_lookup_slot);
+
+ r = sd_bus_call_method_async(
+ u->manager->api_bus,
+ &s->bus_name_pid_lookup_slot,
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus",
+ "GetConnectionUnixProcessID",
+ bus_name_pid_lookup_callback,
+ s,
+ "s",
+ s->bus_name);
+ if (r < 0)
+ log_debug_errno(r, "Failed to request owner PID of service name, ignoring: %m");
}
}