device: merge branch 'th/device-applied-connection-bgo760884'

https://bugzilla.gnome.org/show_bug.cgi?id=760884
https://bugzilla.gnome.org/show_bug.cgi?id=761714
This commit is contained in:
Thomas Haller 2016-02-16 11:28:37 +01:00
commit a058cf41dc
11 changed files with 475 additions and 28 deletions

View file

@ -1928,7 +1928,7 @@ do_device_reapply (NmCli *nmc, int argc, char **argv)
info->queue = g_slist_prepend (info->queue, g_object_ref (device));
/* Now reapply the connection to the device */
nm_device_reapply_async (device, NULL, 0, NULL, reapply_device_cb, info);
nm_device_reapply_async (device, NULL, 0, 0, NULL, reapply_device_cb, info);
}
error:

View file

@ -9,6 +9,15 @@
The Connection.Active object tracks the life-cycle of the connection
attempt and if successful indicates whether the connected network is the
"default" or preferred network for access.
NetworkManager has the concept of connections, which can be thought of as
settings, a profile or a configuration that can be applied on a networking
device.
Such settings-connections are exposed as D-Bus object and the active-connection
expresses this relationship between device and settings-connection.
At any time a settings-connection can only be activated on one device and vice
versa. However, during activation and deactivation multiple active-connections
can reference the same device or settings-connection as they are waiting to
be activated or to be deactivated.
</tp:docstring>
<property name="Connection" type="o" access="read">

View file

@ -172,8 +172,18 @@
<method name="Reapply">
<arg name="connection" type="a{sa{sv}}" direction="in">
<tp:docstring>
The effective connection settings and properties to use. If empty, the connection
settings from the connection that is active on the device will be used.
The optional connection settings that will be reapplied on the device. If empty, the
currently active settings-connection will be used. The connection cannot arbitrarly
differ from the current applied-connection otherwise the call will fail.
Only certain changes are supported, like adding or removing IP addresses.
</tp:docstring>
</arg>
<arg name="version_id" type="t" direction="in">
<tp:docstring>
If non-zero, the current version id of the applied-connection must match.
The current version id can be retrieved via GetAppliedConnection.
This optional argument allows to catch concurrent modifications between
the GetAppliedConnection call and Reapply.
</tp:docstring>
</arg>
<arg name="flags" type="u" direction="in">
@ -183,10 +193,54 @@
</tp:docstring>
</arg>
<tp:docstring>
Attempts to update the configuration of a device without deactivating it.
You can either modify the configuration by passing the desired setup via "connection"
argument or just omit the argument to bring it in sync with the connection that
has been activated but could have been modified since.
Attempts to update the configuration of a device without deactivating it. NetworkManager
has the concept of connections, which are profiles that contain the configuration for
a networking device. Those connections are exposed via D-Bus as individual objects
that can be created, modified and deleted. When activating such a settings-connection
on a device, the settings-connection is cloned to become an applied-connection and used to
configure the device (see GetAppliedConnection). Subsequent modification of the
settings-connection don't propagate automatically to the device's applied-connection
(with exception of the firewall-zone and the metered property). For the changes to take
effect, you can either re-activate the settings-connection, or call Reapply.
The Reapply call allows you to directly update the applied-connection and reconfigure
the device.
Reapply can also be useful if the currently applied-connection is equal to the connection
that is about to be reapplied. This allows to reconfigure the device and revert external
changes like removing or adding an IP address (which NetworkManager doesn't revert
automatically because it is assumed that the user made these changes intentionally outside
of NetworkManager).
Reapply can make the applied-connection different from the settings-connection,
just like updating the settings-connection can make them different.
</tp:docstring>
</method>
<method name="GetAppliedConnection">
<arg name="flags" type="u" direction="in">
<tp:docstring>
Flags which would modify the behavior of the GetAppliedConnection call.
There are no flags defined currently and the users should use the value of 0.
</tp:docstring>
</arg>
<arg name="connection" type="a{sa{sv}}" direction="out">
<tp:docstring>
The effective connection settings that the connection has currently applied.
</tp:docstring>
</arg>
<arg name="version_id" type="t" direction="out">
<tp:docstring>
The version-id of the currently applied connection. This can be specified during
Reapply to avoid races where you first fetch the applied connection, modify it
and try to reapply it. If the applied connection is modified in the meantime, the
version_id gets incremented and Reapply will fail.
</tp:docstring>
</arg>
<tp:docstring>
Get the currently applied connection on the device. This is a snapshot of the last activated
connection on the device, that is the configuration that is currently applied on the device.
Usually this is the same as GetSettings of the referenced settings connection. However, it
can differ if the settings connection was subsequently modified or the applied connection was
modified by Reapply. The applied connection is set when activating a device or when calling
Reapply.
</tp:docstring>
</method>

