diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index d12d97f077..12ef18dc15 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -2309,6 +2309,7 @@ virNodeDevCapsDefFree(virNodeDevCapsDef *caps) for (i = 0; i < data->mdev.nattributes; i++) virMediatedDeviceAttrFree(data->mdev.attributes[i]); g_free(data->mdev.attributes); + g_free(data->mdev.parent_addr); break; case VIR_NODE_DEV_CAP_CSS_DEV: for (i = 0; i < data->ccw_dev.nmdev_types; i++) diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index a60562e4fe..556878b9a8 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -153,6 +153,7 @@ struct _virNodeDevCapMdev { char *uuid; virMediatedDeviceAttr **attributes; size_t nattributes; + char *parent_addr; }; typedef struct _virNodeDevCapPCIDev virNodeDevCapPCIDev; diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c index 6820ec413b..daeaa084bd 100644 --- a/src/node_device/node_device_driver.c +++ b/src/node_device/node_device_driver.c @@ -1088,6 +1088,7 @@ nodeDeviceParseMdevctlChildDevice(const char *parent, mdev = &child->caps->data.mdev; mdev->uuid = g_strdup(uuid); + mdev->parent_addr = g_strdup(parent); mdev->type = g_strdup(virJSONValueObjectGetString(props, "mdev_type")); diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index f99578414d..e7db74b325 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1024,6 +1024,7 @@ udevProcessMediatedDevice(struct udev_device *dev, char *linkpath = NULL; char *canonicalpath = NULL; virNodeDevCapMdev *data = &def->caps->data.mdev; + struct udev_device *parent_device = NULL; /* Because of a kernel uevent race, we might get the 'add' event prior to * the sysfs tree being ready, so any attempt to access any sysfs attribute @@ -1051,6 +1052,21 @@ udevProcessMediatedDevice(struct udev_device *dev, if ((iommugrp = virMediatedDeviceGetIOMMUGroupNum(data->uuid)) < 0) goto cleanup; + /* lookup the address of parent device */ + parent_device = udev_device_get_parent(dev); + if (parent_device) { + const char *parent_sysfs_path = udev_device_get_syspath(parent_device); + if (parent_sysfs_path) + data->parent_addr = g_path_get_basename(parent_sysfs_path); + } + + if (!data->parent_addr) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not get parent of '%s'"), + udev_device_get_syspath(dev)); + return -1; + } + udevGenerateDeviceName(dev, def, NULL); data->iommuGroupNumber = iommugrp;