diff options
author | Thomas Haller <thaller@redhat.com> | 2021-08-06 14:34:24 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2021-08-06 14:34:24 +0200 |
commit | ec126740ceddcfac63d56bcc918efb738c80234d (patch) | |
tree | d8a25d65389bd1b8441506377620c80c81ef7ec5 | |
parent | 17dcef41bdf13f83dd7f5a617609c4e65c610ef5 (diff) | |
parent | 2665fe23c2f93679adfaf4eec7f92be1481b1b20 (diff) | |
download | NetworkManager-ec126740ceddcfac63d56bcc918efb738c80234d.tar.gz |
nm-sudo,dispatcher: merge branch 'th/nm-sudo-cleanup'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/951
-rw-r--r-- | src/libnm-glib-aux/nm-shared-utils.c | 30 | ||||
-rw-r--r-- | src/libnm-glib-aux/nm-shared-utils.h | 2 | ||||
-rw-r--r-- | src/nm-dispatcher/nm-dispatcher.c | 216 | ||||
-rw-r--r-- | src/nm-sudo/nm-sudo.c | 189 |
4 files changed, 277 insertions, 160 deletions
diff --git a/src/libnm-glib-aux/nm-shared-utils.c b/src/libnm-glib-aux/nm-shared-utils.c index f2483da1ad..22354d17df 100644 --- a/src/libnm-glib-aux/nm-shared-utils.c +++ b/src/libnm-glib-aux/nm-shared-utils.c @@ -6548,3 +6548,33 @@ nm_utils_thread_local_register_destroy(gpointer tls_data, GDestroyNotify destroy entry->destroy_notify = destroy_notify; c_list_link_tail(lst_head, &entry->lst); } + +/*****************************************************************************/ + +static gboolean +_iterate_for_msec_timeout(gpointer user_data) +{ + GSource **p_source = user_data; + + nm_clear_g_source_inst(p_source); + return G_SOURCE_CONTINUE; +} + +void +nm_g_main_context_iterate_for_msec(GMainContext *context, guint timeout_msec) +{ + GSource *source; + + /* In production is this function not very useful. It is however useful to + * have in the toolbox for printf debugging. */ + + source = g_timeout_source_new(timeout_msec); + g_source_set_callback(source, _iterate_for_msec_timeout, &source, NULL); + + if (!context) + context = g_main_context_default(); + + g_source_attach(source, context); + while (source) + g_main_context_iteration(context, TRUE); +} diff --git a/src/libnm-glib-aux/nm-shared-utils.h b/src/libnm-glib-aux/nm-shared-utils.h index fd7f7dc309..975897602d 100644 --- a/src/libnm-glib-aux/nm-shared-utils.h +++ b/src/libnm-glib-aux/nm-shared-utils.h @@ -1901,6 +1901,8 @@ nm_g_main_context_iterate_ready(GMainContext *context) } } +void nm_g_main_context_iterate_for_msec(GMainContext *context, guint timeout_msec); + /*****************************************************************************/ static inline int diff --git a/src/nm-dispatcher/nm-dispatcher.c b/src/nm-dispatcher/nm-dispatcher.c index b96cc82ea9..b175d8eed3 100644 --- a/src/nm-dispatcher/nm-dispatcher.c +++ b/src/nm-dispatcher/nm-dispatcher.c @@ -7,15 +7,15 @@ #include "libnm-client-aux-extern/nm-default-client.h" -#include <syslog.h> +#include <arpa/inet.h> +#include <signal.h> #include <stdio.h> -#include <unistd.h> #include <stdlib.h> -#include <sys/types.h> -#include <signal.h> #include <sys/stat.h> +#include <sys/types.h> #include <sys/wait.h> -#include <arpa/inet.h> +#include <syslog.h> +#include <unistd.h> #include "libnm-core-aux-extern/nm-dispatcher-api.h" #include "libnm-glib-aux/nm-dbus-aux.h" @@ -33,29 +33,36 @@ typedef struct Request Request; -static struct { +typedef struct { GDBusConnection *dbus_connection; GCancellable * quit_cancellable; - bool log_verbose; - bool log_stdout; - gboolean persist; - GSource * quit_source; - guint request_id_counter; - guint dbus_regist_id; + + bool log_verbose; + bool log_stdout; + + GSource *source_idle_timeout; gint64 start_timestamp_msec; - bool name_requested; + guint request_id_counter; + guint service_regist_id; + + gboolean persist; + + Request *current_request; + GQueue * requests_waiting; + int num_requests_pending; bool exit_with_failure; + bool name_requested; + bool reject_new_requests; + bool shutdown_timeout; bool shutdown_quitting; +} GlobalData; - Request *current_request; - GQueue * requests_waiting; - int num_requests_pending; -} gl; +GlobalData gl; typedef struct { Request *request; @@ -204,18 +211,20 @@ request_free(Request *request) g_slice_free(Request, request); } +/*****************************************************************************/ + static gboolean -quit_timeout_cb(gpointer user_data) +_idle_timeout_cb(gpointer user_data) { - nm_clear_g_source_inst(&gl.quit_source); + nm_clear_g_source_inst(&gl.source_idle_timeout); gl.shutdown_timeout = TRUE; return G_SOURCE_CONTINUE; } static void -quit_timeout_reschedule(void) +_idle_timeout_restart(void) { - nm_clear_g_source_inst(&gl.quit_source); + nm_clear_g_source_inst(&gl.source_idle_timeout); if (gl.persist) return; @@ -226,9 +235,11 @@ quit_timeout_reschedule(void) if (gl.num_requests_pending > 0) return; - gl.quit_source = nm_g_timeout_add_source(10000, quit_timeout_cb, NULL); + gl.source_idle_timeout = nm_g_timeout_add_source(10000, _idle_timeout_cb, NULL); } +/*****************************************************************************/ + /** * next_request: * @@ -276,7 +287,7 @@ next_request(Request *request) * Checks if all the scripts for the request have terminated and in such case * it sends the D-Bus response and releases the request resources. * - * It also decreases @num_requests_pending and possibly does quit_timeout_reschedule(). + * It also decreases @num_requests_pending and possibly does _idle_timeout_restart(). */ static void complete_request(Request *request) @@ -315,7 +326,7 @@ complete_request(Request *request) nm_assert(gl.num_requests_pending > 0); if (--gl.num_requests_pending <= 0) { nm_assert(!gl.current_request && !g_queue_peek_head(gl.requests_waiting)); - quit_timeout_reschedule(); + _idle_timeout_restart(); } } @@ -693,7 +704,7 @@ script_must_wait(const char *path) } static void -_method_call_action(GDBusMethodInvocation *invocation, GVariant *parameters) +_handle_action(GDBusMethodInvocation *invocation, GVariant *parameters) { const char * action; gs_unref_variant GVariant *connection = NULL; @@ -811,7 +822,7 @@ _method_call_action(GDBusMethodInvocation *invocation, GVariant *parameters) gl.num_requests_pending++; gl.shutdown_timeout = FALSE; - nm_clear_g_source_inst(&gl.quit_source); + nm_clear_g_source_inst(&gl.source_idle_timeout); for (i = 0; i < request->scripts->len; i++) { ScriptInfo *s = g_ptr_array_index(request->scripts, i); @@ -857,7 +868,7 @@ _method_call_action(GDBusMethodInvocation *invocation, GVariant *parameters) } static void -_method_call_ping(GDBusMethodInvocation *invocation, GVariant *parameters) +_handle_ping(GDBusMethodInvocation *invocation, GVariant *parameters) { gs_free char *msg = NULL; gint64 running_msec; @@ -877,22 +888,29 @@ _method_call_ping(GDBusMethodInvocation *invocation, GVariant *parameters) } static void -_method_call(GDBusConnection * connection, - const char * sender, - const char * object_path, - const char * interface_name, - const char * method_name, - GVariant * parameters, - GDBusMethodInvocation *invocation, - gpointer user_data) +_bus_method_call(GDBusConnection * connection, + const char * sender, + const char * object_path, + const char * interface_name, + const char * method_name, + GVariant * parameters, + 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); + _handle_action(invocation, parameters); return; } if (nm_streq(method_name, "Ping")) { - _method_call_ping(invocation, parameters); + _handle_ping(invocation, parameters); return; } } @@ -935,7 +953,7 @@ static gboolean _bus_register_service(void) { static const GDBusInterfaceVTable interface_vtable = { - .method_call = _method_call, + .method_call = _bus_method_call, }; gs_free_error GError * error = NULL; NMDBusConnectionCallBlockingData data = { @@ -944,7 +962,7 @@ _bus_register_service(void) gs_unref_variant GVariant *ret = NULL; guint32 ret_val; - gl.dbus_regist_id = + gl.service_regist_id = g_dbus_connection_register_object(gl.dbus_connection, NM_DISPATCHER_DBUS_PATH, interface_info, @@ -952,7 +970,7 @@ _bus_register_service(void) NULL, NULL, &error); - if (gl.dbus_regist_id == 0) { + if (gl.service_regist_id == 0) { _LOG_X_W("dbus: could not export dispatcher D-Bus interface %s: %s", NM_DISPATCHER_DBUS_PATH, error->message); @@ -1050,7 +1068,7 @@ logging_shutdown(void) } static gboolean -signal_handler(gpointer user_data) +_signal_callback_term(gpointer user_data) { if (!gl.shutdown_quitting) { gl.shutdown_quitting = TRUE; @@ -1060,16 +1078,62 @@ 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 -parse_command_line(int *p_argc, char ***p_argv, GError **error) +_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.source_idle_timeout); + + 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 +_initial_setup(int *p_argc, char ***p_argv, GError **error) { GOptionContext *opt_ctx; gboolean arg_debug = FALSE; @@ -1115,6 +1179,8 @@ parse_command_line(int *p_argc, char ***p_argv, GError **error) return success; } +/*****************************************************************************/ + int main(int argc, char **argv) { @@ -1123,14 +1189,16 @@ main(int argc, char **argv) GSource * source_int = NULL; signal(SIGPIPE, SIG_IGN); - source_term = nm_g_unix_signal_add_source(SIGTERM, signal_handler, GINT_TO_POINTER(SIGTERM)); - source_int = nm_g_unix_signal_add_source(SIGINT, signal_handler, GINT_TO_POINTER(SIGINT)); + source_term = + nm_g_unix_signal_add_source(SIGTERM, _signal_callback_term, GINT_TO_POINTER(SIGTERM)); + source_int = + nm_g_unix_signal_add_source(SIGINT, _signal_callback_term, GINT_TO_POINTER(SIGINT)); gl.start_timestamp_msec = nm_utils_clock_gettime_msec(CLOCK_BOOTTIME); gl.quit_cancellable = g_cancellable_new(); - if (!parse_command_line(&argc, &argv, &error)) { + if (!_initial_setup(&argc, &argv, &error)) { _LOG_X_W("Error parsing command line arguments: %s", error->message); gl.exit_with_failure = TRUE; goto done; @@ -1164,7 +1232,7 @@ main(int argc, char **argv) gl.requests_waiting = g_queue_new(); - quit_timeout_reschedule(); + _idle_timeout_restart(); if (!_bus_register_service()) { /* we failed to start the D-Bus service, and will shut down. However, @@ -1173,68 +1241,39 @@ 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); } done: - nm_g_main_context_iterate_ready(NULL); - gl.shutdown_quitting = TRUE; g_cancellable_cancel(gl.quit_cancellable); nm_assert(gl.num_requests_pending == 0); - if (gl.dbus_regist_id != 0) - g_dbus_connection_unregister_object(gl.dbus_connection, nm_steal_int(&gl.dbus_regist_id)); + if (gl.service_regist_id != 0) { + g_dbus_connection_unregister_object(gl.dbus_connection, + nm_steal_int(&gl.service_regist_id)); + } nm_clear_pointer(&gl.requests_waiting, g_queue_free); - nm_clear_g_source_inst(&gl.quit_source); + nm_clear_g_source_inst(&gl.source_idle_timeout); if (gl.dbus_connection) { g_dbus_connection_flush_sync(gl.dbus_connection, NULL, NULL); @@ -1250,7 +1289,6 @@ done: nm_clear_g_source_inst(&source_term); nm_clear_g_source_inst(&source_int); - g_clear_object(&gl.quit_cancellable); return gl.exit_with_failure ? 1 : 0; diff --git a/src/nm-sudo/nm-sudo.c b/src/nm-sudo/nm-sudo.c index d8cf42f3c8..1e8c941fd0 100644 --- a/src/nm-sudo/nm-sudo.c +++ b/src/nm-sudo/nm-sudo.c @@ -5,12 +5,12 @@ #include <gio/gunixfdlist.h> #include "c-list/src/c-list.h" +#include "libnm-base/nm-sudo-utils.h" #include "libnm-glib-aux/nm-dbus-aux.h" #include "libnm-glib-aux/nm-io-utils.h" #include "libnm-glib-aux/nm-logging-base.h" #include "libnm-glib-aux/nm-shared-utils.h" #include "libnm-glib-aux/nm-time-utils.h" -#include "libnm-base/nm-sudo-utils.h" /* nm-sudo doesn't link with libnm-core nor libnm-base, but these headers * can be used independently. */ @@ -37,28 +37,35 @@ typedef struct { } PendingJobData; struct _GlobalData { - GCancellable * quit_cancellable; GDBusConnection *dbus_connection; - GSource * source_sigterm; + GCancellable * quit_cancellable; + + GSource *source_sigterm; CList pending_jobs_lst_head; GSource *source_idle_timeout; - char * name_owner; - guint name_owner_changed_id; - guint service_regist_id; - gint64 start_timestamp_msec; - guint32 timeout_msec; - bool name_owner_initialized; - bool name_requested; + + char *name_owner; + + gint64 start_timestamp_msec; + + guint name_owner_changed_id; + guint service_regist_id; + + guint32 timeout_msec; + + bool name_owner_initialized; /* This is controlled by $NM_SUDO_NO_AUTH_FOR_TESTING. It disables authentication * of the request, so it is ONLY for testing. */ bool no_auth_for_testing; - bool is_shutting_down_quitting; - bool is_shutting_down_timeout; - bool is_shutting_down_cleanup; + bool name_requested; + bool reject_new_requests; + + bool shutdown_quitting; + bool shutdown_timeout; }; /*****************************************************************************/ @@ -134,7 +141,7 @@ _signal_callback_term(gpointer user_data) _LOGD("sigterm received (%s)", c_list_is_empty(&gl->pending_jobs_lst_head) ? "quit mainloop" : "cancel operations"); - gl->is_shutting_down_quitting = TRUE; + gl->shutdown_quitting = TRUE; g_cancellable_cancel(gl->quit_cancellable); return G_SOURCE_CONTINUE; } @@ -283,7 +290,22 @@ _bus_method_call(GDBusConnection * connection, return; } - _pending_job_register_object(gl, G_OBJECT(invocation)); + if (gl->reject_new_requests) { + /* after the name was released, we must not accept new requests. This new + * request was probably targeted against the unique-name. But we already + * gave up the well-known name. If we'd accept new request now, they would + * keep the service running indefinitely (and thus preventing the service + * to restart and serve the well-known name. */ + _LOGT("dbus: request sender=%s, %s%s, SERVER SHUTTING DOWN", + sender, + method_name, + g_variant_get_type_string(parameters)); + g_dbus_method_invocation_return_error(invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_NO_SERVER, + "Server is exiting"); + return; + } _LOGT("dbus: request sender=%s, %s%s", sender, @@ -399,7 +421,8 @@ _idle_timeout_cb(gpointer user_data) GlobalData *gl = user_data; _LOGT("idle-timeout: expired"); - gl->is_shutting_down_timeout = TRUE; + nm_clear_g_source_inst(&gl->source_idle_timeout); + gl->shutdown_timeout = TRUE; return G_SOURCE_CONTINUE; } @@ -408,10 +431,7 @@ _idle_timeout_restart(GlobalData *gl) { nm_clear_g_source_inst(&gl->source_idle_timeout); - if (gl->is_shutting_down_quitting) - return; - - if (gl->is_shutting_down_cleanup) + if (gl->shutdown_quitting) return; if (!c_list_is_empty(&gl->pending_jobs_lst_head)) @@ -457,7 +477,7 @@ _pending_job_register_object(GlobalData *gl, GObject *obj) PendingJobData *idle_data; /* if we just hit the timeout, we can ignore it. */ - gl->is_shutting_down_timeout = FALSE; + gl->shutdown_timeout = FALSE; if (nm_clear_g_source_inst(&gl->source_idle_timeout)) _LOGT("idle-timeout: suspend timeout for pending request"); @@ -475,11 +495,59 @@ _pending_job_register_object(GlobalData *gl, GObject *obj) static void _bus_release_name_cb(GObject *source, GAsyncResult *result, gpointer user_data) { - _nm_unused gs_unref_object GObject *keep_alive_object = user_data; + _nm_unused gs_unref_object GObject *keep_alive_object = NULL; + GlobalData * gl; + + nm_utils_user_data_unpack(user_data, &gl, &keep_alive_object); + gl->reject_new_requests = TRUE; g_main_context_wakeup(NULL); } +static gboolean +_bus_release_name(GlobalData *gl) +{ + gs_unref_object GObject *keep_alive_object = NULL; + 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; + + _LOGT("shutdown: release-name"); + + keep_alive_object = g_object_new(G_TYPE_OBJECT, NULL); + + /* we use the _pending_job_register_object() mechanism to make the loop busy during + * shutdown. */ + _pending_job_register_object(gl, keep_alive_object); + + r = nm_sd_notify("STOPPING=1"); + if (r < 0) + _LOGW("shutdown: sd_notifiy(STOPPING=1) failed: %s", nm_strerror_native(-r)); + else + _LOGT("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_SUDO_DBUS_BUS_NAME), + G_VARIANT_TYPE("(u)"), + G_DBUS_CALL_FLAGS_NONE, + 10000, + NULL, + _bus_release_name_cb, + nm_utils_user_data_pack(gl, g_steal_pointer(&keep_alive_object))); + return TRUE; +} + /*****************************************************************************/ static void @@ -499,6 +567,8 @@ _initial_setup(GlobalData *gl) gl->source_sigterm = nm_g_unix_signal_add_source(SIGTERM, _signal_callback_term, gl); } +/*****************************************************************************/ + int main(int argc, char **argv) { @@ -553,55 +623,32 @@ main(int argc, char **argv) * Let's fake a shutdown signal, and still process the request below. */ if (!g_cancellable_is_cancelled(gl->quit_cancellable)) exit_code = EXIT_FAILURE; - gl->is_shutting_down_quitting = TRUE; + gl->shutdown_quitting = TRUE; + + if (gl->name_requested) { + /* We requested a name, but something went wrong. Below we will release + * the name right away. */ + } else { + /* In case we didn't even went as far to request the name. New requests + * can only come via the unique name, and as we are shutting down, they + * are rejected. */ + gl->reject_new_requests = TRUE; + } } while (TRUE) { + if (gl->shutdown_quitting) + _bus_release_name(gl); + if (!c_list_is_empty(&gl->pending_jobs_lst_head)) { /* we must first reply to all requests. No matter what. */ - } else if (gl->is_shutting_down_quitting || gl->is_shutting_down_timeout) { + } else if (gl->shutdown_quitting || gl->shutdown_timeout) { /* we either hit the idle timeout or received SIGTERM. Note that * if we received an idle-timeout and the very moment afterwards - * a new request, then _bus_method_call() will clear gl->is_shutting_down_timeout + * a new request, then _bus_method_call() will clear gl->shutdown_timeout * (via _pending_job_register_object()). */ - - if (gl->name_requested) { - gs_unref_object GObject *keep_alive_object = g_object_new(G_TYPE_OBJECT, NULL); - - /* 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->is_shutting_down_quitting = TRUE; - - _LOGT("shutdown: release-name"); - - /* we use the _pending_job_register_object() mechanism to make the loop busy during - * shutdown. */ - _pending_job_register_object(gl, keep_alive_object); - - r = nm_sd_notify("STOPPING=1"); - if (r < 0) - _LOGW("shutdown: sd_notifiy(STOPPING=1) failed: %s", nm_strerror_native(-r)); - else - _LOGT("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_SUDO_DBUS_BUS_NAME), - G_VARIANT_TYPE("(u)"), - G_DBUS_CALL_FLAGS_NONE, - 10000, - NULL, - _bus_release_name_cb, - g_steal_pointer(&keep_alive_object)); - continue; - } - - break; + if (!_bus_release_name(gl)) + break; } g_main_context_iteration(NULL, TRUE); @@ -610,7 +657,7 @@ main(int argc, char **argv) done: _LOGD("shutdown: cleanup"); - gl->is_shutting_down_cleanup = TRUE; + gl->shutdown_quitting = TRUE; g_cancellable_cancel(gl->quit_cancellable); nm_assert(c_list_is_empty(&gl->pending_jobs_lst_head)); @@ -623,19 +670,19 @@ done: g_dbus_connection_signal_unsubscribe(gl->dbus_connection, nm_steal_int(&gl->name_owner_changed_id)); } - nm_clear_g_source_inst(&gl->source_sigterm); - nm_clear_g_source_inst(&gl->source_idle_timeout); - nm_clear_g_free(&gl->name_owner); - - nm_g_main_context_iterate_ready(NULL); if (gl->dbus_connection) { g_dbus_connection_flush_sync(gl->dbus_connection, NULL, NULL); g_clear_object(&gl->dbus_connection); - nm_g_main_context_iterate_ready(NULL); } - nm_clear_g_cancellable(&gl->quit_cancellable); + nm_g_main_context_iterate_ready(NULL); + + nm_clear_g_free(&gl->name_owner); + + nm_clear_g_source_inst(&gl->source_sigterm); + nm_clear_g_source_inst(&gl->source_idle_timeout); + g_clear_object(&gl->quit_cancellable); _LOGD("exit (%d)", exit_code); return exit_code; |