summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2014-09-24 15:13:19 -0500
committerDan Williams <dcbw@redhat.com>2015-05-15 09:46:38 -0500
commit2ac0e142300dbc81e04fc49199ad22a30ad640a9 (patch)
treeceb334dc31000776666203bdd3be52de5f00736c
parent453c4865bbdc0ff588d445c403fa76709981cf58 (diff)
downloadNetworkManager-2ac0e142300dbc81e04fc49199ad22a30ad640a9.tar.gz
core: add class function for device unrealization
-rw-r--r--src/devices/nm-device-vlan.c15
-rw-r--r--src/devices/nm-device.c108
-rw-r--r--src/devices/nm-device.h16
-rw-r--r--src/nm-manager.c25
4 files changed, 150 insertions, 14 deletions
diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c
index 2e372df610..8570db5b43 100644
--- a/src/devices/nm-device-vlan.c
+++ b/src/devices/nm-device-vlan.c
@@ -220,6 +220,20 @@ create_and_realize (NMDevice *device,
return TRUE;
}
+static gboolean
+unrealize (NMDevice *device, gboolean remove_resources, GError **error)
+{
+ gboolean success;
+
+ success = NM_DEVICE_CLASS (nm_device_vlan_parent_class)->unrealize (device, remove_resources, error);
+
+ NM_DEVICE_VLAN_GET_PRIVATE (device)->vlan_id = 0;
+ g_object_notify (G_OBJECT (device), NM_DEVICE_VLAN_ID);
+ nm_device_vlan_set_parent (NM_DEVICE_VLAN (device), NULL);
+
+ return success;
+}
+
/******************************************************************/
static NMDeviceCapabilities
@@ -613,6 +627,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 e5b5fc9ad9..196806559e 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -1681,6 +1681,92 @@ setup (NMDevice *self, NMPlatformLink *plink)
g_object_thaw_notify (G_OBJECT (self));
}
+static gboolean
+unrealize (NMDevice *self, gboolean remove_resources, GError **error)
+{
+ int ifindex = nm_device_get_ifindex (self);
+
+ if (ifindex > 0 && nm_device_is_software (self) && remove_resources)
+ nm_platform_link_delete (NM_PLATFORM_GET, ifindex);
+
+ return TRUE;
+}
+
+/**
+ * nm_device_unrealize():
+ * @self: the #NMDevice
+ * @remove_resources: if %TRUE, remove backing resources
+ * @error: location to store error, or %NULL
+ *
+ * Clears any properties that depend on backing resources (kernel devices,
+ * etc) and removes those resources if @remove_resources is %TRUE.
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ */
+gboolean
+nm_device_unrealize (NMDevice *self, gboolean remove_resources, 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);
+
+ g_object_freeze_notify (G_OBJECT (self));
+
+ if (NM_DEVICE_GET_CLASS (self)->unrealize)
+ success = NM_DEVICE_GET_CLASS (self)->unrealize (self, remove_resources, error);
+
+ if (priv->ifindex > 0) {
+ priv->ifindex = 0;
+ g_object_notify (G_OBJECT (self), NM_DEVICE_IFINDEX);
+ }
+ priv->ip_ifindex = 0;
+ if (priv->ip_iface) {
+ g_clear_pointer (&priv->ip_iface, g_free);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_IP_IFACE);
+ }
+ if (priv->driver_version) {
+ g_clear_pointer (&priv->driver_version, g_free);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_DRIVER_VERSION);
+ }
+ if (priv->firmware_version) {
+ g_clear_pointer (&priv->firmware_version, g_free);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_FIRMWARE_VERSION);
+ }
+ if (priv->udi) {
+ g_clear_pointer (&priv->udi, g_free);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_UDI);
+ }
+ if (priv->hw_addr) {
+ g_clear_pointer (&priv->hw_addr, g_free);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_HW_ADDRESS);
+ }
+ if (priv->physical_port_id) {
+ 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);
+
+ g_object_thaw_notify (G_OBJECT (self));
+
+ nm_device_state_changed (self,
+ NM_DEVICE_STATE_UNMANAGED,
+ remove_resources ?
+ NM_DEVICE_STATE_REASON_USER_REQUESTED : NM_DEVICE_STATE_REASON_NOW_UNMANAGED);
+
+ return success;
+}
+
/**
* nm_device_notify_component_added():
* @self: the #NMDevice
@@ -5931,16 +6017,19 @@ 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;
- }
- _LOGD (LOGD_DEVICE, "delete_on_deactivate: cleanup and delete virtual link #%d (id=%u)",
- data->ifindex, data->idle_add_id);
- nm_platform_link_delete (NM_PLATFORM_GET, data->ifindex);
+ nm_device_unrealize (data->device, TRUE, NULL);
+ } else
+ nm_platform_link_delete (NM_PLATFORM_GET, data->ifindex);
+
g_free (data);
return FALSE;
}
@@ -6068,14 +6157,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_PLATFORM_GET, nm_device_get_ifindex (self));
- dbus_g_method_return (context);
+ if (nm_device_unrealize (self, TRUE, &local))
+ dbus_g_method_return (context);
+ else {
+ dbus_g_method_return_error (context, local);
+ g_clear_error (&local);
+ }
}
static void
@@ -9114,6 +9209,7 @@ nm_device_class_init (NMDeviceClass *klass)
klass->check_connection_available = check_connection_available;
klass->can_unmanaged_external_down = can_unmanaged_external_down;
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 955aec2941..5f87e0da07 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -183,6 +183,19 @@ typedef struct {
*/
void (*setup) (NMDevice *self, NMPlatformLink *plink);
+ /**
+ * unrealize():
+ * @self: the #NMDevice
+ * @remove_resources: if %TRUE remove backing resources
+ * @error: location to store error, or %NULL
+ *
+ * Clears any properties that depend on backing resources (kernel devices,
+ * etc) and removes those resources if @remove_resources is %TRUE.
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ */
+ gboolean (*unrealize) (NMDevice *self, gboolean remove_resources, GError **error);
+
/* Hardware state (IFF_UP) */
gboolean (*can_unmanaged_external_down) (NMDevice *self);
gboolean (*is_up) (NMDevice *self);
@@ -452,6 +465,9 @@ gboolean nm_device_create_and_realize (NMDevice *self,
NMConnection *connection,
NMDevice *parent,
GError **error);
+gboolean nm_device_unrealize (NMDevice *device,
+ gboolean remove_resources,
+ GError **error);
gboolean nm_device_get_autoconnect (NMDevice *device);
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 909eea4651..158164d583 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -1928,19 +1928,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, FALSE, &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;
}