]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
src: convert drivers over to new virInhibitor APIs
authorDaniel P. Berrangé <berrange@redhat.com>
Mon, 16 Dec 2024 16:28:48 +0000 (16:28 +0000)
committerDaniel P. Berrangé <berrange@redhat.com>
Thu, 19 Dec 2024 18:03:15 +0000 (18:03 +0000)
This initial conversion of the drivers switches them over to use
the virInhibitor APIs in local daemon only mode. Communication to
logind is still handled by the virNetDaemon class logic.

This mostly just replaces upto 3 fields in the driver state
with a single new virInhibitor object, but otherwise should not
change functionality besides replacing atomics with mutex protected
APIs.

The exception is the LXC driver which has been trying to inhibit
shutdown shutdown but silently failing to, since nothing ever
remembered to set the 'inhibitCallback' pointer in the driver
state struct.

Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
12 files changed:
src/libxl/libxl_conf.h
src/libxl/libxl_domain.c
src/libxl/libxl_driver.c
src/lxc/lxc_conf.h
src/lxc/lxc_driver.c
src/lxc/lxc_process.c
src/network/bridge_driver.c
src/network/bridge_driver_conf.h
src/qemu/qemu_conf.h
src/qemu/qemu_driver.c
src/qemu/qemu_process.c
src/secret/secret_driver.c

index 7087b41079e8bfaafd78ee2b06141681a30c35de..0edcde079db7615404503d3940d08954820513b4 100644 (file)
@@ -35,6 +35,7 @@
 #include "virfirmware.h"
 #include "libxl_capabilities.h"
 #include "libxl_logger.h"
+#include "virinhibitor.h"
 
 #define LIBXL_DRIVER_EXTERNAL_NAME "Xen"
 /*
@@ -117,12 +118,8 @@ struct _libxlDriverPrivate {
     /* pid file FD, ensures two copies of the driver can't use the same root */
     int lockFD;
 
-    /* Atomic inc/dec only */
-    unsigned int nactive;
-
-    /* Immutable pointers. Caller must provide locking */
-    virStateInhibitCallback inhibitCallback;
-    void *inhibitOpaque;
+    /* Immutable pointer, self-locking APIs */
+    virInhibitor *inhibitor;
 
     /* Immutable pointer, self-locking APIs */
     virDomainObjList *domains;
index cad6c9ce421ab7331bdcc04634695f865400eeda..a049cdb30f45d846d0b19ede6232bea533322ba7 100644 (file)
@@ -873,8 +873,7 @@ libxlDomainCleanup(libxlDriverPrivate *driver,
         priv->deathW = NULL;
     }
 
