summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2013-03-05 09:16:47 -0600
committerDan Williams <dcbw@redhat.com>2013-04-08 11:30:32 -0500
commit110a40358d26fa05604c59ecc1584635e40347b6 (patch)
treee19747e3829af2f97b937ed6a7137d15bfde0f23
parent4a21eb08dbf3a3589e27ab2f8973795cdad30a9f (diff)
downloadNetworkManager-110a40358d26fa05604c59ecc1584635e40347b6.tar.gz
libnm-glib: never call NM D-Bus methods if NM isn't running
Though the client shouldn't be calling anything when NM isn't running (because clients have nm_client_get_manager_running()), make sure that NMClient never calls a NetworkManager method when NM isn't on the bus. Next, ensure NMObject doesn't try to refresh properties when NM isn't running. Creating an NMClient may trigger a property refresh request, but if NM isn't running, defer that until NM starts, to ensure that we don't D-Bus autostart NM. Third, ensure NMRemoteSettings doesn't attempt to list connections unless NM is running. This prevents service activation of NetworkManager in lieu of dbus-glib learning about DBUS_HEADER_FLAG_NO_AUTO_START.
-rw-r--r--libnm-glib/libnm-glib.ver2
-rw-r--r--libnm-glib/nm-client.c142
-rw-r--r--libnm-glib/nm-client.h16
-rw-r--r--libnm-glib/nm-object.c133
-rw-r--r--libnm-glib/nm-remote-settings.c101
-rw-r--r--libnm-glib/nm-secret-agent.c11
6 files changed, 296 insertions, 109 deletions
diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver
index e17e368f75..1848171e6e 100644
--- a/libnm-glib/libnm-glib.ver
+++ b/libnm-glib/libnm-glib.ver
@@ -32,6 +32,8 @@ global:
nm_client_activate_connection;
nm_client_add_and_activate_connection;
nm_client_deactivate_connection;
+ nm_client_error_get_type;
+ nm_client_error_quark;
nm_client_get_active_connections;
nm_client_get_device_by_iface;
nm_client_get_device_by_path;
diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c
index b42eaecd4a..4f7d1ed692 100644
--- a/libnm-glib/nm-client.c
+++ b/libnm-glib/nm-client.c
@@ -116,6 +116,29 @@ static void proxy_name_owner_changed (DBusGProxy *proxy,
static void client_device_added (NMObject *client, NMObject *device);
static void client_device_removed (NMObject *client, NMObject *device);
+/**********************************************************************/
+
+/**
+ * nm_client_error_quark:
+ *
+ * Registers an error quark for #NMClient if necessary.
+ *
+ * Returns: the error quark used for #NMClient errors.
+ *
+ * Since: 0.9.10
+ **/
+GQuark
+nm_client_error_quark (void)
+{
+ static GQuark quark;
+
+ if (G_UNLIKELY (!quark))
+ quark = g_quark_from_static_string ("nm-client-error-quark");
+ return quark;
+}
+
+/**********************************************************************/
+
static void
nm_client_init (NMClient *client)
{
@@ -427,12 +450,15 @@ typedef struct {
NMClientAddActivateFn add_act_fn;
char *active_path;
char *new_connection_path;
+ guint idle_id;
gpointer user_data;
} ActivateInfo;
static void
activate_info_free (ActivateInfo *info)
{
+ if (info->idle_id)
+ g_source_remove (info->idle_id);
g_free (info->active_path);
g_free (info->new_connection_path);
memset (info, 0, sizeof (*info));
@@ -535,6 +561,23 @@ activate_cb (DBusGProxy *proxy,
}
}
+static gboolean
+activate_nm_not_running (gpointer user_data)
+{
+ ActivateInfo *info = user_data;
+ GError *error;
+
+ info->idle_id = 0;
+
+ error = g_error_new_literal (NM_CLIENT_ERROR,
+ NM_CLIENT_ERROR_MANAGER_NOT_RUNNING,
+ "NetworkManager is not running");
+ activate_info_complete (info, NULL, error);
+ activate_info_free (info);
+ g_clear_error (&error);
+ return FALSE;
+}
+
/**
* nm_client_activate_connection:
* @client: a #NMClient
@@ -582,6 +625,11 @@ nm_client_activate_connection (NMClient *client,
priv = NM_CLIENT_GET_PRIVATE (client);
priv->pending_activations = g_slist_prepend (priv->pending_activations, info);
+ if (priv->manager_running == FALSE) {
+ info->idle_id = g_idle_add (activate_nm_not_running, info);
+ return;
+ }
+
dbus_g_proxy_begin_call (priv->client_proxy, "ActivateConnection",
activate_cb, info, NULL,
DBUS_TYPE_G_OBJECT_PATH, nm_connection_get_path (connection),
@@ -664,12 +712,16 @@ nm_client_add_and_activate_connection (NMClient *client,
priv = NM_CLIENT_GET_PRIVATE (client);
priv->pending_activations = g_slist_prepend (priv->pending_activations, info);
- dbus_g_proxy_begin_call (priv->client_proxy, "AddAndActivateConnection",
- add_activate_cb, info, NULL,
- DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, hash,
- DBUS_TYPE_G_OBJECT_PATH, nm_object_get_path (NM_OBJECT (device)),
- DBUS_TYPE_G_OBJECT_PATH, specific_object ? specific_object : "/",
- G_TYPE_INVALID);
+ if (priv->manager_running) {
+ dbus_g_proxy_begin_call (priv->client_proxy, "AddAndActivateConnection",
+ add_activate_cb, info, NULL,
+ DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, hash,
+ DBUS_TYPE_G_OBJECT_PATH, nm_object_get_path (NM_OBJECT (device)),
+ DBUS_TYPE_G_OBJECT_PATH, specific_object ? specific_object : "/",
+ G_TYPE_INVALID);
+ } else
+ info->idle_id = g_idle_add (activate_nm_not_running, info);
+
g_hash_table_unref (hash);
}
@@ -703,8 +755,10 @@ nm_client_deactivate_connection (NMClient *client, NMActiveConnection *active)
g_return_if_fail (NM_IS_CLIENT (client));
g_return_if_fail (NM_IS_ACTIVE_CONNECTION (active));
- // FIXME: return errors
priv = NM_CLIENT_GET_PRIVATE (client);
+ if (!priv->manager_running)
+ return;
+
path = nm_object_get_path (NM_OBJECT (active));
if (!dbus_g_proxy_call (priv->client_proxy, "DeactivateConnection", &error,
DBUS_TYPE_G_OBJECT_PATH, path,
@@ -772,13 +826,16 @@ nm_client_wireless_set_enabled (NMClient *client, gboolean enabled)
g_return_if_fail (NM_IS_CLIENT (client));
+ if (!NM_CLIENT_GET_PRIVATE (client)->manager_running)
+ return;
+
g_value_init (&value, G_TYPE_BOOLEAN);
g_value_set_boolean (&value, enabled);
_nm_object_set_property (NM_OBJECT (client),
- NM_DBUS_INTERFACE,
- "WirelessEnabled",
- &value);
+ NM_DBUS_INTERFACE,
+ "WirelessEnabled",
+ &value);
}
/**
@@ -829,6 +886,9 @@ nm_client_wwan_set_enabled (NMClient *client, gboolean enabled)
g_return_if_fail (NM_IS_CLIENT (client));
+ if (!NM_CLIENT_GET_PRIVATE (client)->manager_running)
+ return;
+
g_value_init (&value, G_TYPE_BOOLEAN);
g_value_set_boolean (&value, enabled);
@@ -886,6 +946,9 @@ nm_client_wimax_set_enabled (NMClient *client, gboolean enabled)
g_return_if_fail (NM_IS_CLIENT (client));
+ if (!NM_CLIENT_GET_PRIVATE (client)->manager_running)
+ return;
+
g_value_init (&value, G_TYPE_BOOLEAN);
g_value_set_boolean (&value, enabled);
@@ -985,6 +1048,9 @@ nm_client_networking_set_enabled (NMClient *client, gboolean enable)
g_return_if_fail (NM_IS_CLIENT (client));
+ if (!NM_CLIENT_GET_PRIVATE (client)->manager_running)
+ return;
+
if (!dbus_g_proxy_call (NM_CLIENT_GET_PRIVATE (client)->client_proxy, "Enable", &err,
G_TYPE_BOOLEAN, enable,
G_TYPE_INVALID,
@@ -1062,28 +1128,30 @@ nm_client_get_permission_result (NMClient *client, NMClientPermission permission
gboolean
nm_client_get_logging (NMClient *client, char **level, char **domains, GError **error)
{
- GError *err = NULL;
+ NMClientPrivate *priv;
g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
g_return_val_if_fail (level == NULL || *level == NULL, FALSE);
g_return_val_if_fail (domains == NULL || *domains == NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
- if (!level && !domains)
- return TRUE;
-
- if (!dbus_g_proxy_call (NM_CLIENT_GET_PRIVATE (client)->client_proxy, "GetLogging", &err,
- G_TYPE_INVALID,
- G_TYPE_STRING, level,
- G_TYPE_STRING, domains,
- G_TYPE_INVALID)) {
- if (error)
- *error = g_error_copy (err);
- g_error_free (err);
+ priv = NM_CLIENT_GET_PRIVATE (client);
+ if (!priv->manager_running) {
+ g_set_error_literal (error,
+ NM_CLIENT_ERROR,
+ NM_CLIENT_ERROR_MANAGER_NOT_RUNNING,
+ "NetworkManager is not running");
return FALSE;
}
- return TRUE;
+ if (!level && !domains)
+ return TRUE;
+
+ return dbus_g_proxy_call (priv->client_proxy, "GetLogging", error,
+ G_TYPE_INVALID,
+ G_TYPE_STRING, level,
+ G_TYPE_STRING, domains,
+ G_TYPE_INVALID);
}
/**
@@ -1103,26 +1171,28 @@ nm_client_get_logging (NMClient *client, char **level, char **domains, GError **
gboolean
nm_client_set_logging (NMClient *client, const char *level, const char *domains, GError **error)
{
- GError *err = NULL;
+ NMClientPrivate *priv;
g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
- if (!level && !domains)
- return TRUE;
-
- if (!dbus_g_proxy_call (NM_CLIENT_GET_PRIVATE (client)->client_proxy, "SetLogging", &err,
- G_TYPE_STRING, level ? level : "",
- G_TYPE_STRING, domains ? domains : "",
- G_TYPE_INVALID,
- G_TYPE_INVALID)) {
- if (error)
- *error = g_error_copy (err);
- g_error_free (err);
+ priv = NM_CLIENT_GET_PRIVATE (client);
+ if (!priv->manager_running) {
+ g_set_error_literal (error,
+ NM_CLIENT_ERROR,
+ NM_CLIENT_ERROR_MANAGER_NOT_RUNNING,
+ "NetworkManager is not running");
return FALSE;
}
- return TRUE;
+ if (!level && !domains)
+ return TRUE;
+
+ return dbus_g_proxy_call (priv->client_proxy, "SetLogging", error,
+ G_TYPE_STRING, level ? level : "",
+ G_TYPE_STRING, domains ? domains : "",
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
}
/****************************************************************/
diff --git a/libnm-glib/nm-client.h b/libnm-glib/nm-client.h
index 6c83e4cebe..96c7d9866e 100644
--- a/libnm-glib/nm-client.h
+++ b/libnm-glib/nm-client.h
@@ -120,6 +120,22 @@ typedef enum {
NM_CLIENT_PERMISSION_RESULT_NO
} NMClientPermissionResult;
+/**
+ * NMClientError:
+ * @NM_CLIENT_ERROR_UNKNOWN: unknown or unclassified error
+ * @NM_CLIENT_ERROR_CONNECTION_REMOVED: an operation that requires NetworkManager
+ * failed because NetworkManager is not running
+ *
+ * Describes errors that may result from operations involving a #NMClient.
+ *
+ **/
+typedef enum {
+ NM_CLIENT_ERROR_UNKNOWN = 0, /*< nick=UnknownError >*/
+ NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, /*< nick=ManagerNotRunning >*/
+} NMClientError;
+
+#define NM_CLIENT_ERROR nm_client_error_quark ()
+GQuark nm_client_error_quark (void);
typedef struct {
NMObject parent;
diff --git a/libnm-glib/nm-object.c b/libnm-glib/nm-object.c
index aa3ce799e8..70d6144b47 100644
--- a/libnm-glib/nm-object.c
+++ b/libnm-glib/nm-object.c
@@ -70,6 +70,9 @@ typedef struct {
typedef struct {
DBusGConnection *connection;
+ DBusGProxy *bus_proxy;
+ gboolean nm_running;
+
char *path;
DBusGProxy *properties_proxy;
GSList *property_interfaces;
@@ -121,6 +124,27 @@ nm_object_error_quark (void)
}
static void
+proxy_name_owner_changed (DBusGProxy *proxy,
+ const char *name,
+ const char *old_owner,
+ const char *new_owner,
+ gpointer user_data)
+{
+ NMObject *self = NM_OBJECT (user_data);
+ NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self);
+
+ if (g_strcmp0 (name, NM_DBUS_SERVICE) == 0) {
+ gboolean old_good = (old_owner && old_owner[0]);
+ gboolean new_good = (new_owner && new_owner[0]);
+
+ if (!old_good && new_good)
+ priv->nm_running = TRUE;
+ else if (old_good && !new_good)
+ priv->nm_running = FALSE;
+ }
+}
+
+static void
nm_object_init (NMObject *object)
{
}
@@ -153,14 +177,31 @@ constructor (GType type,
static void
constructed (GObject *object)
{
+ NMObject *self = NM_OBJECT (object);
NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
if (G_OBJECT_CLASS (nm_object_parent_class)->constructed)
G_OBJECT_CLASS (nm_object_parent_class)->constructed (object);
- priv->properties_proxy = _nm_object_new_proxy (NM_OBJECT (object),
- NULL,
- "org.freedesktop.DBus.Properties");
+ priv->properties_proxy = _nm_object_new_proxy (self, NULL, "org.freedesktop.DBus.Properties");
+
+ if (_nm_object_is_connection_private (self))
+ priv->nm_running = TRUE;
+ else {
+ priv->bus_proxy = dbus_g_proxy_new_for_name (priv->connection,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS);
+ g_assert (priv->bus_proxy);
+
+ dbus_g_proxy_add_signal (priv->bus_proxy, "NameOwnerChanged",
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->bus_proxy,
+ "NameOwnerChanged",
+ G_CALLBACK (proxy_name_owner_changed),
+ object, NULL);
+ }
}
static gboolean
@@ -168,25 +209,70 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
{
NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (initable);
+ if (priv->bus_proxy) {
+ if (!dbus_g_proxy_call (priv->bus_proxy,
+ "NameHasOwner", error,
+ G_TYPE_STRING, NM_DBUS_SERVICE,
+ G_TYPE_INVALID,
+ G_TYPE_BOOLEAN, &priv->nm_running,
+ G_TYPE_INVALID))
+ return FALSE;
+ }
+
priv->inited = TRUE;
return _nm_object_reload_properties (NM_OBJECT (initable), error);
}
+/* Takes ownership of @error */
+static void
+init_async_complete (GSimpleAsyncResult *simple, GError *error)
+{
+ if (error)
+ g_simple_async_result_take_error (simple, error);
+ else
+ g_simple_async_result_set_op_res_gboolean (simple, TRUE);
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+}
+
static void
init_async_got_properties (GObject *object, GAsyncResult *result, gpointer user_data)
{
- NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
GSimpleAsyncResult *simple = user_data;
GError *error = NULL;
- priv->inited = TRUE;
- if (_nm_object_reload_properties_finish (NM_OBJECT (object), result, &error))
- g_simple_async_result_set_op_res_gboolean (simple, TRUE);
- else
- g_simple_async_result_take_error (simple, error);
+ NM_OBJECT_GET_PRIVATE (object)->inited = TRUE;
+ if (!_nm_object_reload_properties_finish (NM_OBJECT (object), result, &error))
+ g_assert (error);
+ init_async_complete (simple, error);
+}
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+static void
+init_async_got_manager_running (DBusGProxy *proxy, DBusGProxyCall *call,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple = user_data;
+ NMObject *self;
+ NMObjectPrivate *priv;
+ GError *error = NULL;
+
+ self = NM_OBJECT (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
+ priv = NM_OBJECT_GET_PRIVATE (self);
+
+ if (!dbus_g_proxy_end_call (proxy, call, &error,
+ G_TYPE_BOOLEAN, &priv->nm_running,
+ G_TYPE_INVALID)) {
+ init_async_complete (simple, error);
+ return;
+ }
+
+ if (!priv->nm_running) {
+ priv->inited = TRUE;
+ init_async_complete (simple, NULL);
+ return;
+ }
+
+ _nm_object_reload_properties_async (self, init_async_got_properties, simple);
}
static void
@@ -194,10 +280,21 @@ init_async (GAsyncInitable *initable, int io_priority,
GCancellable *cancellable, GAsyncReadyCallback callback,
gpointer user_data)
{
+ NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (initable);
GSimpleAsyncResult *simple;
simple = g_simple_async_result_new (G_OBJECT (initable), callback, user_data, init_async);
- _nm_object_reload_properties_async (NM_OBJECT (initable), init_async_got_properties, simple);
+
+ if (_nm_object_is_connection_private (NM_OBJECT (initable)))
+ _nm_object_reload_properties_async (NM_OBJECT (initable), init_async_got_properties, simple);
+ else {
+ /* Check if NM is running */
+ dbus_g_proxy_begin_call (priv->bus_proxy, "NameHasOwner",
+ init_async_got_manager_running,
+ simple, NULL,
+ G_TYPE_STRING, NM_DBUS_SERVICE,
+ G_TYPE_INVALID);
+ }
}
static gboolean
@@ -230,6 +327,7 @@ dispose (GObject *object)
priv->property_interfaces = NULL;
g_clear_object (&priv->properties_proxy);
+ g_clear_object (&priv->bus_proxy);
if (priv->connection) {
dbus_g_connection_unref (priv->connection);
@@ -1031,7 +1129,7 @@ _nm_object_reload_properties (NMObject *object, GError **error)
GHashTableIter pp;
gpointer name, info;
- if (!priv->property_interfaces)
+ if (!priv->property_interfaces || !priv->nm_running)
return TRUE;
for (p = priv->property_interfaces; p; p = p->next) {
@@ -1095,6 +1193,9 @@ _nm_object_reload_property (NMObject *object,
g_return_if_fail (interface != NULL);
g_return_if_fail (prop_name != NULL);
+ if (!NM_OBJECT_GET_PRIVATE (object)->nm_running)
+ return;
+
if (!dbus_g_proxy_call_with_timeout (NM_OBJECT_GET_PRIVATE (object)->properties_proxy,
"Get", 15000, &err,
G_TYPE_STRING, interface,
@@ -1132,6 +1233,9 @@ _nm_object_set_property (NMObject *object,
g_return_if_fail (prop_name != NULL);
g_return_if_fail (G_IS_VALUE (value));
+ if (!NM_OBJECT_GET_PRIVATE (object)->nm_running)
+ return;
+
if (!dbus_g_proxy_call_with_timeout (NM_OBJECT_GET_PRIVATE (object)->properties_proxy,
"Set", 2000, NULL,
G_TYPE_STRING, interface,
@@ -1284,6 +1388,9 @@ _nm_object_reload_pseudo_property (NMObject *object,
g_return_if_fail (NM_IS_OBJECT (object));
g_return_if_fail (name != NULL);
+ if (!NM_OBJECT_GET_PRIVATE (object)->nm_running)
+ return;
+
ppi = g_hash_table_lookup (priv->pseudo_properties, name);
g_return_if_fail (ppi != NULL);
diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c
index 5c5ff24c10..1e8e086f05 100644
--- a/libnm-glib/nm-remote-settings.c
+++ b/libnm-glib/nm-remote-settings.c
@@ -64,8 +64,7 @@ typedef struct {
DBusGProxy *dbus_proxy;
- guint fetch_id;
- gboolean fetching;
+ DBusGProxyCall *listcon_call;
} NMRemoteSettingsPrivate;
enum {
@@ -384,10 +383,8 @@ connection_inited (GObject *source, GAsyncResult *result, gpointer user_data)
/* Let listeners know that all connections have been found */
priv->init_left--;
- if (priv->init_left == 0) {
- priv->fetching = FALSE;
+ if (priv->init_left == 0)
g_signal_emit (self, signals[CONNECTIONS_READ], 0);
- }
}
static NMRemoteConnection *
@@ -433,12 +430,15 @@ fetch_connections_done (DBusGProxy *proxy,
GError *error = NULL;
int i;
+ g_warn_if_fail (priv->listcon_call == call);
+ priv->listcon_call = NULL;
+
if (!dbus_g_proxy_end_call (proxy, call, &error,
DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &connections,
G_TYPE_INVALID)) {
- /* Ignore settings service spawn errors */
if ( !g_error_matches (error, DBUS_GERROR, DBUS_GERROR_SERVICE_UNKNOWN)
- && !g_error_matches (error, DBUS_GERROR, DBUS_GERROR_NAME_HAS_NO_OWNER)) {
+ && !g_error_matches (error, DBUS_GERROR, DBUS_GERROR_NAME_HAS_NO_OWNER)
+ && priv->service_running) {
g_warning ("%s: error fetching connections: (%d) %s.",
__func__,
error->code,
@@ -447,16 +447,14 @@ fetch_connections_done (DBusGProxy *proxy,
g_clear_error (&error);
/* We tried to read connections and failed */
- priv->fetching = FALSE;
g_signal_emit (self, signals[CONNECTIONS_READ], 0);
return;
}
/* Let listeners know we are done getting connections */
- if (connections->len == 0) {
- priv->fetching = FALSE;
+ if (connections->len == 0)
g_signal_emit (self, signals[CONNECTIONS_READ], 0);
- } else {
+ else {
priv->init_left = connections->len;
for (i = 0; i < connections->len; i++) {
char *path = g_ptr_array_index (connections, i);
@@ -469,20 +467,6 @@ fetch_connections_done (DBusGProxy *proxy,
g_ptr_array_free (connections, TRUE);
}
-static gboolean
-fetch_connections (gpointer user_data)
-{
- NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data);
- NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
-
- priv->fetch_id = 0;
-
- dbus_g_proxy_begin_call (priv->proxy, "ListConnections",
- fetch_connections_done, self, NULL,
- G_TYPE_INVALID);
- return FALSE;
-}
-
/**
* nm_remote_settings_list_connections:
* @settings: the %NMRemoteSettings
@@ -566,6 +550,9 @@ nm_remote_settings_add_connection (NMRemoteSettings *settings,
_nm_remote_settings_ensure_inited (settings);
+ if (!priv->service_running)
+ return FALSE;
+
info = g_malloc0 (sizeof (AddConnectionInfo));
info->self = settings;
info->callback = callback;
@@ -608,17 +595,6 @@ clear_one_hash (GHashTable *table)
g_hash_table_remove_all (table);
}
-static gboolean
-remove_connections (gpointer user_data)
-{
- NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data);
- NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
-
- clear_one_hash (priv->pending);
- clear_one_hash (priv->connections);
- return FALSE;
-}
-
typedef struct {
NMRemoteSettings *settings;
NMRemoteSettingsSaveHostnameFunc callback;
@@ -670,6 +646,9 @@ nm_remote_settings_save_hostname (NMRemoteSettings *settings,
_nm_remote_settings_ensure_inited (settings);
+ if (!priv->service_running)
+ return FALSE;
+
info = g_malloc0 (sizeof (SaveHostnameInfo));
info->settings = settings;
info->callback = callback;
@@ -738,21 +717,23 @@ name_owner_changed (DBusGProxy *proxy,
const char *sname = NM_DBUS_SERVICE;
if (!strcmp (name, sname)) {
- if (priv->fetch_id)
- g_source_remove (priv->fetch_id);
-
if (new_owner && strlen (new_owner) > 0) {
- priv->fetch_id = g_idle_add (fetch_connections, self);
priv->service_running = TRUE;
+ priv->listcon_call = dbus_g_proxy_begin_call (priv->proxy, "ListConnections",
+ fetch_connections_done, self, NULL,
+ G_TYPE_INVALID);
+
dbus_g_proxy_begin_call (priv->props_proxy, "GetAll",
nm_appeared_got_properties, self, NULL,
G_TYPE_STRING, NM_DBUS_IFACE_SETTINGS,
G_TYPE_INVALID);
} else {
- priv->fetch_id = g_idle_add (remove_connections, self);
priv->service_running = FALSE;
+ clear_one_hash (priv->pending);
+ clear_one_hash (priv->connections);
+
/* Clear properties */
g_free (priv->hostname);
priv->hostname = NULL;
@@ -760,6 +741,11 @@ name_owner_changed (DBusGProxy *proxy,
priv->can_modify = FALSE;
g_object_notify (G_OBJECT (self), NM_REMOTE_SETTINGS_CAN_MODIFY);
+
+ if (priv->listcon_call) {
+ dbus_g_proxy_cancel_call (priv->proxy, priv->listcon_call);
+ priv->listcon_call = NULL;
+ }
}
g_object_notify (G_OBJECT (self), NM_REMOTE_SETTINGS_SERVICE_RUNNING);
}
@@ -782,7 +768,11 @@ name_owner_changed (DBusGProxy *proxy,
NMRemoteSettings *
nm_remote_settings_new (DBusGConnection *bus)
{
- return g_object_new (NM_TYPE_REMOTE_SETTINGS, NM_REMOTE_SETTINGS_BUS, bus, NULL);
+ NMRemoteSettings *self;
+
+ self = g_object_new (NM_TYPE_REMOTE_SETTINGS, NM_REMOTE_SETTINGS_BUS, bus, NULL);
+ _nm_remote_settings_ensure_inited (self);
+ return self;
}
static void
@@ -913,10 +903,6 @@ constructed (GObject *object)
object,
NULL);
- priv->fetching = TRUE;
- priv->fetch_id = g_idle_add (fetch_connections, object);
-
-
/* D-Bus properties proxy */
priv->props_proxy = _nm_dbus_new_proxy_for_connection (priv->bus,
NM_DBUS_PATH_SETTINGS,
@@ -962,6 +948,10 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
} else
priv->service_running = TRUE;
+ priv->listcon_call = dbus_g_proxy_begin_call (priv->proxy, "ListConnections",
+ fetch_connections_done, NM_REMOTE_SETTINGS (initable), NULL,
+ G_TYPE_INVALID);
+
/* Get properties */
if (!dbus_g_proxy_call (priv->props_proxy, "GetAll", error,
G_TYPE_STRING, NM_DBUS_IFACE_SETTINGS,
@@ -1020,14 +1010,12 @@ init_async_got_properties (DBusGProxy *proxy, DBusGProxyCall *call,
} else
g_simple_async_result_take_error (init_data->result, error);
- if (priv->fetching) {
- /* Still creating initial connections; wait for that to complete */
- g_signal_connect (init_data->settings, "connections-read",
- G_CALLBACK (init_read_connections), init_data);
- return;
- }
-
- init_async_complete (init_data);
+ /* Read connections and wait for the result */
+ priv->listcon_call = dbus_g_proxy_begin_call (priv->proxy, "ListConnections",
+ fetch_connections_done, init_data->settings, NULL,
+ G_TYPE_INVALID);
+ g_signal_connect (init_data->settings, "connections-read",
+ G_CALLBACK (init_read_connections), init_data);
}
static void
@@ -1108,11 +1096,6 @@ dispose (GObject *object)
NMRemoteSettings *self = NM_REMOTE_SETTINGS (object);
NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
- if (priv->fetch_id) {
- g_source_remove (priv->fetch_id);
- priv->fetch_id = 0;
- }
-
while (g_slist_length (priv->add_list))
add_connection_info_dispose (self, (AddConnectionInfo *) priv->add_list->data);
diff --git a/libnm-glib/nm-secret-agent.c b/libnm-glib/nm-secret-agent.c
index 400d042766..b573592d6b 100644
--- a/libnm-glib/nm-secret-agent.c
+++ b/libnm-glib/nm-secret-agent.c
@@ -589,6 +589,9 @@ nm_secret_agent_register (NMSecretAgent *self)
g_return_val_if_fail (class->save_secrets != NULL, FALSE);
g_return_val_if_fail (class->delete_secrets != NULL, FALSE);
+ if (!priv->nm_owner && !priv->private_bus)
+ return FALSE;
+
priv->suppress_auto = FALSE;
/* Export our secret agent interface before registering with the manager */
@@ -631,6 +634,9 @@ nm_secret_agent_unregister (NMSecretAgent *self)
g_return_val_if_fail (priv->bus != NULL, FALSE);
g_return_val_if_fail (priv->manager_proxy != NULL, FALSE);
+ if (!priv->nm_owner && !priv->private_bus)
+ return FALSE;
+
dbus_g_proxy_call_no_reply (priv->manager_proxy, "Unregister", G_TYPE_INVALID);
_internal_unregister (self);
@@ -829,6 +835,8 @@ nm_secret_agent_init (NMSecretAgent *self)
"NameOwnerChanged",
G_CALLBACK (name_owner_changed),
self, NULL);
+
+ get_nm_owner (self);
}
priv->manager_proxy = _nm_dbus_new_proxy_for_connection (priv->bus,
@@ -839,7 +847,8 @@ nm_secret_agent_init (NMSecretAgent *self)
return;
}
- priv->auto_register_id = g_idle_add (auto_register_cb, self);
+ if (priv->nm_owner || priv->private_bus)
+ priv->auto_register_id = g_idle_add (auto_register_cb, self);
}
static void