Projects
Mega:23.03
systemd
_service:tar_scm:backport-pid1-lookup-owning-PI...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:backport-pid1-lookup-owning-PID-of-BusName-name-of-services-a.patch of Package systemd
From 1daa382a7f9e55d11f7b59b144a9963688169843 Mon Sep 17 00:00:00 2001 From: Lennart Poettering <lennart@poettering.net> Date: Thu, 17 Feb 2022 14:40:25 +0100 Subject: [PATCH] pid1: lookup owning PID of BusName= name of services asynchronously A first step of removing blocking calls to the D-Bus broker from PID 1. There's a lot more to got (i.e. grep src/core/ for sd_bus_creds basically), but it's a start. Removing blocking calls to D-Bus broker deals systematicallly with deadlocks caused by dbus-daemon blocking on synchronous IPC calls back to PID1 (e.g. Varlink calls through nss-systemd). Bugs such as #15316. Also-see: https://github.com/systemd/systemd/pull/22038#issuecomment-1042958390 (cherry picked from commit e39eb045a502d599e6cd3fda7a46020dd438d018) (cherry picked from commit cf390149cb25248169c482e315a1a7ff02eaf956) Conflict:NA Reference:https://github.com/systemd/systemd/commit/1daa382a7f9e55d11f7b59b144a9963688169843 --- src/core/service.c | 91 ++++++++++++++++++++++++++++++++++++---------- src/core/service.h | 2 + 2 files changed, 74 insertions(+), 19 deletions(-) diff --git a/src/core/service.c b/src/core/service.c index 5f56217904..f6eb46cb54 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -398,6 +398,8 @@ static void service_done(Unit *u) { 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); } @@ -4216,6 +4218,60 @@ static int service_get_timeout(Unit *u, usec_t *timeout) { 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); @@ -4246,28 +4302,25 @@ static void service_bus_name_owner_change(Unit *u, const char *new_owner) { 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"); } } diff --git a/src/core/service.h b/src/core/service.h index 6d931c3d5e..6c47c91f85 100644 --- a/src/core/service.h +++ b/src/core/service.h @@ -185,6 +185,8 @@ struct Service { NotifyAccess notify_access; NotifyState notify_state; + sd_bus_slot *bus_name_pid_lookup_slot; + sd_event_source *exec_fd_event_source; ServiceFDStore *fd_store; -- 2.33.0
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2