-    if (g_atomic_int_dec_and_test(&driver->nactive) && driver->inhibitCallback)
-        driver->inhibitCallback(false, driver->inhibitOpaque);
+    virInhibitorRelease(driver->inhibitor);
 
     /* Release auto-allocated graphics ports */
     for (i = 0; i < vm->def->ngraphics; i++) {
@@ -1421,8 +1420,7 @@ libxlDomainStart(libxlDriverPrivate *driver,
         return -1;
     }
 
-    if (g_atomic_int_add(&driver->nactive, 1) == 0 && driver->inhibitCallback)
-        driver->inhibitCallback(true, driver->inhibitOpaque);
+    virInhibitorHold(driver->inhibitor);
 
     event = virDomainEventLifecycleNewFromObj(vm, VIR_DOMAIN_EVENT_STARTED,
                                               restore_fd < 0 ?
index e72553603d944b4068da5b15afa104840bba9eee..eb293172f7d563b84ae4fcc12bb7776826c70d45 100644 (file)
@@ -437,8 +437,7 @@ libxlReconnectDomain(virDomainObj *vm,
         virDomainObjSetState(vm, VIR_DOMAIN_RUNNING,
                              VIR_DOMAIN_RUNNING_UNKNOWN);
 
-    if (g_atomic_int_add(&driver->nactive, 1) == 0 && driver->inhibitCallback)
-        driver->inhibitCallback(true, driver->inhibitOpaque);
+    virInhibitorHold(driver->inhibitor);
 
     /* Enable domain death events */
     libxl_evenable_domain_death(cfg->ctx, vm->def->id, 0, &priv->deathW);
@@ -514,6 +513,7 @@ libxlStateCleanup(void)
 
     virObjectUnref(libxl_driver->domainEventState);
     virSysinfoDefFree(libxl_driver->hostsysinfo);
+    virInhibitorFree(libxl_driver->inhibitor);
 
     if (libxl_driver->lockFD != -1)
         virPidFileRelease(libxl_driver->config->stateDir, "driver", libxl_driver->lockFD);
@@ -675,9 +675,6 @@ libxlStateInitialize(bool privileged,
         return VIR_DRV_STATE_INIT_ERROR;
     }
 
-    libxl_driver->inhibitCallback = callback;
-    libxl_driver->inhibitOpaque = opaque;
-
     /* Allocate bitmap for vnc port reservation */
     if (!(libxl_driver->reservedGraphicsPorts =
           virPortAllocatorRangeNew(_("VNC"),
@@ -709,6 +706,14 @@ libxlStateInitialize(bool privileged,
     if (libxlDriverConfigLoadFile(cfg, driverConf) < 0)
         goto error;
 
+    libxl_driver->inhibitor = virInhibitorNew(
+        VIR_INHIBITOR_WHAT_NONE,
+        _("Libvirt Xen"),
+        _("Xen virtual machines are running"),
+        VIR_INHIBITOR_MODE_DELAY,
+        callback,
+        opaque);
+
     /* Register the callbacks providing access to libvirt's event loop */
     libxl_osevent_register_hooks(cfg->ctx, &libxl_osevent_callbacks, cfg->ctx);
 
index a639e3989f08d356e84e4fa4129e744331652982..1969ed74cba3f0d9487639ae173ca585a7483581 100644 (file)
@@ -30,6 +30,7 @@
 #include "virsysinfo.h"
 #include "virclosecallbacks.h"
 #include "virhostdev.h"
+#include "virinhibitor.h"
 
 #define LXC_DRIVER_NAME "LXC"
 
@@ -75,12 +76,8 @@ struct _virLXCDriver {
     /* Immutable pointer, lockless APIs */
     virSysinfoDef *hostsysinfo;
 
-    /* Atomic inc/dec only */
-    unsigned int nactive;
-
-    /* Immutable pointers. Caller must provide locking */
-    virStateInhibitCallback inhibitCallback;
-    void *inhibitOpaque;
+    /* Immutable pointer, self-locking APIs */
+    virInhibitor *inhibitor;
 
     /* Immutable pointer, self-locking APIs */
     virDomainObjList *domains;
index 2488940feb70e7cfd9c8efb05ae07227c13ebd74..08516c82972ed8d9cb252637771a11a89bc51ea9 100644 (file)
@@ -1398,8 +1398,8 @@ static virDrvStateInitResult
 lxcStateInitialize(bool privileged,
                    const char *root,
                    bool monolithic G_GNUC_UNUSED,
-                   virStateInhibitCallback callback G_GNUC_UNUSED,
-                   void *opaque G_GNUC_UNUSED)
+                   virStateInhibitCallback callback,
+                   void *opaque)
 {
     virLXCDriverConfig *cfg = NULL;
     bool autostart = true;
@@ -1451,6 +1451,14 @@ lxcStateInitialize(bool privileged,
     if (virLXCLoadDriverConfig(cfg, SYSCONFDIR "/libvirt/lxc.conf") < 0)
         goto cleanup;
 
+    lxc_driver->inhibitor = virInhibitorNew(
+        VIR_INHIBITOR_WHAT_NONE,
+        _("Libvirt LXC"),
+        _("LXC containers are running"),
+        VIR_INHIBITOR_MODE_DELAY,
+        callback,
+        opaque);
+
     if (!(lxc_driver->securityManager = lxcSecurityInit(cfg)))
         goto cleanup;
 
@@ -1555,6 +1563,7 @@ static int lxcStateCleanup(void)
     virObjectUnref(lxc_driver->caps);
     virObjectUnref(lxc_driver->securityManager);
     virObjectUnref(lxc_driver->xmlopt);
+    virInhibitorFree(lxc_driver->inhibitor);
 
     if (lxc_driver->lockFD != -1)
         virPidFileRelease(lxc_driver->config->stateDir, "driver", lxc_driver->lockFD);
index cd8bcfc282f424c7a9e6caceaab10d71b3e0dd74..c2982244f095935ec9d5070c6fecf9e6ce2b789f 100644 (file)
@@ -203,8 +203,7 @@ static void virLXCProcessCleanup(virLXCDriver *driver,
     vm->pid = 0;
     vm->def->id = -1;
 
-    if (g_atomic_int_dec_and_test(&driver->nactive) && driver->inhibitCallback)
-        driver->inhibitCallback(false, driver->inhibitOpaque);
+    virInhibitorRelease(driver->inhibitor);
 
     virLXCDomainReAttachHostDevices(driver, vm->def);
 
@@ -1466,8 +1465,7 @@ int virLXCProcessStart(virLXCDriver * driver,
     if (virCommandHandshakeNotify(cmd) < 0)
         goto cleanup;
 
-    if (g_atomic_int_add(&driver->nactive, 1) == 0 && driver->inhibitCallback)
-        driver->inhibitCallback(true, driver->inhibitOpaque);
+    virInhibitorHold(driver->inhibitor);
 
     /* The first synchronization point is when the controller creates CGroups. */
     if (lxcContainerWaitForContinue(handshakefds[0]) < 0) {
@@ -1665,8 +1663,7 @@ virLXCProcessReconnectDomain(virDomainObj *vm,
         virDomainObjSetState(vm, VIR_DOMAIN_RUNNING,
                              VIR_DOMAIN_RUNNING_UNKNOWN);
 
-        if (g_atomic_int_add(&driver->nactive, 1) == 0 && driver->inhibitCallback)
-            driver->inhibitCallback(true, driver->inhibitOpaque);
+        virInhibitorHold(driver->inhibitor);
 
         if (!(priv->monitor = virLXCProcessConnectMonitor(driver, vm)))
             goto error;
index e700a614a9a369e3afb67b838d2828431bc2861a..ce793c12efdaaecb557ded6e2ba8b820a8e1b3c5 100644 (file)
@@ -504,8 +504,7 @@ networkUpdateState(virNetworkObj *obj,
     if (virNetworkObjIsActive(obj)) {
         virNetworkObjPortForEach(obj, networkUpdatePort, obj);
 
-        if (g_atomic_int_add(&driver->nactive, 1) == 0 && driver->inhibitCallback)
-            driver->inhibitCallback(true, driver->inhibitOpaque);
+        virInhibitorHold(driver->inhibitor);
     }
 
     /* Try and read dnsmasq pids of both active and inactive networks, just in
@@ -644,9 +643,6 @@ networkStateInitialize(bool privileged,
         goto error;
     }
 
-    network_driver->inhibitCallback = callback;
-    network_driver->inhibitOpaque = opaque;
-
     network_driver->privileged = privileged;
 
     if (!(network_driver->xmlopt = networkDnsmasqCreateXMLConf()))
@@ -655,6 +651,14 @@ networkStateInitialize(bool privileged,
     if (!(network_driver->config = cfg = virNetworkDriverConfigNew(privileged)))
         goto error;
 
+    network_driver->inhibitor = virInhibitorNew(
+        VIR_INHIBITOR_WHAT_NONE,
+        _("Libvirt Network"),
+        _("Virtual networks are active"),
+        VIR_INHIBITOR_MODE_DELAY,
+        callback,
+        opaque);
+
     if ((network_driver->lockFD =
          virPidFileAcquire(cfg->stateDir, "driver", getpid())) < 0)
         goto error;
@@ -2432,8 +2436,7 @@ networkStartNetwork(virNetworkDriverState *driver,
                                 obj, network_driver->xmlopt) < 0)
         goto cleanup;
 
-    if (g_atomic_int_add(&driver->nactive, 1) == 0 && driver->inhibitCallback)
-        driver->inhibitCallback(true, driver->inhibitOpaque);
+    virInhibitorHold(driver->inhibitor);
 
     virNetworkObjSetActive(obj, true);
     VIR_INFO("Network '%s' started up", def->name);
@@ -2509,8 +2512,7 @@ networkShutdownNetwork(virNetworkDriverState *driver,
 
     virNetworkObjSetActive(obj, false);
 
-    if (g_atomic_int_dec_and_test(&driver->nactive) && driver->inhibitCallback)
-        driver->inhibitCallback(false, driver->inhibitOpaque);
+    virInhibitorRelease(driver->inhibitor);
 
     virNetworkObjUnsetDefTransient(obj);
     return ret;
index 1beed01efbd1dbe54c738a74a7b2ff383f8461a8..2a2e2bc16d08c80f950755226c27c83d48e22ac2 100644 (file)
@@ -27,6 +27,7 @@
 #include "virnetworkobj.h"
 #include "object_event.h"
 #include "virfirewall.h"
+#include "virinhibitor.h"
 
 typedef struct _virNetworkDriverConfig virNetworkDriverConfig;
 struct _virNetworkDriverConfig {
@@ -49,12 +50,8 @@ typedef struct _virNetworkDriverState virNetworkDriverState;
 struct _virNetworkDriverState {
     virMutex lock;
 
-    /* Atomic inc/dec only */
-    unsigned int nactive;
-
-    /* Immutable pointers. Caller must provide locking */
-    virStateInhibitCallback inhibitCallback;
-    void *inhibitOpaque;
+    /* Immutable pointer, self-locking APIs */
+    virInhibitor *inhibitor;
 
     /* Read-only */
     bool privileged;
index 23a900193e0946c0860cbf7019513fadc94c3a62..42cdb6f8831908c1c6b44f55353a91d00649ebe3 100644 (file)
@@ -42,6 +42,7 @@
 #include "virfile.h"
 #include "virfilecache.h"
 #include "virfirmware.h"
+#include "virinhibitor.h"
 
 #define QEMU_DRIVER_NAME "QEMU"
 
@@ -257,16 +258,12 @@ struct _virQEMUDriver {
     /* Atomic increment only */
     int lastvmid;
 
-    /* Atomic inc/dec only */
-    unsigned int nactive;
-
     /* Immutable values */
     bool privileged;
     char *embeddedRoot;
 
-    /* Immutable pointers. Caller must provide locking */
-    virStateInhibitCallback inhibitCallback;
-    void *inhibitOpaque;
+    /* Immutable pointer, self-locking APIs */
+    virInhibitor *inhibitor;
 
     /* Immutable pointer, self-locking APIs */
     virDomainObjList *domains;
index 672b42b44ea89894a68c6c68c9f3c5e1a334ac40..80d6ac65722cb55776aaad82b44a935cbefea9b3 100644 (file)
@@ -573,9 +573,6 @@ qemuStateInitialize(bool privileged,
         return VIR_DRV_STATE_INIT_ERROR;
     }
 
-    qemu_driver->inhibitCallback = callback;
-    qemu_driver->inhibitOpaque = opaque;
-
     qemu_driver->privileged = privileged;
     qemu_driver->hostarch = virArchFromHost();
     if (root != NULL)
@@ -675,6 +672,14 @@ qemuStateInitialize(bool privileged,
         goto error;
     }
 
+    qemu_driver->inhibitor = virInhibitorNew(
+        VIR_INHIBITOR_WHAT_NONE,
+        _("Libvirt QEMU"),
+        _("QEMU/KVM virtual machines are running"),
+        VIR_INHIBITOR_MODE_DELAY,
+        callback,
+        opaque);
+
     if ((qemu_driver->lockFD =
          virPidFileAcquire(cfg->stateDir, "driver", getpid())) < 0)
         goto error;
@@ -1065,6 +1070,7 @@ qemuStateCleanup(void)
     ebtablesContextFree(qemu_driver->ebtables);
     virObjectUnref(qemu_driver->domains);
     virObjectUnref(qemu_driver->nbdkitCapsCache);
+    virInhibitorFree(qemu_driver->inhibitor);
 
     if (qemu_driver->lockFD != -1)
         virPidFileRelease(qemu_driver->config->stateDir, "driver", qemu_driver->lockFD);
index 5f2e2781562516d821011a520efdbfd64b343a7f..ba581cf05af9d434f392410d83993e43e8a1e652 100644 (file)
@@ -5809,8 +5809,7 @@ qemuProcessInit(virQEMUDriver *driver,
         qemuDomainSetFakeReboot(vm, false);
         virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_STARTING_UP);
 
-        if (g_atomic_int_add(&driver->nactive, 1) == 0 && driver->inhibitCallback)
-            driver->inhibitCallback(true, driver->inhibitOpaque);
+        virInhibitorHold(driver->inhibitor);
 
         /* Run an early hook to set-up missing devices */
         if (qemuProcessStartHook(driver, vm,
@@ -8823,8 +8822,7 @@ void qemuProcessStop(virQEMUDriver *driver,
     if (priv->eventThread)
         g_object_unref(g_steal_pointer(&priv->eventThread));
 
-    if (g_atomic_int_dec_and_test(&driver->nactive) && driver->inhibitCallback)
-        driver->inhibitCallback(false, driver->inhibitOpaque);
+    virInhibitorRelease(driver->inhibitor);
 
     /* Clear network bandwidth */
     virDomainClearNetBandwidth(vm->def);
@@ -9582,8 +9580,7 @@ qemuProcessReconnect(void *opaque)
             goto error;
     }
 
-    if (g_atomic_int_add(&driver->nactive, 1) == 0 && driver->inhibitCallback)
-        driver->inhibitCallback(true, driver->inhibitOpaque);
+    virInhibitorHold(driver->inhibitor);
 
  cleanup:
     if (jobStarted)
index a2d6b879d0805ef655c392c12090c80142c73821..04c3ca49f18d1740dba6d2491a6f1b4d8f61b289 100644 (file)
@@ -41,6 +41,7 @@
 #include "viraccessapicheck.h"
 #include "secret_event.h"
 #include "virutil.h"
+#include "virinhibitor.h"
 
 #define VIR_FROM_THIS VIR_FROM_SECRET
 
@@ -67,9 +68,8 @@ struct _virSecretDriverState {
     /* Immutable pointer, self-locking APIs */
     virObjectEventState *secretEventState;
 
-    /* Immutable pointers. Caller must provide locking */
-    virStateInhibitCallback inhibitCallback;
-    void *inhibitOpaque;
+    /* Immutable pointer, self-locking APIs */
+    virInhibitor *inhibitor;
 };
 
 static virSecretDriverState *driver;
@@ -90,23 +90,6 @@ secretObjFromSecret(virSecretPtr secret)
 }
 
 
-static bool
-secretNumOfEphemeralSecretsHelper(virConnectPtr conn G_GNUC_UNUSED,
-                                  virSecretDef *def)
-{
-    return def->isephemeral;
-}
-
-
-static int
-secretNumOfEphemeralSecrets(void)
-{
-    return virSecretObjListNumOfSecrets(driver->secrets,
-                                        secretNumOfEphemeralSecretsHelper,
-                                        NULL);
-}
-
-
 /* Driver functions */
 
 static int
@@ -271,6 +254,10 @@ secretDefineXML(virConnectPtr conn,
                        objDef->uuid,
                        objDef->usage_type,
                        objDef->usage_id);
+
+    if (objDef->isephemeral)
+        virInhibitorHold(driver->inhibitor);
+
     goto cleanup;
 
  restore_backup:
@@ -288,8 +275,6 @@ secretDefineXML(virConnectPtr conn,
     virSecretDefFree(def);
     virSecretObjEndAPI(&obj);
 
-    if (secretNumOfEphemeralSecrets() > 0)
-        driver->inhibitCallback(true, driver->inhibitOpaque);
 
     virObjectEventStateQueue(driver->secretEventState, event);
 
@@ -440,6 +425,9 @@ secretUndefine(virSecretPtr secret)
                                        VIR_SECRET_EVENT_UNDEFINED,
                                        0);
 
+    if (def->isephemeral)
+        virInhibitorRelease(driver->inhibitor);
+
     virSecretObjDeleteData(obj);
 
     virSecretObjListRemove(driver->secrets, obj);
@@ -450,9 +438,6 @@ secretUndefine(virSecretPtr secret)
  cleanup:
     virSecretObjEndAPI(&obj);
 
-    if (secretNumOfEphemeralSecrets() == 0)
-        driver->inhibitCallback(false, driver->inhibitOpaque);
-
     virObjectEventStateQueue(driver->secretEventState, event);
 
     return ret;
@@ -469,6 +454,7 @@ secretStateCleanupLocked(void)
     VIR_FREE(driver->configDir);
 
     virObjectUnref(driver->secretEventState);
+    virInhibitorFree(driver->inhibitor);
 
     if (driver->lockFD != -1)
         virPidFileRelease(driver->stateDir, "driver", driver->lockFD);
@@ -502,8 +488,6 @@ secretStateInitialize(bool privileged,
     driver->lockFD = -1;
     driver->secretEventState = virObjectEventStateNew();
     driver->privileged = privileged;
-    driver->inhibitCallback = callback;
-    driver->inhibitOpaque = opaque;
 
     if (root) {
         driver->embeddedRoot = g_strdup(root);
@@ -535,6 +519,14 @@ secretStateInitialize(bool privileged,
         goto error;
     }
 
+    driver->inhibitor = virInhibitorNew(
+        VIR_INHIBITOR_WHAT_NONE,
+        _("Libvirt Secret"),
+        _("Ephemeral secrets are loaded"),
+        VIR_INHIBITOR_MODE_DELAY,
+        callback,
+        opaque);
+
     if ((driver->lockFD =
          virPidFileAcquire(driver->stateDir, "driver", getpid())) < 0)
         goto error;