core: upgrade EXTERNAL activation type when user saves connection

An EXTERNAL activation type comes with a nm-generated, volatile,
in-memory connection. When the user actively modifies that connection, we
shall mark the active connection as fully managed.
This commit is contained in:
Thomas Haller 2017-03-08 15:58:59 +01:00
parent b32746cec3
commit bde6782591

View file

@ -51,8 +51,6 @@ typedef struct _NMActiveConnectionPrivate {
bool vpn:1;
bool master_ready:1;
/* TODO: when the user updates a connection with an extern activation
* type, the activation type must be updated to FULL. */
NMActivationType activation_type:3;
NMAuthSubject *subject;
@ -105,8 +103,13 @@ G_DEFINE_ABSTRACT_TYPE (NMActiveConnection, nm_active_connection, NM_TYPE_EXPORT
#define NM_ACTIVE_CONNECTION_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMActiveConnection, NM_IS_ACTIVE_CONNECTION)
/*****************************************************************************/
static void check_master_ready (NMActiveConnection *self);
static void _device_cleanup (NMActiveConnection *self);
static void _settings_connection_notify_flags (NMSettingsConnection *settings_connection,
GParamSpec *param,
NMActiveConnection *self);
/*****************************************************************************/
@ -184,12 +187,15 @@ _set_settings_connection (NMActiveConnection *self, NMSettingsConnection *connec
if (priv->settings_connection) {
g_signal_handlers_disconnect_by_func (priv->settings_connection, _settings_connection_updated, self);
g_signal_handlers_disconnect_by_func (priv->settings_connection, _settings_connection_removed, self);
g_signal_handlers_disconnect_by_func (priv->settings_connection, _settings_connection_notify_flags, self);
g_clear_object (&priv->settings_connection);
}
if (connection) {
priv->settings_connection = g_object_ref (connection);
g_signal_connect (connection, NM_SETTINGS_CONNECTION_UPDATED_INTERNAL, (GCallback) _settings_connection_updated, self);
g_signal_connect (connection, NM_SETTINGS_CONNECTION_REMOVED, (GCallback) _settings_connection_removed, self);
if (nm_active_connection_get_activation_type (self) == NM_ACTIVATION_TYPE_EXTERNAL)
g_signal_connect (connection, "notify::"NM_SETTINGS_CONNECTION_FLAGS, (GCallback) _settings_connection_notify_flags, self);
}
}
@ -723,6 +729,21 @@ nm_active_connection_get_activation_type (NMActiveConnection *self)
return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->activation_type;
}
static void
_set_activation_type (NMActiveConnection *self,
NMActivationType activation_type)
{
NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
if (priv->activation_type == activation_type)
return;
_LOGD ("update activation type from %s to %s",
nm_activation_type_to_string (priv->activation_type),
nm_activation_type_to_string (activation_type));
priv->activation_type = activation_type;
}
gboolean
nm_active_connection_has_activation_type_assume_or_external (NMActiveConnection *self)
{
@ -733,6 +754,26 @@ nm_active_connection_has_activation_type_assume_or_external (NMActiveConnection
/*****************************************************************************/
static void
_settings_connection_notify_flags (NMSettingsConnection *settings_connection,
GParamSpec *param,
NMActiveConnection *self)
{
nm_assert (NM_IS_ACTIVE_CONNECTION (self));
nm_assert (NM_IS_SETTINGS_CONNECTION (settings_connection));
nm_assert (nm_active_connection_get_activation_type (self) == NM_ACTIVATION_TYPE_EXTERNAL);
nm_assert (NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->settings_connection == settings_connection);
if (nm_settings_connection_get_nm_generated (settings_connection))
return;
g_signal_handlers_disconnect_by_func (settings_connection, _settings_connection_notify_flags, self);
_set_activation_type (self, NM_ACTIVATION_TYPE_MANAGED);
nm_device_reapply_settings_immediately (nm_active_connection_get_device (self));
}
/*****************************************************************************/
static void unwatch_parent (NMActiveConnection *self, gboolean unref);
static void
@ -1138,10 +1179,8 @@ constructed (GObject *object)
G_OBJECT_CLASS (nm_active_connection_parent_class)->constructed (object);
if (!priv->applied_connection && priv->settings_connection) {
priv->applied_connection =
nm_simple_connection_new_clone ((NMConnection *) priv->settings_connection);
}
if (!priv->applied_connection && priv->settings_connection)
priv->applied_connection = nm_simple_connection_new_clone (NM_CONNECTION (priv->settings_connection));
if (priv->applied_connection)
nm_connection_clear_secrets (priv->applied_connection);