2014-09-24 13:14:48 -04:00
|
|
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
|
|
|
|
/*
|
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
* License along with this library; if not, write to the
|
|
|
|
|
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
|
* Boston, MA 02110-1301 USA.
|
|
|
|
|
*
|
|
|
|
|
* Copyright 2007 - 2008 Novell, Inc.
|
|
|
|
|
* Copyright 2007 - 2014 Red Hat, Inc.
|
|
|
|
|
*/
|
|
|
|
|
|
2015-07-17 14:38:54 +02:00
|
|
|
#include "nm-default.h"
|
2016-02-19 14:57:48 +01:00
|
|
|
|
2014-09-24 13:14:48 -04:00
|
|
|
#include "nm-manager.h"
|
2016-02-12 14:44:52 +01:00
|
|
|
|
|
|
|
|
#include "nm-utils.h"
|
2017-10-21 16:05:19 +02:00
|
|
|
#include "nm-checkpoint.h"
|
2016-06-01 12:31:36 +02:00
|
|
|
#include "nm-common-macros.h"
|
2014-09-24 13:14:48 -04:00
|
|
|
#include "nm-device-ethernet.h"
|
|
|
|
|
#include "nm-device-wifi.h"
|
|
|
|
|
#include "nm-core-internal.h"
|
|
|
|
|
#include "nm-object-private.h"
|
|
|
|
|
#include "nm-active-connection.h"
|
|
|
|
|
#include "nm-vpn-connection.h"
|
|
|
|
|
#include "nm-dbus-helpers.h"
|
2018-04-06 16:40:23 +02:00
|
|
|
#include "c-list/src/c-list.h"
|
2014-09-24 13:14:48 -04:00
|
|
|
|
2016-11-23 13:14:08 +01:00
|
|
|
#include "introspection/org.freedesktop.NetworkManager.h"
|
2014-09-24 13:14:48 -04:00
|
|
|
|
|
|
|
|
void _nm_device_wifi_set_wireless_enabled (NMDeviceWifi *device, gboolean enabled);
|
|
|
|
|
|
|
|
|
|
static void nm_manager_initable_iface_init (GInitableIface *iface);
|
|
|
|
|
static void nm_manager_async_initable_iface_init (GAsyncInitableIface *iface);
|
|
|
|
|
static GInitableIface *nm_manager_parent_initable_iface;
|
|
|
|
|
static GAsyncInitableIface *nm_manager_parent_async_initable_iface;
|
|
|
|
|
|
|
|
|
|
G_DEFINE_TYPE_WITH_CODE (NMManager, nm_manager, NM_TYPE_OBJECT,
|
|
|
|
|
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_manager_initable_iface_init);
|
|
|
|
|
G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, nm_manager_async_initable_iface_init);
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
#define NM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MANAGER, NMManagerPrivate))
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
2016-11-14 18:47:56 +01:00
|
|
|
NMDBusManager *proxy;
|
2014-10-21 19:43:34 -05:00
|
|
|
GCancellable *props_cancellable;
|
2014-09-24 13:14:48 -04:00
|
|
|
char *version;
|
|
|
|
|
NMState state;
|
|
|
|
|
gboolean startup;
|
|
|
|
|
GPtrArray *devices;
|
2014-10-10 14:28:49 -05:00
|
|
|
GPtrArray *all_devices;
|
2014-09-24 13:14:48 -04:00
|
|
|
GPtrArray *active_connections;
|
2017-10-21 16:05:19 +02:00
|
|
|
GPtrArray *checkpoints;
|
|
|
|
|
GSList *added_checkpoints;
|
2014-09-24 13:14:48 -04:00
|
|
|
NMConnectivityState connectivity;
|
|
|
|
|
NMActiveConnection *primary_connection;
|
|
|
|
|
NMActiveConnection *activating_connection;
|
2015-06-03 09:15:24 +02:00
|
|
|
NMMetered metered;
|
2014-09-24 13:14:48 -04:00
|
|
|
|
|
|
|
|
GCancellable *perm_call_cancellable;
|
|
|
|
|
GHashTable *permissions;
|
|
|
|
|
|
|
|
|
|
/* Activations waiting for their NMActiveConnection
|
|
|
|
|
* to appear and then their callback to be called.
|
|
|
|
|
*/
|
2017-05-06 20:27:29 +02:00
|
|
|
CList pending_activations;
|
2014-09-24 13:14:48 -04:00
|
|
|
|
|
|
|
|
gboolean networking_enabled;
|
|
|
|
|
gboolean wireless_enabled;
|
|
|
|
|
gboolean wireless_hw_enabled;
|
|
|
|
|
|
|
|
|
|
gboolean wwan_enabled;
|
|
|
|
|
gboolean wwan_hw_enabled;
|
|
|
|
|
|
|
|
|
|
gboolean wimax_enabled;
|
|
|
|
|
gboolean wimax_hw_enabled;
|
2017-08-09 15:21:28 +08:00
|
|
|
|
|
|
|
|
gboolean connectivity_check_available;
|
|
|
|
|
gboolean connectivity_check_enabled;
|
2014-09-24 13:14:48 -04:00
|
|
|
} NMManagerPrivate;
|
|
|
|
|
|
|
|
|
|
enum {
|
|
|
|
|
PROP_0,
|
|
|
|
|
PROP_VERSION,
|
|
|
|
|
PROP_STATE,
|
|
|
|
|
PROP_STARTUP,
|
|
|
|
|
PROP_NETWORKING_ENABLED,
|
|
|
|
|
PROP_WIRELESS_ENABLED,
|
|
|
|
|
PROP_WIRELESS_HARDWARE_ENABLED,
|
|
|
|
|
PROP_WWAN_ENABLED,
|
|
|
|
|
PROP_WWAN_HARDWARE_ENABLED,
|
|
|
|
|
PROP_WIMAX_ENABLED,
|
|
|
|
|
PROP_WIMAX_HARDWARE_ENABLED,
|
|
|
|
|
PROP_ACTIVE_CONNECTIONS,
|
|
|
|
|
PROP_CONNECTIVITY,
|
2017-08-09 15:21:28 +08:00
|
|
|
PROP_CONNECTIVITY_CHECK_AVAILABLE,
|
|
|
|
|
PROP_CONNECTIVITY_CHECK_ENABLED,
|
2014-09-24 13:14:48 -04:00
|
|
|
PROP_PRIMARY_CONNECTION,
|
|
|
|
|
PROP_ACTIVATING_CONNECTION,
|
|
|
|
|
PROP_DEVICES,
|
2017-10-21 16:05:19 +02:00
|
|
|
PROP_CHECKPOINTS,
|
2015-06-03 09:15:24 +02:00
|
|
|
PROP_METERED,
|
2014-10-10 14:28:49 -05:00
|
|
|
PROP_ALL_DEVICES,
|
2014-09-24 13:14:48 -04:00
|
|
|
|
|
|
|
|
LAST_PROP
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum {
|
|
|
|
|
DEVICE_ADDED,
|
|
|
|
|
DEVICE_REMOVED,
|
2014-10-10 14:28:49 -05:00
|
|
|
ANY_DEVICE_ADDED,
|
|
|
|
|
ANY_DEVICE_REMOVED,
|
2014-10-10 14:06:44 -04:00
|
|
|
ACTIVE_CONNECTION_ADDED,
|
|
|
|
|
ACTIVE_CONNECTION_REMOVED,
|
2017-10-21 16:05:19 +02:00
|
|
|
CHECKPOINT_ADDED,
|
|
|
|
|
CHECKPOINT_REMOVED,
|
2014-09-24 13:14:48 -04:00
|
|
|
PERMISSION_CHANGED,
|
|
|
|
|
|
|
|
|
|
LAST_SIGNAL
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static guint signals[LAST_SIGNAL] = { 0 };
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2014-09-24 13:14:48 -04:00
|
|
|
|
2017-10-21 16:05:19 +02:00
|
|
|
typedef struct {
|
|
|
|
|
NMManager *manager;
|
|
|
|
|
GSimpleAsyncResult *simple;
|
|
|
|
|
char *path;
|
|
|
|
|
} CheckpointInfo;
|
|
|
|
|
|
|
|
|
|
static CheckpointInfo *
|
|
|
|
|
find_checkpoint_info (NMManager *manager, const char *path)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
|
|
|
|
CheckpointInfo *info;
|
|
|
|
|
GSList *iter;
|
|
|
|
|
|
|
|
|
|
for (iter = priv->added_checkpoints; iter; iter = g_slist_next (iter)) {
|
|
|
|
|
info = iter->data;
|
libnm: fix crash creating checkpoint during find_checkpoint_info()
Now that the D-Bus signals in server are reordered, creating
a checkpoint in libnm crashes:
$ examples/python/gi/checkpoint.py create 4
#0 0x00007ffff6d011ee in __strcmp_sse2_unaligned () at /lib64/libc.so.6
#1 0x00007fffeb611c90 in find_checkpoint_info (manager=manager@entry=0x5555559e5110 [NMManager], path=0x7fffdc0092f0 "/org/freedesktop/NetworkManager/Checkpoint/6")
at libnm/nm-manager.c:153
#2 0x00007fffeb611d8f in checkpoint_added (manager=0x5555559e5110 [NMManager], checkpoint=checkpoint@entry=0x555555a122d0 [NMCheckpoint]) at libnm/nm-manager.c:1194
#3 0x00007fffef7db929 in g_cclosure_marshal_VOID__OBJECTv (closure=0x5555559e4b30, return_value=<optimized out>, instance=<optimized out>, args=<optimized out>, marshal_data=<optimized out>, n_params=<optimized out>, param_types=0x5555559e2fc0) at gmarshal.c:2102
#4 0x00007fffef7d8976 in _g_closure_invoke_va (closure=0x5555559e4b30, return_value=0x0, instance=0x5555559e5110, args=0x7fffffffc1c8, n_params=1, param_types=0x5555559e2fc0)
at gclosure.c:867
#5 0x00007fffef7f3ff4 in g_signal_emit_valist (instance=instance@entry=0x5555559e5110, signal_id=signal_id@entry=97, detail=0, var_args=var_args@entry=0x7fffffffc1c8) at gsignal.c:3300
#6 0x00007fffef7f4b48 in g_signal_emit_by_name (instance=instance@entry=0x5555559e5110, detailed_signal=detailed_signal@entry=0x7fffffffc310 "checkpoint-added") at gsignal.c:3487
#7 0x00007fffeb6156d1 in deferred_notify_cb (data=0x5555559e5110) at libnm/nm-object.c:219
#8 0x00007fffeb615ae7 in object_property_maybe_complete (self=0x5555559e5110 [NMManager]) at libnm/nm-object.c:555
#9 0x00007fffeb615e5d in object_created (obj=<optimized out>, path=<optimized out>, user_data=<optimized out>) at libnm/nm-object.c:576
#10 0x00007fffeb61648b in handle_object_array_property (pi=<optimized out>, value=0x7fffdc075070, property_name=0x7fffeb67f117 "checkpoints", self=0x5555559e5110 [NMManager])
at libnm/nm-object.c:671
#11 0x00007fffeb61648b in handle_property_changed (self=self@entry=0x5555559e5110 [NMManager], dbus_name=<optimized out>, value=<optimized out>) at libnm/nm-object.c:740
#12 0x00007fffeb6166e9 in properties_changed (proxy=<optimized out>, changed_properties=<optimized out>, invalidated_properties=<optimized out>, user_data=0x5555559e5110)
at libnm/nm-object.c:772
...
That is, because NetworkManager now first emits signals that the checkpoint
object was created, before answering the D-Bus request. That makes more
sense, but leads to this crash.
The ugliness of how libnm handles object visibility is considerable.
libnm hides objects until they are fully initialized. So, when
the async create-checkpoint operation returns, the object might not
yet be ready to be exposed. We need to delay the result. It would be
better if the API would simply return the created path.
2018-03-28 12:31:43 +02:00
|
|
|
if (nm_streq0 (path, info->path))
|
2017-10-21 16:05:19 +02:00
|
|
|
return info;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
checkpoint_info_complete (NMManager *self,
|
|
|
|
|
CheckpointInfo *info,
|
|
|
|
|
NMCheckpoint *checkpoint,
|
|
|
|
|
GError *error)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (info);
|
|
|
|
|
|
|
|
|
|
if (checkpoint) {
|
|
|
|
|
g_simple_async_result_set_op_res_gpointer (info->simple,
|
|
|
|
|
g_object_ref (checkpoint),
|
|
|
|
|
g_object_unref);
|
|
|
|
|
} else
|
|
|
|
|
g_simple_async_result_set_from_error (info->simple, error);
|
|
|
|
|
g_simple_async_result_complete (info->simple);
|
|
|
|
|
|
|
|
|
|
g_object_unref (info->simple);
|
|
|
|
|
priv->added_checkpoints = g_slist_remove (priv->added_checkpoints, info);
|
|
|
|
|
|
|
|
|
|
g_free (info->path);
|
|
|
|
|
g_slice_free (CheckpointInfo, info);
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-24 13:14:48 -04:00
|
|
|
static void
|
|
|
|
|
nm_manager_init (NMManager *manager)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
|
|
|
|
|
2017-05-06 20:27:29 +02:00
|
|
|
c_list_init (&priv->pending_activations);
|
|
|
|
|
|
2014-09-24 13:14:48 -04:00
|
|
|
priv->state = NM_STATE_UNKNOWN;
|
|
|
|
|
priv->connectivity = NM_CONNECTIVITY_UNKNOWN;
|
|
|
|
|
|
2017-11-15 16:06:43 +01:00
|
|
|
priv->permissions = g_hash_table_new (nm_direct_hash, NULL);
|
2014-10-06 21:16:00 -04:00
|
|
|
priv->devices = g_ptr_array_new ();
|
2014-10-10 14:28:49 -05:00
|
|
|
priv->all_devices = g_ptr_array_new ();
|
2014-10-06 21:16:00 -04:00
|
|
|
priv->active_connections = g_ptr_array_new ();
|
2014-09-24 13:14:48 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
poke_wireless_devices_with_rf_status (NMManager *manager)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
|
|
|
|
int i;
|
|
|
|
|
|
2014-10-10 14:28:49 -05:00
|
|
|
for (i = 0; i < priv->all_devices->len; i++) {
|
|
|
|
|
NMDevice *device = g_ptr_array_index (priv->all_devices, i);
|
2014-09-24 13:14:48 -04:00
|
|
|
|
|
|
|
|
if (NM_IS_DEVICE_WIFI (device))
|
|
|
|
|
_nm_device_wifi_set_wireless_enabled (NM_DEVICE_WIFI (device), priv->wireless_enabled);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
wireless_enabled_cb (GObject *object, GParamSpec *pspec, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
poke_wireless_devices_with_rf_status (NM_MANAGER (object));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void manager_recheck_permissions (NMDBusManager *proxy, gpointer user_data);
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
init_dbus (NMObject *object)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (object);
|
|
|
|
|
const NMPropertiesInfo property_info[] = {
|
|
|
|
|
{ NM_MANAGER_VERSION, &priv->version },
|
|
|
|
|
{ NM_MANAGER_STATE, &priv->state },
|
|
|
|
|
{ NM_MANAGER_STARTUP, &priv->startup },
|
|
|
|
|
{ NM_MANAGER_NETWORKING_ENABLED, &priv->networking_enabled },
|
|
|
|
|
{ NM_MANAGER_WIRELESS_ENABLED, &priv->wireless_enabled },
|
|
|
|
|
{ NM_MANAGER_WIRELESS_HARDWARE_ENABLED, &priv->wireless_hw_enabled },
|
|
|
|
|
{ NM_MANAGER_WWAN_ENABLED, &priv->wwan_enabled },
|
|
|
|
|
{ NM_MANAGER_WWAN_HARDWARE_ENABLED, &priv->wwan_hw_enabled },
|
|
|
|
|
{ NM_MANAGER_WIMAX_ENABLED, &priv->wimax_enabled },
|
|
|
|
|
{ NM_MANAGER_WIMAX_HARDWARE_ENABLED, &priv->wimax_hw_enabled },
|
2014-10-10 14:06:44 -04:00
|
|
|
{ NM_MANAGER_ACTIVE_CONNECTIONS, &priv->active_connections, NULL, NM_TYPE_ACTIVE_CONNECTION, "active-connection" },
|
2014-09-24 13:14:48 -04:00
|
|
|
{ NM_MANAGER_CONNECTIVITY, &priv->connectivity },
|
2017-08-09 15:21:28 +08:00
|
|
|
{ NM_MANAGER_CONNECTIVITY_CHECK_AVAILABLE, &priv->connectivity_check_available },
|
|
|
|
|
{ NM_MANAGER_CONNECTIVITY_CHECK_ENABLED, &priv->connectivity_check_enabled },
|
2014-09-24 13:14:48 -04:00
|
|
|
{ NM_MANAGER_PRIMARY_CONNECTION, &priv->primary_connection, NULL, NM_TYPE_ACTIVE_CONNECTION },
|
|
|
|
|
{ NM_MANAGER_ACTIVATING_CONNECTION, &priv->activating_connection, NULL, NM_TYPE_ACTIVE_CONNECTION },
|
|
|
|
|
{ NM_MANAGER_DEVICES, &priv->devices, NULL, NM_TYPE_DEVICE, "device" },
|
2017-10-21 16:05:19 +02:00
|
|
|
{ NM_MANAGER_CHECKPOINTS, &priv->checkpoints, NULL, NM_TYPE_CHECKPOINT, "checkpoint" },
|
2015-06-03 09:15:24 +02:00
|
|
|
{ NM_MANAGER_METERED, &priv->metered },
|
2014-10-10 14:28:49 -05:00
|
|
|
{ NM_MANAGER_ALL_DEVICES, &priv->all_devices, NULL, NM_TYPE_DEVICE, "any-device" },
|
2014-09-24 13:14:48 -04:00
|
|
|
{ NULL },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
NM_OBJECT_CLASS (nm_manager_parent_class)->init_dbus (object);
|
|
|
|
|
|
2016-11-14 18:47:56 +01:00
|
|
|
priv->proxy = NMDBUS_MANAGER (_nm_object_get_proxy (object, NM_DBUS_INTERFACE));
|
2014-09-24 13:14:48 -04:00
|
|
|
_nm_object_register_properties (object,
|
|
|
|
|
NM_DBUS_INTERFACE,
|
|
|
|
|
property_info);
|
|
|
|
|
|
|
|
|
|
/* Permissions */
|
2017-09-20 15:01:41 +01:00
|
|
|
g_signal_connect_object (priv->proxy, "check-permissions",
|
|
|
|
|
G_CALLBACK (manager_recheck_permissions), object, 0);
|
2014-09-24 13:14:48 -04:00
|
|
|
}
|
|
|
|
|
|
2017-10-21 16:05:19 +02:00
|
|
|
static void
|
|
|
|
|
object_creation_failed (NMObject *object, const char *failed_path)
|
|
|
|
|
{
|
|
|
|
|
NMManager *self = NM_MANAGER (object);
|
|
|
|
|
CheckpointInfo *info;
|
|
|
|
|
GError *add_error;
|
|
|
|
|
|
|
|
|
|
info = find_checkpoint_info (self, failed_path);
|
|
|
|
|
if (info) {
|
|
|
|
|
add_error = g_error_new_literal (NM_CLIENT_ERROR,
|
|
|
|
|
NM_CLIENT_ERROR_OBJECT_CREATION_FAILED,
|
|
|
|
|
_("Checkpoint was removed before it was initialized"));
|
|
|
|
|
checkpoint_info_complete (self, info, NULL, add_error);
|
|
|
|
|
g_error_free (add_error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-24 13:14:48 -04:00
|
|
|
static NMClientPermission
|
|
|
|
|
nm_permission_to_client (const char *nm)
|
|
|
|
|
{
|
|
|
|
|
if (!strcmp (nm, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK))
|
|
|
|
|
return NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK;
|
|
|
|
|
else if (!strcmp (nm, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI))
|
|
|
|
|
return NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI;
|
|
|
|
|
else if (!strcmp (nm, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN))
|
|
|
|
|
return NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN;
|
|
|
|
|
else if (!strcmp (nm, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX))
|
|
|
|
|
return NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX;
|
|
|
|
|
else if (!strcmp (nm, NM_AUTH_PERMISSION_SLEEP_WAKE))
|
|
|
|
|
return NM_CLIENT_PERMISSION_SLEEP_WAKE;
|
|
|
|
|
else if (!strcmp (nm, NM_AUTH_PERMISSION_NETWORK_CONTROL))
|
|
|
|
|
return NM_CLIENT_PERMISSION_NETWORK_CONTROL;
|
|
|
|
|
else if (!strcmp (nm, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED))
|
|
|
|
|
return NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED;
|
|
|
|
|
else if (!strcmp (nm, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN))
|
|
|
|
|
return NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN;
|
|
|
|
|
else if (!strcmp (nm, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM))
|
|
|
|
|
return NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM;
|
|
|
|
|
else if (!strcmp (nm, NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN))
|
|
|
|
|
return NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN;
|
|
|
|
|
else if (!strcmp (nm, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME))
|
|
|
|
|
return NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME;
|
2016-06-01 12:54:05 +02:00
|
|
|
else if (!strcmp (nm, NM_AUTH_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS))
|
|
|
|
|
return NM_CLIENT_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS;
|
2016-05-30 15:42:44 +02:00
|
|
|
else if (!strcmp (nm, NM_AUTH_PERMISSION_RELOAD))
|
|
|
|
|
return NM_CLIENT_PERMISSION_RELOAD;
|
2016-08-17 15:34:55 +02:00
|
|
|
else if (!strcmp (nm, NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK))
|
|
|
|
|
return NM_CLIENT_PERMISSION_CHECKPOINT_ROLLBACK;
|
2016-08-10 11:54:32 +02:00
|
|
|
else if (!strcmp (nm, NM_AUTH_PERMISSION_ENABLE_DISABLE_STATISTICS))
|
|
|
|
|
return NM_CLIENT_PERMISSION_ENABLE_DISABLE_STATISTICS;
|
2017-08-09 15:21:28 +08:00
|
|
|
else if (!strcmp (nm, NM_AUTH_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK))
|
|
|
|
|
return NM_CLIENT_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK;
|
2019-01-25 14:33:11 +08:00
|
|
|
else if (!strcmp (nm, NM_AUTH_PERMISSION_WIFI_SCAN))
|
|
|
|
|
return NM_CLIENT_PERMISSION_WIFI_SCAN;
|
2014-09-24 13:14:48 -04:00
|
|
|
|
|
|
|
|
return NM_CLIENT_PERMISSION_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static NMClientPermissionResult
|
|
|
|
|
nm_permission_result_to_client (const char *nm)
|
|
|
|
|
{
|
|
|
|
|
if (!strcmp (nm, "yes"))
|
|
|
|
|
return NM_CLIENT_PERMISSION_RESULT_YES;
|
|
|
|
|
else if (!strcmp (nm, "no"))
|
|
|
|
|
return NM_CLIENT_PERMISSION_RESULT_NO;
|
|
|
|
|
else if (!strcmp (nm, "auth"))
|
|
|
|
|
return NM_CLIENT_PERMISSION_RESULT_AUTH;
|
|
|
|
|
return NM_CLIENT_PERMISSION_RESULT_UNKNOWN;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
update_permissions (NMManager *self, GVariant *permissions)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
GHashTableIter iter;
|
|
|
|
|
gpointer key, value;
|
|
|
|
|
NMClientPermission perm;
|
|
|
|
|
NMClientPermissionResult perm_result;
|
|
|
|
|
GList *keys, *keys_iter;
|
|
|
|
|
|
|
|
|
|
/* get list of old permissions for change notification */
|
|
|
|
|
keys = g_hash_table_get_keys (priv->permissions);
|
|
|
|
|
g_hash_table_remove_all (priv->permissions);
|
|
|
|
|
|
|
|
|
|
if (permissions) {
|
|
|
|
|
GVariantIter viter;
|
|
|
|
|
const char *pkey, *pvalue;
|
|
|
|
|
|
|
|
|
|
/* Process new permissions */
|
|
|
|
|
g_variant_iter_init (&viter, permissions);
|
|
|
|
|
while (g_variant_iter_next (&viter, "{&s&s}", &pkey, &pvalue)) {
|
|
|
|
|
perm = nm_permission_to_client (pkey);
|
|
|
|
|
perm_result = nm_permission_result_to_client (pvalue);
|
|
|
|
|
if (perm) {
|
|
|
|
|
g_hash_table_insert (priv->permissions,
|
|
|
|
|
GUINT_TO_POINTER (perm),
|
|
|
|
|
GUINT_TO_POINTER (perm_result));
|
|
|
|
|
|
|
|
|
|
/* Remove this permission from the list of previous permissions
|
|
|
|
|
* we'll be sending NM_CLIENT_PERMISSION_RESULT_UNKNOWN for
|
|
|
|
|
* in the change signal since it is still a known permission.
|
|
|
|
|
*/
|
|
|
|
|
keys = g_list_remove (keys, GUINT_TO_POINTER (perm));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Signal changes in all updated permissions */
|
|
|
|
|
g_hash_table_iter_init (&iter, priv->permissions);
|
|
|
|
|
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
|
|
|
|
g_signal_emit (self, signals[PERMISSION_CHANGED], 0,
|
|
|
|
|
GPOINTER_TO_UINT (key),
|
|
|
|
|
GPOINTER_TO_UINT (value));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* And signal changes in all permissions that used to be valid but for
|
|
|
|
|
* some reason weren't received in the last request (if any).
|
|
|
|
|
*/
|
|
|
|
|
for (keys_iter = keys; keys_iter; keys_iter = g_list_next (keys_iter)) {
|
|
|
|
|
g_signal_emit (self, signals[PERMISSION_CHANGED], 0,
|
|
|
|
|
GPOINTER_TO_UINT (keys_iter->data),
|
|
|
|
|
NM_CLIENT_PERMISSION_RESULT_UNKNOWN);
|
|
|
|
|
}
|
|
|
|
|
g_list_free (keys);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
get_permissions_sync (NMManager *self, GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
GVariant *permissions;
|
|
|
|
|
|
2016-11-14 18:47:56 +01:00
|
|
|
if (nmdbus_manager_call_get_permissions_sync (priv->proxy,
|
2014-09-24 13:14:48 -04:00
|
|
|
&permissions,
|
|
|
|
|
NULL, error)) {
|
|
|
|
|
update_permissions (self, permissions);
|
|
|
|
|
g_variant_unref (permissions);
|
|
|
|
|
return TRUE;
|
|
|
|
|
} else {
|
2014-10-15 18:26:32 -04:00
|
|
|
if (error && *error)
|
|
|
|
|
g_dbus_error_strip_remote_error (*error);
|
2014-09-24 13:14:48 -04:00
|
|
|
update_permissions (self, NULL);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
get_permissions_reply (GObject *object,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMManager *self;
|
|
|
|
|
NMManagerPrivate *priv;
|
|
|
|
|
GVariant *permissions = NULL;
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
|
|
/* WARNING: this may be called after the manager is disposed, so we can't
|
|
|
|
|
* look at self/priv until after we've determined that that isn't the case.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
nmdbus_manager_call_get_permissions_finish (NMDBUS_MANAGER (object),
|
|
|
|
|
&permissions,
|
|
|
|
|
result, &error);
|
|
|
|
|
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
|
|
|
|
/* @self has been disposed. */
|
|
|
|
|
g_error_free (error);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
self = user_data;
|
|
|
|
|
priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
update_permissions (self, permissions);
|
|
|
|
|
|
|
|
|
|
g_clear_pointer (&permissions, g_variant_unref);
|
|
|
|
|
g_clear_error (&error);
|
|
|
|
|
g_clear_object (&priv->perm_call_cancellable);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
manager_recheck_permissions (NMDBusManager *proxy, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMManager *self = NM_MANAGER (user_data);
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
if (priv->perm_call_cancellable)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
priv->perm_call_cancellable = g_cancellable_new ();
|
2016-11-14 18:47:56 +01:00
|
|
|
nmdbus_manager_call_get_permissions (priv->proxy,
|
2014-09-24 13:14:48 -04:00
|
|
|
priv->perm_call_cancellable,
|
|
|
|
|
get_permissions_reply,
|
|
|
|
|
self);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
|
nm_manager_get_version (NMManager *manager)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
|
|
|
|
|
|
2016-10-12 19:50:32 +02:00
|
|
|
return nm_str_not_empty (NM_MANAGER_GET_PRIVATE (manager)->version);
|
2014-09-24 13:14:48 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NMState
|
|
|
|
|
nm_manager_get_state (NMManager *manager)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), NM_STATE_UNKNOWN);
|
|
|
|
|
|
|
|
|
|
return NM_MANAGER_GET_PRIVATE (manager)->state;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
|
nm_manager_get_startup (NMManager *manager)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), NM_STATE_UNKNOWN);
|
|
|
|
|
|
|
|
|
|
return NM_MANAGER_GET_PRIVATE (manager)->startup;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
|
nm_manager_networking_get_enabled (NMManager *manager)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE);
|
|
|
|
|
|
|
|
|
|
return NM_MANAGER_GET_PRIVATE (manager)->networking_enabled;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
|
nm_manager_networking_set_enabled (NMManager *manager, gboolean enable, GError **error)
|
|
|
|
|
{
|
2014-10-15 18:26:32 -04:00
|
|
|
gboolean ret;
|
|
|
|
|
|
2014-09-24 13:14:48 -04:00
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE);
|
|
|
|
|
|
2016-11-14 18:47:56 +01:00
|
|
|
ret = nmdbus_manager_call_enable_sync (NM_MANAGER_GET_PRIVATE (manager)->proxy,
|
2014-10-15 18:26:32 -04:00
|
|
|
enable,
|
|
|
|
|
NULL, error);
|
|
|
|
|
if (error && *error)
|
|
|
|
|
g_dbus_error_strip_remote_error (*error);
|
|
|
|
|
return ret;
|
2014-09-24 13:14:48 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
|
nm_manager_wireless_get_enabled (NMManager *manager)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE);
|
|
|
|
|
|
|
|
|
|
return NM_MANAGER_GET_PRIVATE (manager)->wireless_enabled;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_manager_wireless_set_enabled (NMManager *manager, gboolean enabled)
|
|
|
|
|
{
|
|
|
|
|
g_return_if_fail (NM_IS_MANAGER (manager));
|
|
|
|
|
|
|
|
|
|
_nm_object_set_property (NM_OBJECT (manager),
|
|
|
|
|
NM_DBUS_INTERFACE,
|
|
|
|
|
"WirelessEnabled",
|
|
|
|
|
"b", enabled);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
|
nm_manager_wireless_hardware_get_enabled (NMManager *manager)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE);
|
|
|
|
|
|
|
|
|
|
return NM_MANAGER_GET_PRIVATE (manager)->wireless_hw_enabled;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
|
nm_manager_wwan_get_enabled (NMManager *manager)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE);
|
|
|
|
|
|
|
|
|
|
return NM_MANAGER_GET_PRIVATE (manager)->wwan_enabled;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_manager_wwan_set_enabled (NMManager *manager, gboolean enabled)
|
|
|
|
|
{
|
|
|
|
|
g_return_if_fail (NM_IS_MANAGER (manager));
|
|
|
|
|
|
|
|
|
|
_nm_object_set_property (NM_OBJECT (manager),
|
|
|
|
|
NM_DBUS_INTERFACE,
|
|
|
|
|
"WwanEnabled",
|
|
|
|
|
"b", enabled);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
|
nm_manager_wwan_hardware_get_enabled (NMManager *manager)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE);
|
|
|
|
|
|
|
|
|
|
return NM_MANAGER_GET_PRIVATE (manager)->wwan_hw_enabled;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
|
nm_manager_wimax_get_enabled (NMManager *manager)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE);
|
|
|
|
|
|
|
|
|
|
return NM_MANAGER_GET_PRIVATE (manager)->wimax_enabled;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_manager_wimax_set_enabled (NMManager *manager, gboolean enabled)
|
|
|
|
|
{
|
|
|
|
|
g_return_if_fail (NM_IS_MANAGER (manager));
|
|
|
|
|
|
|
|
|
|
_nm_object_set_property (NM_OBJECT (manager),
|
|
|
|
|
NM_DBUS_INTERFACE,
|
|
|
|
|
"WimaxEnabled",
|
|
|
|
|
"b", enabled);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
|
nm_manager_wimax_hardware_get_enabled (NMManager *manager)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE);
|
|
|
|
|
|
|
|
|
|
return NM_MANAGER_GET_PRIVATE (manager)->wimax_hw_enabled;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-09 15:21:28 +08:00
|
|
|
gboolean
|
|
|
|
|
nm_manager_connectivity_check_get_available (NMManager *manager)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE);
|
|
|
|
|
|
|
|
|
|
return NM_MANAGER_GET_PRIVATE (manager)->connectivity_check_available;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
|
nm_manager_connectivity_check_get_enabled (NMManager *manager)
|
|
|
|
|
{
|
|
|
|
|
return NM_MANAGER_GET_PRIVATE (manager)->connectivity_check_enabled;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_manager_connectivity_check_set_enabled (NMManager *manager, gboolean enabled)
|
|
|
|
|
{
|
|
|
|
|
g_return_if_fail (NM_IS_MANAGER (manager));
|
|
|
|
|
|
|
|
|
|
_nm_object_set_property (NM_OBJECT (manager),
|
|
|
|
|
NM_DBUS_INTERFACE,
|
|
|
|
|
"ConnectivityCheckEnabled",
|
|
|
|
|
"b", enabled);
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-24 13:14:48 -04:00
|
|
|
gboolean
|
|
|
|
|
nm_manager_get_logging (NMManager *manager, char **level, char **domains, GError **error)
|
|
|
|
|
{
|
2014-10-15 18:26:32 -04:00
|
|
|
gboolean ret;
|
|
|
|
|
|
2014-09-24 13:14:48 -04:00
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), 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;
|
|
|
|
|
|
2016-11-14 18:47:56 +01:00
|
|
|
ret = nmdbus_manager_call_get_logging_sync (NM_MANAGER_GET_PRIVATE (manager)->proxy,
|
2014-10-15 18:26:32 -04:00
|
|
|
level, domains,
|
|
|
|
|
NULL, error);
|
|
|
|
|
if (error && *error)
|
|
|
|
|
g_dbus_error_strip_remote_error (*error);
|
|
|
|
|
return ret;
|
2014-09-24 13:14:48 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
|
nm_manager_set_logging (NMManager *manager, const char *level, const char *domains, GError **error)
|
|
|
|
|
{
|
2014-10-15 18:26:32 -04:00
|
|
|
gboolean ret;
|
|
|
|
|
|
2014-09-24 13:14:48 -04:00
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE);
|
|
|
|
|
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
|
|
|
|
|
|
|
|
|
if (!level && !domains)
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
|
|
if (!level)
|
|
|
|
|
level = "";
|
|
|
|
|
if (!domains)
|
|
|
|
|
domains = "";
|
|
|
|
|
|
2016-11-14 18:47:56 +01:00
|
|
|
ret = nmdbus_manager_call_set_logging_sync (NM_MANAGER_GET_PRIVATE (manager)->proxy,
|
2014-10-15 18:26:32 -04:00
|
|
|
level, domains,
|
|
|
|
|
NULL, error);
|
|
|
|
|
if (error && *error)
|
|
|
|
|
g_dbus_error_strip_remote_error (*error);
|
|
|
|
|
return ret;
|
2014-09-24 13:14:48 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NMClientPermissionResult
|
|
|
|
|
nm_manager_get_permission_result (NMManager *manager, NMClientPermission permission)
|
|
|
|
|
{
|
|
|
|
|
gpointer result;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), NM_CLIENT_PERMISSION_RESULT_UNKNOWN);
|
|
|
|
|
|
|
|
|
|
result = g_hash_table_lookup (NM_MANAGER_GET_PRIVATE (manager)->permissions,
|
|
|
|
|
GUINT_TO_POINTER (permission));
|
|
|
|
|
return GPOINTER_TO_UINT (result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NMConnectivityState
|
|
|
|
|
nm_manager_get_connectivity (NMManager *manager)
|
|
|
|
|
{
|
2015-03-18 18:08:24 +01:00
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), NM_CONNECTIVITY_UNKNOWN);
|
2014-09-24 13:14:48 -04:00
|
|
|
|
|
|
|
|
return NM_MANAGER_GET_PRIVATE (manager)->connectivity;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NMConnectivityState
|
|
|
|
|
nm_manager_check_connectivity (NMManager *manager,
|
|
|
|
|
GCancellable *cancellable,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv;
|
|
|
|
|
guint32 connectivity;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), NM_CONNECTIVITY_UNKNOWN);
|
|
|
|
|
priv = NM_MANAGER_GET_PRIVATE (manager);
|
|
|
|
|
|
2016-11-14 18:47:56 +01:00
|
|
|
if (nmdbus_manager_call_check_connectivity_sync (priv->proxy,
|
2014-09-24 13:14:48 -04:00
|
|
|
&connectivity,
|
2017-07-27 15:32:05 +02:00
|
|
|
cancellable, error)) {
|
|
|
|
|
if (connectivity != priv->connectivity) {
|
|
|
|
|
priv->connectivity = connectivity;
|
|
|
|
|
g_object_notify (G_OBJECT (manager), NM_MANAGER_CONNECTIVITY);
|
|
|
|
|
}
|
2014-09-24 13:14:48 -04:00
|
|
|
return connectivity;
|
2017-07-27 15:32:05 +02:00
|
|
|
}
|
2014-10-15 18:26:32 -04:00
|
|
|
else {
|
|
|
|
|
if (error && *error)
|
|
|
|
|
g_dbus_error_strip_remote_error (*error);
|
2014-09-24 13:14:48 -04:00
|
|
|
return NM_CONNECTIVITY_UNKNOWN;
|
2014-10-15 18:26:32 -04:00
|
|
|
}
|
2014-09-24 13:14:48 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
check_connectivity_cb (GObject *object,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
GSimpleAsyncResult *simple = user_data;
|
|
|
|
|
guint32 connectivity;
|
|
|
|
|
GError *error = NULL;
|
2017-07-27 15:32:05 +02:00
|
|
|
NMManager *manager;
|
|
|
|
|
NMManagerPrivate *priv;
|
2014-09-24 13:14:48 -04:00
|
|
|
|
|
|
|
|
if (nmdbus_manager_call_check_connectivity_finish (NMDBUS_MANAGER (object),
|
|
|
|
|
&connectivity,
|
2017-07-27 15:32:05 +02:00
|
|
|
result, &error)) {
|
2014-09-24 13:14:48 -04:00
|
|
|
g_simple_async_result_set_op_res_gssize (simple, connectivity);
|
2017-07-27 15:32:05 +02:00
|
|
|
|
|
|
|
|
manager = NM_MANAGER (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
|
|
|
|
|
priv = NM_MANAGER_GET_PRIVATE (manager);
|
|
|
|
|
if (connectivity != priv->connectivity) {
|
|
|
|
|
priv->connectivity = connectivity;
|
|
|
|
|
g_object_notify (G_OBJECT (manager), NM_MANAGER_CONNECTIVITY);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2014-10-15 18:26:32 -04:00
|
|
|
g_dbus_error_strip_remote_error (error);
|
2014-09-24 13:14:48 -04:00
|
|
|
g_simple_async_result_take_error (simple, error);
|
2014-10-15 18:26:32 -04:00
|
|
|
}
|
2014-09-24 13:14:48 -04:00
|
|
|
|
|
|
|
|
g_simple_async_result_complete (simple);
|
|
|
|
|
g_object_unref (simple);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_manager_check_connectivity_async (NMManager *manager,
|
|
|
|
|
GCancellable *cancellable,
|
|
|
|
|
GAsyncReadyCallback callback,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv;
|
|
|
|
|
GSimpleAsyncResult *simple;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (NM_IS_MANAGER (manager));
|
|
|
|
|
priv = NM_MANAGER_GET_PRIVATE (manager);
|
|
|
|
|
|
|
|
|
|
simple = g_simple_async_result_new (G_OBJECT (manager), callback, user_data,
|
|
|
|
|
nm_manager_check_connectivity_async);
|
2018-03-05 16:02:24 +01:00
|
|
|
if (cancellable)
|
|
|
|
|
g_simple_async_result_set_check_cancellable (simple, cancellable);
|
2016-11-14 18:47:56 +01:00
|
|
|
nmdbus_manager_call_check_connectivity (priv->proxy,
|
2014-09-24 13:14:48 -04:00
|
|
|
cancellable,
|
|
|
|
|
check_connectivity_cb, simple);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NMConnectivityState
|
|
|
|
|
nm_manager_check_connectivity_finish (NMManager *manager,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
GSimpleAsyncResult *simple;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (manager), nm_manager_check_connectivity_async), NM_CONNECTIVITY_UNKNOWN);
|
|
|
|
|
|
|
|
|
|
simple = G_SIMPLE_ASYNC_RESULT (result);
|
|
|
|
|
|
|
|
|
|
if (g_simple_async_result_propagate_error (simple, error))
|
|
|
|
|
return NM_CONNECTIVITY_UNKNOWN;
|
|
|
|
|
return (NMConnectivityState) g_simple_async_result_get_op_res_gssize (simple);
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2014-09-24 13:14:48 -04:00
|
|
|
/* Devices */
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2014-09-24 13:14:48 -04:00
|
|
|
|
|
|
|
|
const GPtrArray *
|
|
|
|
|
nm_manager_get_devices (NMManager *manager)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
|
|
|
|
|
|
|
|
|
|
return NM_MANAGER_GET_PRIVATE (manager)->devices;
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-10 14:28:49 -05:00
|
|
|
const GPtrArray *
|
|
|
|
|
nm_manager_get_all_devices (NMManager *manager)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
|
|
|
|
|
|
|
|
|
|
return NM_MANAGER_GET_PRIVATE (manager)->all_devices;
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-24 13:14:48 -04:00
|
|
|
NMDevice *
|
|
|
|
|
nm_manager_get_device_by_path (NMManager *manager, const char *object_path)
|
|
|
|
|
{
|
|
|
|
|
const GPtrArray *devices;
|
2018-03-28 16:59:39 +02:00
|
|
|
guint i;
|
2014-09-24 13:14:48 -04:00
|
|
|
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
|
|
|
|
|
g_return_val_if_fail (object_path, NULL);
|
|
|
|
|
|
|
|
|
|
devices = nm_manager_get_devices (manager);
|
|
|
|
|
for (i = 0; i < devices->len; i++) {
|
|
|
|
|
NMDevice *candidate = g_ptr_array_index (devices, i);
|
|
|
|
|
if (!strcmp (nm_object_get_path (NM_OBJECT (candidate)), object_path)) {
|
2018-03-28 16:59:39 +02:00
|
|
|
return candidate;
|
2014-09-24 13:14:48 -04:00
|
|
|
}
|
|
|
|
|
}
|
libnm: fix crash creating checkpoint during find_checkpoint_info()
Now that the D-Bus signals in server are reordered, creating
a checkpoint in libnm crashes:
$ examples/python/gi/checkpoint.py create 4
#0 0x00007ffff6d011ee in __strcmp_sse2_unaligned () at /lib64/libc.so.6
#1 0x00007fffeb611c90 in find_checkpoint_info (manager=manager@entry=0x5555559e5110 [NMManager], path=0x7fffdc0092f0 "/org/freedesktop/NetworkManager/Checkpoint/6")
at libnm/nm-manager.c:153
#2 0x00007fffeb611d8f in checkpoint_added (manager=0x5555559e5110 [NMManager], checkpoint=checkpoint@entry=0x555555a122d0 [NMCheckpoint]) at libnm/nm-manager.c:1194
#3 0x00007fffef7db929 in g_cclosure_marshal_VOID__OBJECTv (closure=0x5555559e4b30, return_value=<optimized out>, instance=<optimized out>, args=<optimized out>, marshal_data=<optimized out>, n_params=<optimized out>, param_types=0x5555559e2fc0) at gmarshal.c:2102
#4 0x00007fffef7d8976 in _g_closure_invoke_va (closure=0x5555559e4b30, return_value=0x0, instance=0x5555559e5110, args=0x7fffffffc1c8, n_params=1, param_types=0x5555559e2fc0)
at gclosure.c:867
#5 0x00007fffef7f3ff4 in g_signal_emit_valist (instance=instance@entry=0x5555559e5110, signal_id=signal_id@entry=97, detail=0, var_args=var_args@entry=0x7fffffffc1c8) at gsignal.c:3300
#6 0x00007fffef7f4b48 in g_signal_emit_by_name (instance=instance@entry=0x5555559e5110, detailed_signal=detailed_signal@entry=0x7fffffffc310 "checkpoint-added") at gsignal.c:3487
#7 0x00007fffeb6156d1 in deferred_notify_cb (data=0x5555559e5110) at libnm/nm-object.c:219
#8 0x00007fffeb615ae7 in object_property_maybe_complete (self=0x5555559e5110 [NMManager]) at libnm/nm-object.c:555
#9 0x00007fffeb615e5d in object_created (obj=<optimized out>, path=<optimized out>, user_data=<optimized out>) at libnm/nm-object.c:576
#10 0x00007fffeb61648b in handle_object_array_property (pi=<optimized out>, value=0x7fffdc075070, property_name=0x7fffeb67f117 "checkpoints", self=0x5555559e5110 [NMManager])
at libnm/nm-object.c:671
#11 0x00007fffeb61648b in handle_property_changed (self=self@entry=0x5555559e5110 [NMManager], dbus_name=<optimized out>, value=<optimized out>) at libnm/nm-object.c:740
#12 0x00007fffeb6166e9 in properties_changed (proxy=<optimized out>, changed_properties=<optimized out>, invalidated_properties=<optimized out>, user_data=0x5555559e5110)
at libnm/nm-object.c:772
...
That is, because NetworkManager now first emits signals that the checkpoint
object was created, before answering the D-Bus request. That makes more
sense, but leads to this crash.
The ugliness of how libnm handles object visibility is considerable.
libnm hides objects until they are fully initialized. So, when
the async create-checkpoint operation returns, the object might not
yet be ready to be exposed. We need to delay the result. It would be
better if the API would simply return the created path.
2018-03-28 12:31:43 +02:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static NMCheckpoint *
|
|
|
|
|
get_checkpoint_by_path (NMManager *manager, const char *object_path)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
|
|
|
|
NMCheckpoint *candidate;
|
|
|
|
|
guint i;
|
2014-09-24 13:14:48 -04:00
|
|
|
|
libnm: fix crash creating checkpoint during find_checkpoint_info()
Now that the D-Bus signals in server are reordered, creating
a checkpoint in libnm crashes:
$ examples/python/gi/checkpoint.py create 4
#0 0x00007ffff6d011ee in __strcmp_sse2_unaligned () at /lib64/libc.so.6
#1 0x00007fffeb611c90 in find_checkpoint_info (manager=manager@entry=0x5555559e5110 [NMManager], path=0x7fffdc0092f0 "/org/freedesktop/NetworkManager/Checkpoint/6")
at libnm/nm-manager.c:153
#2 0x00007fffeb611d8f in checkpoint_added (manager=0x5555559e5110 [NMManager], checkpoint=checkpoint@entry=0x555555a122d0 [NMCheckpoint]) at libnm/nm-manager.c:1194
#3 0x00007fffef7db929 in g_cclosure_marshal_VOID__OBJECTv (closure=0x5555559e4b30, return_value=<optimized out>, instance=<optimized out>, args=<optimized out>, marshal_data=<optimized out>, n_params=<optimized out>, param_types=0x5555559e2fc0) at gmarshal.c:2102
#4 0x00007fffef7d8976 in _g_closure_invoke_va (closure=0x5555559e4b30, return_value=0x0, instance=0x5555559e5110, args=0x7fffffffc1c8, n_params=1, param_types=0x5555559e2fc0)
at gclosure.c:867
#5 0x00007fffef7f3ff4 in g_signal_emit_valist (instance=instance@entry=0x5555559e5110, signal_id=signal_id@entry=97, detail=0, var_args=var_args@entry=0x7fffffffc1c8) at gsignal.c:3300
#6 0x00007fffef7f4b48 in g_signal_emit_by_name (instance=instance@entry=0x5555559e5110, detailed_signal=detailed_signal@entry=0x7fffffffc310 "checkpoint-added") at gsignal.c:3487
#7 0x00007fffeb6156d1 in deferred_notify_cb (data=0x5555559e5110) at libnm/nm-object.c:219
#8 0x00007fffeb615ae7 in object_property_maybe_complete (self=0x5555559e5110 [NMManager]) at libnm/nm-object.c:555
#9 0x00007fffeb615e5d in object_created (obj=<optimized out>, path=<optimized out>, user_data=<optimized out>) at libnm/nm-object.c:576
#10 0x00007fffeb61648b in handle_object_array_property (pi=<optimized out>, value=0x7fffdc075070, property_name=0x7fffeb67f117 "checkpoints", self=0x5555559e5110 [NMManager])
at libnm/nm-object.c:671
#11 0x00007fffeb61648b in handle_property_changed (self=self@entry=0x5555559e5110 [NMManager], dbus_name=<optimized out>, value=<optimized out>) at libnm/nm-object.c:740
#12 0x00007fffeb6166e9 in properties_changed (proxy=<optimized out>, changed_properties=<optimized out>, invalidated_properties=<optimized out>, user_data=0x5555559e5110)
at libnm/nm-object.c:772
...
That is, because NetworkManager now first emits signals that the checkpoint
object was created, before answering the D-Bus request. That makes more
sense, but leads to this crash.
The ugliness of how libnm handles object visibility is considerable.
libnm hides objects until they are fully initialized. So, when
the async create-checkpoint operation returns, the object might not
yet be ready to be exposed. We need to delay the result. It would be
better if the API would simply return the created path.
2018-03-28 12:31:43 +02:00
|
|
|
for (i = 0; i < priv->checkpoints->len; i++) {
|
|
|
|
|
candidate = priv->checkpoints->pdata[i];
|
|
|
|
|
if (nm_streq (nm_object_get_path (NM_OBJECT (candidate)), object_path))
|
|
|
|
|
return candidate;
|
|
|
|
|
}
|
2018-03-28 16:59:39 +02:00
|
|
|
return NULL;
|
2014-09-24 13:14:48 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NMDevice *
|
|
|
|
|
nm_manager_get_device_by_iface (NMManager *manager, const char *iface)
|
|
|
|
|
{
|
|
|
|
|
const GPtrArray *devices;
|
|
|
|
|
int i;
|
|
|
|
|
NMDevice *device = NULL;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
|
|
|
|
|
g_return_val_if_fail (iface, NULL);
|
|
|
|
|
|
|
|
|
|
devices = nm_manager_get_devices (manager);
|
|
|
|
|
for (i = 0; i < devices->len; i++) {
|
|
|
|
|
NMDevice *candidate = g_ptr_array_index (devices, i);
|
|
|
|
|
if (!strcmp (nm_device_get_iface (candidate), iface)) {
|
|
|
|
|
device = candidate;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return device;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2014-09-24 13:14:48 -04:00
|
|
|
/* Active Connections */
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2014-09-24 13:14:48 -04:00
|
|
|
|
|
|
|
|
const GPtrArray *
|
|
|
|
|
nm_manager_get_active_connections (NMManager *manager)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
|
|
|
|
|
|
|
|
|
|
return NM_MANAGER_GET_PRIVATE (manager)->active_connections;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NMActiveConnection *
|
|
|
|
|
nm_manager_get_primary_connection (NMManager *manager)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
|
|
|
|
|
|
|
|
|
|
return NM_MANAGER_GET_PRIVATE (manager)->primary_connection;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NMActiveConnection *
|
|
|
|
|
nm_manager_get_activating_connection (NMManager *manager)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
|
|
|
|
|
|
|
|
|
|
return NM_MANAGER_GET_PRIVATE (manager)->activating_connection;
|
|
|
|
|
}
|
|
|
|
|
|
all: return output dictionary from "AddAndActivate2"
Add a "a{sv}" output argument to "AddAndActivate2" D-Bus API.
"AddAndActivate2" replaces "AddAndActivate" with more options.
It also has a dictionary argument to be forward compatible so that we
hopefully won't need an "AddAndActivate3". However, it lacked a similar
output dictionary. Add it for future extensibility. I think this is
really to workaround a shortcoming of D-Bus, which does provide strong
typing and type information about its API, but does not allow to extend
an existing API in a backward compatible manner. So we either resort to
Method(), Method2(), Method3() variants, or a catch-all variant with a
generic "a{sv}" input/output argument.
In libnm, rename "nm_client_add_and_activate_connection_options()" to
"nm_client_add_and_activate_connection2()". I think libnm API should have
an obvious correspondence with D-Bus API. Or stated differently, if
"AddAndActivateOptions" would be a better name, then the D-Bus API should
be renamed. We should prefer one name over the other, but regardless
of which is preferred, the naming for D-Bus and libnm API should
correspond.
In this case, I do think that AddAndActivate2() is a better name than
AddAndActivateOptions(). Hence I rename the libnm API.
Also, unless necessary, let libnm still call "AddAndActivate" instead of
"AddAndActivate2". Our backward compatibility works the way that libnm
requires a server version at least as new as itself. As such, libnm
theoretically could assume that server version is new enough to support
"AddAndActivate2" and could always use the more powerful variant.
However, we don't need to break compatibility intentionally and for
little gain. Here, it's easy to let libnm also handle old server API, by
continuing to use "AddAndActivate" for nm_client_add_and_activate_connection().
Note that during package update, we don't restart the currently running
NetworkManager instance. In such a scenario, it can easily happen that
nmcli/libnm is newer than the server version. Let's try a bit harder
to not break that.
Changes as discussed in [1].
[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/37#note_79876
2018-12-20 07:48:31 +01:00
|
|
|
typedef enum {
|
|
|
|
|
ACTIVATE_TYPE_ACTIVATE_CONNECTION,
|
|
|
|
|
ACTIVATE_TYPE_ADD_AND_ACTIVATE_CONNECTION,
|
|
|
|
|
ACTIVATE_TYPE_ADD_AND_ACTIVATE_CONNECTION2,
|
|
|
|
|
} ActivateType;
|
|
|
|
|
|
2014-09-24 13:14:48 -04:00
|
|
|
typedef struct {
|
2017-05-06 20:27:29 +02:00
|
|
|
CList lst;
|
2014-09-24 13:14:48 -04:00
|
|
|
NMManager *manager;
|
|
|
|
|
GSimpleAsyncResult *simple;
|
|
|
|
|
GCancellable *cancellable;
|
|
|
|
|
char *active_path;
|
|
|
|
|
char *new_connection_path;
|
all: return output dictionary from "AddAndActivate2"
Add a "a{sv}" output argument to "AddAndActivate2" D-Bus API.
"AddAndActivate2" replaces "AddAndActivate" with more options.
It also has a dictionary argument to be forward compatible so that we
hopefully won't need an "AddAndActivate3". However, it lacked a similar
output dictionary. Add it for future extensibility. I think this is
really to workaround a shortcoming of D-Bus, which does provide strong
typing and type information about its API, but does not allow to extend
an existing API in a backward compatible manner. So we either resort to
Method(), Method2(), Method3() variants, or a catch-all variant with a
generic "a{sv}" input/output argument.
In libnm, rename "nm_client_add_and_activate_connection_options()" to
"nm_client_add_and_activate_connection2()". I think libnm API should have
an obvious correspondence with D-Bus API. Or stated differently, if
"AddAndActivateOptions" would be a better name, then the D-Bus API should
be renamed. We should prefer one name over the other, but regardless
of which is preferred, the naming for D-Bus and libnm API should
correspond.
In this case, I do think that AddAndActivate2() is a better name than
AddAndActivateOptions(). Hence I rename the libnm API.
Also, unless necessary, let libnm still call "AddAndActivate" instead of
"AddAndActivate2". Our backward compatibility works the way that libnm
requires a server version at least as new as itself. As such, libnm
theoretically could assume that server version is new enough to support
"AddAndActivate2" and could always use the more powerful variant.
However, we don't need to break compatibility intentionally and for
little gain. Here, it's easy to let libnm also handle old server API, by
continuing to use "AddAndActivate" for nm_client_add_and_activate_connection().
Note that during package update, we don't restart the currently running
NetworkManager instance. In such a scenario, it can easily happen that
nmcli/libnm is newer than the server version. Let's try a bit harder
to not break that.
Changes as discussed in [1].
[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/37#note_79876
2018-12-20 07:48:31 +01:00
|
|
|
GVariant *add_and_activate_output;
|
|
|
|
|
gulong cancelled_id;
|
|
|
|
|
ActivateType activate_type;
|
2014-09-24 13:14:48 -04:00
|
|
|
} ActivateInfo;
|
|
|
|
|
|
all: return output dictionary from "AddAndActivate2"
Add a "a{sv}" output argument to "AddAndActivate2" D-Bus API.
"AddAndActivate2" replaces "AddAndActivate" with more options.
It also has a dictionary argument to be forward compatible so that we
hopefully won't need an "AddAndActivate3". However, it lacked a similar
output dictionary. Add it for future extensibility. I think this is
really to workaround a shortcoming of D-Bus, which does provide strong
typing and type information about its API, but does not allow to extend
an existing API in a backward compatible manner. So we either resort to
Method(), Method2(), Method3() variants, or a catch-all variant with a
generic "a{sv}" input/output argument.
In libnm, rename "nm_client_add_and_activate_connection_options()" to
"nm_client_add_and_activate_connection2()". I think libnm API should have
an obvious correspondence with D-Bus API. Or stated differently, if
"AddAndActivateOptions" would be a better name, then the D-Bus API should
be renamed. We should prefer one name over the other, but regardless
of which is preferred, the naming for D-Bus and libnm API should
correspond.
In this case, I do think that AddAndActivate2() is a better name than
AddAndActivateOptions(). Hence I rename the libnm API.
Also, unless necessary, let libnm still call "AddAndActivate" instead of
"AddAndActivate2". Our backward compatibility works the way that libnm
requires a server version at least as new as itself. As such, libnm
theoretically could assume that server version is new enough to support
"AddAndActivate2" and could always use the more powerful variant.
However, we don't need to break compatibility intentionally and for
little gain. Here, it's easy to let libnm also handle old server API, by
continuing to use "AddAndActivate" for nm_client_add_and_activate_connection().
Note that during package update, we don't restart the currently running
NetworkManager instance. In such a scenario, it can easily happen that
nmcli/libnm is newer than the server version. Let's try a bit harder
to not break that.
Changes as discussed in [1].
[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/37#note_79876
2018-12-20 07:48:31 +01:00
|
|
|
_NMActivateResult *
|
|
|
|
|
_nm_activate_result_new (NMActiveConnection *active,
|
|
|
|
|
GVariant *add_and_activate_output)
|
|
|
|
|
{
|
|
|
|
|
_NMActivateResult *r;
|
|
|
|
|
|
|
|
|
|
nm_assert (!add_and_activate_output || g_variant_is_of_type (add_and_activate_output, G_VARIANT_TYPE ("a{sv}")));
|
|
|
|
|
nm_assert (!add_and_activate_output || !g_variant_is_floating (add_and_activate_output));
|
|
|
|
|
|
|
|
|
|
r = g_slice_new (_NMActivateResult);
|
|
|
|
|
*r = (_NMActivateResult) {
|
|
|
|
|
.active = g_object_ref (active),
|
|
|
|
|
.add_and_activate_output = nm_g_variant_ref (add_and_activate_output),
|
|
|
|
|
};
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
_nm_activate_result_free (_NMActivateResult *result)
|
|
|
|
|
{
|
|
|
|
|
g_object_unref (result->active);
|
|
|
|
|
nm_g_variant_unref (result->add_and_activate_output);
|
|
|
|
|
g_slice_free (_NMActivateResult, result);
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-24 13:14:48 -04:00
|
|
|
static void
|
|
|
|
|
activate_info_complete (ActivateInfo *info,
|
|
|
|
|
NMActiveConnection *active,
|
|
|
|
|
GError *error)
|
|
|
|
|
{
|
2019-02-22 08:00:01 +01:00
|
|
|
nm_assert ((!error) != (!active));
|
|
|
|
|
|
2018-10-25 12:08:47 +02:00
|
|
|
nm_clear_g_signal_handler (info->cancellable, &info->cancelled_id);
|
|
|
|
|
|
|
|
|
|
c_list_unlink_stale (&info->lst);
|
|
|
|
|
|
all: return output dictionary from "AddAndActivate2"
Add a "a{sv}" output argument to "AddAndActivate2" D-Bus API.
"AddAndActivate2" replaces "AddAndActivate" with more options.
It also has a dictionary argument to be forward compatible so that we
hopefully won't need an "AddAndActivate3". However, it lacked a similar
output dictionary. Add it for future extensibility. I think this is
really to workaround a shortcoming of D-Bus, which does provide strong
typing and type information about its API, but does not allow to extend
an existing API in a backward compatible manner. So we either resort to
Method(), Method2(), Method3() variants, or a catch-all variant with a
generic "a{sv}" input/output argument.
In libnm, rename "nm_client_add_and_activate_connection_options()" to
"nm_client_add_and_activate_connection2()". I think libnm API should have
an obvious correspondence with D-Bus API. Or stated differently, if
"AddAndActivateOptions" would be a better name, then the D-Bus API should
be renamed. We should prefer one name over the other, but regardless
of which is preferred, the naming for D-Bus and libnm API should
correspond.
In this case, I do think that AddAndActivate2() is a better name than
AddAndActivateOptions(). Hence I rename the libnm API.
Also, unless necessary, let libnm still call "AddAndActivate" instead of
"AddAndActivate2". Our backward compatibility works the way that libnm
requires a server version at least as new as itself. As such, libnm
theoretically could assume that server version is new enough to support
"AddAndActivate2" and could always use the more powerful variant.
However, we don't need to break compatibility intentionally and for
little gain. Here, it's easy to let libnm also handle old server API, by
continuing to use "AddAndActivate" for nm_client_add_and_activate_connection().
Note that during package update, we don't restart the currently running
NetworkManager instance. In such a scenario, it can easily happen that
nmcli/libnm is newer than the server version. Let's try a bit harder
to not break that.
Changes as discussed in [1].
[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/37#note_79876
2018-12-20 07:48:31 +01:00
|
|
|
if (active) {
|
|
|
|
|
g_simple_async_result_set_op_res_gpointer (info->simple,
|
|
|
|
|
_nm_activate_result_new (active,
|
|
|
|
|
info->add_and_activate_output),
|
|
|
|
|
(GDestroyNotify) _nm_activate_result_free);
|
|
|
|
|
} else
|
2014-09-24 13:14:48 -04:00
|
|
|
g_simple_async_result_set_from_error (info->simple, error);
|
all: return output dictionary from "AddAndActivate2"
Add a "a{sv}" output argument to "AddAndActivate2" D-Bus API.
"AddAndActivate2" replaces "AddAndActivate" with more options.
It also has a dictionary argument to be forward compatible so that we
hopefully won't need an "AddAndActivate3". However, it lacked a similar
output dictionary. Add it for future extensibility. I think this is
really to workaround a shortcoming of D-Bus, which does provide strong
typing and type information about its API, but does not allow to extend
an existing API in a backward compatible manner. So we either resort to
Method(), Method2(), Method3() variants, or a catch-all variant with a
generic "a{sv}" input/output argument.
In libnm, rename "nm_client_add_and_activate_connection_options()" to
"nm_client_add_and_activate_connection2()". I think libnm API should have
an obvious correspondence with D-Bus API. Or stated differently, if
"AddAndActivateOptions" would be a better name, then the D-Bus API should
be renamed. We should prefer one name over the other, but regardless
of which is preferred, the naming for D-Bus and libnm API should
correspond.
In this case, I do think that AddAndActivate2() is a better name than
AddAndActivateOptions(). Hence I rename the libnm API.
Also, unless necessary, let libnm still call "AddAndActivate" instead of
"AddAndActivate2". Our backward compatibility works the way that libnm
requires a server version at least as new as itself. As such, libnm
theoretically could assume that server version is new enough to support
"AddAndActivate2" and could always use the more powerful variant.
However, we don't need to break compatibility intentionally and for
little gain. Here, it's easy to let libnm also handle old server API, by
continuing to use "AddAndActivate" for nm_client_add_and_activate_connection().
Note that during package update, we don't restart the currently running
NetworkManager instance. In such a scenario, it can easily happen that
nmcli/libnm is newer than the server version. Let's try a bit harder
to not break that.
Changes as discussed in [1].
[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/37#note_79876
2018-12-20 07:48:31 +01:00
|
|
|
|
2014-09-24 13:14:48 -04:00
|
|
|
g_simple_async_result_complete (info->simple);
|
|
|
|
|
|
all: return output dictionary from "AddAndActivate2"
Add a "a{sv}" output argument to "AddAndActivate2" D-Bus API.
"AddAndActivate2" replaces "AddAndActivate" with more options.
It also has a dictionary argument to be forward compatible so that we
hopefully won't need an "AddAndActivate3". However, it lacked a similar
output dictionary. Add it for future extensibility. I think this is
really to workaround a shortcoming of D-Bus, which does provide strong
typing and type information about its API, but does not allow to extend
an existing API in a backward compatible manner. So we either resort to
Method(), Method2(), Method3() variants, or a catch-all variant with a
generic "a{sv}" input/output argument.
In libnm, rename "nm_client_add_and_activate_connection_options()" to
"nm_client_add_and_activate_connection2()". I think libnm API should have
an obvious correspondence with D-Bus API. Or stated differently, if
"AddAndActivateOptions" would be a better name, then the D-Bus API should
be renamed. We should prefer one name over the other, but regardless
of which is preferred, the naming for D-Bus and libnm API should
correspond.
In this case, I do think that AddAndActivate2() is a better name than
AddAndActivateOptions(). Hence I rename the libnm API.
Also, unless necessary, let libnm still call "AddAndActivate" instead of
"AddAndActivate2". Our backward compatibility works the way that libnm
requires a server version at least as new as itself. As such, libnm
theoretically could assume that server version is new enough to support
"AddAndActivate2" and could always use the more powerful variant.
However, we don't need to break compatibility intentionally and for
little gain. Here, it's easy to let libnm also handle old server API, by
continuing to use "AddAndActivate" for nm_client_add_and_activate_connection().
Note that during package update, we don't restart the currently running
NetworkManager instance. In such a scenario, it can easily happen that
nmcli/libnm is newer than the server version. Let's try a bit harder
to not break that.
Changes as discussed in [1].
[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/37#note_79876
2018-12-20 07:48:31 +01:00
|
|
|
nm_g_variant_unref (info->add_and_activate_output);
|
2014-09-24 13:14:48 -04:00
|
|
|
g_free (info->active_path);
|
|
|
|
|
g_free (info->new_connection_path);
|
|
|
|
|
g_object_unref (info->simple);
|
2018-10-25 12:08:47 +02:00
|
|
|
nm_g_object_unref (info->cancellable);
|
2014-09-24 13:14:48 -04:00
|
|
|
g_slice_free (ActivateInfo, info);
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-10 14:43:55 -04:00
|
|
|
static NMActiveConnection *
|
|
|
|
|
find_active_connection_by_path (NMManager *self, const char *ac_path)
|
2014-09-24 13:14:48 -04:00
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
int i;
|
|
|
|
|
|
2014-10-10 14:43:55 -04:00
|
|
|
for (i = 0; i < priv->active_connections->len; i++) {
|
|
|
|
|
NMActiveConnection *candidate = g_ptr_array_index (priv->active_connections, i);
|
|
|
|
|
const char *candidate_path = nm_object_get_path (NM_OBJECT (candidate));
|
|
|
|
|
|
|
|
|
|
if (g_strcmp0 (ac_path, candidate_path) == 0)
|
|
|
|
|
return candidate;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
recheck_pending_activations (NMManager *self)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2017-05-06 20:27:29 +02:00
|
|
|
CList *iter, *safe;
|
2014-10-10 14:43:55 -04:00
|
|
|
NMActiveConnection *candidate;
|
|
|
|
|
const GPtrArray *devices;
|
|
|
|
|
NMDevice *device;
|
2016-10-18 16:35:07 +02:00
|
|
|
GDBusObjectManager *object_manager = NULL;
|
|
|
|
|
GError *error;
|
|
|
|
|
|
|
|
|
|
object_manager = _nm_object_get_dbus_object_manager (NM_OBJECT (self));
|
2014-09-24 13:14:48 -04:00
|
|
|
|
2014-10-10 14:43:55 -04:00
|
|
|
/* For each pending activation, look for an active connection that has the
|
|
|
|
|
* pending activation's object path, where the active connection and its
|
|
|
|
|
* device have both updated their properties to point to each other, and
|
|
|
|
|
* call the pending connection's callback.
|
2014-09-24 13:14:48 -04:00
|
|
|
*/
|
2017-05-06 20:27:29 +02:00
|
|
|
c_list_for_each_safe (iter, safe, &priv->pending_activations) {
|
|
|
|
|
ActivateInfo *info = c_list_entry (iter, ActivateInfo, lst);
|
2016-10-18 16:35:07 +02:00
|
|
|
gs_unref_object GDBusObject *dbus_obj = NULL;
|
2014-09-24 13:14:48 -04:00
|
|
|
|
2016-10-18 16:35:07 +02:00
|
|
|
if (!info->active_path)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* Check that the object manager still knows about the object.
|
|
|
|
|
* It could be that it vanished before we even learned its name. */
|
|
|
|
|
dbus_obj = g_dbus_object_manager_get_object (object_manager, info->active_path);
|
|
|
|
|
if (!dbus_obj) {
|
|
|
|
|
error = g_error_new_literal (NM_CLIENT_ERROR,
|
|
|
|
|
NM_CLIENT_ERROR_OBJECT_CREATION_FAILED,
|
|
|
|
|
_("Active connection removed before it was initialized"));
|
|
|
|
|
activate_info_complete (info, NULL, error);
|
|
|
|
|
g_clear_error (&error);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-10 14:43:55 -04:00
|
|
|
candidate = find_active_connection_by_path (self, info->active_path);
|
|
|
|
|
if (!candidate)
|
|
|
|
|
continue;
|
2014-09-24 13:14:48 -04:00
|
|
|
|
2014-10-10 14:43:55 -04:00
|
|
|
/* Check that the AC and device are both ready */
|
|
|
|
|
devices = nm_active_connection_get_devices (candidate);
|
|
|
|
|
if (devices->len == 0)
|
|
|
|
|
continue;
|
2014-11-09 14:09:40 +01:00
|
|
|
|
|
|
|
|
if (!NM_IS_VPN_CONNECTION (candidate)) {
|
|
|
|
|
device = devices->pdata[0];
|
|
|
|
|
if (nm_device_get_active_connection (device) != candidate)
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2014-09-24 13:14:48 -04:00
|
|
|
|
2014-10-10 14:43:55 -04:00
|
|
|
activate_info_complete (info, candidate, NULL);
|
|
|
|
|
break;
|
2014-09-24 13:14:48 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
activation_cancelled (GCancellable *cancellable,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
ActivateInfo *info = user_data;
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
|
|
if (!g_cancellable_set_error_if_cancelled (cancellable, &error))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
activate_info_complete (info, NULL, error);
|
|
|
|
|
g_clear_error (&error);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
activate_cb (GObject *object,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
ActivateInfo *info = user_data;
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
|
|
if (nmdbus_manager_call_activate_connection_finish (NMDBUS_MANAGER (object),
|
|
|
|
|
&info->active_path,
|
|
|
|
|
result, &error)) {
|
|
|
|
|
if (info->cancellable) {
|
|
|
|
|
info->cancelled_id = g_signal_connect (info->cancellable, "cancelled",
|
|
|
|
|
G_CALLBACK (activation_cancelled), info);
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-10 14:43:55 -04:00
|
|
|
recheck_pending_activations (info->manager);
|
2014-09-24 13:14:48 -04:00
|
|
|
} else {
|
2014-10-15 18:26:32 -04:00
|
|
|
g_dbus_error_strip_remote_error (error);
|
2014-09-24 13:14:48 -04:00
|
|
|
activate_info_complete (info, NULL, error);
|
|
|
|
|
g_clear_error (&error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_manager_activate_connection_async (NMManager *manager,
|
|
|
|
|
NMConnection *connection,
|
|
|
|
|
NMDevice *device,
|
|
|
|
|
const char *specific_object,
|
|
|
|
|
GCancellable *cancellable,
|
|
|
|
|
GAsyncReadyCallback callback,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv;
|
|
|
|
|
ActivateInfo *info;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (NM_IS_MANAGER (manager));
|
|
|
|
|
if (device)
|
|
|
|
|
g_return_if_fail (NM_IS_DEVICE (device));
|
|
|
|
|
if (connection)
|
|
|
|
|
g_return_if_fail (NM_IS_CONNECTION (connection));
|
|
|
|
|
|
2017-05-06 20:27:29 +02:00
|
|
|
priv = NM_MANAGER_GET_PRIVATE (manager);
|
|
|
|
|
|
2014-09-24 13:14:48 -04:00
|
|
|
info = g_slice_new0 (ActivateInfo);
|
all: return output dictionary from "AddAndActivate2"
Add a "a{sv}" output argument to "AddAndActivate2" D-Bus API.
"AddAndActivate2" replaces "AddAndActivate" with more options.
It also has a dictionary argument to be forward compatible so that we
hopefully won't need an "AddAndActivate3". However, it lacked a similar
output dictionary. Add it for future extensibility. I think this is
really to workaround a shortcoming of D-Bus, which does provide strong
typing and type information about its API, but does not allow to extend
an existing API in a backward compatible manner. So we either resort to
Method(), Method2(), Method3() variants, or a catch-all variant with a
generic "a{sv}" input/output argument.
In libnm, rename "nm_client_add_and_activate_connection_options()" to
"nm_client_add_and_activate_connection2()". I think libnm API should have
an obvious correspondence with D-Bus API. Or stated differently, if
"AddAndActivateOptions" would be a better name, then the D-Bus API should
be renamed. We should prefer one name over the other, but regardless
of which is preferred, the naming for D-Bus and libnm API should
correspond.
In this case, I do think that AddAndActivate2() is a better name than
AddAndActivateOptions(). Hence I rename the libnm API.
Also, unless necessary, let libnm still call "AddAndActivate" instead of
"AddAndActivate2". Our backward compatibility works the way that libnm
requires a server version at least as new as itself. As such, libnm
theoretically could assume that server version is new enough to support
"AddAndActivate2" and could always use the more powerful variant.
However, we don't need to break compatibility intentionally and for
little gain. Here, it's easy to let libnm also handle old server API, by
continuing to use "AddAndActivate" for nm_client_add_and_activate_connection().
Note that during package update, we don't restart the currently running
NetworkManager instance. In such a scenario, it can easily happen that
nmcli/libnm is newer than the server version. Let's try a bit harder
to not break that.
Changes as discussed in [1].
[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/37#note_79876
2018-12-20 07:48:31 +01:00
|
|
|
info->activate_type = ACTIVATE_TYPE_ACTIVATE_CONNECTION;
|
2014-09-24 13:14:48 -04:00
|
|
|
info->manager = manager;
|
|
|
|
|
info->simple = g_simple_async_result_new (G_OBJECT (manager), callback, user_data,
|
|
|
|
|
nm_manager_activate_connection_async);
|
2018-03-05 16:02:24 +01:00
|
|
|
if (cancellable)
|
|
|
|
|
g_simple_async_result_set_check_cancellable (info->simple, cancellable);
|
2014-09-24 13:14:48 -04:00
|
|
|
info->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
|
|
|
|
|
|
2017-05-06 20:27:29 +02:00
|
|
|
c_list_link_tail (&priv->pending_activations, &info->lst);
|
2014-09-24 13:14:48 -04:00
|
|
|
|
2016-11-14 18:47:56 +01:00
|
|
|
nmdbus_manager_call_activate_connection (priv->proxy,
|
2014-09-24 13:14:48 -04:00
|
|
|
connection ? nm_connection_get_path (connection) : "/",
|
|
|
|
|
device ? nm_object_get_path (NM_OBJECT (device)) : "/",
|
2018-04-24 11:20:03 +02:00
|
|
|
specific_object ?: "/",
|
2014-09-24 13:14:48 -04:00
|
|
|
cancellable,
|
|
|
|
|
activate_cb, info);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NMActiveConnection *
|
|
|
|
|
nm_manager_activate_connection_finish (NMManager *manager,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
GSimpleAsyncResult *simple;
|
all: return output dictionary from "AddAndActivate2"
Add a "a{sv}" output argument to "AddAndActivate2" D-Bus API.
"AddAndActivate2" replaces "AddAndActivate" with more options.
It also has a dictionary argument to be forward compatible so that we
hopefully won't need an "AddAndActivate3". However, it lacked a similar
output dictionary. Add it for future extensibility. I think this is
really to workaround a shortcoming of D-Bus, which does provide strong
typing and type information about its API, but does not allow to extend
an existing API in a backward compatible manner. So we either resort to
Method(), Method2(), Method3() variants, or a catch-all variant with a
generic "a{sv}" input/output argument.
In libnm, rename "nm_client_add_and_activate_connection_options()" to
"nm_client_add_and_activate_connection2()". I think libnm API should have
an obvious correspondence with D-Bus API. Or stated differently, if
"AddAndActivateOptions" would be a better name, then the D-Bus API should
be renamed. We should prefer one name over the other, but regardless
of which is preferred, the naming for D-Bus and libnm API should
correspond.
In this case, I do think that AddAndActivate2() is a better name than
AddAndActivateOptions(). Hence I rename the libnm API.
Also, unless necessary, let libnm still call "AddAndActivate" instead of
"AddAndActivate2". Our backward compatibility works the way that libnm
requires a server version at least as new as itself. As such, libnm
theoretically could assume that server version is new enough to support
"AddAndActivate2" and could always use the more powerful variant.
However, we don't need to break compatibility intentionally and for
little gain. Here, it's easy to let libnm also handle old server API, by
continuing to use "AddAndActivate" for nm_client_add_and_activate_connection().
Note that during package update, we don't restart the currently running
NetworkManager instance. In such a scenario, it can easily happen that
nmcli/libnm is newer than the server version. Let's try a bit harder
to not break that.
Changes as discussed in [1].
[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/37#note_79876
2018-12-20 07:48:31 +01:00
|
|
|
_NMActivateResult *r;
|
2014-09-24 13:14:48 -04:00
|
|
|
|
|
|
|
|
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (manager), nm_manager_activate_connection_async), NULL);
|
|
|
|
|
|
|
|
|
|
simple = G_SIMPLE_ASYNC_RESULT (result);
|
|
|
|
|
if (g_simple_async_result_propagate_error (simple, error))
|
|
|
|
|
return NULL;
|
all: return output dictionary from "AddAndActivate2"
Add a "a{sv}" output argument to "AddAndActivate2" D-Bus API.
"AddAndActivate2" replaces "AddAndActivate" with more options.
It also has a dictionary argument to be forward compatible so that we
hopefully won't need an "AddAndActivate3". However, it lacked a similar
output dictionary. Add it for future extensibility. I think this is
really to workaround a shortcoming of D-Bus, which does provide strong
typing and type information about its API, but does not allow to extend
an existing API in a backward compatible manner. So we either resort to
Method(), Method2(), Method3() variants, or a catch-all variant with a
generic "a{sv}" input/output argument.
In libnm, rename "nm_client_add_and_activate_connection_options()" to
"nm_client_add_and_activate_connection2()". I think libnm API should have
an obvious correspondence with D-Bus API. Or stated differently, if
"AddAndActivateOptions" would be a better name, then the D-Bus API should
be renamed. We should prefer one name over the other, but regardless
of which is preferred, the naming for D-Bus and libnm API should
correspond.
In this case, I do think that AddAndActivate2() is a better name than
AddAndActivateOptions(). Hence I rename the libnm API.
Also, unless necessary, let libnm still call "AddAndActivate" instead of
"AddAndActivate2". Our backward compatibility works the way that libnm
requires a server version at least as new as itself. As such, libnm
theoretically could assume that server version is new enough to support
"AddAndActivate2" and could always use the more powerful variant.
However, we don't need to break compatibility intentionally and for
little gain. Here, it's easy to let libnm also handle old server API, by
continuing to use "AddAndActivate" for nm_client_add_and_activate_connection().
Note that during package update, we don't restart the currently running
NetworkManager instance. In such a scenario, it can easily happen that
nmcli/libnm is newer than the server version. Let's try a bit harder
to not break that.
Changes as discussed in [1].
[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/37#note_79876
2018-12-20 07:48:31 +01:00
|
|
|
|
|
|
|
|
r = g_simple_async_result_get_op_res_gpointer (simple);
|
|
|
|
|
return g_object_ref (r->active);
|
2014-09-24 13:14:48 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
add_activate_cb (GObject *object,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
ActivateInfo *info = user_data;
|
2019-01-21 17:21:35 +01:00
|
|
|
gs_free_error GError *error = NULL;
|
all: return output dictionary from "AddAndActivate2"
Add a "a{sv}" output argument to "AddAndActivate2" D-Bus API.
"AddAndActivate2" replaces "AddAndActivate" with more options.
It also has a dictionary argument to be forward compatible so that we
hopefully won't need an "AddAndActivate3". However, it lacked a similar
output dictionary. Add it for future extensibility. I think this is
really to workaround a shortcoming of D-Bus, which does provide strong
typing and type information about its API, but does not allow to extend
an existing API in a backward compatible manner. So we either resort to
Method(), Method2(), Method3() variants, or a catch-all variant with a
generic "a{sv}" input/output argument.
In libnm, rename "nm_client_add_and_activate_connection_options()" to
"nm_client_add_and_activate_connection2()". I think libnm API should have
an obvious correspondence with D-Bus API. Or stated differently, if
"AddAndActivateOptions" would be a better name, then the D-Bus API should
be renamed. We should prefer one name over the other, but regardless
of which is preferred, the naming for D-Bus and libnm API should
correspond.
In this case, I do think that AddAndActivate2() is a better name than
AddAndActivateOptions(). Hence I rename the libnm API.
Also, unless necessary, let libnm still call "AddAndActivate" instead of
"AddAndActivate2". Our backward compatibility works the way that libnm
requires a server version at least as new as itself. As such, libnm
theoretically could assume that server version is new enough to support
"AddAndActivate2" and could always use the more powerful variant.
However, we don't need to break compatibility intentionally and for
little gain. Here, it's easy to let libnm also handle old server API, by
continuing to use "AddAndActivate" for nm_client_add_and_activate_connection().
Note that during package update, we don't restart the currently running
NetworkManager instance. In such a scenario, it can easily happen that
nmcli/libnm is newer than the server version. Let's try a bit harder
to not break that.
Changes as discussed in [1].
[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/37#note_79876
2018-12-20 07:48:31 +01:00
|
|
|
gboolean success;
|
|
|
|
|
|
2019-02-22 08:00:01 +01:00
|
|
|
nm_assert (info);
|
|
|
|
|
nm_assert (!info->active_path);
|
|
|
|
|
nm_assert (!info->add_and_activate_output);
|
|
|
|
|
|
all: return output dictionary from "AddAndActivate2"
Add a "a{sv}" output argument to "AddAndActivate2" D-Bus API.
"AddAndActivate2" replaces "AddAndActivate" with more options.
It also has a dictionary argument to be forward compatible so that we
hopefully won't need an "AddAndActivate3". However, it lacked a similar
output dictionary. Add it for future extensibility. I think this is
really to workaround a shortcoming of D-Bus, which does provide strong
typing and type information about its API, but does not allow to extend
an existing API in a backward compatible manner. So we either resort to
Method(), Method2(), Method3() variants, or a catch-all variant with a
generic "a{sv}" input/output argument.
In libnm, rename "nm_client_add_and_activate_connection_options()" to
"nm_client_add_and_activate_connection2()". I think libnm API should have
an obvious correspondence with D-Bus API. Or stated differently, if
"AddAndActivateOptions" would be a better name, then the D-Bus API should
be renamed. We should prefer one name over the other, but regardless
of which is preferred, the naming for D-Bus and libnm API should
correspond.
In this case, I do think that AddAndActivate2() is a better name than
AddAndActivateOptions(). Hence I rename the libnm API.
Also, unless necessary, let libnm still call "AddAndActivate" instead of
"AddAndActivate2". Our backward compatibility works the way that libnm
requires a server version at least as new as itself. As such, libnm
theoretically could assume that server version is new enough to support
"AddAndActivate2" and could always use the more powerful variant.
However, we don't need to break compatibility intentionally and for
little gain. Here, it's easy to let libnm also handle old server API, by
continuing to use "AddAndActivate" for nm_client_add_and_activate_connection().
Note that during package update, we don't restart the currently running
NetworkManager instance. In such a scenario, it can easily happen that
nmcli/libnm is newer than the server version. Let's try a bit harder
to not break that.
Changes as discussed in [1].
[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/37#note_79876
2018-12-20 07:48:31 +01:00
|
|
|
if (info->activate_type == ACTIVATE_TYPE_ADD_AND_ACTIVATE_CONNECTION) {
|
|
|
|
|
success = nmdbus_manager_call_add_and_activate_connection_finish (NMDBUS_MANAGER (object),
|
|
|
|
|
NULL,
|
|
|
|
|
&info->active_path,
|
|
|
|
|
result,
|
|
|
|
|
&error);
|
2014-09-24 13:14:48 -04:00
|
|
|
} else {
|
all: return output dictionary from "AddAndActivate2"
Add a "a{sv}" output argument to "AddAndActivate2" D-Bus API.
"AddAndActivate2" replaces "AddAndActivate" with more options.
It also has a dictionary argument to be forward compatible so that we
hopefully won't need an "AddAndActivate3". However, it lacked a similar
output dictionary. Add it for future extensibility. I think this is
really to workaround a shortcoming of D-Bus, which does provide strong
typing and type information about its API, but does not allow to extend
an existing API in a backward compatible manner. So we either resort to
Method(), Method2(), Method3() variants, or a catch-all variant with a
generic "a{sv}" input/output argument.
In libnm, rename "nm_client_add_and_activate_connection_options()" to
"nm_client_add_and_activate_connection2()". I think libnm API should have
an obvious correspondence with D-Bus API. Or stated differently, if
"AddAndActivateOptions" would be a better name, then the D-Bus API should
be renamed. We should prefer one name over the other, but regardless
of which is preferred, the naming for D-Bus and libnm API should
correspond.
In this case, I do think that AddAndActivate2() is a better name than
AddAndActivateOptions(). Hence I rename the libnm API.
Also, unless necessary, let libnm still call "AddAndActivate" instead of
"AddAndActivate2". Our backward compatibility works the way that libnm
requires a server version at least as new as itself. As such, libnm
theoretically could assume that server version is new enough to support
"AddAndActivate2" and could always use the more powerful variant.
However, we don't need to break compatibility intentionally and for
little gain. Here, it's easy to let libnm also handle old server API, by
continuing to use "AddAndActivate" for nm_client_add_and_activate_connection().
Note that during package update, we don't restart the currently running
NetworkManager instance. In such a scenario, it can easily happen that
nmcli/libnm is newer than the server version. Let's try a bit harder
to not break that.
Changes as discussed in [1].
[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/37#note_79876
2018-12-20 07:48:31 +01:00
|
|
|
success = nmdbus_manager_call_add_and_activate_connection2_finish (NMDBUS_MANAGER (object),
|
|
|
|
|
NULL,
|
|
|
|
|
&info->active_path,
|
|
|
|
|
&info->add_and_activate_output,
|
|
|
|
|
result,
|
|
|
|
|
&error);
|
|
|
|
|
}
|
|
|
|
|
if (!success) {
|
2014-10-15 18:26:32 -04:00
|
|
|
g_dbus_error_strip_remote_error (error);
|
2014-09-24 13:14:48 -04:00
|
|
|
activate_info_complete (info, NULL, error);
|
all: return output dictionary from "AddAndActivate2"
Add a "a{sv}" output argument to "AddAndActivate2" D-Bus API.
"AddAndActivate2" replaces "AddAndActivate" with more options.
It also has a dictionary argument to be forward compatible so that we
hopefully won't need an "AddAndActivate3". However, it lacked a similar
output dictionary. Add it for future extensibility. I think this is
really to workaround a shortcoming of D-Bus, which does provide strong
typing and type information about its API, but does not allow to extend
an existing API in a backward compatible manner. So we either resort to
Method(), Method2(), Method3() variants, or a catch-all variant with a
generic "a{sv}" input/output argument.
In libnm, rename "nm_client_add_and_activate_connection_options()" to
"nm_client_add_and_activate_connection2()". I think libnm API should have
an obvious correspondence with D-Bus API. Or stated differently, if
"AddAndActivateOptions" would be a better name, then the D-Bus API should
be renamed. We should prefer one name over the other, but regardless
of which is preferred, the naming for D-Bus and libnm API should
correspond.
In this case, I do think that AddAndActivate2() is a better name than
AddAndActivateOptions(). Hence I rename the libnm API.
Also, unless necessary, let libnm still call "AddAndActivate" instead of
"AddAndActivate2". Our backward compatibility works the way that libnm
requires a server version at least as new as itself. As such, libnm
theoretically could assume that server version is new enough to support
"AddAndActivate2" and could always use the more powerful variant.
However, we don't need to break compatibility intentionally and for
little gain. Here, it's easy to let libnm also handle old server API, by
continuing to use "AddAndActivate" for nm_client_add_and_activate_connection().
Note that during package update, we don't restart the currently running
NetworkManager instance. In such a scenario, it can easily happen that
nmcli/libnm is newer than the server version. Let's try a bit harder
to not break that.
Changes as discussed in [1].
[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/37#note_79876
2018-12-20 07:48:31 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (info->cancellable) {
|
|
|
|
|
info->cancelled_id = g_signal_connect (info->cancellable, "cancelled",
|
|
|
|
|
G_CALLBACK (activation_cancelled), info);
|
2014-09-24 13:14:48 -04:00
|
|
|
}
|
all: return output dictionary from "AddAndActivate2"
Add a "a{sv}" output argument to "AddAndActivate2" D-Bus API.
"AddAndActivate2" replaces "AddAndActivate" with more options.
It also has a dictionary argument to be forward compatible so that we
hopefully won't need an "AddAndActivate3". However, it lacked a similar
output dictionary. Add it for future extensibility. I think this is
really to workaround a shortcoming of D-Bus, which does provide strong
typing and type information about its API, but does not allow to extend
an existing API in a backward compatible manner. So we either resort to
Method(), Method2(), Method3() variants, or a catch-all variant with a
generic "a{sv}" input/output argument.
In libnm, rename "nm_client_add_and_activate_connection_options()" to
"nm_client_add_and_activate_connection2()". I think libnm API should have
an obvious correspondence with D-Bus API. Or stated differently, if
"AddAndActivateOptions" would be a better name, then the D-Bus API should
be renamed. We should prefer one name over the other, but regardless
of which is preferred, the naming for D-Bus and libnm API should
correspond.
In this case, I do think that AddAndActivate2() is a better name than
AddAndActivateOptions(). Hence I rename the libnm API.
Also, unless necessary, let libnm still call "AddAndActivate" instead of
"AddAndActivate2". Our backward compatibility works the way that libnm
requires a server version at least as new as itself. As such, libnm
theoretically could assume that server version is new enough to support
"AddAndActivate2" and could always use the more powerful variant.
However, we don't need to break compatibility intentionally and for
little gain. Here, it's easy to let libnm also handle old server API, by
continuing to use "AddAndActivate" for nm_client_add_and_activate_connection().
Note that during package update, we don't restart the currently running
NetworkManager instance. In such a scenario, it can easily happen that
nmcli/libnm is newer than the server version. Let's try a bit harder
to not break that.
Changes as discussed in [1].
[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/37#note_79876
2018-12-20 07:48:31 +01:00
|
|
|
|
|
|
|
|
recheck_pending_activations (info->manager);
|
2014-09-24 13:14:48 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_manager_add_and_activate_connection_async (NMManager *manager,
|
|
|
|
|
NMConnection *partial,
|
|
|
|
|
NMDevice *device,
|
|
|
|
|
const char *specific_object,
|
2018-10-26 13:44:38 +02:00
|
|
|
GVariant *options,
|
all: return output dictionary from "AddAndActivate2"
Add a "a{sv}" output argument to "AddAndActivate2" D-Bus API.
"AddAndActivate2" replaces "AddAndActivate" with more options.
It also has a dictionary argument to be forward compatible so that we
hopefully won't need an "AddAndActivate3". However, it lacked a similar
output dictionary. Add it for future extensibility. I think this is
really to workaround a shortcoming of D-Bus, which does provide strong
typing and type information about its API, but does not allow to extend
an existing API in a backward compatible manner. So we either resort to
Method(), Method2(), Method3() variants, or a catch-all variant with a
generic "a{sv}" input/output argument.
In libnm, rename "nm_client_add_and_activate_connection_options()" to
"nm_client_add_and_activate_connection2()". I think libnm API should have
an obvious correspondence with D-Bus API. Or stated differently, if
"AddAndActivateOptions" would be a better name, then the D-Bus API should
be renamed. We should prefer one name over the other, but regardless
of which is preferred, the naming for D-Bus and libnm API should
correspond.
In this case, I do think that AddAndActivate2() is a better name than
AddAndActivateOptions(). Hence I rename the libnm API.
Also, unless necessary, let libnm still call "AddAndActivate" instead of
"AddAndActivate2". Our backward compatibility works the way that libnm
requires a server version at least as new as itself. As such, libnm
theoretically could assume that server version is new enough to support
"AddAndActivate2" and could always use the more powerful variant.
However, we don't need to break compatibility intentionally and for
little gain. Here, it's easy to let libnm also handle old server API, by
continuing to use "AddAndActivate" for nm_client_add_and_activate_connection().
Note that during package update, we don't restart the currently running
NetworkManager instance. In such a scenario, it can easily happen that
nmcli/libnm is newer than the server version. Let's try a bit harder
to not break that.
Changes as discussed in [1].
[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/37#note_79876
2018-12-20 07:48:31 +01:00
|
|
|
gboolean force_v2,
|
2014-09-24 13:14:48 -04:00
|
|
|
GCancellable *cancellable,
|
|
|
|
|
GAsyncReadyCallback callback,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv;
|
|
|
|
|
GVariant *dict = NULL;
|
|
|
|
|
ActivateInfo *info;
|
all: return output dictionary from "AddAndActivate2"
Add a "a{sv}" output argument to "AddAndActivate2" D-Bus API.
"AddAndActivate2" replaces "AddAndActivate" with more options.
It also has a dictionary argument to be forward compatible so that we
hopefully won't need an "AddAndActivate3". However, it lacked a similar
output dictionary. Add it for future extensibility. I think this is
really to workaround a shortcoming of D-Bus, which does provide strong
typing and type information about its API, but does not allow to extend
an existing API in a backward compatible manner. So we either resort to
Method(), Method2(), Method3() variants, or a catch-all variant with a
generic "a{sv}" input/output argument.
In libnm, rename "nm_client_add_and_activate_connection_options()" to
"nm_client_add_and_activate_connection2()". I think libnm API should have
an obvious correspondence with D-Bus API. Or stated differently, if
"AddAndActivateOptions" would be a better name, then the D-Bus API should
be renamed. We should prefer one name over the other, but regardless
of which is preferred, the naming for D-Bus and libnm API should
correspond.
In this case, I do think that AddAndActivate2() is a better name than
AddAndActivateOptions(). Hence I rename the libnm API.
Also, unless necessary, let libnm still call "AddAndActivate" instead of
"AddAndActivate2". Our backward compatibility works the way that libnm
requires a server version at least as new as itself. As such, libnm
theoretically could assume that server version is new enough to support
"AddAndActivate2" and could always use the more powerful variant.
However, we don't need to break compatibility intentionally and for
little gain. Here, it's easy to let libnm also handle old server API, by
continuing to use "AddAndActivate" for nm_client_add_and_activate_connection().
Note that during package update, we don't restart the currently running
NetworkManager instance. In such a scenario, it can easily happen that
nmcli/libnm is newer than the server version. Let's try a bit harder
to not break that.
Changes as discussed in [1].
[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/37#note_79876
2018-12-20 07:48:31 +01:00
|
|
|
ActivateType activate_type = ACTIVATE_TYPE_ADD_AND_ACTIVATE_CONNECTION;
|
2014-09-24 13:14:48 -04:00
|
|
|
|
|
|
|
|
g_return_if_fail (NM_IS_MANAGER (manager));
|
|
|
|
|
g_return_if_fail (NM_IS_DEVICE (device));
|
|
|
|
|
if (partial)
|
|
|
|
|
g_return_if_fail (NM_IS_CONNECTION (partial));
|
|
|
|
|
|
2017-05-06 20:27:29 +02:00
|
|
|
priv = NM_MANAGER_GET_PRIVATE (manager);
|
|
|
|
|
|
2014-09-24 13:14:48 -04:00
|
|
|
info = g_slice_new0 (ActivateInfo);
|
|
|
|
|
info->manager = manager;
|
|
|
|
|
info->simple = g_simple_async_result_new (G_OBJECT (manager), callback, user_data,
|
|
|
|
|
nm_manager_add_and_activate_connection_async);
|
2018-03-05 16:02:24 +01:00
|
|
|
if (cancellable)
|
|
|
|
|
g_simple_async_result_set_check_cancellable (info->simple, cancellable);
|
2014-09-24 13:14:48 -04:00
|
|
|
info->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
|
|
|
|
|
|
2017-05-06 20:27:29 +02:00
|
|
|
c_list_link_tail (&priv->pending_activations, &info->lst);
|
2014-09-24 13:14:48 -04:00
|
|
|
|
|
|
|
|
if (partial)
|
|
|
|
|
dict = nm_connection_to_dbus (partial, NM_CONNECTION_SERIALIZE_ALL);
|
|
|
|
|
if (!dict)
|
|
|
|
|
dict = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0);
|
all: return output dictionary from "AddAndActivate2"
Add a "a{sv}" output argument to "AddAndActivate2" D-Bus API.
"AddAndActivate2" replaces "AddAndActivate" with more options.
It also has a dictionary argument to be forward compatible so that we
hopefully won't need an "AddAndActivate3". However, it lacked a similar
output dictionary. Add it for future extensibility. I think this is
really to workaround a shortcoming of D-Bus, which does provide strong
typing and type information about its API, but does not allow to extend
an existing API in a backward compatible manner. So we either resort to
Method(), Method2(), Method3() variants, or a catch-all variant with a
generic "a{sv}" input/output argument.
In libnm, rename "nm_client_add_and_activate_connection_options()" to
"nm_client_add_and_activate_connection2()". I think libnm API should have
an obvious correspondence with D-Bus API. Or stated differently, if
"AddAndActivateOptions" would be a better name, then the D-Bus API should
be renamed. We should prefer one name over the other, but regardless
of which is preferred, the naming for D-Bus and libnm API should
correspond.
In this case, I do think that AddAndActivate2() is a better name than
AddAndActivateOptions(). Hence I rename the libnm API.
Also, unless necessary, let libnm still call "AddAndActivate" instead of
"AddAndActivate2". Our backward compatibility works the way that libnm
requires a server version at least as new as itself. As such, libnm
theoretically could assume that server version is new enough to support
"AddAndActivate2" and could always use the more powerful variant.
However, we don't need to break compatibility intentionally and for
little gain. Here, it's easy to let libnm also handle old server API, by
continuing to use "AddAndActivate" for nm_client_add_and_activate_connection().
Note that during package update, we don't restart the currently running
NetworkManager instance. In such a scenario, it can easily happen that
nmcli/libnm is newer than the server version. Let's try a bit harder
to not break that.
Changes as discussed in [1].
[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/37#note_79876
2018-12-20 07:48:31 +01:00
|
|
|
if (force_v2) {
|
|
|
|
|
if (!options)
|
|
|
|
|
options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
|
|
|
|
|
activate_type = ACTIVATE_TYPE_ADD_AND_ACTIVATE_CONNECTION2;
|
|
|
|
|
} else {
|
|
|
|
|
if (options) {
|
|
|
|
|
if (g_variant_n_children (options) > 0)
|
|
|
|
|
activate_type = ACTIVATE_TYPE_ADD_AND_ACTIVATE_CONNECTION2;
|
|
|
|
|
else
|
|
|
|
|
nm_g_variant_unref_floating (options);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
info->activate_type = activate_type;
|
|
|
|
|
|
|
|
|
|
if (activate_type == ACTIVATE_TYPE_ADD_AND_ACTIVATE_CONNECTION2) {
|
|
|
|
|
nmdbus_manager_call_add_and_activate_connection2 (priv->proxy,
|
|
|
|
|
dict,
|
|
|
|
|
nm_object_get_path (NM_OBJECT (device)),
|
|
|
|
|
specific_object ?: "/",
|
|
|
|
|
options,
|
|
|
|
|
cancellable,
|
|
|
|
|
add_activate_cb,
|
|
|
|
|
info);
|
|
|
|
|
} else {
|
|
|
|
|
nmdbus_manager_call_add_and_activate_connection (priv->proxy,
|
2019-02-22 08:00:01 +01:00
|
|
|
dict,
|
|
|
|
|
nm_object_get_path (NM_OBJECT (device)),
|
|
|
|
|
specific_object ?: "/",
|
|
|
|
|
cancellable,
|
|
|
|
|
add_activate_cb,
|
|
|
|
|
info);
|
all: return output dictionary from "AddAndActivate2"
Add a "a{sv}" output argument to "AddAndActivate2" D-Bus API.
"AddAndActivate2" replaces "AddAndActivate" with more options.
It also has a dictionary argument to be forward compatible so that we
hopefully won't need an "AddAndActivate3". However, it lacked a similar
output dictionary. Add it for future extensibility. I think this is
really to workaround a shortcoming of D-Bus, which does provide strong
typing and type information about its API, but does not allow to extend
an existing API in a backward compatible manner. So we either resort to
Method(), Method2(), Method3() variants, or a catch-all variant with a
generic "a{sv}" input/output argument.
In libnm, rename "nm_client_add_and_activate_connection_options()" to
"nm_client_add_and_activate_connection2()". I think libnm API should have
an obvious correspondence with D-Bus API. Or stated differently, if
"AddAndActivateOptions" would be a better name, then the D-Bus API should
be renamed. We should prefer one name over the other, but regardless
of which is preferred, the naming for D-Bus and libnm API should
correspond.
In this case, I do think that AddAndActivate2() is a better name than
AddAndActivateOptions(). Hence I rename the libnm API.
Also, unless necessary, let libnm still call "AddAndActivate" instead of
"AddAndActivate2". Our backward compatibility works the way that libnm
requires a server version at least as new as itself. As such, libnm
theoretically could assume that server version is new enough to support
"AddAndActivate2" and could always use the more powerful variant.
However, we don't need to break compatibility intentionally and for
little gain. Here, it's easy to let libnm also handle old server API, by
continuing to use "AddAndActivate" for nm_client_add_and_activate_connection().
Note that during package update, we don't restart the currently running
NetworkManager instance. In such a scenario, it can easily happen that
nmcli/libnm is newer than the server version. Let's try a bit harder
to not break that.
Changes as discussed in [1].
[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/37#note_79876
2018-12-20 07:48:31 +01:00
|
|
|
}
|
2014-09-24 13:14:48 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NMActiveConnection *
|
|
|
|
|
nm_manager_add_and_activate_connection_finish (NMManager *manager,
|
|
|
|
|
GAsyncResult *result,
|
all: return output dictionary from "AddAndActivate2"
Add a "a{sv}" output argument to "AddAndActivate2" D-Bus API.
"AddAndActivate2" replaces "AddAndActivate" with more options.
It also has a dictionary argument to be forward compatible so that we
hopefully won't need an "AddAndActivate3". However, it lacked a similar
output dictionary. Add it for future extensibility. I think this is
really to workaround a shortcoming of D-Bus, which does provide strong
typing and type information about its API, but does not allow to extend
an existing API in a backward compatible manner. So we either resort to
Method(), Method2(), Method3() variants, or a catch-all variant with a
generic "a{sv}" input/output argument.
In libnm, rename "nm_client_add_and_activate_connection_options()" to
"nm_client_add_and_activate_connection2()". I think libnm API should have
an obvious correspondence with D-Bus API. Or stated differently, if
"AddAndActivateOptions" would be a better name, then the D-Bus API should
be renamed. We should prefer one name over the other, but regardless
of which is preferred, the naming for D-Bus and libnm API should
correspond.
In this case, I do think that AddAndActivate2() is a better name than
AddAndActivateOptions(). Hence I rename the libnm API.
Also, unless necessary, let libnm still call "AddAndActivate" instead of
"AddAndActivate2". Our backward compatibility works the way that libnm
requires a server version at least as new as itself. As such, libnm
theoretically could assume that server version is new enough to support
"AddAndActivate2" and could always use the more powerful variant.
However, we don't need to break compatibility intentionally and for
little gain. Here, it's easy to let libnm also handle old server API, by
continuing to use "AddAndActivate" for nm_client_add_and_activate_connection().
Note that during package update, we don't restart the currently running
NetworkManager instance. In such a scenario, it can easily happen that
nmcli/libnm is newer than the server version. Let's try a bit harder
to not break that.
Changes as discussed in [1].
[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/37#note_79876
2018-12-20 07:48:31 +01:00
|
|
|
GVariant **out_result,
|
2014-09-24 13:14:48 -04:00
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
GSimpleAsyncResult *simple;
|
all: return output dictionary from "AddAndActivate2"
Add a "a{sv}" output argument to "AddAndActivate2" D-Bus API.
"AddAndActivate2" replaces "AddAndActivate" with more options.
It also has a dictionary argument to be forward compatible so that we
hopefully won't need an "AddAndActivate3". However, it lacked a similar
output dictionary. Add it for future extensibility. I think this is
really to workaround a shortcoming of D-Bus, which does provide strong
typing and type information about its API, but does not allow to extend
an existing API in a backward compatible manner. So we either resort to
Method(), Method2(), Method3() variants, or a catch-all variant with a
generic "a{sv}" input/output argument.
In libnm, rename "nm_client_add_and_activate_connection_options()" to
"nm_client_add_and_activate_connection2()". I think libnm API should have
an obvious correspondence with D-Bus API. Or stated differently, if
"AddAndActivateOptions" would be a better name, then the D-Bus API should
be renamed. We should prefer one name over the other, but regardless
of which is preferred, the naming for D-Bus and libnm API should
correspond.
In this case, I do think that AddAndActivate2() is a better name than
AddAndActivateOptions(). Hence I rename the libnm API.
Also, unless necessary, let libnm still call "AddAndActivate" instead of
"AddAndActivate2". Our backward compatibility works the way that libnm
requires a server version at least as new as itself. As such, libnm
theoretically could assume that server version is new enough to support
"AddAndActivate2" and could always use the more powerful variant.
However, we don't need to break compatibility intentionally and for
little gain. Here, it's easy to let libnm also handle old server API, by
continuing to use "AddAndActivate" for nm_client_add_and_activate_connection().
Note that during package update, we don't restart the currently running
NetworkManager instance. In such a scenario, it can easily happen that
nmcli/libnm is newer than the server version. Let's try a bit harder
to not break that.
Changes as discussed in [1].
[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/37#note_79876
2018-12-20 07:48:31 +01:00
|
|
|
_NMActivateResult *r;
|
2014-09-24 13:14:48 -04:00
|
|
|
|
|
|
|
|
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (manager), nm_manager_add_and_activate_connection_async), NULL);
|
|
|
|
|
|
|
|
|
|
simple = G_SIMPLE_ASYNC_RESULT (result);
|
all: return output dictionary from "AddAndActivate2"
Add a "a{sv}" output argument to "AddAndActivate2" D-Bus API.
"AddAndActivate2" replaces "AddAndActivate" with more options.
It also has a dictionary argument to be forward compatible so that we
hopefully won't need an "AddAndActivate3". However, it lacked a similar
output dictionary. Add it for future extensibility. I think this is
really to workaround a shortcoming of D-Bus, which does provide strong
typing and type information about its API, but does not allow to extend
an existing API in a backward compatible manner. So we either resort to
Method(), Method2(), Method3() variants, or a catch-all variant with a
generic "a{sv}" input/output argument.
In libnm, rename "nm_client_add_and_activate_connection_options()" to
"nm_client_add_and_activate_connection2()". I think libnm API should have
an obvious correspondence with D-Bus API. Or stated differently, if
"AddAndActivateOptions" would be a better name, then the D-Bus API should
be renamed. We should prefer one name over the other, but regardless
of which is preferred, the naming for D-Bus and libnm API should
correspond.
In this case, I do think that AddAndActivate2() is a better name than
AddAndActivateOptions(). Hence I rename the libnm API.
Also, unless necessary, let libnm still call "AddAndActivate" instead of
"AddAndActivate2". Our backward compatibility works the way that libnm
requires a server version at least as new as itself. As such, libnm
theoretically could assume that server version is new enough to support
"AddAndActivate2" and could always use the more powerful variant.
However, we don't need to break compatibility intentionally and for
little gain. Here, it's easy to let libnm also handle old server API, by
continuing to use "AddAndActivate" for nm_client_add_and_activate_connection().
Note that during package update, we don't restart the currently running
NetworkManager instance. In such a scenario, it can easily happen that
nmcli/libnm is newer than the server version. Let's try a bit harder
to not break that.
Changes as discussed in [1].
[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/37#note_79876
2018-12-20 07:48:31 +01:00
|
|
|
if (g_simple_async_result_propagate_error (simple, error)) {
|
|
|
|
|
NM_SET_OUT (out_result, NULL);
|
2014-09-24 13:14:48 -04:00
|
|
|
return NULL;
|
all: return output dictionary from "AddAndActivate2"
Add a "a{sv}" output argument to "AddAndActivate2" D-Bus API.
"AddAndActivate2" replaces "AddAndActivate" with more options.
It also has a dictionary argument to be forward compatible so that we
hopefully won't need an "AddAndActivate3". However, it lacked a similar
output dictionary. Add it for future extensibility. I think this is
really to workaround a shortcoming of D-Bus, which does provide strong
typing and type information about its API, but does not allow to extend
an existing API in a backward compatible manner. So we either resort to
Method(), Method2(), Method3() variants, or a catch-all variant with a
generic "a{sv}" input/output argument.
In libnm, rename "nm_client_add_and_activate_connection_options()" to
"nm_client_add_and_activate_connection2()". I think libnm API should have
an obvious correspondence with D-Bus API. Or stated differently, if
"AddAndActivateOptions" would be a better name, then the D-Bus API should
be renamed. We should prefer one name over the other, but regardless
of which is preferred, the naming for D-Bus and libnm API should
correspond.
In this case, I do think that AddAndActivate2() is a better name than
AddAndActivateOptions(). Hence I rename the libnm API.
Also, unless necessary, let libnm still call "AddAndActivate" instead of
"AddAndActivate2". Our backward compatibility works the way that libnm
requires a server version at least as new as itself. As such, libnm
theoretically could assume that server version is new enough to support
"AddAndActivate2" and could always use the more powerful variant.
However, we don't need to break compatibility intentionally and for
little gain. Here, it's easy to let libnm also handle old server API, by
continuing to use "AddAndActivate" for nm_client_add_and_activate_connection().
Note that during package update, we don't restart the currently running
NetworkManager instance. In such a scenario, it can easily happen that
nmcli/libnm is newer than the server version. Let's try a bit harder
to not break that.
Changes as discussed in [1].
[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/37#note_79876
2018-12-20 07:48:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
r = g_simple_async_result_get_op_res_gpointer (simple);
|
|
|
|
|
NM_SET_OUT (out_result, nm_g_variant_ref (r->add_and_activate_output));
|
|
|
|
|
return g_object_ref (r->active);
|
2014-09-24 13:14:48 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2014-10-10 14:43:55 -04:00
|
|
|
device_ac_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
|
2014-09-24 13:14:48 -04:00
|
|
|
{
|
2014-10-10 14:43:55 -04:00
|
|
|
NMManager *self = user_data;
|
|
|
|
|
|
|
|
|
|
recheck_pending_activations (self);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
device_added (NMManager *self, NMDevice *device)
|
|
|
|
|
{
|
2017-02-27 11:06:39 +01:00
|
|
|
g_signal_connect_object (device, "notify::" NM_DEVICE_ACTIVE_CONNECTION,
|
|
|
|
|
G_CALLBACK (device_ac_changed), self, 0);
|
2014-10-10 14:43:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
device_removed (NMManager *self, NMDevice *device)
|
|
|
|
|
{
|
|
|
|
|
g_signal_handlers_disconnect_by_func (device, G_CALLBACK (device_ac_changed), self);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
ac_devices_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMManager *self = user_data;
|
|
|
|
|
|
|
|
|
|
recheck_pending_activations (self);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
active_connection_added (NMManager *self, NMActiveConnection *ac)
|
|
|
|
|
{
|
2017-02-27 11:06:39 +01:00
|
|
|
g_signal_connect_object (ac, "notify::" NM_ACTIVE_CONNECTION_DEVICES,
|
|
|
|
|
G_CALLBACK (ac_devices_changed), self, 0);
|
2014-10-10 14:43:55 -04:00
|
|
|
recheck_pending_activations (self);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
active_connection_removed (NMManager *self, NMActiveConnection *ac)
|
|
|
|
|
{
|
|
|
|
|
g_signal_handlers_disconnect_by_func (ac, G_CALLBACK (ac_devices_changed), self);
|
2016-10-18 16:35:07 +02:00
|
|
|
recheck_pending_activations (self);
|
2014-09-24 13:14:48 -04:00
|
|
|
}
|
|
|
|
|
|
2017-10-21 16:05:19 +02:00
|
|
|
static void
|
|
|
|
|
checkpoint_added (NMManager *manager, NMCheckpoint *checkpoint)
|
|
|
|
|
{
|
|
|
|
|
CheckpointInfo *info;
|
|
|
|
|
|
|
|
|
|
info = find_checkpoint_info (manager, nm_object_get_path (NM_OBJECT (checkpoint)));
|
|
|
|
|
if (info)
|
|
|
|
|
checkpoint_info_complete (manager, info, checkpoint, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-24 13:14:48 -04:00
|
|
|
gboolean
|
|
|
|
|
nm_manager_deactivate_connection (NMManager *manager,
|
|
|
|
|
NMActiveConnection *active,
|
|
|
|
|
GCancellable *cancellable,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
const char *path;
|
2014-10-15 18:26:32 -04:00
|
|
|
gboolean ret;
|
2014-09-24 13:14:48 -04:00
|
|
|
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE);
|
|
|
|
|
g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (active), FALSE);
|
|
|
|
|
|
|
|
|
|
path = nm_object_get_path (NM_OBJECT (active));
|
2016-11-14 18:47:56 +01:00
|
|
|
ret = nmdbus_manager_call_deactivate_connection_sync (NM_MANAGER_GET_PRIVATE (manager)->proxy,
|
2014-10-15 18:26:32 -04:00
|
|
|
path,
|
|
|
|
|
cancellable, error);
|
|
|
|
|
if (error && *error)
|
|
|
|
|
g_dbus_error_strip_remote_error (*error);
|
|
|
|
|
return ret;
|
2014-09-24 13:14:48 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
deactivated_cb (GObject *object,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
GSimpleAsyncResult *simple = user_data;
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
|
|
if (nmdbus_manager_call_deactivate_connection_finish (NMDBUS_MANAGER (object),
|
|
|
|
|
result, &error))
|
|
|
|
|
g_simple_async_result_set_op_res_gboolean (simple, TRUE);
|
2014-10-15 18:26:32 -04:00
|
|
|
else {
|
|
|
|
|
g_dbus_error_strip_remote_error (error);
|
2014-09-24 13:14:48 -04:00
|
|
|
g_simple_async_result_take_error (simple, error);
|
2014-10-15 18:26:32 -04:00
|
|
|
}
|
2014-09-24 13:14:48 -04:00
|
|
|
g_simple_async_result_complete (simple);
|
|
|
|
|
g_object_unref (simple);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_manager_deactivate_connection_async (NMManager *manager,
|
|
|
|
|
NMActiveConnection *active,
|
|
|
|
|
GCancellable *cancellable,
|
|
|
|
|
GAsyncReadyCallback callback,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
const char *path;
|
|
|
|
|
GSimpleAsyncResult *simple;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (NM_IS_MANAGER (manager));
|
|
|
|
|
g_return_if_fail (NM_IS_ACTIVE_CONNECTION (active));
|
|
|
|
|
|
|
|
|
|
simple = g_simple_async_result_new (G_OBJECT (manager), callback, user_data,
|
|
|
|
|
nm_manager_deactivate_connection_async);
|
2018-03-05 16:02:24 +01:00
|
|
|
if (cancellable)
|
|
|
|
|
g_simple_async_result_set_check_cancellable (simple, cancellable);
|
2014-09-24 13:14:48 -04:00
|
|
|
|
|
|
|
|
path = nm_object_get_path (NM_OBJECT (active));
|
2016-11-14 18:47:56 +01:00
|
|
|
nmdbus_manager_call_deactivate_connection (NM_MANAGER_GET_PRIVATE (manager)->proxy,
|
2014-09-24 13:14:48 -04:00
|
|
|
path,
|
|
|
|
|
cancellable,
|
|
|
|
|
deactivated_cb, simple);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
|
nm_manager_deactivate_connection_finish (NMManager *manager,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
GSimpleAsyncResult *simple;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (manager), nm_manager_deactivate_connection_async), FALSE);
|
|
|
|
|
|
|
|
|
|
simple = G_SIMPLE_ASYNC_RESULT (result);
|
|
|
|
|
if (g_simple_async_result_propagate_error (simple, error))
|
|
|
|
|
return FALSE;
|
|
|
|
|
else
|
|
|
|
|
return g_simple_async_result_get_op_res_gboolean (simple);
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2014-09-24 13:14:48 -04:00
|
|
|
|
|
|
|
|
static void
|
2016-10-18 16:35:07 +02:00
|
|
|
free_active_connections (NMManager *manager)
|
2014-09-24 13:14:48 -04:00
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
if (!priv->active_connections)
|
|
|
|
|
return;
|
|
|
|
|
|
2016-10-18 16:35:07 +02:00
|
|
|
/* Break circular refs */
|
|
|
|
|
for (i = 0; i < priv->active_connections->len; i++)
|
|
|
|
|
g_object_run_dispose (G_OBJECT (priv->active_connections->pdata[i]));
|
|
|
|
|
g_ptr_array_unref (priv->active_connections);
|
|
|
|
|
priv->active_connections = NULL;
|
2014-09-24 13:14:48 -04:00
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2014-09-24 13:14:48 -04:00
|
|
|
|
2017-10-21 16:05:19 +02:00
|
|
|
static const char **
|
|
|
|
|
get_device_paths (const GPtrArray *devices)
|
|
|
|
|
{
|
|
|
|
|
const char **array;
|
|
|
|
|
guint i;
|
|
|
|
|
|
|
|
|
|
array = g_new (const char *, devices->len + 1);
|
|
|
|
|
for (i = 0; i < devices->len; i++)
|
|
|
|
|
array[i] = nm_object_get_path (NM_OBJECT (devices->pdata[i]));
|
|
|
|
|
|
|
|
|
|
array[i] = NULL;
|
|
|
|
|
|
|
|
|
|
return array;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const GPtrArray *
|
|
|
|
|
nm_manager_get_checkpoints (NMManager *manager)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
|
|
|
|
|
|
|
|
|
|
return NM_MANAGER_GET_PRIVATE (manager)->checkpoints;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
checkpoint_created_cb (GObject *object,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
CheckpointInfo *info = user_data;
|
libnm: fix crash creating checkpoint during find_checkpoint_info()
Now that the D-Bus signals in server are reordered, creating
a checkpoint in libnm crashes:
$ examples/python/gi/checkpoint.py create 4
#0 0x00007ffff6d011ee in __strcmp_sse2_unaligned () at /lib64/libc.so.6
#1 0x00007fffeb611c90 in find_checkpoint_info (manager=manager@entry=0x5555559e5110 [NMManager], path=0x7fffdc0092f0 "/org/freedesktop/NetworkManager/Checkpoint/6")
at libnm/nm-manager.c:153
#2 0x00007fffeb611d8f in checkpoint_added (manager=0x5555559e5110 [NMManager], checkpoint=checkpoint@entry=0x555555a122d0 [NMCheckpoint]) at libnm/nm-manager.c:1194
#3 0x00007fffef7db929 in g_cclosure_marshal_VOID__OBJECTv (closure=0x5555559e4b30, return_value=<optimized out>, instance=<optimized out>, args=<optimized out>, marshal_data=<optimized out>, n_params=<optimized out>, param_types=0x5555559e2fc0) at gmarshal.c:2102
#4 0x00007fffef7d8976 in _g_closure_invoke_va (closure=0x5555559e4b30, return_value=0x0, instance=0x5555559e5110, args=0x7fffffffc1c8, n_params=1, param_types=0x5555559e2fc0)
at gclosure.c:867
#5 0x00007fffef7f3ff4 in g_signal_emit_valist (instance=instance@entry=0x5555559e5110, signal_id=signal_id@entry=97, detail=0, var_args=var_args@entry=0x7fffffffc1c8) at gsignal.c:3300
#6 0x00007fffef7f4b48 in g_signal_emit_by_name (instance=instance@entry=0x5555559e5110, detailed_signal=detailed_signal@entry=0x7fffffffc310 "checkpoint-added") at gsignal.c:3487
#7 0x00007fffeb6156d1 in deferred_notify_cb (data=0x5555559e5110) at libnm/nm-object.c:219
#8 0x00007fffeb615ae7 in object_property_maybe_complete (self=0x5555559e5110 [NMManager]) at libnm/nm-object.c:555
#9 0x00007fffeb615e5d in object_created (obj=<optimized out>, path=<optimized out>, user_data=<optimized out>) at libnm/nm-object.c:576
#10 0x00007fffeb61648b in handle_object_array_property (pi=<optimized out>, value=0x7fffdc075070, property_name=0x7fffeb67f117 "checkpoints", self=0x5555559e5110 [NMManager])
at libnm/nm-object.c:671
#11 0x00007fffeb61648b in handle_property_changed (self=self@entry=0x5555559e5110 [NMManager], dbus_name=<optimized out>, value=<optimized out>) at libnm/nm-object.c:740
#12 0x00007fffeb6166e9 in properties_changed (proxy=<optimized out>, changed_properties=<optimized out>, invalidated_properties=<optimized out>, user_data=0x5555559e5110)
at libnm/nm-object.c:772
...
That is, because NetworkManager now first emits signals that the checkpoint
object was created, before answering the D-Bus request. That makes more
sense, but leads to this crash.
The ugliness of how libnm handles object visibility is considerable.
libnm hides objects until they are fully initialized. So, when
the async create-checkpoint operation returns, the object might not
yet be ready to be exposed. We need to delay the result. It would be
better if the API would simply return the created path.
2018-03-28 12:31:43 +02:00
|
|
|
NMManager *self = info->manager;
|
|
|
|
|
gs_free_error GError *error = NULL;
|
|
|
|
|
NMCheckpoint *checkpoint;
|
2017-10-21 16:05:19 +02:00
|
|
|
|
|
|
|
|
nmdbus_manager_call_checkpoint_create_finish (NMDBUS_MANAGER (object),
|
|
|
|
|
&info->path, result, &error);
|
|
|
|
|
if (error) {
|
|
|
|
|
g_dbus_error_strip_remote_error (error);
|
libnm: fix crash creating checkpoint during find_checkpoint_info()
Now that the D-Bus signals in server are reordered, creating
a checkpoint in libnm crashes:
$ examples/python/gi/checkpoint.py create 4
#0 0x00007ffff6d011ee in __strcmp_sse2_unaligned () at /lib64/libc.so.6
#1 0x00007fffeb611c90 in find_checkpoint_info (manager=manager@entry=0x5555559e5110 [NMManager], path=0x7fffdc0092f0 "/org/freedesktop/NetworkManager/Checkpoint/6")
at libnm/nm-manager.c:153
#2 0x00007fffeb611d8f in checkpoint_added (manager=0x5555559e5110 [NMManager], checkpoint=checkpoint@entry=0x555555a122d0 [NMCheckpoint]) at libnm/nm-manager.c:1194
#3 0x00007fffef7db929 in g_cclosure_marshal_VOID__OBJECTv (closure=0x5555559e4b30, return_value=<optimized out>, instance=<optimized out>, args=<optimized out>, marshal_data=<optimized out>, n_params=<optimized out>, param_types=0x5555559e2fc0) at gmarshal.c:2102
#4 0x00007fffef7d8976 in _g_closure_invoke_va (closure=0x5555559e4b30, return_value=0x0, instance=0x5555559e5110, args=0x7fffffffc1c8, n_params=1, param_types=0x5555559e2fc0)
at gclosure.c:867
#5 0x00007fffef7f3ff4 in g_signal_emit_valist (instance=instance@entry=0x5555559e5110, signal_id=signal_id@entry=97, detail=0, var_args=var_args@entry=0x7fffffffc1c8) at gsignal.c:3300
#6 0x00007fffef7f4b48 in g_signal_emit_by_name (instance=instance@entry=0x5555559e5110, detailed_signal=detailed_signal@entry=0x7fffffffc310 "checkpoint-added") at gsignal.c:3487
#7 0x00007fffeb6156d1 in deferred_notify_cb (data=0x5555559e5110) at libnm/nm-object.c:219
#8 0x00007fffeb615ae7 in object_property_maybe_complete (self=0x5555559e5110 [NMManager]) at libnm/nm-object.c:555
#9 0x00007fffeb615e5d in object_created (obj=<optimized out>, path=<optimized out>, user_data=<optimized out>) at libnm/nm-object.c:576
#10 0x00007fffeb61648b in handle_object_array_property (pi=<optimized out>, value=0x7fffdc075070, property_name=0x7fffeb67f117 "checkpoints", self=0x5555559e5110 [NMManager])
at libnm/nm-object.c:671
#11 0x00007fffeb61648b in handle_property_changed (self=self@entry=0x5555559e5110 [NMManager], dbus_name=<optimized out>, value=<optimized out>) at libnm/nm-object.c:740
#12 0x00007fffeb6166e9 in properties_changed (proxy=<optimized out>, changed_properties=<optimized out>, invalidated_properties=<optimized out>, user_data=0x5555559e5110)
at libnm/nm-object.c:772
...
That is, because NetworkManager now first emits signals that the checkpoint
object was created, before answering the D-Bus request. That makes more
sense, but leads to this crash.
The ugliness of how libnm handles object visibility is considerable.
libnm hides objects until they are fully initialized. So, when
the async create-checkpoint operation returns, the object might not
yet be ready to be exposed. We need to delay the result. It would be
better if the API would simply return the created path.
2018-03-28 12:31:43 +02:00
|
|
|
checkpoint_info_complete (self, info, NULL, error);
|
|
|
|
|
return;
|
2017-10-21 16:05:19 +02:00
|
|
|
}
|
libnm: fix crash creating checkpoint during find_checkpoint_info()
Now that the D-Bus signals in server are reordered, creating
a checkpoint in libnm crashes:
$ examples/python/gi/checkpoint.py create 4
#0 0x00007ffff6d011ee in __strcmp_sse2_unaligned () at /lib64/libc.so.6
#1 0x00007fffeb611c90 in find_checkpoint_info (manager=manager@entry=0x5555559e5110 [NMManager], path=0x7fffdc0092f0 "/org/freedesktop/NetworkManager/Checkpoint/6")
at libnm/nm-manager.c:153
#2 0x00007fffeb611d8f in checkpoint_added (manager=0x5555559e5110 [NMManager], checkpoint=checkpoint@entry=0x555555a122d0 [NMCheckpoint]) at libnm/nm-manager.c:1194
#3 0x00007fffef7db929 in g_cclosure_marshal_VOID__OBJECTv (closure=0x5555559e4b30, return_value=<optimized out>, instance=<optimized out>, args=<optimized out>, marshal_data=<optimized out>, n_params=<optimized out>, param_types=0x5555559e2fc0) at gmarshal.c:2102
#4 0x00007fffef7d8976 in _g_closure_invoke_va (closure=0x5555559e4b30, return_value=0x0, instance=0x5555559e5110, args=0x7fffffffc1c8, n_params=1, param_types=0x5555559e2fc0)
at gclosure.c:867
#5 0x00007fffef7f3ff4 in g_signal_emit_valist (instance=instance@entry=0x5555559e5110, signal_id=signal_id@entry=97, detail=0, var_args=var_args@entry=0x7fffffffc1c8) at gsignal.c:3300
#6 0x00007fffef7f4b48 in g_signal_emit_by_name (instance=instance@entry=0x5555559e5110, detailed_signal=detailed_signal@entry=0x7fffffffc310 "checkpoint-added") at gsignal.c:3487
#7 0x00007fffeb6156d1 in deferred_notify_cb (data=0x5555559e5110) at libnm/nm-object.c:219
#8 0x00007fffeb615ae7 in object_property_maybe_complete (self=0x5555559e5110 [NMManager]) at libnm/nm-object.c:555
#9 0x00007fffeb615e5d in object_created (obj=<optimized out>, path=<optimized out>, user_data=<optimized out>) at libnm/nm-object.c:576
#10 0x00007fffeb61648b in handle_object_array_property (pi=<optimized out>, value=0x7fffdc075070, property_name=0x7fffeb67f117 "checkpoints", self=0x5555559e5110 [NMManager])
at libnm/nm-object.c:671
#11 0x00007fffeb61648b in handle_property_changed (self=self@entry=0x5555559e5110 [NMManager], dbus_name=<optimized out>, value=<optimized out>) at libnm/nm-object.c:740
#12 0x00007fffeb6166e9 in properties_changed (proxy=<optimized out>, changed_properties=<optimized out>, invalidated_properties=<optimized out>, user_data=0x5555559e5110)
at libnm/nm-object.c:772
...
That is, because NetworkManager now first emits signals that the checkpoint
object was created, before answering the D-Bus request. That makes more
sense, but leads to this crash.
The ugliness of how libnm handles object visibility is considerable.
libnm hides objects until they are fully initialized. So, when
the async create-checkpoint operation returns, the object might not
yet be ready to be exposed. We need to delay the result. It would be
better if the API would simply return the created path.
2018-03-28 12:31:43 +02:00
|
|
|
|
|
|
|
|
checkpoint = get_checkpoint_by_path (self, info->path);
|
|
|
|
|
if (!checkpoint) {
|
|
|
|
|
/* this is really problematic. The async request returned, but
|
|
|
|
|
* we don't yet have a visible (fully initialized) NMCheckpoint instance
|
|
|
|
|
* to return. Wait longer for it to appear. However, it's ugly. */
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
checkpoint_info_complete (self, info, checkpoint, NULL);
|
2017-10-21 16:05:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2018-04-04 13:33:53 +02:00
|
|
|
nm_manager_checkpoint_create (NMManager *manager,
|
|
|
|
|
const GPtrArray *devices,
|
|
|
|
|
guint32 rollback_timeout,
|
|
|
|
|
NMCheckpointCreateFlags flags,
|
|
|
|
|
GCancellable *cancellable,
|
|
|
|
|
GAsyncReadyCallback callback,
|
|
|
|
|
gpointer user_data)
|
2017-10-21 16:05:19 +02:00
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
|
|
|
|
gs_free const char **paths = NULL;
|
|
|
|
|
CheckpointInfo *info;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (NM_IS_MANAGER (manager));
|
|
|
|
|
|
|
|
|
|
info = g_slice_new0 (CheckpointInfo);
|
|
|
|
|
info->manager = manager;
|
|
|
|
|
info->simple = g_simple_async_result_new (G_OBJECT (manager), callback, user_data,
|
2018-04-04 13:33:53 +02:00
|
|
|
nm_manager_checkpoint_create);
|
2018-03-05 16:02:24 +01:00
|
|
|
if (cancellable)
|
|
|
|
|
g_simple_async_result_set_check_cancellable (info->simple, cancellable);
|
2017-10-21 16:05:19 +02:00
|
|
|
paths = get_device_paths (devices);
|
|
|
|
|
nmdbus_manager_call_checkpoint_create (NM_MANAGER_GET_PRIVATE (manager)->proxy,
|
|
|
|
|
paths,
|
|
|
|
|
rollback_timeout,
|
|
|
|
|
flags,
|
|
|
|
|
cancellable,
|
|
|
|
|
checkpoint_created_cb,
|
|
|
|
|
info);
|
|
|
|
|
priv->added_checkpoints = g_slist_append (priv->added_checkpoints, info);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NMCheckpoint *
|
|
|
|
|
nm_manager_checkpoint_create_finish (NMManager *manager,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
GSimpleAsyncResult *simple;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
|
|
|
|
|
g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
|
|
|
|
|
|
|
|
|
|
simple = G_SIMPLE_ASYNC_RESULT (result);
|
|
|
|
|
if (g_simple_async_result_propagate_error (simple, error))
|
|
|
|
|
return NULL;
|
|
|
|
|
else
|
|
|
|
|
return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
checkpoint_destroy_cb (GObject *object,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
GSimpleAsyncResult *simple = user_data;
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
|
|
if (nmdbus_manager_call_checkpoint_destroy_finish (NMDBUS_MANAGER (object),
|
|
|
|
|
result, &error))
|
|
|
|
|
g_simple_async_result_set_op_res_gboolean (simple, TRUE);
|
|
|
|
|
else {
|
|
|
|
|
g_dbus_error_strip_remote_error (error);
|
|
|
|
|
g_simple_async_result_take_error (simple, error);
|
|
|
|
|
}
|
|
|
|
|
g_simple_async_result_complete (simple);
|
|
|
|
|
g_object_unref (simple);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2018-04-04 13:33:53 +02:00
|
|
|
nm_manager_checkpoint_destroy (NMManager *manager,
|
|
|
|
|
const char *checkpoint_path,
|
|
|
|
|
GCancellable *cancellable,
|
|
|
|
|
GAsyncReadyCallback callback,
|
|
|
|
|
gpointer user_data)
|
2017-10-21 16:05:19 +02:00
|
|
|
{
|
|
|
|
|
GSimpleAsyncResult *simple;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (NM_IS_MANAGER (manager));
|
2018-04-04 13:33:53 +02:00
|
|
|
g_return_if_fail (checkpoint_path && checkpoint_path[0] == '/');
|
2017-10-21 16:05:19 +02:00
|
|
|
|
|
|
|
|
simple = g_simple_async_result_new (G_OBJECT (manager), callback, user_data,
|
2018-04-04 13:33:53 +02:00
|
|
|
nm_manager_checkpoint_destroy);
|
2018-03-05 16:02:24 +01:00
|
|
|
if (cancellable)
|
|
|
|
|
g_simple_async_result_set_check_cancellable (simple, cancellable);
|
2017-10-21 16:05:19 +02:00
|
|
|
|
|
|
|
|
nmdbus_manager_call_checkpoint_destroy (NM_MANAGER_GET_PRIVATE (manager)->proxy,
|
2018-04-04 13:33:53 +02:00
|
|
|
checkpoint_path,
|
2017-10-21 16:05:19 +02:00
|
|
|
cancellable,
|
|
|
|
|
checkpoint_destroy_cb, simple);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
|
nm_manager_checkpoint_destroy_finish (NMManager *manager,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
GSimpleAsyncResult *simple;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (manager),
|
2018-04-04 13:33:53 +02:00
|
|
|
nm_manager_checkpoint_destroy),
|
2017-10-21 16:05:19 +02:00
|
|
|
FALSE);
|
|
|
|
|
|
|
|
|
|
simple = G_SIMPLE_ASYNC_RESULT (result);
|
|
|
|
|
if (g_simple_async_result_propagate_error (simple, error))
|
|
|
|
|
return FALSE;
|
|
|
|
|
else
|
|
|
|
|
return g_simple_async_result_get_op_res_gboolean (simple);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
checkpoint_rollback_cb (GObject *object,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
GSimpleAsyncResult *simple = user_data;
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
GVariant *variant = NULL;
|
|
|
|
|
GVariantIter iter;
|
|
|
|
|
GHashTable *hash;
|
|
|
|
|
const char *path;
|
|
|
|
|
guint r;
|
|
|
|
|
|
|
|
|
|
if (nmdbus_manager_call_checkpoint_rollback_finish (NMDBUS_MANAGER (object),
|
|
|
|
|
&variant,
|
|
|
|
|
result,
|
|
|
|
|
&error)) {
|
2017-11-15 16:06:43 +01:00
|
|
|
hash = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, NULL);
|
2017-10-21 16:05:19 +02:00
|
|
|
g_variant_iter_init (&iter, variant);
|
|
|
|
|
while (g_variant_iter_next (&iter, "{&su}", &path, &r))
|
|
|
|
|
g_hash_table_insert (hash, g_strdup (path), GUINT_TO_POINTER (r));
|
|
|
|
|
g_simple_async_result_set_op_res_gpointer (simple, hash, (GDestroyNotify) g_hash_table_unref);
|
|
|
|
|
} else {
|
|
|
|
|
g_dbus_error_strip_remote_error (error);
|
|
|
|
|
g_simple_async_result_take_error (simple, error);
|
|
|
|
|
}
|
|
|
|
|
g_simple_async_result_complete (simple);
|
|
|
|
|
g_object_unref (simple);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2018-04-04 13:33:53 +02:00
|
|
|
nm_manager_checkpoint_rollback (NMManager *manager,
|
|
|
|
|
const char *checkpoint_path,
|
|
|
|
|
GCancellable *cancellable,
|
|
|
|
|
GAsyncReadyCallback callback,
|
|
|
|
|
gpointer user_data)
|
2017-10-21 16:05:19 +02:00
|
|
|
{
|
|
|
|
|
GSimpleAsyncResult *simple;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (NM_IS_MANAGER (manager));
|
2018-04-04 13:33:53 +02:00
|
|
|
g_return_if_fail (checkpoint_path && checkpoint_path[0] == '/');
|
2017-10-21 16:05:19 +02:00
|
|
|
|
|
|
|
|
simple = g_simple_async_result_new (G_OBJECT (manager), callback, user_data,
|
2018-04-04 13:33:53 +02:00
|
|
|
nm_manager_checkpoint_rollback);
|
2018-03-05 16:02:24 +01:00
|
|
|
if (cancellable)
|
|
|
|
|
g_simple_async_result_set_check_cancellable (simple, cancellable);
|
2017-10-21 16:05:19 +02:00
|
|
|
|
|
|
|
|
nmdbus_manager_call_checkpoint_rollback (NM_MANAGER_GET_PRIVATE (manager)->proxy,
|
2018-04-04 13:33:53 +02:00
|
|
|
checkpoint_path,
|
2017-10-21 16:05:19 +02:00
|
|
|
cancellable,
|
|
|
|
|
checkpoint_rollback_cb, simple);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GHashTable *
|
|
|
|
|
nm_manager_checkpoint_rollback_finish (NMManager *manager,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
GSimpleAsyncResult *simple;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (manager),
|
2018-04-04 13:33:53 +02:00
|
|
|
nm_manager_checkpoint_rollback),
|
2017-10-21 16:05:19 +02:00
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
simple = G_SIMPLE_ASYNC_RESULT (result);
|
|
|
|
|
if (g_simple_async_result_propagate_error (simple, error))
|
|
|
|
|
return NULL;
|
|
|
|
|
else
|
libnm: fix duplicate free in nm_client_checkpoint_rollback()
#0 0x00007fffea7481e5 in _g_log_abort (breakpoint=1) at gmessages.c:554
#1 0x00007fffea74951d in g_logv (log_domain=0x7fffea78e00e "GLib", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fffffffcbb0)
at gmessages.c:1371
#2 0x00007fffea7496f3 in g_log
(log_domain=log_domain@entry=0x7fffea78e00e "GLib", log_level=log_level@entry=G_LOG_LEVEL_CRITICAL, format=format@entry=0x7fffea798320 "%s: assertion '%s' failed")
at gmessages.c:1413
#3 0x00007fffea749f2d in g_return_if_fail_warning
(log_domain=log_domain@entry=0x7fffea78e00e "GLib", pretty_function=pretty_function@entry=0x7fffea799d40 <__func__.4759> "g_atomic_ref_count_dec", expression=expression@entry=0x7fffea799ca1 "g_atomic_int_get (arc) > 0") at gmessages.c:2762
#4 0x00007fffea754c12 in g_atomic_ref_count_dec (arc=arc@entry=0x5555558c5280) at grefcount.c:260
#5 0x00007fffea7302c6 in g_hash_table_unref (hash_table=0x5555558c5240) at ghash.c:1101
#6 0x00007fffea4b6dbc in clear_op_res (simple=0x55555587ed90 [GSimpleAsyncResult]) at gsimpleasyncresult.c:248
#7 0x00007fffea4b6dbc in g_simple_async_result_finalize (object=0x55555587ed90 [GSimpleAsyncResult]) at gsimpleasyncresult.c:268
#8 0x00007fffea67b949 in g_object_unref (_object=<optimized out>) at gobject.c:3346
#9 0x00007fffea67b949 in g_object_unref (_object=0x55555587ed90) at gobject.c:3238
#10 0x00007fffe95dea2d in checkpoint_rollback_cb (object=<optimized out>, result=<optimized out>, user_data=0x55555587ed90) at libnm/nm-manager.c:1584
#11 0x00007fffea4ca834 in g_task_return_now (task=0x5555558b5c80 [GTask]) at gtask.c:1148
#12 0x00007fffea4cb196 in g_task_return (task=0x5555558b5c80 [GTask], type=<optimized out>) at gtask.c:1206
#13 0x00007fffea5096bb in reply_cb (connection=<optimized out>, res=<optimized out>, user_data=0x5555558b5c80) at gdbusproxy.c:2596
#14 0x00007fffea4ca834 in g_task_return_now (task=0x5555558b5d50 [GTask]) at gtask.c:1148
#15 0x00007fffea4cb196 in g_task_return (task=0x5555558b5d50 [GTask], type=<optimized out>) at gtask.c:1206
#16 0x00007fffea4fdd4a in g_dbus_connection_call_done (source=<optimized out>, result=0x5555558b5e20, user_data=0x5555558b5d50) at gdbusconnection.c:5715
#17 0x00007fffea4ca834 in g_task_return_now (task=0x5555558b5e20 [GTask]) at gtask.c:1148
#18 0x00007fffea4ca86d in complete_in_idle_cb (task=task@entry=0x5555558b5e20) at gtask.c:1162
#19 0x00007fffea73e97b in g_idle_dispatch (source=0x7fffdc04eb90, callback=0x7fffea4ca860 <complete_in_idle_cb>, user_data=0x5555558b5e20) at gmain.c:5620
#20 0x00007fffea74206d in g_main_dispatch (context=0x5555557c8410) at gmain.c:3182
#21 0x00007fffea74206d in g_main_context_dispatch (context=context@entry=0x5555557c8410) at gmain.c:3847
#22 0x00007fffea742438 in g_main_context_iterate (context=0x5555557c8410, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3920
#23 0x00007fffea742762 in g_main_loop_run (loop=0x55555584ed00) at gmain.c:4116
Fixes: c3efedf54bc64fd130849096849540ed1294df55
2019-02-19 07:50:35 +01:00
|
|
|
return g_hash_table_ref (g_simple_async_result_get_op_res_gpointer (simple));
|
2017-10-21 16:05:19 +02:00
|
|
|
}
|
|
|
|
|
|
checkpoint: allow resetting the rollback timeout via D-Bus
This allows to adjust the timeout of an existing checkpoint.
The main usecase of checkpoints, is to have a fail-safe when
configuring the network remotely. By allowing to reset the timeout,
the user can perform a series of actions, and keep bumping the
timeout. That way, the entire series is still guarded by the same
checkpoint, but the user can start with short timeout, and
re-adjust the timeout as he goes along.
The libnm API only implements the async form (at least for now).
Sync methods are fundamentally wrong with D-Bus, and it's probably
not needed. Also, follow glib convenction, where the async form
doesn't have the _async name suffix. Also, accept a D-Bus path
as argument, not a NMCheckpoint instance. The libnm API should
not be more restricted than the underlying D-Bus API. It would
be cumbersome to require the user to lookup the NMCheckpoint
instance first, especially since libnm doesn't provide an efficient
or convenient lookup-by-path method. On the other hand, retrieving
the path from a NMCheckpoint instance is always possible.
2018-03-28 08:09:56 +02:00
|
|
|
static void
|
|
|
|
|
checkpoint_adjust_rollback_timeout_cb (GObject *object,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
gs_unref_object GSimpleAsyncResult *simple = user_data;
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
|
|
if (nmdbus_manager_call_checkpoint_adjust_rollback_timeout_finish (NMDBUS_MANAGER (object),
|
|
|
|
|
result,
|
|
|
|
|
&error))
|
|
|
|
|
g_simple_async_result_set_op_res_gboolean (simple, TRUE);
|
|
|
|
|
else {
|
|
|
|
|
g_dbus_error_strip_remote_error (error);
|
|
|
|
|
g_simple_async_result_take_error (simple, error);
|
|
|
|
|
}
|
|
|
|
|
g_simple_async_result_complete (simple);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_manager_checkpoint_adjust_rollback_timeout (NMManager *manager,
|
|
|
|
|
const char *checkpoint_path,
|
|
|
|
|
guint32 add_timeout,
|
|
|
|
|
GCancellable *cancellable,
|
|
|
|
|
GAsyncReadyCallback callback,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
GSimpleAsyncResult *simple;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (NM_IS_MANAGER (manager));
|
|
|
|
|
g_return_if_fail (checkpoint_path && checkpoint_path[0] == '/');
|
|
|
|
|
|
|
|
|
|
simple = g_simple_async_result_new (G_OBJECT (manager), callback, user_data,
|
|
|
|
|
nm_manager_checkpoint_adjust_rollback_timeout);
|
|
|
|
|
if (cancellable)
|
|
|
|
|
g_simple_async_result_set_check_cancellable (simple, cancellable);
|
|
|
|
|
|
|
|
|
|
nmdbus_manager_call_checkpoint_adjust_rollback_timeout (NM_MANAGER_GET_PRIVATE (manager)->proxy,
|
|
|
|
|
checkpoint_path,
|
|
|
|
|
add_timeout,
|
|
|
|
|
cancellable,
|
|
|
|
|
checkpoint_adjust_rollback_timeout_cb,
|
|
|
|
|
simple);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
|
nm_manager_checkpoint_adjust_rollback_timeout_finish (NMManager *manager,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
GSimpleAsyncResult *simple;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (manager),
|
|
|
|
|
nm_manager_checkpoint_adjust_rollback_timeout),
|
|
|
|
|
FALSE);
|
|
|
|
|
|
|
|
|
|
simple = G_SIMPLE_ASYNC_RESULT (result);
|
|
|
|
|
return !g_simple_async_result_propagate_error (simple, error);
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-21 16:05:19 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2014-09-24 13:14:48 -04:00
|
|
|
static void
|
|
|
|
|
constructed (GObject *object)
|
|
|
|
|
{
|
|
|
|
|
G_OBJECT_CLASS (nm_manager_parent_class)->constructed (object);
|
|
|
|
|
|
|
|
|
|
g_signal_connect (object, "notify::" NM_MANAGER_WIRELESS_ENABLED,
|
|
|
|
|
G_CALLBACK (wireless_enabled_cb), NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMManager *manager = NM_MANAGER (initable);
|
2016-11-11 17:42:07 +01:00
|
|
|
GError *local_error = NULL;
|
2014-09-24 13:14:48 -04:00
|
|
|
|
2016-11-11 17:42:07 +01:00
|
|
|
if (!nm_manager_parent_initable_iface->init (initable, cancellable, error)) {
|
|
|
|
|
/* Never happens. */
|
|
|
|
|
g_return_val_if_reached (FALSE);
|
|
|
|
|
}
|
2014-09-24 13:14:48 -04:00
|
|
|
|
2016-11-11 17:42:07 +01:00
|
|
|
if (!get_permissions_sync (manager, &local_error)) {
|
|
|
|
|
g_warning ("Unable to get permissions: %s\n", local_error->message);
|
|
|
|
|
g_error_free (local_error);
|
|
|
|
|
}
|
2014-09-24 13:14:48 -04:00
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
NMManager *manager;
|
|
|
|
|
GCancellable *cancellable;
|
|
|
|
|
GSimpleAsyncResult *result;
|
|
|
|
|
} NMManagerInitData;
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
init_async_complete (NMManagerInitData *init_data)
|
|
|
|
|
{
|
|
|
|
|
g_simple_async_result_complete (init_data->result);
|
|
|
|
|
g_object_unref (init_data->result);
|
|
|
|
|
g_clear_object (&init_data->cancellable);
|
|
|
|
|
g_slice_free (NMManagerInitData, init_data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
init_async_got_permissions (GObject *object, GAsyncResult *result, gpointer user_data)
|
|
|
|
|
{
|
2016-10-08 14:44:45 +02:00
|
|
|
NMManager *manager = user_data;
|
2014-09-24 13:14:48 -04:00
|
|
|
GVariant *permissions;
|
|
|
|
|
|
|
|
|
|
if (nmdbus_manager_call_get_permissions_finish (NMDBUS_MANAGER (object),
|
|
|
|
|
&permissions,
|
|
|
|
|
result, NULL)) {
|
2016-10-08 14:44:45 +02:00
|
|
|
update_permissions (manager, permissions);
|
2014-09-24 13:14:48 -04:00
|
|
|
g_variant_unref (permissions);
|
|
|
|
|
} else
|
2016-10-08 14:44:45 +02:00
|
|
|
update_permissions (manager, NULL);
|
2014-09-24 13:14:48 -04:00
|
|
|
|
2016-10-08 14:44:45 +02:00
|
|
|
g_object_unref (manager);
|
2014-09-24 13:14:48 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
init_async_parent_inited (GObject *source, GAsyncResult *result, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMManagerInitData *init_data = user_data;
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (init_data->manager);
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
|
|
if (!nm_manager_parent_async_initable_iface->init_finish (G_ASYNC_INITABLE (source), result, &error)) {
|
|
|
|
|
g_simple_async_result_take_error (init_data->result, error);
|
|
|
|
|
init_async_complete (init_data);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-14 18:47:56 +01:00
|
|
|
nmdbus_manager_call_get_permissions (priv->proxy,
|
2014-09-24 13:14:48 -04:00
|
|
|
init_data->cancellable,
|
2016-10-08 14:44:45 +02:00
|
|
|
init_async_got_permissions,
|
|
|
|
|
g_object_ref (init_data->manager));
|
|
|
|
|
|
|
|
|
|
init_async_complete (init_data);
|
2014-09-24 13:14:48 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
init_async (GAsyncInitable *initable, int io_priority,
|
|
|
|
|
GCancellable *cancellable, GAsyncReadyCallback callback,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMManagerInitData *init_data;
|
|
|
|
|
|
|
|
|
|
init_data = g_slice_new0 (NMManagerInitData);
|
|
|
|
|
init_data->manager = NM_MANAGER (initable);
|
|
|
|
|
init_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
|
|
|
|
|
init_data->result = g_simple_async_result_new (G_OBJECT (initable), callback,
|
|
|
|
|
user_data, init_async);
|
2018-03-05 16:02:24 +01:00
|
|
|
if (cancellable)
|
|
|
|
|
g_simple_async_result_set_check_cancellable (init_data->result, cancellable);
|
2014-09-24 13:14:48 -04:00
|
|
|
g_simple_async_result_set_op_res_gboolean (init_data->result, TRUE);
|
|
|
|
|
|
|
|
|
|
nm_manager_parent_async_initable_iface->init_async (initable, io_priority, cancellable,
|
|
|
|
|
init_async_parent_inited, init_data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
init_finish (GAsyncInitable *initable, GAsyncResult *result, GError **error)
|
|
|
|
|
{
|
|
|
|
|
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
|
|
|
|
|
|
|
|
|
|
if (g_simple_async_result_propagate_error (simple, error))
|
|
|
|
|
return FALSE;
|
|
|
|
|
else
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dispose (GObject *object)
|
|
|
|
|
{
|
|
|
|
|
NMManager *manager = NM_MANAGER (object);
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (object);
|
|
|
|
|
|
2017-03-13 11:51:33 +01:00
|
|
|
nm_clear_g_cancellable (&priv->perm_call_cancellable);
|
2016-10-18 16:35:07 +02:00
|
|
|
|
|
|
|
|
if (priv->devices) {
|
|
|
|
|
g_ptr_array_unref (priv->devices);
|
|
|
|
|
priv->devices = NULL;
|
|
|
|
|
}
|
|
|
|
|
if (priv->all_devices) {
|
|
|
|
|
g_ptr_array_unref (priv->all_devices);
|
|
|
|
|
priv->all_devices = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-19 09:16:06 +01:00
|
|
|
nm_clear_pointer (&priv->checkpoints, g_ptr_array_unref);
|
|
|
|
|
|
2016-10-18 16:35:07 +02:00
|
|
|
free_active_connections (manager);
|
2014-09-24 13:14:48 -04:00
|
|
|
g_clear_object (&priv->primary_connection);
|
|
|
|
|
g_clear_object (&priv->activating_connection);
|
|
|
|
|
|
2016-11-14 18:47:56 +01:00
|
|
|
g_clear_object (&priv->proxy);
|
|
|
|
|
|
2014-09-24 13:14:48 -04:00
|
|
|
/* Each activation should hold a ref on @manager, so if we're being disposed,
|
|
|
|
|
* there shouldn't be any pending.
|
|
|
|
|
*/
|
2017-05-06 20:27:29 +02:00
|
|
|
g_warn_if_fail (c_list_is_empty (&priv->pending_activations));
|
2014-09-24 13:14:48 -04:00
|
|
|
|
|
|
|
|
g_hash_table_destroy (priv->permissions);
|
|
|
|
|
priv->permissions = NULL;
|
|
|
|
|
|
|
|
|
|
G_OBJECT_CLASS (nm_manager_parent_class)->dispose (object);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
finalize (GObject *object)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (object);
|
|
|
|
|
|
|
|
|
|
g_free (priv->version);
|
|
|
|
|
|
|
|
|
|
G_OBJECT_CLASS (nm_manager_parent_class)->finalize (object);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
set_property (GObject *object, guint prop_id,
|
|
|
|
|
const GValue *value, GParamSpec *pspec)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (object);
|
|
|
|
|
gboolean b;
|
|
|
|
|
|
|
|
|
|
switch (prop_id) {
|
|
|
|
|
case PROP_NETWORKING_ENABLED:
|
|
|
|
|
b = g_value_get_boolean (value);
|
|
|
|
|
if (priv->networking_enabled != b) {
|
|
|
|
|
nm_manager_networking_set_enabled (NM_MANAGER (object), b, NULL);
|
|
|
|
|
/* Let the property value flip when we get the change signal from NM */
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case PROP_WIRELESS_ENABLED:
|
|
|
|
|
b = g_value_get_boolean (value);
|
|
|
|
|
if (priv->wireless_enabled != b) {
|
|
|
|
|
nm_manager_wireless_set_enabled (NM_MANAGER (object), b);
|
|
|
|
|
/* Let the property value flip when we get the change signal from NM */
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case PROP_WWAN_ENABLED:
|
|
|
|
|
b = g_value_get_boolean (value);
|
|
|
|
|
if (priv->wwan_enabled != b) {
|
|
|
|
|
nm_manager_wwan_set_enabled (NM_MANAGER (object), b);
|
|
|
|
|
/* Let the property value flip when we get the change signal from NM */
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case PROP_WIMAX_ENABLED:
|
|
|
|
|
b = g_value_get_boolean (value);
|
|
|
|
|
if (priv->wimax_enabled != b) {
|
|
|
|
|
nm_manager_wimax_set_enabled (NM_MANAGER (object), b);
|
|
|
|
|
/* Let the property value flip when we get the change signal from NM */
|
|
|
|
|
}
|
|
|
|
|
break;
|
2017-08-09 15:21:28 +08:00
|
|
|
case PROP_CONNECTIVITY_CHECK_ENABLED:
|
|
|
|
|
b = g_value_get_boolean (value);
|
|
|
|
|
if (priv->connectivity_check_enabled != b) {
|
|
|
|
|
nm_manager_connectivity_check_set_enabled (NM_MANAGER (object), b);
|
|
|
|
|
/* Let the property value flip when we get the change signal from NM */
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-09-24 13:14:48 -04:00
|
|
|
default:
|
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
get_property (GObject *object,
|
|
|
|
|
guint prop_id,
|
|
|
|
|
GValue *value,
|
|
|
|
|
GParamSpec *pspec)
|
|
|
|
|
{
|
|
|
|
|
NMManager *self = NM_MANAGER (object);
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
switch (prop_id) {
|
|
|
|
|
case PROP_VERSION:
|
|
|
|
|
g_value_set_string (value, nm_manager_get_version (self));
|
|
|
|
|
break;
|
|
|
|
|
case PROP_STATE:
|
|
|
|
|
g_value_set_enum (value, nm_manager_get_state (self));
|
|
|
|
|
break;
|
|
|
|
|
case PROP_STARTUP:
|
|
|
|
|
g_value_set_boolean (value, nm_manager_get_startup (self));
|
|
|
|
|
break;
|
|
|
|
|
case PROP_NETWORKING_ENABLED:
|
|
|
|
|
g_value_set_boolean (value, nm_manager_networking_get_enabled (self));
|
|
|
|
|
break;
|
|
|
|
|
case PROP_WIRELESS_ENABLED:
|
|
|
|
|
g_value_set_boolean (value, priv->wireless_enabled);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_WIRELESS_HARDWARE_ENABLED:
|
|
|
|
|
g_value_set_boolean (value, priv->wireless_hw_enabled);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_WWAN_ENABLED:
|
|
|
|
|
g_value_set_boolean (value, priv->wwan_enabled);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_WWAN_HARDWARE_ENABLED:
|
|
|
|
|
g_value_set_boolean (value, priv->wwan_hw_enabled);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_WIMAX_ENABLED:
|
|
|
|
|
g_value_set_boolean (value, priv->wimax_enabled);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_WIMAX_HARDWARE_ENABLED:
|
|
|
|
|
g_value_set_boolean (value, priv->wimax_hw_enabled);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_ACTIVE_CONNECTIONS:
|
|
|
|
|
g_value_take_boxed (value, _nm_utils_copy_object_array (nm_manager_get_active_connections (self)));
|
|
|
|
|
break;
|
|
|
|
|
case PROP_CONNECTIVITY:
|
|
|
|
|
g_value_set_enum (value, priv->connectivity);
|
|
|
|
|
break;
|
2017-08-09 15:21:28 +08:00
|
|
|
case PROP_CONNECTIVITY_CHECK_AVAILABLE:
|
|
|
|
|
g_value_set_boolean (value, priv->connectivity_check_available);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_CONNECTIVITY_CHECK_ENABLED:
|
|
|
|
|
g_value_set_boolean (value, priv->connectivity_check_enabled);
|
|
|
|
|
break;
|
2014-09-24 13:14:48 -04:00
|
|
|
case PROP_PRIMARY_CONNECTION:
|
|
|
|
|
g_value_set_object (value, priv->primary_connection);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_ACTIVATING_CONNECTION:
|
|
|
|
|
g_value_set_object (value, priv->activating_connection);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_DEVICES:
|
|
|
|
|
g_value_take_boxed (value, _nm_utils_copy_object_array (nm_manager_get_devices (self)));
|
|
|
|
|
break;
|
2017-10-21 16:05:19 +02:00
|
|
|
case PROP_CHECKPOINTS:
|
|
|
|
|
g_value_take_boxed (value, _nm_utils_copy_object_array (nm_manager_get_checkpoints (self)));
|
|
|
|
|
break;
|
2015-06-03 09:15:24 +02:00
|
|
|
case PROP_METERED:
|
|
|
|
|
g_value_set_uint (value, priv->metered);
|
|
|
|
|
break;
|
2014-10-10 14:28:49 -05:00
|
|
|
case PROP_ALL_DEVICES:
|
|
|
|
|
g_value_take_boxed (value, _nm_utils_copy_object_array (nm_manager_get_all_devices (self)));
|
|
|
|
|
break;
|
2014-09-24 13:14:48 -04:00
|
|
|
default:
|
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
nm_manager_class_init (NMManagerClass *manager_class)
|
|
|
|
|
{
|
|
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
|
|
|
|
|
NMObjectClass *nm_object_class = NM_OBJECT_CLASS (manager_class);
|
|
|
|
|
|
|
|
|
|
g_type_class_add_private (manager_class, sizeof (NMManagerPrivate));
|
|
|
|
|
|
|
|
|
|
/* virtual methods */
|
|
|
|
|
object_class->constructed = constructed;
|
|
|
|
|
object_class->set_property = set_property;
|
|
|
|
|
object_class->get_property = get_property;
|
|
|
|
|
object_class->dispose = dispose;
|
|
|
|
|
object_class->finalize = finalize;
|
|
|
|
|
|
|
|
|
|
nm_object_class->init_dbus = init_dbus;
|
2017-10-21 16:05:19 +02:00
|
|
|
nm_object_class->object_creation_failed = object_creation_failed;
|
2014-09-24 13:14:48 -04:00
|
|
|
|
2014-10-10 14:43:55 -04:00
|
|
|
manager_class->device_added = device_added;
|
|
|
|
|
manager_class->device_removed = device_removed;
|
|
|
|
|
manager_class->active_connection_added = active_connection_added;
|
|
|
|
|
manager_class->active_connection_removed = active_connection_removed;
|
2017-10-21 16:05:19 +02:00
|
|
|
manager_class->checkpoint_added = checkpoint_added;
|
2014-10-10 14:43:55 -04:00
|
|
|
|
2014-09-24 13:14:48 -04:00
|
|
|
/* properties */
|
|
|
|
|
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_VERSION,
|
|
|
|
|
g_param_spec_string (NM_MANAGER_VERSION, "", "",
|
|
|
|
|
NULL,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_STATE,
|
|
|
|
|
g_param_spec_enum (NM_CLIENT_STATE, "", "",
|
|
|
|
|
NM_TYPE_STATE,
|
|
|
|
|
NM_STATE_UNKNOWN,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_STARTUP,
|
|
|
|
|
g_param_spec_boolean (NM_MANAGER_STARTUP, "", "",
|
|
|
|
|
FALSE,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_NETWORKING_ENABLED,
|
|
|
|
|
g_param_spec_boolean (NM_MANAGER_NETWORKING_ENABLED, "", "",
|
|
|
|
|
TRUE,
|
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_WIRELESS_ENABLED,
|
|
|
|
|
g_param_spec_boolean (NM_MANAGER_WIRELESS_ENABLED, "", "",
|
|
|
|
|
FALSE,
|
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_WIRELESS_HARDWARE_ENABLED,
|
|
|
|
|
g_param_spec_boolean (NM_MANAGER_WIRELESS_HARDWARE_ENABLED, "", "",
|
|
|
|
|
TRUE,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_WWAN_ENABLED,
|
|
|
|
|
g_param_spec_boolean (NM_MANAGER_WWAN_ENABLED, "", "",
|
|
|
|
|
FALSE,
|
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_WWAN_HARDWARE_ENABLED,
|
|
|
|
|
g_param_spec_boolean (NM_MANAGER_WWAN_HARDWARE_ENABLED, "", "",
|
|
|
|
|
FALSE,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_WIMAX_ENABLED,
|
|
|
|
|
g_param_spec_boolean (NM_MANAGER_WIMAX_ENABLED, "", "",
|
|
|
|
|
FALSE,
|
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_WIMAX_HARDWARE_ENABLED,
|
|
|
|
|
g_param_spec_boolean (NM_MANAGER_WIMAX_HARDWARE_ENABLED, "", "",
|
|
|
|
|
FALSE,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_ACTIVE_CONNECTIONS,
|
|
|
|
|
g_param_spec_boxed (NM_MANAGER_ACTIVE_CONNECTIONS, "", "",
|
|
|
|
|
G_TYPE_PTR_ARRAY,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_CONNECTIVITY,
|
|
|
|
|
g_param_spec_enum (NM_CLIENT_CONNECTIVITY, "", "",
|
|
|
|
|
NM_TYPE_CONNECTIVITY_STATE,
|
|
|
|
|
NM_CONNECTIVITY_UNKNOWN,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2017-08-09 15:21:28 +08:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_CONNECTIVITY_CHECK_AVAILABLE,
|
|
|
|
|
g_param_spec_boolean (NM_MANAGER_CONNECTIVITY_CHECK_AVAILABLE, "", "",
|
|
|
|
|
FALSE,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_CONNECTIVITY_CHECK_ENABLED,
|
|
|
|
|
g_param_spec_boolean (NM_MANAGER_CONNECTIVITY_CHECK_ENABLED, "", "",
|
|
|
|
|
FALSE,
|
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2014-09-24 13:14:48 -04:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_PRIMARY_CONNECTION,
|
|
|
|
|
g_param_spec_object (NM_MANAGER_PRIMARY_CONNECTION, "", "",
|
|
|
|
|
NM_TYPE_ACTIVE_CONNECTION,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_ACTIVATING_CONNECTION,
|
|
|
|
|
g_param_spec_object (NM_MANAGER_ACTIVATING_CONNECTION, "", "",
|
|
|
|
|
NM_TYPE_ACTIVE_CONNECTION,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_DEVICES,
|
|
|
|
|
g_param_spec_boxed (NM_MANAGER_DEVICES, "", "",
|
|
|
|
|
G_TYPE_PTR_ARRAY,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2017-10-21 16:05:19 +02:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_CHECKPOINTS,
|
|
|
|
|
g_param_spec_boxed (NM_MANAGER_CHECKPOINTS, "", "",
|
|
|
|
|
G_TYPE_PTR_ARRAY,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2015-06-03 09:15:24 +02:00
|
|
|
/**
|
|
|
|
|
* NMManager:metered:
|
|
|
|
|
*
|
|
|
|
|
* Whether the connectivity is metered.
|
|
|
|
|
*
|
|
|
|
|
* Since: 1.2
|
|
|
|
|
**/
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_METERED,
|
|
|
|
|
g_param_spec_uint (NM_MANAGER_METERED, "", "",
|
|
|
|
|
0, G_MAXUINT32, NM_METERED_UNKNOWN,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2014-09-24 13:14:48 -04:00
|
|
|
|
2014-10-10 14:28:49 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_ALL_DEVICES,
|
|
|
|
|
g_param_spec_boxed (NM_MANAGER_ALL_DEVICES, "", "",
|
|
|
|
|
G_TYPE_PTR_ARRAY,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
|
|
2014-09-24 13:14:48 -04:00
|
|
|
/* signals */
|
|
|
|
|
|
|
|
|
|
signals[DEVICE_ADDED] =
|
|
|
|
|
g_signal_new ("device-added",
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
|
G_STRUCT_OFFSET (NMManagerClass, device_added),
|
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
|
G_TYPE_NONE, 1,
|
|
|
|
|
G_TYPE_OBJECT);
|
|
|
|
|
signals[DEVICE_REMOVED] =
|
|
|
|
|
g_signal_new ("device-removed",
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
|
G_STRUCT_OFFSET (NMManagerClass, device_removed),
|
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
|
G_TYPE_NONE, 1,
|
|
|
|
|
G_TYPE_OBJECT);
|
2014-10-10 14:28:49 -05:00
|
|
|
signals[ANY_DEVICE_ADDED] =
|
|
|
|
|
g_signal_new ("any-device-added",
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
|
0,
|
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
|
G_TYPE_NONE, 1,
|
|
|
|
|
G_TYPE_OBJECT);
|
|
|
|
|
signals[ANY_DEVICE_REMOVED] =
|
|
|
|
|
g_signal_new ("any-device-removed",
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
|
0,
|
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
|
G_TYPE_NONE, 1,
|
|
|
|
|
G_TYPE_OBJECT);
|
2014-10-10 14:06:44 -04:00
|
|
|
signals[ACTIVE_CONNECTION_ADDED] =
|
|
|
|
|
g_signal_new ("active-connection-added",
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
|
G_STRUCT_OFFSET (NMManagerClass, active_connection_added),
|
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
|
G_TYPE_NONE, 1,
|
|
|
|
|
G_TYPE_OBJECT);
|
|
|
|
|
signals[ACTIVE_CONNECTION_REMOVED] =
|
|
|
|
|
g_signal_new ("active-connection-removed",
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
|
G_STRUCT_OFFSET (NMManagerClass, active_connection_removed),
|
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
|
G_TYPE_NONE, 1,
|
|
|
|
|
G_TYPE_OBJECT);
|
2017-10-21 16:05:19 +02:00
|
|
|
signals[CHECKPOINT_ADDED] =
|
|
|
|
|
g_signal_new ("checkpoint-added",
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
|
G_STRUCT_OFFSET (NMManagerClass, checkpoint_added),
|
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
|
G_TYPE_NONE, 1,
|
|
|
|
|
G_TYPE_OBJECT);
|
|
|
|
|
signals[CHECKPOINT_REMOVED] =
|
|
|
|
|
g_signal_new ("checkpoint-removed",
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
|
G_STRUCT_OFFSET (NMManagerClass, checkpoint_removed),
|
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
|
G_TYPE_NONE, 1,
|
|
|
|
|
G_TYPE_OBJECT);
|
|
|
|
|
|
2014-09-24 13:14:48 -04:00
|
|
|
signals[PERMISSION_CHANGED] =
|
|
|
|
|
g_signal_new ("permission-changed",
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
|
0, NULL, NULL, NULL,
|
|
|
|
|
G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
nm_manager_initable_iface_init (GInitableIface *iface)
|
|
|
|
|
{
|
|
|
|
|
nm_manager_parent_initable_iface = g_type_interface_peek_parent (iface);
|
|
|
|
|
|
|
|
|
|
iface->init = init_sync;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
nm_manager_async_initable_iface_init (GAsyncInitableIface *iface)
|
|
|
|
|
{
|
|
|
|
|
nm_manager_parent_async_initable_iface = g_type_interface_peek_parent (iface);
|
|
|
|
|
|
|
|
|
|
iface->init_async = init_async;
|
|
|
|
|
iface->init_finish = init_finish;
|
|
|
|
|
}
|