summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2017-06-16 13:06:26 +0200
committerThomas Haller <thaller@redhat.com>2017-06-16 14:55:43 +0200
commit74035b7bd5fa34fae76351382c7d8f63898d5be5 (patch)
tree482f6455994b73b7846b7c227ed581fd9407882d
parenteddf6cef61c78e25384b95d1e814a1a84e311812 (diff)
downloadNetworkManager-th/device-reapply-external-rh1462223.tar.gz
device: fix taking over device after modifying external connectionth/device-reapply-external-rh1462223
For externally managed interfaces, we create an in-memory connection and keep the device with sys-iface-state=external. When the user actively modifies the connection, we persist it to storage. But we also must take over managing the device. One problem is that nm_device_reapply() errors out if the device is still activating. It's unclear how to reapply the connection while the device is in the process of activation. So, if the user modifies the created connection very quickly, reapplying the settings will fail. https://bugzilla.redhat.com/show_bug.cgi?id=1462223
-rw-r--r--src/devices/nm-device.c24
-rw-r--r--src/devices/nm-device.h3
-rw-r--r--src/nm-active-connection.c10
3 files changed, 32 insertions, 5 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index d7635dcfac..b27e1ff180 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -9099,10 +9099,12 @@ check_and_reapply_connection (NMDevice *self,
NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS,
&diffs);
- if (diffs && nm_audit_manager_audit_enabled (nm_audit_manager_get ()))
- *audit_args = nm_utils_format_con_diff_for_audit (diffs);
- else
- *audit_args = NULL;
+ if (audit_args) {
+ if (diffs && nm_audit_manager_audit_enabled (nm_audit_manager_get ()))
+ *audit_args = nm_utils_format_con_diff_for_audit (diffs);
+ else
+ *audit_args = NULL;
+ }
/**************************************************************************
* check for unsupported changes and reject to reapply
@@ -9204,6 +9206,20 @@ check_and_reapply_connection (NMDevice *self,
return TRUE;
}
+gboolean
+nm_device_reapply (NMDevice *self,
+ NMConnection *connection,
+ GError **error)
+{
+ g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
+
+ return check_and_reapply_connection (self,
+ connection,
+ 0,
+ NULL,
+ error);
+}
+
typedef struct {
NMConnection *connection;
guint64 version_id;
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index 71000834f5..0323a78291 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -700,6 +700,9 @@ const NMPlatformIP6Route *nm_device_get_ip6_default_route (NMDevice *self, gbool
void nm_device_spawn_iface_helper (NMDevice *self);
+gboolean nm_device_reapply (NMDevice *self,
+ NMConnection *connection,
+ GError **error);
void nm_device_reapply_settings_immediately (NMDevice *self);
void nm_device_update_firewall_zone (NMDevice *self);
diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c
index 05feec2033..59902d2a64 100644
--- a/src/nm-active-connection.c
+++ b/src/nm-active-connection.c
@@ -787,6 +787,8 @@ _settings_connection_notify_flags (NMSettingsConnection *settings_connection,
GParamSpec *param,
NMActiveConnection *self)
{
+ GError *error = NULL;
+
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);
@@ -796,7 +798,13 @@ _settings_connection_notify_flags (NMSettingsConnection *settings_connection,
return;
_set_activation_type (self, NM_ACTIVATION_TYPE_MANAGED, TRUE);
- nm_device_reapply_settings_immediately (nm_active_connection_get_device (self));
+ if (!nm_device_reapply (nm_active_connection_get_device (self),
+ NM_CONNECTION (nm_active_connection_get_settings_connection (self)),
+ &error)) {
+ _LOGW ("failed to reapply new device settings on previously externally managed device: %s",
+ error->message);
+ g_error_free (error);
+ }
}
/*****************************************************************************/