mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-07-23 11:14:29 +00:00
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.
This commit is contained in:
parent
4a21eb08db
commit
110a40358d
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -70,6 +70,9 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
DBusGConnection *connection;
|
||||
DBusGProxy *bus_proxy;
|
||||
gboolean nm_running;
|
||||
|
||||
char *path;
|
||||
DBusGProxy *properties_proxy;
|
||||
GSList *property_interfaces;
|
||||
|
@ -120,6 +123,27 @@ nm_object_error_quark (void)
|
|||
return quark;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue