[libvirt] [PATCH 5/6] libvirt: Ensure modern APIs are implemented

Eric Blake eblake at redhat.com
Tue Jul 9 03:37:02 UTC 2019


As shown in recent patches, several drivers provided only an older
counterpart of an API, making it harder to uniformly use the newer
preferred API form. We can prevent future instances of this by failing
the driver at initialization time if a modern API is forgotten when an
older API is present.  For now, the list includes any interface with a
Flags counterpart, except virDomainBlockStatsFlags which is a bit more
complex than virDomainBlockStats.

Signed-off-by: Eric Blake <eblake at redhat.com>
---
 src/libvirt.c | 42 ++++++++++++++++++++++++++++++++++++++----
 1 file changed, 38 insertions(+), 4 deletions(-)

diff --git a/src/libvirt.c b/src/libvirt.c
index 7e665b6cba..a12a72a31b 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -567,19 +567,53 @@ int
 virRegisterConnectDriver(virConnectDriverPtr driver,
                          bool setSharedDrivers)
 {
-    VIR_DEBUG("driver=%p name=%s", driver,
-              driver ? NULLSTR(driver->hypervisorDriver->name) : "(null)");
+    const char *driver_name;
+
+    driver_name = driver ? NULLSTR(driver->hypervisorDriver->name) : "(null)";
+    VIR_DEBUG("driver=%p name=%s", driver, driver_name);

     virCheckNonNullArgReturn(driver, -1);
     if (virConnectDriverTabCount >= MAX_DRIVERS) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Too many drivers, cannot register %s"),
-                       driver->hypervisorDriver->name);
+                       driver_name);
         return -1;
     }

+    /* Check for drivers failing to provide a modern counterpart to an
+     * older API */
+#define REQUIRE_API(old, new) \
+    do { \
+        if (driver->hypervisorDriver->old && \
+            !driver->hypervisorDriver->new) { \
+            fprintf(stderr, " ***FIXME!: driver %s is broken on %s\n", \
+                    driver ? NULLSTR(driver->hypervisorDriver->name) : "(null)", #new); \
+            virReportError(VIR_ERR_INTERNAL_ERROR, \
+                           _("driver %s is missing %s interface"), \
+                           driver_name, #new); \
+            return -1; \
+        } \
+    } while (0)
+    REQUIRE_API(domainShutdown, domainShutdownFlags);
+    REQUIRE_API(domainDestroy, domainDestroyFlags);
+    REQUIRE_API(domainSetMemory, domainSetMemoryFlags);
+    REQUIRE_API(domainSave, domainSaveFlags);
+    REQUIRE_API(domainRestore, domainRestoreFlags);
+    REQUIRE_API(domainSetVcpus, domainSetVcpusFlags);
+    REQUIRE_API(domainGetVcpus, domainGetVcpusFlags);
+    REQUIRE_API(domainPinVcpu, domainPinVcpuFlags);
+    REQUIRE_API(domainCreate, domainCreateWithFlags);
+    REQUIRE_API(domainDefineXML, domainDefineXMLFlags);
+    REQUIRE_API(domainUndefine, domainUndefineFlags);
+    REQUIRE_API(domainAttachDevice, domainAttachDeviceFlags);
+    REQUIRE_API(domainDetachDevice, domainDetachDeviceFlags);
+    REQUIRE_API(domainGetSchedulerParameters, domainGetSchedulerParametersFlags);
+    REQUIRE_API(domainSetSchedulerParameters, domainSetSchedulerParametersFlags);
+    REQUIRE_API(nodeDeviceDettach, nodeDeviceDetachFlags);
+#undef REQUIRE_API
+
     VIR_DEBUG("registering %s as driver %d",
-           driver->hypervisorDriver->name, virConnectDriverTabCount);
+              driver_name, virConnectDriverTabCount);

     if (setSharedDrivers) {
         if (driver->interfaceDriver == NULL)
-- 
2.20.1




More information about the libvir-list mailing list