]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
nodedev: add PostParse callback for nodedev parsing
authorJonathon Jongsma <jjongsma@redhat.com>
Fri, 16 Jul 2021 21:33:43 +0000 (16:33 -0500)
committerJonathon Jongsma <jjongsma@redhat.com>
Fri, 6 Aug 2021 20:02:36 +0000 (15:02 -0500)
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 <jjongsma@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/conf/node_device_conf.c
src/node_device/node_device_driver.c
src/node_device/node_device_driver.h
src/node_device/node_device_udev.c
tests/nodedevmdevctltest.c

index f2d17b31f425a9858586198275291c3720b1b69c..eb8981874449fb3c7ff78b08d6447a088f042eb3 100644 (file)
@@ -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);
index 328819e778304b37aee5eef6d158c16a26b72917..5af4a01d735493c2d6fcf454ccca4fc4c4352a0f 100644 (file)
@@ -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;
 }
 
index d9b9b7a961deacfb4d13956cd3b4b6c31ebf695b..fdc92b8aef1c63f47a10d061f143b13b4b8ba596 100644 (file)
@@ -172,5 +172,8 @@ int
 nodeDeviceCreate(virNodeDevice *dev,
                  unsigned int flags);
 
+int nodeDeviceDefPostParse(virNodeDeviceDef *def,
+                           void *opaque);
+
 int nodeDeviceDefValidate(virNodeDeviceDef *def,
                           void *opaque);
index ccf94d8e7da3ea054375533b5b572a71b4f81200..81037d81396fbe295f57ed941497930ffccb5bf9 100644 (file)
@@ -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)
index f5f882e8b5a62fd1ba4619e3ab65903df92f4393..3d1a7e4b6c2922e931491b11559eeda95cbbe7b1 100644 (file)
@@ -13,6 +13,7 @@
 #define VIRT_TYPE "QEMU"
 
 static virNodeDeviceDefParserCallbacks parser_callbacks = {
+    .postParse = nodeDeviceDefPostParse,
     .validate = nodeDeviceDefValidate
 };