summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2016-04-20 09:16:41 +0200
committerLubomir Rintel <lkundrak@v3.sk>2016-04-20 10:49:01 +0200
commita93807c288743f499362f7edfe0674020762811c (patch)
treeded5fb78dbb84224858b24a2a4520b5074d94e10
parent940a423de400fc01e0bedfb5bab85b1abd43b9e4 (diff)
downloadNetworkManager-a93807c288743f499362f7edfe0674020762811c.tar.gz
infiniband: remove the partitions on unrealizing
The infiniband drivers don't implement the rtnetlink link deletions. Therefore we unrealize the NMDevice instance but the backing resources stay around, preventing us from ever realizing the device again.
-rw-r--r--src/devices/nm-device-infiniband.c42
-rw-r--r--src/devices/nm-device.c6
-rw-r--r--src/devices/nm-device.h8
3 files changed, 48 insertions, 8 deletions
diff --git a/src/devices/nm-device-infiniband.c b/src/devices/nm-device-infiniband.c
index 0465ae36b2..ae9543e4e9 100644
--- a/src/devices/nm-device-infiniband.c
+++ b/src/devices/nm-device-infiniband.c
@@ -42,6 +42,7 @@ G_DEFINE_TYPE (NMDeviceInfiniband, nm_device_infiniband, NM_TYPE_DEVICE)
typedef struct {
gboolean is_partition;
+ int parent_ifindex, p_key;
} NMDeviceInfinibandPrivate;
enum {
@@ -235,16 +236,16 @@ create_and_realize (NMDevice *device,
const NMPlatformLink **out_plink,
GError **error)
{
+ NMDeviceInfinibandPrivate *priv = NM_DEVICE_INFINIBAND_GET_PRIVATE (device);
NMSettingInfiniband *s_infiniband;
- int parent_ifindex, p_key;
NMPlatformError plerr;
s_infiniband = nm_connection_get_setting_infiniband (connection);
g_assert (s_infiniband);
/* Can only create partitions at this time */
- p_key = nm_setting_infiniband_get_p_key (s_infiniband);
- if (p_key < 0) {
+ priv->p_key = nm_setting_infiniband_get_p_key (s_infiniband);
+ if (priv->p_key < 0) {
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
"only InfiniBand partitions can be created");
return FALSE;
@@ -263,15 +264,15 @@ create_and_realize (NMDevice *device,
return FALSE;
}
- parent_ifindex = nm_device_get_ifindex (parent);
- if (parent_ifindex <= 0) {
+ priv->parent_ifindex = nm_device_get_ifindex (parent);
+ if (priv->parent_ifindex <= 0) {
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
"failed to get InfiniBand parent %s ifindex",
nm_device_get_iface (parent));
return FALSE;
}
- plerr = nm_platform_link_infiniband_add (NM_PLATFORM_GET, parent_ifindex, p_key, out_plink);
+ plerr = nm_platform_link_infiniband_add (NM_PLATFORM_GET, priv->parent_ifindex, priv->p_key, out_plink);
if (plerr != NM_PLATFORM_ERROR_SUCCESS) {
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
"Failed to create InfiniBand P_Key interface '%s' for '%s': %s",
@@ -281,7 +282,33 @@ create_and_realize (NMDevice *device,
return FALSE;
}
- NM_DEVICE_INFINIBAND_GET_PRIVATE (device)->is_partition = TRUE;
+ priv->is_partition = TRUE;
+ return TRUE;
+}
+
+static gboolean
+unrealize (NMDevice *device, GError **error)
+{
+ NMDeviceInfinibandPrivate *priv = NM_DEVICE_INFINIBAND_GET_PRIVATE (device);
+ NMPlatformError plerr;
+
+ g_return_val_if_fail (NM_IS_DEVICE_INFINIBAND (device), FALSE);
+
+ if (priv->p_key < 0) {
+ g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
+ "Only InfiniBand partitions can be removed");
+ return FALSE;
+ }
+
+ plerr = nm_platform_link_infiniband_delete (NM_PLATFORM_GET, priv->parent_ifindex, priv->p_key);
+ if (plerr != NM_PLATFORM_ERROR_SUCCESS) {
+ g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
+ "Failed to remove InfiniBand P_Key interface '%s': %s",
+ nm_device_get_iface (device),
+ nm_platform_error_to_string (plerr));
+ return FALSE;
+ }
+
return TRUE;
}
@@ -335,6 +362,7 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass)
object_class->set_property = set_property;
parent_class->create_and_realize = create_and_realize;
+ parent_class->unrealize = unrealize;
parent_class->get_generic_capabilities = get_generic_capabilities;
parent_class->check_connection_compatible = check_connection_compatible;
parent_class->complete_connection = complete_connection;
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 1c6612df8f..499a624c84 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -2138,8 +2138,12 @@ nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error)
_LOGD (LOGD_DEVICE, "unrealize (ifindex %d)", ifindex > 0 ? ifindex : 0);
if (remove_resources) {
- if (ifindex > 0)
+ if (NM_DEVICE_GET_CLASS (self)->unrealize) {
+ if (!NM_DEVICE_GET_CLASS (self)->unrealize (self, error))
+ return FALSE;
+ } else if (ifindex > 0) {
nm_platform_link_delete (NM_PLATFORM_GET, ifindex);
+ }
}
NM_DEVICE_GET_CLASS (self)->unrealize_notify (self);
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index 368e77f746..2221ede12d 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -180,6 +180,14 @@ typedef struct {
void (*realize_start_notify) (NMDevice *self, const NMPlatformLink *plink);
/**
+ * unrealize():
+ * @self: the #NMDevice
+ *
+ * Remove the device backing resources.
+ */
+ gboolean (*unrealize) (NMDevice *self, GError **error);
+
+ /**
* unrealize_notify():
* @self: the #NMDevice
*