core: add version-id to NMActiveConnection

This field will be later used by NMDevice's Reapply and
GetAppliedConnection methods. The usecase is to first fetch
the currently applied connection, adjust it and reapply it.
Using the version-id, a concurrent modification can be detected
and Reapply can reject the invocation.
This commit is contained in:
Thomas Haller 2016-02-11 08:36:39 +01:00
parent 4b76d86698
commit b96a40c2ec
3 changed files with 54 additions and 5 deletions

View file

@ -7181,6 +7181,7 @@ reapply_connection (NMDevice *self,
NMConnection *con_old, *con_new;
NMSettingIPConfig *s_ip4_old, *s_ip4_new;
NMSettingIPConfig *s_ip6_old, *s_ip6_new;
guint64 version_id;
if (priv->state != NM_DEVICE_STATE_ACTIVATED) {
g_set_error_literal (error,
@ -7212,12 +7213,17 @@ reapply_connection (NMDevice *self,
NM_SETTING_CONNECTION_METERED))
return FALSE;
_LOGD (LOGD_DEVICE, "reapply");
/**************************************************************************
* 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;
@ -9218,6 +9224,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 +9247,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 +9259,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,

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,