summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.c5
-rw-r--r--src/nm-dbus-manager.c42
-rw-r--r--src/nm-dbus-manager.h4
-rw-r--r--src/nm-dbus-object.c13
-rw-r--r--src/nm-dbus-object.h4
-rw-r--r--src/nm-dbus-utils.h1
-rw-r--r--src/nm-iface-helper.c6
-rw-r--r--src/nm-manager.c3
8 files changed, 53 insertions, 25 deletions
diff --git a/src/main.c b/src/main.c
index fbfba4a16e..714d7bcf46 100644
--- a/src/main.c
+++ b/src/main.c
@@ -443,11 +443,6 @@ done:
* it misses to update the state. */
nm_manager_write_device_state (manager);
- /* FIXME(shutdown): we don't properly shut down on exit. That is a bug.
- * NMDBusObject have an assertion that they get unexported before disposing.
- * We need this workaround and disable the assertion during our leaky shutdown. */
- nm_dbus_object_set_quitting ();
-
nm_manager_stop (manager);
nm_config_state_set (config, TRUE, TRUE);
diff --git a/src/nm-dbus-manager.c b/src/nm-dbus-manager.c
index 060ae81d83..7f1121f650 100644
--- a/src/nm-dbus-manager.c
+++ b/src/nm-dbus-manager.c
@@ -83,7 +83,8 @@ typedef struct {
GDBusConnection *connection;
GDBusProxy *proxy;
guint objmgr_registration_id;
- gboolean started;
+ bool started:1;
+ bool shutting_down:1;
} NMDBusManagerPrivate;
struct _NMDBusManager {
@@ -788,6 +789,8 @@ dbus_vtable_method_call (GDBusConnection *connection,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
+ NMDBusManager *self;
+ NMDBusManagerPrivate *priv;
RegistrationData *reg_data = user_data;
NMDBusObject *obj = reg_data->obj;
const NMDBusInterfaceInfoExtended *interface_info = _reg_data_get_interface_info (reg_data);
@@ -800,13 +803,14 @@ dbus_vtable_method_call (GDBusConnection *connection,
if ( !on_same_interface
&& nm_streq (interface_name, DBUS_INTERFACE_PROPERTIES)
&& nm_streq (method_name, "Set")) {
- NMDBusManager *self = nm_dbus_object_get_manager (obj);
- NMDBusManagerPrivate *priv = NM_DBUS_MANAGER_GET_PRIVATE (self);
const NMDBusPropertyInfoExtended *property_info = NULL;
const char *property_interface;
const char *property_name;
gs_unref_variant GVariant *value = NULL;
+ self = nm_dbus_object_get_manager (obj);
+ priv = NM_DBUS_MANAGER_GET_PRIVATE (self);
+
g_variant_get (parameters, "(&s&sv)", &property_interface, &property_name, &value);
nm_assert (nm_streq (property_interface, interface_info->parent.name));
@@ -851,6 +855,17 @@ dbus_vtable_method_call (GDBusConnection *connection,
return;
}
+ self = nm_dbus_object_get_manager (obj);
+ priv = NM_DBUS_MANAGER_GET_PRIVATE (self);
+ if ( priv->shutting_down
+ && !method_info->allow_during_shutdown) {
+ g_dbus_method_invocation_return_error_literal (invocation,
+ G_DBUS_ERROR,
+ G_DBUS_ERROR_FAILED,
+ "NetworkManager is exiting");
+ return;
+ }
+
method_info->handle (reg_data->obj,
interface_info,
method_info,
@@ -1574,6 +1589,27 @@ nm_dbus_manager_acquire_bus (NMDBusManager *self)
return TRUE;
}
+void
+nm_dbus_manager_stop (NMDBusManager *self)
+{
+ NMDBusManagerPrivate *priv = NM_DBUS_MANAGER_GET_PRIVATE (self);
+
+ priv->shutting_down = TRUE;
+
+ /* during shutdown we also clear the set-property-handler. It's no longer
+ * possible to set a property, because doing so would require authorization,
+ * which is async, which is just complicated to get right. No more property
+ * setting from now on. */
+ priv->set_property_handler = NULL;
+ priv->set_property_handler_data = NULL;
+}
+
+gboolean
+nm_dbus_manager_is_stopping (NMDBusManager *self)
+{
+ return NM_DBUS_MANAGER_GET_PRIVATE (self)->shutting_down;
+}
+
/*****************************************************************************/
static void
diff --git a/src/nm-dbus-manager.h b/src/nm-dbus-manager.h
index cacda966f6..a07413168d 100644
--- a/src/nm-dbus-manager.h
+++ b/src/nm-dbus-manager.h
@@ -55,6 +55,10 @@ void nm_dbus_manager_start (NMDBusManager *self,
NMDBusManagerSetPropertyHandler set_property_handler,
gpointer set_property_handler_data);
+void nm_dbus_manager_stop (NMDBusManager *self);
+
+gboolean nm_dbus_manager_is_stopping (NMDBusManager *self);
+
GDBusConnection *nm_dbus_manager_get_connection (NMDBusManager *self);
NMDBusObject *nm_dbus_manager_lookup_object (NMDBusManager *self, const char *path);
diff --git a/src/nm-dbus-object.c b/src/nm-dbus-object.c
index 514fda4977..e92a8f5fa5 100644
--- a/src/nm-dbus-object.c
+++ b/src/nm-dbus-object.c
@@ -26,17 +26,6 @@
/*****************************************************************************/
-static gboolean quitting = FALSE;
-
-void
-nm_dbus_object_set_quitting (void)
-{
- nm_assert (!quitting);
- quitting = TRUE;
-}
-
-/*****************************************************************************/
-
enum {
EXPORTED_CHANGED,
@@ -291,7 +280,7 @@ dispose (GObject *object)
* we are quitting, where many objects stick around until exit.
*/
if (self->internal.path) {
- if (!quitting)
+ if (!nm_dbus_manager_is_stopping (nm_dbus_object_get_manager (self)))
g_warn_if_reached ();
nm_dbus_object_unexport (self);
}
diff --git a/src/nm-dbus-object.h b/src/nm-dbus-object.h
index 43613630bb..8b3ffdbded 100644
--- a/src/nm-dbus-object.h
+++ b/src/nm-dbus-object.h
@@ -28,10 +28,6 @@
/*****************************************************************************/
-void nm_dbus_object_set_quitting (void);
-
-/*****************************************************************************/
-
typedef struct {
const char *path;
diff --git a/src/nm-dbus-utils.h b/src/nm-dbus-utils.h
index e7e930e938..1f8e96c4c9 100644
--- a/src/nm-dbus-utils.h
+++ b/src/nm-dbus-utils.h
@@ -122,6 +122,7 @@ typedef struct _NMDBusMethodInfoExtended {
const char *sender,
GDBusMethodInvocation *invocation,
GVariant *parameters);
+ bool allow_during_shutdown;
} NMDBusMethodInfoExtended;
#define NM_DEFINE_DBUS_METHOD_INFO_EXTENDED(parent_, ...) \
diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c
index 601c72acac..58d766c124 100644
--- a/src/nm-iface-helper.c
+++ b/src/nm-iface-helper.c
@@ -635,6 +635,12 @@ nm_dbus_manager_get (void)
return NULL;
}
+gboolean
+nm_dbus_manager_is_stopping (NMDBusManager *self)
+{
+ return FALSE;
+}
+
void
_nm_dbus_manager_obj_export (NMDBusObject *obj)
{
diff --git a/src/nm-manager.c b/src/nm-manager.c
index fd341538a3..0ffc33f385 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -5918,7 +5918,6 @@ nm_manager_stop (NMManager *self)
NMDevice *device;
/* FIXME(shutdown): we don't do a proper shutdown yet:
- * - need to tell NMDBusManager that all future D-Bus requests are rejected
* - need to ensure that all pending async operations are cancelled
* - e.g. operations in priv->async_op_lst_head
* - need to ensure that no more asynchronous requests are started,
@@ -5931,6 +5930,8 @@ nm_manager_stop (NMManager *self)
* - e.g. see comment at nm_auth_manager_force_shutdown()
*/
+ nm_dbus_manager_stop (nm_dbus_object_get_manager (NM_DBUS_OBJECT (self)));
+
while ((device = c_list_first_entry (&priv->devices_lst_head, NMDevice, devices_lst)))
remove_device (self, device, TRUE, TRUE);