View file

@ -142,6 +142,7 @@ GQuark nm_crypto_error_quark (void);
* @NM_DEVICE_ERROR_SPECIFIC_OBJECT_NOT_FOUND: the "specific object" in the
* activation request (eg, the #NMAccessPoint or #NMWimaxNsp) was not
* found.
* @NM_DEVICE_ERROR_VERSION_ID_MISMATCH: the version id did not match.
*
* Device-related errors.
*
@ -158,6 +159,7 @@ typedef enum {
NM_DEVICE_ERROR_NOT_SOFTWARE, /*< nick=NotSoftware >*/
NM_DEVICE_ERROR_NOT_ALLOWED, /*< nick=NotAllowed >*/
NM_DEVICE_ERROR_SPECIFIC_OBJECT_NOT_FOUND, /*< nick=SpecificObjectNotFound >*/
NM_DEVICE_ERROR_VERSION_ID_MISMATCH, /*< nick=VersionIdMismatch >*/
} NMDeviceError;
#define NM_DEVICE_ERROR nm_device_error_quark ()

View file

@ -875,6 +875,9 @@ global:
nm_connection_get_setting_vxlan;
nm_connection_verify_secrets;
nm_device_ethernet_get_s390_subchannels;
nm_device_get_applied_connection;
nm_device_get_applied_connection_async;
nm_device_get_applied_connection_finish;
nm_device_get_lldp_neighbors;
nm_device_get_metered;
nm_device_get_nm_plugin_missing;

View file

@ -2167,6 +2167,9 @@ nm_device_is_software (NMDevice *device)
* nm_device_reapply:
* @device: a #NMDevice
* @connection: the #NMConnection to replace the applied settings with or %NULL to reuse existing
* @version_id: zero or the expected version id of the applied connection. If specified
* and the version id mismatches, the call fails without modification. This allows to
* catch concurrent accesses.
* @flags: always set this to zero
* @cancellable: a #GCancellable, or %NULL
* @error: location for a #GError, or %NULL
@ -2181,7 +2184,8 @@ nm_device_is_software (NMDevice *device)
gboolean
nm_device_reapply (NMDevice *device,
NMConnection *connection,
guint flags,
guint64 version_id,
guint32 flags,
GCancellable *cancellable,
GError **error)
{
@ -2197,7 +2201,7 @@ nm_device_reapply (NMDevice *device,
ret = nmdbus_device_call_reapply_sync (NM_DEVICE_GET_PRIVATE (device)->proxy,
dict, flags, cancellable, error);
dict, version_id, flags, cancellable, error);
if (error && *error)
g_dbus_error_strip_remote_error (*error);
return ret;
@ -2226,6 +2230,9 @@ device_reapply_cb (GObject *proxy,
* nm_device_reapply_async:
* @device: a #NMDevice
* @connection: the #NMConnection to replace the applied settings with or %NULL to reuse existing
* @version_id: zero or the expected version id of the applied connection. If specified
* and the version id mismatches, the call fails without modification. This allows to
* catch concurrent accesses.
* @flags: always set this to zero
* @cancellable: a #GCancellable, or %NULL
* @callback: callback to be called when the reapply operation completes
@ -2239,7 +2246,8 @@ device_reapply_cb (GObject *proxy,
void
nm_device_reapply_async (NMDevice *device,
NMConnection *connection,
guint flags,
guint64 version_id,
guint32 flags,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
@ -2258,7 +2266,7 @@ nm_device_reapply_async (NMDevice *device,
nm_device_reapply_async);
nmdbus_device_call_reapply (NM_DEVICE_GET_PRIVATE (device)->proxy,
dict, flags, cancellable,
dict, version_id, flags, cancellable,
device_reapply_cb, simple);
}
@ -2291,6 +2299,179 @@ nm_device_reapply_finish (NMDevice *device,
return g_simple_async_result_get_op_res_gboolean (simple);
}
/*****************************************************************************/
/**
* nm_device_get_applied_connection:
* @device: a #NMDevice
* @flags: the flags argument. Currently this value must always be zero.
* @version_id: (out): (allow-none): returns the current version id of
* the applied connection
* @cancellable: a #GCancellable, or %NULL
* @error: location for a #GError, or %NULL
*
* Fetch the currently applied connection on the device.
*
* Returns: (transfer-full): a %NMConnection with the currently applied settings
* or %NULL on error.
*
* Since: 1.2
**/
NMConnection *
nm_device_get_applied_connection (NMDevice *device,
guint32 flags,
guint64 *version_id,
GCancellable *cancellable,
GError **error)
{
gs_unref_variant GVariant *dict = NULL;
guint64 my_version_id;
gboolean success;
NMConnection *connection;
g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL);
g_return_val_if_fail (!error || !*error, NULL);
success = nmdbus_device_call_get_applied_connection_sync (NM_DEVICE_GET_PRIVATE (device)->proxy,
flags, &dict, &my_version_id, cancellable, error);
if (!success) {
if (error && *error)
g_dbus_error_strip_remote_error (*error);
return NULL;
}
connection = nm_simple_connection_new_from_dbus (dict, error);
if (!connection)
return NULL;
NM_SET_OUT (version_id, my_version_id);
return connection;
}
typedef struct {
NMConnection *connection;
guint64 version_id;
} GetAppliedConnectionData;
static void
device_get_applied_connection_data_free (gpointer user_data)
{
GetAppliedConnectionData *data = user_data;
g_return_if_fail (data);
g_object_unref (data->connection);
g_slice_free (GetAppliedConnectionData, data);
}
static void
device_get_applied_connection_cb (GObject *proxy,
GAsyncResult *result,
gpointer user_data)
{
gs_unref_object GSimpleAsyncResult *simple = user_data;
gs_unref_variant GVariant *dict = NULL;
guint64 my_version_id;
GError *error = NULL;
NMConnection *connection;
GetAppliedConnectionData *data;
if (!nmdbus_device_call_get_applied_connection_finish (NMDBUS_DEVICE (proxy), &dict, &my_version_id, result, &error)) {
g_dbus_error_strip_remote_error (error);
g_simple_async_result_take_error (simple, error);
goto out;
}
connection = nm_simple_connection_new_from_dbus (dict, &error);
if (!connection) {
g_simple_async_result_take_error (simple, error);
goto out;
}
data = g_slice_new (GetAppliedConnectionData);
data->connection = connection;
data->version_id = my_version_id;
g_simple_async_result_set_op_res_gpointer (simple, data, device_get_applied_connection_data_free);
out:
g_simple_async_result_complete (simple);
}
/**
* nm_device_get_applied_connection_async:
* @device: a #NMDevice
* @flags: the flags argument. Currently this value must always be zero.
* @cancellable: a #GCancellable, or %NULL
* @callback: callback to be called when the reapply operation completes
* @user_data: caller-specific data passed to @callback
*
* Asynchronously begins an get the a currently applied connection.
*
* Since: 1.2
**/
void
nm_device_get_applied_connection_async (NMDevice *device,
guint32 flags,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *simple;
g_return_if_fail (NM_IS_DEVICE (device));
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
simple = g_simple_async_result_new (G_OBJECT (device), callback, user_data,
nm_device_get_applied_connection_async);
nmdbus_device_call_get_applied_connection (NM_DEVICE_GET_PRIVATE (device)->proxy,
flags, cancellable,
device_get_applied_connection_cb, simple);
}
/**
* nm_device_get_applied_connection_finish:
* @device: a #NMDevice
* @result: the result passed to the #GAsyncReadyCallback
* @version_id: (out): (allow-none): the current version id of the applied
* connection.
* @error: location for a #GError, or %NULL
*
* Gets the result of a call to nm_device_get_applied_connection_async().
*
* Returns: (transfer-full): a currently applied %NMConnection or %NULL in case
* of error.
*
* Since: 1.2
**/
NMConnection *
nm_device_get_applied_connection_finish (NMDevice *device,
GAsyncResult *result,
guint64 *version_id,
GError **error)
{
GSimpleAsyncResult *simple;
GetAppliedConnectionData *data;
g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (device), nm_device_get_applied_connection_async), NULL);
g_return_val_if_fail (!error || !*error, NULL);
simple = G_SIMPLE_ASYNC_RESULT (result);
if (g_simple_async_result_propagate_error (simple, error))
return NULL;
data = g_simple_async_result_get_op_res_gpointer (simple);
g_return_val_if_fail (data, NULL);
g_return_val_if_fail (NM_IS_CONNECTION (data->connection), NULL);
NM_SET_OUT (version_id, data->version_id);
return g_object_ref (data->connection);
}
/*****************************************************************************/
/**
* nm_device_disconnect:
* @device: a #NMDevice

View file

@ -140,13 +140,15 @@ char ** nm_device_disambiguate_names (NMDevice **devices,
NM_AVAILABLE_IN_1_2
gboolean nm_device_reapply (NMDevice *device,
NMConnection *connection,
guint flags,
guint64 version_id,
guint32 flags,
GCancellable *cancellable,
GError **error);
NM_AVAILABLE_IN_1_2
void nm_device_reapply_async (NMDevice *device,
NMConnection *connection,
guint flags,
guint64 version_id,
guint32 flags,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
@ -155,6 +157,24 @@ gboolean nm_device_reapply_finish (NMDevice *device,
GAsyncResult *result,
GError **error);
NM_AVAILABLE_IN_1_2
NMConnection *nm_device_get_applied_connection (NMDevice *device,
guint32 flags,
guint64 *version_id,
GCancellable *cancellable,
GError **error);
NM_AVAILABLE_IN_1_2
void nm_device_get_applied_connection_async (NMDevice *device,
guint32 flags,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
NM_AVAILABLE_IN_1_2
NMConnection *nm_device_get_applied_connection_finish (NMDevice *device,
GAsyncResult *result,
guint64 *version_id,
GError **error);
gboolean nm_device_disconnect (NMDevice *device,
GCancellable *cancellable,
GError **error);

View file

@ -7162,6 +7162,8 @@ nm_device_reactivate_ip6_config (NMDevice *self,
/* reapply_connection:
* @connection: the new connection settings to be applied or %NULL to reapply
* the current settings connection
* @version_id: either zero, or the current version id for the applied
* connection.
* @error: the error if %FALSE is returned
*
* Change configuration of an already configured device if possible.
@ -7172,6 +7174,7 @@ nm_device_reactivate_ip6_config (NMDevice *self,
static gboolean
reapply_connection (NMDevice *self,
NMConnection *connection,
guint64 version_id,
GError **error)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
@ -7212,12 +7215,26 @@ reapply_connection (NMDevice *self,
NM_SETTING_CONNECTION_METERED))
return FALSE;
_LOGD (LOGD_DEVICE, "reapply");
if ( version_id != 0
&& version_id != nm_active_connection_version_id_get ((NMActiveConnection *) priv->act_request)) {
g_set_error_literal (error,
NM_DEVICE_ERROR,
NM_DEVICE_ERROR_VERSION_ID_MISMATCH,
"Reapply failed because device changed in the meantime and the version-id mismatches");
return FALSE;
}
/**************************************************************************
* Update applied connection
*************************************************************************/
if (diffs)
nm_active_connection_version_id_bump ((NMActiveConnection *) priv->act_request);
_LOGD (LOGD_DEVICE, "reapply (version-id %llu%s)",
(long long unsigned) nm_active_connection_version_id_get (((NMActiveConnection *) priv->act_request)),
diffs ? "" : " (unmodified)");
if (diffs) {
con_old = applied_clone = nm_simple_connection_new_clone (applied);
con_new = applied;
@ -7243,6 +7260,11 @@ reapply_connection (NMDevice *self,
return TRUE;
}
typedef struct {
NMConnection *connection;
guint64 version_id;
} ReapplyData;
static void
reapply_cb (NMDevice *self,
GDBusMethodInvocation *context,
@ -7250,9 +7272,17 @@ reapply_cb (NMDevice *self,
GError *error,
gpointer user_data)
{
gs_unref_object NMConnection *connection = NM_CONNECTION (user_data);
ReapplyData *reapply_data = user_data;
guint64 version_id = 0;
gs_unref_object NMConnection *connection = NULL;
GError *local = NULL;
if (reapply_data) {
connection = reapply_data->connection;
version_id = reapply_data->version_id;
g_slice_free (ReapplyData, reapply_data);
}
if (error) {
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, subject, error->message);
g_dbus_method_invocation_return_gerror (context, error);
@ -7261,6 +7291,7 @@ reapply_cb (NMDevice *self,
if (!reapply_connection (self,
connection ? : (NMConnection *) nm_device_get_settings_connection (self),
version_id,
&local)) {
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, subject, local->message);
g_dbus_method_invocation_take_error (context, local);
@ -7275,17 +7306,19 @@ static void
impl_device_reapply (NMDevice *self,
GDBusMethodInvocation *context,
GVariant *settings,
guint flags)
guint64 version_id,
guint32 flags)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMSettingsConnection *settings_connection;
NMConnection *connection = NULL;
GError *error = NULL;
ReapplyData *reapply_data;
/* No flags supported as of now. */
if (flags != 0) {
error = g_error_new_literal (NM_DEVICE_ERROR,
NM_DEVICE_ERROR_NOT_ACTIVE,
NM_DEVICE_ERROR_FAILED,
"Invalid flags specified");
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, context, error->message);
g_dbus_method_invocation_take_error (context, error);
@ -7316,6 +7349,13 @@ impl_device_reapply (NMDevice *self,
nm_connection_clear_secrets (connection);
}
if (connection || version_id) {
reapply_data = g_slice_new (ReapplyData);
reapply_data->connection = connection;
reapply_data->version_id = version_id;
} else
reapply_data = NULL;
/* Ask the manager to authenticate this request for us */
g_signal_emit (self, signals[AUTH_REQUEST], 0,
context,
@ -7323,9 +7363,103 @@ impl_device_reapply (NMDevice *self,
NM_AUTH_PERMISSION_NETWORK_CONTROL,
TRUE,
reapply_cb,
connection);
reapply_data);
}
/*****************************************************************************/
static void
get_applied_connection_cb (NMDevice *self,
GDBusMethodInvocation *context,
NMAuthSubject *subject,
GError *error,
gpointer user_data /* possibly dangling pointer */)
{
NMDevicePrivate *priv;
NMConnection *applied_connection;
GVariant *settings;
g_return_if_fail (NM_IS_DEVICE (self));
if (error) {
g_dbus_method_invocation_return_gerror (context, error);
return;
}
priv = NM_DEVICE_GET_PRIVATE (self);
applied_connection = nm_device_get_applied_connection (self);
if (!applied_connection) {
error = g_error_new_literal (NM_DEVICE_ERROR,
NM_DEVICE_ERROR_NOT_ACTIVE,
"Device is not activated");
g_dbus_method_invocation_take_error (context, error);
return;
}
if (applied_connection != user_data) {
/* The applied connection changed due to a race. Reauthenticate. */
g_signal_emit (self, signals[AUTH_REQUEST], 0,
context,
applied_connection,
NM_AUTH_PERMISSION_NETWORK_CONTROL,
TRUE,
get_applied_connection_cb,
applied_connection /* no need take a ref. We will not dereference this pointer. */);
return;
}
settings = nm_connection_to_dbus (applied_connection, NM_CONNECTION_SERIALIZE_NO_SECRETS);
if (!settings)
settings = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0);
g_dbus_method_invocation_return_value (context,
g_variant_new ("(@a{sa{sv}}t)",
settings,
nm_active_connection_version_id_get ((NMActiveConnection *) priv->act_request)));
}
static void
impl_device_get_applied_connection (NMDevice *self,
GDBusMethodInvocation *context,
guint32 flags)
{
NMConnection *applied_connection;
GError *error = NULL;
g_return_if_fail (NM_IS_DEVICE (self));
/* No flags supported as of now. */
if (flags != 0) {
error = g_error_new_literal (NM_DEVICE_ERROR,
NM_DEVICE_ERROR_FAILED,
"Invalid flags specified");
g_dbus_method_invocation_take_error (context, error);
return;
}
applied_connection = nm_device_get_applied_connection (self);
if (!applied_connection) {
error = g_error_new_literal (NM_DEVICE_ERROR,
NM_DEVICE_ERROR_NOT_ACTIVE,
"Device is not activated");
g_dbus_method_invocation_take_error (context, error);
return;
}
/* Ask the manager to authenticate this request for us */
g_signal_emit (self, signals[AUTH_REQUEST], 0,
context,
applied_connection,
NM_AUTH_PERMISSION_NETWORK_CONTROL,
TRUE,
get_applied_connection_cb,
applied_connection /* no need take a ref. We will not dereference this pointer. */);
}
/*****************************************************************************/
static void
disconnect_cb (NMDevice *self,
GDBusMethodInvocation *context,
@ -9218,6 +9352,7 @@ nm_device_reapply_settings_immediately (NMDevice *self)
NMSettingConnection *s_con_applied;
const char *zone;
NMMetered metered;
guint64 version_id;
g_return_if_fail (NM_IS_DEVICE (self));
@ -9240,7 +9375,8 @@ nm_device_reapply_settings_immediately (NMDevice *self)
if (g_strcmp0 ((zone = nm_setting_connection_get_zone (s_con_settings)),
nm_setting_connection_get_zone (s_con_applied)) != 0) {
_LOGD (LOGD_DEVICE, "reapply setting: zone = %s%s%s", NM_PRINT_FMT_QUOTE_STRING (zone));
version_id = nm_active_connection_version_id_bump ((NMActiveConnection *) self->priv->act_request);
_LOGD (LOGD_DEVICE, "reapply setting: zone = %s%s%s (version-id %llu)", NM_PRINT_FMT_QUOTE_STRING (zone), (long long unsigned) version_id);
g_object_set (G_OBJECT (s_con_applied),
NM_SETTING_CONNECTION_ZONE, zone,
@ -9251,7 +9387,8 @@ nm_device_reapply_settings_immediately (NMDevice *self)
if ((metered = nm_setting_connection_get_metered (s_con_settings)) != nm_setting_connection_get_metered (s_con_applied)) {
_LOGD (LOGD_DEVICE, "reapply setting: metered = %d", (int) metered);
version_id = nm_active_connection_version_id_bump ((NMActiveConnection *) self->priv->act_request);
_LOGD (LOGD_DEVICE, "reapply setting: metered = %d (version-id %llu)", (int) metered, (long long unsigned) version_id);
g_object_set (G_OBJECT (s_con_applied),
NM_SETTING_CONNECTION_METERED, metered,
@ -11681,6 +11818,7 @@ nm_device_class_init (NMDeviceClass *klass)
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass),
NMDBUS_TYPE_DEVICE_SKELETON,
"Reapply", impl_device_reapply,
"GetAppliedConnection", impl_device_get_applied_connection,
"Disconnect", impl_device_disconnect,
"Delete", impl_device_delete,
NULL);

View file

@ -46,6 +46,8 @@ typedef struct {
char *specific_object;
NMDevice *device;
guint64 version_id;
char *pending_activation_id;
gboolean is_default;
@ -796,10 +798,45 @@ nm_active_connection_authorize (NMActiveConnection *self,
/****************************************************************/
static guint64
_version_id_new (void)
{
static guint64 id = 0;
return ++id;
}
guint64
nm_active_connection_version_id_get (NMActiveConnection *self)
{
g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), 0);
return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->version_id;
}
guint64
nm_active_connection_version_id_bump (NMActiveConnection *self)
{
NMActiveConnectionPrivate *priv;
g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), 0);
priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
priv->version_id = _version_id_new ();
_LOGT ("new version-id %llu", (long long unsigned) priv->version_id);
return priv->version_id;
}
/****************************************************************/
static void
nm_active_connection_init (NMActiveConnection *self)
{
NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
_LOGT ("creating");
priv->version_id = _version_id_new ();
}
static void
@ -810,7 +847,7 @@ constructed (GObject *object)
G_OBJECT_CLASS (nm_active_connection_parent_class)->constructed (object);
_LOGD ("constructed (%s)", G_OBJECT_TYPE_NAME (self));
_LOGD ("constructed (%s, version-id %llu)", G_OBJECT_TYPE_NAME (self), (long long unsigned) priv->version_id);
g_return_if_fail (priv->subject);
}

View file

@ -83,6 +83,9 @@ typedef struct {
NMMetered new_value);
} NMActiveConnectionClass;
guint64 nm_active_connection_version_id_get (NMActiveConnection *self);
guint64 nm_active_connection_version_id_bump (NMActiveConnection *self);
GType nm_active_connection_get_type (void);
typedef void (*NMActiveConnectionAuthResultFunc) (NMActiveConnection *self,

View file

@ -1716,10 +1716,10 @@ get_update_modify_permission (NMConnection *old, NMConnection *new)
}
static void
impl_settings_connection_update_helper (NMSettingsConnection *self,
GDBusMethodInvocation *context,
GVariant *new_settings,
gboolean save_to_disk)
settings_connection_update_helper (NMSettingsConnection *self,
GDBusMethodInvocation *context,
GVariant *new_settings,
gboolean save_to_disk)
{
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
NMAuthSubject *subject = NULL;
@ -1790,7 +1790,7 @@ impl_settings_connection_update (NMSettingsConnection *self,
GDBusMethodInvocation *context,
GVariant *new_settings)
{
impl_settings_connection_update_helper (self, context, new_settings, TRUE);
settings_connection_update_helper (self, context, new_settings, TRUE);
}
static void
@ -1798,7 +1798,7 @@ impl_settings_connection_update_unsaved (NMSettingsConnection *self,
GDBusMethodInvocation *context,
GVariant *new_settings)
{
impl_settings_connection_update_helper (self, context, new_settings, FALSE);
settings_connection_update_helper (self, context, new_settings, FALSE);
}
static void
@ -1807,7 +1807,7 @@ impl_settings_connection_save (NMSettingsConnection *self,
{
/* Do nothing if the connection is already synced with disk */
if (nm_settings_connection_get_unsaved (self))
impl_settings_connection_update_helper (self, context, NULL, TRUE);
settings_connection_update_helper (self, context, NULL, TRUE);
else
g_dbus_method_invocation_return_value (context, NULL);
}