From 08d29eb3b1d2361b7c70eaf0e269165387cf2756 Mon Sep 17 00:00:00 2001 From: Jonathon Jongsma Date: Fri, 16 Jul 2021 16:33:43 -0500 Subject: [PATCH] nodedev: add PostParse callback for nodedev parsing This can be used similarly to other postparse callbacks in libvirt -- filling in additional information that can be determined by using the information provided in the XML. In this case, we determine the address of the parent device and cache it in the mdev caps so that we can use it for generating a unique name and interacting with mdevctl. Signed-off-by: Jonathon Jongsma Reviewed-by: Michal Privoznik --- src/conf/node_device_conf.c | 7 +++++ src/node_device/node_device_driver.c | 45 +++++++++++++++++++++------- src/node_device/node_device_driver.h | 3 ++ src/node_device/node_device_udev.c | 1 + tests/nodedevmdevctltest.c | 1 + 5 files changed, 46 insertions(+), 11 deletions(-) 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 };