summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2021-08-04 11:33:46 +0200
committerThomas Haller <thaller@redhat.com>2021-08-06 14:32:55 +0200
commit412b5b4fa78fd788f539c8e304faccc82d3d83a2 (patch)
tree7794ba033c5e4a0d4372dc0fdbba8c9ed951829e
parent9f0984c63b4279cb50818e7545fa45a5c7f991ce (diff)
downloadNetworkManager-412b5b4fa78fd788f539c8e304faccc82d3d83a2.tar.gz
dispatcher: reject new requests after releasing name
After we released the well-known name (or if we failed to ever request it), we must exit as fast as possible, so that a new instance can be started to serve new requests. At that point, reject new requests because they are targeted against the unique name, which they should not do (when talking to a D-Bus activated service that exits on idle, it's important to talk to the well-known name). Also, if we receive SIGTERM, start releasing the name. We are told to shut down, and must do so in a timely manner. Again, new requests shall not be served by this instance.
-rw-r--r--src/nm-dispatcher/nm-dispatcher.c100
1 files changed, 63 insertions, 37 deletions
diff --git a/src/nm-dispatcher/nm-dispatcher.c b/src/nm-dispatcher/nm-dispatcher.c
index b96cc82ea9..dba726e4e0 100644
--- a/src/nm-dispatcher/nm-dispatcher.c
+++ b/src/nm-dispatcher/nm-dispatcher.c
@@ -47,6 +47,8 @@ static struct {
bool name_requested;
+ bool reject_new_requests;
+
bool exit_with_failure;
bool shutdown_timeout;
@@ -886,6 +888,13 @@ _method_call(GDBusConnection * connection,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
+ if (gl.reject_new_requests) {
+ g_dbus_method_invocation_return_error(invocation,
+ G_DBUS_ERROR,
+ G_DBUS_ERROR_NO_SERVER,
+ "Server is exiting");
+ return;
+ }
if (nm_streq(interface_name, NM_DISPATCHER_DBUS_INTERFACE)) {
if (nm_streq(method_name, "Action")) {
_method_call_action(invocation, parameters);
@@ -1060,15 +1069,61 @@ signal_handler(gpointer user_data)
return G_SOURCE_CONTINUE;
}
+/*****************************************************************************/
+
static void
_bus_release_name_cb(GObject *source, GAsyncResult *result, gpointer user_data)
{
nm_assert(gl.num_requests_pending > 0);
+ gl.reject_new_requests = TRUE;
gl.num_requests_pending--;
g_main_context_wakeup(NULL);
}
static gboolean
+_bus_release_name(void)
+{
+ int r;
+
+ /* We already requested a name. To exit-on-idle without race, we need to dance.
+ * See https://lists.freedesktop.org/archives/dbus/2015-May/016671.html . */
+
+ if (!gl.name_requested)
+ return FALSE;
+
+ gl.name_requested = FALSE;
+ gl.shutdown_quitting = TRUE;
+
+ _LOG_X_T("shutdown: release-name");
+
+ /* we create a fake pending request. */
+ gl.num_requests_pending++;
+ nm_clear_g_source_inst(&gl.quit_source);
+
+ r = nm_sd_notify("STOPPING=1");
+ if (r < 0)
+ _LOG_X_W("shutdown: sd_notifiy(STOPPING=1) failed: %s", nm_strerror_native(-r));
+ else
+ _LOG_X_T("shutdown: sd_notifiy(STOPPING=1) succeeded");
+
+ g_dbus_connection_call(gl.dbus_connection,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS,
+ "ReleaseName",
+ g_variant_new("(s)", NM_DISPATCHER_DBUS_SERVICE),
+ G_VARIANT_TYPE("(u)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ 10000,
+ NULL,
+ _bus_release_name_cb,
+ NULL);
+ return TRUE;
+}
+
+/*****************************************************************************/
+
+static gboolean
parse_command_line(int *p_argc, char ***p_argv, GError **error)
{
GOptionContext *opt_ctx;
@@ -1173,49 +1228,20 @@ main(int argc, char **argv)
if (!g_cancellable_is_cancelled(gl.quit_cancellable))
gl.exit_with_failure = TRUE;
gl.shutdown_quitting = TRUE;
+
+ if (!gl.name_requested)
+ gl.reject_new_requests = TRUE;
}
while (TRUE) {
+ if (gl.shutdown_quitting)
+ _bus_release_name();
+
if (gl.num_requests_pending > 0) {
/* while we have requests pending, we cannot stop processing them... */
} else if (gl.shutdown_timeout || gl.shutdown_quitting) {
- if (gl.name_requested) {
- int r;
-
- /* We already requested a name. To exit-on-idle without race, we need to dance.
- * See https://lists.freedesktop.org/archives/dbus/2015-May/016671.html . */
-
- gl.name_requested = FALSE;
- gl.shutdown_quitting = TRUE;
-
- _LOG_X_T("shutdown: release-name");
-
- /* we create a fake pending request. */
- gl.num_requests_pending++;
- nm_clear_g_source_inst(&gl.quit_source);
-
- r = nm_sd_notify("STOPPING=1");
- if (r < 0)
- _LOG_X_W("shutdown: sd_notifiy(STOPPING=1) failed: %s", nm_strerror_native(-r));
- else
- _LOG_X_T("shutdown: sd_notifiy(STOPPING=1) succeeded");
-
- g_dbus_connection_call(gl.dbus_connection,
- DBUS_SERVICE_DBUS,
- DBUS_PATH_DBUS,
- DBUS_INTERFACE_DBUS,
- "ReleaseName",
- g_variant_new("(s)", NM_DISPATCHER_DBUS_SERVICE),
- G_VARIANT_TYPE("(u)"),
- G_DBUS_CALL_FLAGS_NONE,
- 10000,
- NULL,
- _bus_release_name_cb,
- NULL);
- continue;
- }
-
- break;
+ if (!_bus_release_name())
+ break;
}
g_main_context_iteration(NULL, TRUE);