diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index f2d17b31f4..eb89818744 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -2185,6 +2185,13 @@ virNodeDeviceDefParse(const char *str, if (parserCallbacks) { int ret = 0; + /* fill in backend-specific aspects */ + if (parserCallbacks->postParse) { + ret = parserCallbacks->postParse(def, opaque); + if (ret < 0) + return NULL; + } + /* validate definition */ if (parserCallbacks->validate) { ret = parserCallbacks->validate(def, opaque); diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c index 328819e778..5af4a01d73 100644 --- a/src/node_device/node_device_driver.c +++ b/src/node_device/node_device_driver.c @@ -718,11 +718,9 @@ nodeDeviceGetMdevctlCommand(virNodeDeviceDef *def, char **outbuf, char **errbuf) { - g_autofree char *parent_addr = NULL; 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: @@ -747,12 +745,7 @@ nodeDeviceGetMdevctlCommand(virNodeDeviceDef *def, switch (cmd_type) { case MDEVCTL_CMD_CREATE: case MDEVCTL_CMD_DEFINE: - if ((parent_obj = nodeDeviceObjFindByName(def->parent))) { - parent_addr = nodeDeviceObjFormatAddress(parent_obj); - virNodeDeviceObjEndAPI(&parent_obj); - } - - if (!parent_addr) { + if (!def->caps->data.mdev.parent_addr) { virReportError(VIR_ERR_INTERNAL_ERROR, _("unable to find parent device '%s'"), def->parent); return NULL; @@ -764,7 +757,7 @@ nodeDeviceGetMdevctlCommand(virNodeDeviceDef *def, return NULL; } - virCommandAddArgPair(cmd, "--parent", parent_addr); + virCommandAddArgPair(cmd, "--parent", def->caps->data.mdev.parent_addr); virCommandAddArgPair(cmd, "--jsonfile", "/dev/stdin"); virCommandSetInputBuffer(cmd, inbuf); @@ -1764,9 +1757,30 @@ nodeDeviceDefCopyFromMdevctl(virNodeDeviceDef *dst, } +int nodeDeviceDefPostParse(virNodeDeviceDef *def, + G_GNUC_UNUSED void *opaque) +{ + virNodeDevCapsDef *caps = NULL; + for (caps = def->caps; caps != NULL; caps = caps->next) { + if (caps->data.type == VIR_NODE_DEV_CAP_MDEV) { + virNodeDeviceObj *obj = NULL; + + if (def->parent) + obj = virNodeDeviceObjListFindByName(driver->devs, def->parent); + + if (obj) { + caps->data.mdev.parent_addr = nodeDeviceObjFormatAddress(obj); + virNodeDeviceObjEndAPI(&obj); + } + } + } + return 0; +} + + /* validate that parent exists */ static int nodeDeviceDefValidateMdev(virNodeDeviceDef *def, - G_GNUC_UNUSED virNodeDevCapMdev *mdev, + virNodeDevCapMdev *mdev, G_GNUC_UNUSED void *opaque) { virNodeDeviceObj *obj = NULL; @@ -1782,8 +1796,17 @@ static int nodeDeviceDefValidateMdev(virNodeDeviceDef *def, def->parent); return -1; } - virNodeDeviceObjEndAPI(&obj); + + /* the post-parse callback should have found the address of the parent + * device and stored it in the mdev caps */ + if (!mdev->parent_addr) { + virReportError(VIR_ERR_PARSE_FAILED, + _("Unable to find address for parent device '%s'"), + def->parent); + return -1; + } + return 0; } diff --git a/src/node_device/node_device_driver.h b/src/node_device/node_device_driver.h index d9b9b7a961..fdc92b8aef 100644 --- a/src/node_device/node_device_driver.h +++ b/src/node_device/node_device_driver.h @@ -172,5 +172,8 @@ int nodeDeviceCreate(virNodeDevice *dev, unsigned int flags); +int nodeDeviceDefPostParse(virNodeDeviceDef *def, + void *opaque); + int nodeDeviceDefValidate(virNodeDeviceDef *def, void *opaque); diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index ccf94d8e7d..81037d8139 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -2243,6 +2243,7 @@ nodeStateInitialize(bool privileged, driver->privateData = priv; driver->nodeDeviceEventState = virObjectEventStateNew(); + driver->parserCallbacks.postParse = nodeDeviceDefPostParse; driver->parserCallbacks.validate = nodeDeviceDefValidate; if (udevPCITranslateInit(privileged) < 0) diff --git a/tests/nodedevmdevctltest.c b/tests/nodedevmdevctltest.c index f5f882e8b5..3d1a7e4b6c 100644 --- a/tests/nodedevmdevctltest.c +++ b/tests/nodedevmdevctltest.c @@ -13,6 +13,7 @@ #define VIRT_TYPE "QEMU" static virNodeDeviceDefParserCallbacks parser_callbacks = { + .postParse = nodeDeviceDefPostParse, .validate = nodeDeviceDefValidate };