[libvirt PATCH 08/16] nodedev: handle mdevs that disappear from mdevctl

Jonathon Jongsma jjongsma at redhat.com
Thu Jul 16 22:21:38 UTC 2020


mdevctl does not currently provide any events when the list of defined
devices changes, so we will need to poll mdevctl for the list of defined
devices periodically. When a mediated device no longer exists from one
iteration to the next, we need to treat it as an "undefine" event.

When we get such an event, we remove the device from the list if it's
not active. Otherwise, we simply mark it as non-persistent.

Signed-off-by: Jonathon Jongsma <jjongsma at redhat.com>
---
 src/node_device/node_device_driver.c | 61 ++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c
index 9d07ff0e38..032e7f42fa 100644
--- a/src/node_device/node_device_driver.c
+++ b/src/node_device/node_device_driver.c
@@ -1087,6 +1087,37 @@ nodeDeviceGenerateName(virNodeDeviceDefPtr def,
     }
 }
 
+static bool
+mdevMatchPersistentDevices(virConnectPtr conn G_GNUC_UNUSED,
+                           virNodeDeviceDefPtr def)
+{
+            return (def->caps->data.type == VIR_NODE_DEV_CAP_MDEV &&
+                    def->caps->data.mdev.persistent);
+
+
+}
+
+/* returns a null-terminated array of strings. Free with virStringListFree() */
+static char **
+nodeDeviceGetMdevPersistentDevices(virNodeDeviceObjListPtr devlist)
+{
+    char **ret = NULL;
+    int ndevs = virNodeDeviceObjListNumOfDevices(devlist,
+                                                 NULL,
+                                                 "mdev",
+                                                 mdevMatchPersistentDevices);
+    if (VIR_ALLOC_N(ret, ndevs+1) < 0)
+        return NULL;
+
+    if (virNodeDeviceObjListGetNames(devlist, NULL,
+                                     mdevMatchPersistentDevices,
+                                     "mdev",
+                                     ret,
+                                     ndevs) < 0)
+        VIR_FREE(ret);
+
+    return ret;
+}
 
 static int
 virMdevctlListDefined(virNodeDeviceDefPtr **devs)
@@ -1110,6 +1141,7 @@ mdevctlEnumerateDevices(void)
 {
     g_autofree virNodeDeviceDefPtr *devs = NULL;
     int ndevs;
+    char **oldmdevs = nodeDeviceGetMdevPersistentDevices(driver->devs);
 
     if ((ndevs = virMdevctlListDefined(&devs)) < 0) {
         virReportSystemError(errno, "%s",
@@ -1157,7 +1189,36 @@ mdevctlEnumerateDevices(void)
             event = virNodeDeviceEventUpdateNew(dev->name);
         virNodeDeviceObjEndAPI(&obj);
         virObjectEventStateQueue(driver->nodeDeviceEventState, event);
+
+        virStringListRemove(&oldmdevs, dev->name);
+    }
+
+    /* Any mdevs that were previously defined but were not returned by mdevctl
+     * this time will need to be checked to see if they should be removed from
+     * the device list */
+    for (int i = 0; i < virStringListLength((const char **)oldmdevs); i++) {
+        const char *name = oldmdevs[i];
+        virNodeDeviceObjPtr obj = NULL;
+        if ((obj = virNodeDeviceObjListFindByName(driver->devs, name))) {
+            if (!virNodeDeviceObjIsActive(obj)) {
+                /* An existing device is not active and is no longer defined by
+                 * mdevctl, so remove it */
+                virObjectEventPtr event = virNodeDeviceEventLifecycleNew(name,
+                                                                         VIR_NODE_DEVICE_EVENT_DELETED,
+                                                                         0);
+
+                virNodeDeviceObjListRemove(driver->devs, obj);
+                virObjectEventStateQueue(driver->nodeDeviceEventState, event);
+            } else {
+                /* An existing device is active, but no longer defined. Keep
+                 * the device in the list, but mark it as non-persistent */
+                virNodeDeviceDefPtr def = virNodeDeviceObjGetDef(obj);
+                def->caps->data.mdev.persistent = false;
+            }
+            virNodeDeviceObjEndAPI(&obj);
+        }
     }
+    virStringListFree(oldmdevs);
 
     return 0;
 }
-- 
2.21.3




More information about the libvir-list mailing list