static char *
-nodeDeviceFindAddressByName(const char *name)
+nodeDeviceObjFormatAddress(virNodeDeviceObj *obj)
{
- virNodeDeviceDef *def = NULL;
virNodeDevCapsDef *caps = NULL;
char *addr = NULL;
- virNodeDeviceObj *dev = virNodeDeviceObjListFindByName(driver->devs, name);
-
- if (!dev)
- return NULL;
-
- def = virNodeDeviceObjGetDef(dev);
+ virNodeDeviceDef *def = virNodeDeviceObjGetDef(obj);
for (caps = def->caps; caps != NULL; caps = caps->next) {
switch (caps->data.type) {
case VIR_NODE_DEV_CAP_PCI_DEV: {
break;
}
- virNodeDeviceObjEndAPI(&dev);
-
return addr;
}
g_autoptr(virCommand) cmd = NULL;
const char *subcommand = virMdevctlCommandTypeToString(cmd_type);
g_autofree char *inbuf = NULL;
+ virNodeDeviceObj *parent_obj = NULL;
switch (cmd_type) {
case MDEVCTL_CMD_CREATE:
switch (cmd_type) {
case MDEVCTL_CMD_CREATE:
case MDEVCTL_CMD_DEFINE:
- parent_addr = nodeDeviceFindAddressByName(def->parent);
+ if ((parent_obj = nodeDeviceObjFindByName(def->parent))) {
+ parent_addr = nodeDeviceObjFormatAddress(parent_obj);
+ virNodeDeviceObjEndAPI(&parent_obj);
+ }
if (!parent_addr) {
virReportError(VIR_ERR_INTERNAL_ERROR,
}
+static bool
+matchDeviceAddress(virNodeDeviceObj *obj,
+ const void *opaque)
+{
+ g_autofree char *addr = NULL;
+ bool want = false;
+
+ virObjectLock(obj);
+ addr = nodeDeviceObjFormatAddress(obj);
+ want = STREQ_NULLABLE(addr, opaque);
+ virObjectUnlock(obj);
+ return want;
+}
+
+
static virNodeDeviceDef*
nodeDeviceParseMdevctlChildDevice(const char *parent,
virJSONValue *json)
virJSONValue *props;
virJSONValue *attrs;
g_autoptr(virNodeDeviceDef) child = g_new0(virNodeDeviceDef, 1);
- g_autofree char *parent_sysfs_path = NULL;
+ virNodeDeviceObj *parent_obj;
/* the child object should have a single key equal to its uuid.
* The value is an object describing the properties of the mdev */
/* Look up id of parent device. mdevctl supports defining mdevs for parent
* devices that are not present on the system (to support starting mdevs on
* hotplug, etc) so the parent may not actually exist. */
- parent_sysfs_path = g_strdup_printf("/sys/class/mdev_bus/%s", parent);
- if (virFileExists(parent_sysfs_path)) {
- g_autofree char *canon_syspath = virFileCanonicalizePath(parent_sysfs_path);
- virNodeDeviceObj *parentobj = NULL;
-
- if ((parentobj = virNodeDeviceObjListFindBySysfsPath(driver->devs,
- canon_syspath))) {
- virNodeDeviceDef *parentdef = virNodeDeviceObjGetDef(parentobj);
- child->parent = g_strdup(parentdef->name);
- virNodeDeviceObjEndAPI(&parentobj);
-
- child->parent_sysfs_path = g_steal_pointer(&canon_syspath);
- }
- }
+ if ((parent_obj = virNodeDeviceObjListFind(driver->devs, matchDeviceAddress,
+ (void *)parent))) {
+ virNodeDeviceDef *parentdef = virNodeDeviceObjGetDef(parent_obj);
+ child->parent = g_strdup(parentdef->name);
+ virNodeDeviceObjEndAPI(&parent_obj);
+ };
if (!child->parent)
child->parent = g_strdup("computer");
child->caps = g_new0(virNodeDevCapsDef, 1);
<device>
<name>mdev_200f228a_c80a_4d50_bfb7_f5a0e4e34045</name>
- <parent>computer</parent>
+ <parent>pci_0000_00_02_0</parent>
<capability type='mdev'>
<type id='i915-GVTg_V5_4'/>
<uuid>200f228a-c80a-4d50-bfb7-f5a0e4e34045</uuid>
</device>
<device>
<name>mdev_de807ffc_1923_4d5f_b6c9_b20ecebc6d4b</name>
- <parent>computer</parent>
+ <parent>pci_0000_00_02_0</parent>
<capability type='mdev'>
<type id='i915-GVTg_V5_4'/>
<uuid>de807ffc-1923-4d5f-b6c9-b20ecebc6d4b</uuid>
</device>
<device>
<name>mdev_435722ea_5f43_468a_874f_da34f1217f13</name>
- <parent>computer</parent>
+ <parent>pci_0000_00_02_0</parent>
<capability type='mdev'>
<type id='i915-GVTg_V5_8'/>
<uuid>435722ea-5f43-468a-874f-da34f1217f13</uuid>
</device>
<device>
<name>mdev_783e6dbb_ea0e_411f_94e2_717eaad438bf</name>
- <parent>computer</parent>
+ <parent>ap_matrix</parent>
<capability type='mdev'>
<type id='vfio_ap-passthrough'/>
<uuid>783e6dbb-ea0e-411f-94e2-717eaad438bf</uuid>
* parent of the mdev, and it needs a PCI address
*/
static virNodeDeviceDef *
-fakeParentDevice(void)
+fakePCIDevice(void)
{
virNodeDeviceDef *def = NULL;
virNodeDevCapPCIDev *pci_dev;
return def;
}
+
+/* Add a fake matrix device that can be used as a parent device for mediated
+ * devices. For our purposes, it only needs to have a name that matches the
+ * parent of the mdev, and it needs the proper name
+ */
+static virNodeDeviceDef *
+fakeMatrixDevice(void)
+{
+ virNodeDeviceDef *def = NULL;
+ virNodeDevCapAPMatrix *cap;
+
+ def = g_new0(virNodeDeviceDef, 1);
+ def->caps = g_new0(virNodeDevCapsDef, 1);
+
+ def->name = g_strdup("ap_matrix");
+ def->parent = g_strdup("computer");
+
+ def->caps->data.type = VIR_NODE_DEV_CAP_AP_MATRIX;
+ cap = &def->caps->data.ap_matrix;
+ cap->addr = g_strdup("matrix");
+
+ return def;
+}
static int
addDevice(virNodeDeviceDef *def)
{
nodedevTestDriverAddTestDevices(void)
{
if (addDevice(fakeRootDevice()) < 0 ||
- addDevice(fakeParentDevice()) < 0)
+ addDevice(fakePCIDevice()) < 0 ||
+ addDevice(fakeMatrixDevice()) < 0)
return -1;
return 0;