summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2014-09-24 15:13:19 -0500
committerDan Williams <dcbw@redhat.com>2014-12-11 10:07:41 -0600
commitdb602934cc509c27cc7ce0f11dc3d48dd1865b48 (patch)
tree7818fd4f2646b7db343b763f96012fe66f58c9f2
parent594a58120ad9bf91c054270d38ed63f5d883948c (diff)
downloadNetworkManager-db602934cc509c27cc7ce0f11dc3d48dd1865b48.tar.gz
core: add class function for device unrealization
-rw-r--r--src/devices/nm-device-vlan.c9
-rw-r--r--src/devices/nm-device.c82
-rw-r--r--src/devices/nm-device.h17
-rw-r--r--src/nm-manager.c25
4 files changed, 120 insertions, 13 deletions
diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c
index 4f50d7481a..cd639de7d7 100644
--- a/src/devices/nm-device-vlan.c
+++ b/src/devices/nm-device-vlan.c
@@ -169,6 +169,14 @@ create_and_realize (NMDevice *device,
return TRUE;
}
+static gboolean
+unrealize (NMDevice *device, gboolean link_deleted, GError **error)
+{
+ NM_DEVICE_VLAN_GET_PRIVATE (device)->vlan_id = 0;
+ nm_device_vlan_set_parent (NM_DEVICE_VLAN (device), NULL);
+ return TRUE;
+}
+
static guint32
get_generic_capabilities (NMDevice *dev)
{
@@ -564,6 +572,7 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass)
parent_class->create_and_realize = create_and_realize;
parent_class->realize = realize;
parent_class->setup = setup;
+ parent_class->unrealize = unrealize;
parent_class->get_generic_capabilities = get_generic_capabilities;
parent_class->bring_up = bring_up;
parent_class->act_stage1_prepare = act_stage1_prepare;
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index e2c9db4d5c..e4d7f765f7 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -1488,6 +1488,67 @@ setup (NMDevice *self, NMPlatformLink *plink)
g_object_notify (G_OBJECT (self), NM_DEVICE_REAL);
}
+static gboolean
+unrealize (NMDevice *self, gboolean link_deleted, GError **error)
+{
+ int ifindex = nm_device_get_ifindex (self);
+
+ if (ifindex > 0 && nm_device_is_software (self) && !link_deleted)
+ nm_platform_link_delete (ifindex);
+
+ return TRUE;
+}
+
+/**
+ * nm_device_unrealize():
+ * @self: the #NMDevice
+ * @error: location to store error, or %NULL
+ *
+ * Release any backing resources (kernel devices, etc) created for this
+ * device and clear properties associated with external resources.
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ */
+gboolean
+nm_device_unrealize (NMDevice *self, gboolean link_deleted, GError **error)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+ gboolean success = TRUE;
+
+ g_return_val_if_fail (nm_device_is_real (self), FALSE);
+ g_return_val_if_fail (nm_device_is_software (self), FALSE);
+ g_return_val_if_fail (priv->iface != NULL, FALSE);
+
+ if (NM_DEVICE_GET_CLASS (self)->unrealize)
+ success = NM_DEVICE_GET_CLASS (self)->unrealize (self, link_deleted, error);
+
+ priv->ifindex = 0;
+ priv->ip_ifindex = 0;
+ g_clear_pointer (&priv->ip_iface, g_free);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_IP_IFACE);
+ g_clear_pointer (&priv->driver_version, g_free);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_DRIVER_VERSION);
+ g_clear_pointer (&priv->firmware_version, g_free);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_FIRMWARE_VERSION);
+ g_clear_pointer (&priv->udi, g_free);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_UDI);
+ g_clear_pointer (&priv->hw_addr, g_free);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_HW_ADDRESS);
+ g_clear_pointer (&priv->physical_port_id, g_free);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_PHYSICAL_PORT_ID);
+
+ g_clear_pointer (&priv->perm_hw_addr, g_free);
+ g_clear_pointer (&priv->initial_hw_addr, g_free);
+
+ priv->capabilities = NM_DEVICE_CAP_NM_SUPPORTED;
+ g_object_notify (G_OBJECT (self), NM_DEVICE_CAPABILITIES);
+
+ priv->real = FALSE;
+ g_object_notify (G_OBJECT (self), NM_DEVICE_REAL);
+
+ return success;
+}
+
/**
* nm_device_notify_component_added():
* @self: the #NMDevice
@@ -5603,16 +5664,20 @@ delete_on_deactivate_link_delete (gpointer user_data)
DeleteOnDeactivateData *data = user_data;
NMDevice *self = data->device;
+ _LOGD (LOGD_DEVICE, "delete_on_deactivate: cleanup and delete virtual link #%d (id=%u)",
+ data->ifindex, data->idle_add_id);
+
if (data->device) {
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (data->device);
g_object_remove_weak_pointer (G_OBJECT (data->device), (void **) &data->device);
priv->delete_on_deactivate_data = NULL;
+
+ nm_device_unrealize (data->device, FALSE, NULL);
+ } else {
+ nm_platform_link_delete (data->ifindex);
}
- _LOGD (LOGD_DEVICE, "delete_on_deactivate: cleanup and delete virtual link #%d (id=%u)",
- data->ifindex, data->idle_add_id);
- nm_platform_link_delete (data->ifindex);
g_free (data);
return FALSE;
}
@@ -5731,14 +5796,20 @@ delete_cb (NMDevice *self,
GError *error,
gpointer user_data)
{
+ GError *local = NULL;
+
if (error) {
dbus_g_method_return_error (context, error);
return;
}
/* Authorized */
- nm_platform_link_delete (nm_device_get_ifindex (self));
- dbus_g_method_return (context);
+ if (nm_device_unrealize (self, FALSE, &local))
+ dbus_g_method_return (context);
+ else {
+ dbus_g_method_return_error (context, local);
+ g_clear_error (&local);
+ }
}
static void
@@ -8488,6 +8559,7 @@ nm_device_class_init (NMDeviceClass *klass)
klass->check_connection_compatible = check_connection_compatible;
klass->check_connection_available = check_connection_available;
klass->setup = setup;
+ klass->unrealize = unrealize;
klass->is_up = is_up;
klass->bring_up = bring_up;
klass->take_down = take_down;
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index 9c5e264dd4..25429deff8 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -154,6 +154,20 @@ typedef struct {
*/
void (*setup) (NMDevice *self, NMPlatformLink *plink);
+ /**
+ * unrealize():
+ * @self: the #NMDevice
+ * @link_deleted: if %TRUE, the backing kernel resources are already deleted
+ * @error: location to store error, or %NULL
+ *
+ * Releases any backing resources (kernel devices, etc) created for this
+ * device and clears properties that depend on them. Does not destroy
+ * the device object itself.
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ */
+ gboolean (*unrealize) (NMDevice *self, gboolean link_deleted, GError **error);
+
/* Hardware state (IFF_UP) */
gboolean (*is_up) (NMDevice *self);
gboolean (*bring_up) (NMDevice *self, gboolean *no_firmware);
@@ -390,6 +404,9 @@ gboolean nm_device_create_and_realize (NMDevice *self,
NMConnection *connection,
NMDevice *parent,
GError **error);
+gboolean nm_device_unrealize (NMDevice *device,
+ gboolean link_deleted,
+ GError **error);
gboolean nm_device_get_autoconnect (NMDevice *device);
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 3b8e30b94c..4889517742 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -1897,19 +1897,28 @@ platform_link_cb (NMPlatform *platform,
NMPlatformReason reason,
gpointer user_data)
{
+ NMManager *self = NM_MANAGER (user_data);
+ NMDevice *device;
+ GError *error = NULL;
+
switch (change_type) {
case NM_PLATFORM_SIGNAL_ADDED:
- platform_link_added (NM_MANAGER (user_data), ifindex, plink, reason);
+ platform_link_added (self, ifindex, plink, reason);
break;
- case NM_PLATFORM_SIGNAL_REMOVED: {
- NMManager *self = NM_MANAGER (user_data);
- NMDevice *device;
-
+ case NM_PLATFORM_SIGNAL_REMOVED:
device = nm_manager_get_device_by_ifindex (self, ifindex);
- if (device)
- remove_device (self, device, FALSE, TRUE);
+ if (!device)
+ break;
+ if (nm_device_is_software (device)) {
+ if (!nm_device_unrealize (device, TRUE, &error)) {
+ nm_log_warn (LOGD_DEVICE, "(%s): failed to unrealize: %s",
+ nm_device_get_iface (device),
+ error->message);
+ g_clear_error (&error);
+ }
+ }
+ remove_device (self, device, FALSE, TRUE);
break;
- }
default:
break;
}