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.
This commit is contained in:
Lubomir Rintel
2016-04-20 09:16:41 +02:00
parent 940a423de4
commit a93807c288
3 changed files with 48 additions and 8 deletions

View File

@@ -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;

View File

@@ -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);

View File

@@ -179,6 +179,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