[libvirt] [PATCH v4 2/6] libvirt: pass a directory path into drivers for embedded usage

Daniel P. Berrangé berrange at redhat.com
Fri Jan 10 10:34:26 UTC 2020


The intent here is to allow the virt drivers to be run directly embedded
in an arbitrary process without interfering with libvirtd. To achieve
this they need to store all their configuration & state in a separate
directory tree from the main system or session libvirtd instances.

This can be useful for doing testing of the virt drivers in "make check"
without interfering with the user's own libvirtd instances.

It can also be used for applications using KVM/QEMU as a piece of
infrastructure to build an service, rather than for general purpose
OS hosting. A long standing example is libguestfs, which would prefer
if its temporary VMs did show up in the main libvirtd VM list, because
this confuses apps such as OpenStack Nova. A more recent example would
be Kata which is using KVM as a technology to build containers.

Reviewed-by: Michal Privoznik <mprivozn at redhat.com>
Reviewed-by: Cole Robinson <crobinso at redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
---
 src/driver-state.h                      |  1 +
 src/interface/interface_backend_netcf.c |  7 +++++++
 src/interface/interface_backend_udev.c  |  7 +++++++
 src/libvirt.c                           | 21 +++++++++++++++++++++
 src/libvirt_internal.h                  |  4 +++-
 src/libxl/libxl_driver.c                |  7 +++++++
 src/lxc/lxc_driver.c                    |  8 ++++++++
 src/network/bridge_driver.c             |  7 +++++++
 src/node_device/node_device_hal.c       |  7 +++++++
 src/node_device/node_device_udev.c      |  7 +++++++
 src/nwfilter/nwfilter_driver.c          |  7 +++++++
 src/qemu/qemu_driver.c                  |  7 +++++++
 src/remote/remote_daemon.c              |  1 +
 src/remote/remote_driver.c              |  1 +
 src/secret/secret_driver.c              |  7 +++++++
 src/storage/storage_driver.c            |  7 +++++++
 src/vz/vz_driver.c                      |  7 +++++++
 17 files changed, 112 insertions(+), 1 deletion(-)

diff --git a/src/driver-state.h b/src/driver-state.h
index 69e2678dfc..1e2f6ed247 100644
--- a/src/driver-state.h
+++ b/src/driver-state.h
@@ -32,6 +32,7 @@ typedef enum {
 
 typedef virDrvStateInitResult
 (*virDrvStateInitialize)(bool privileged,
+                         const char *root,
                          virStateInhibitCallback callback,
                          void *opaque);
 
diff --git a/src/interface/interface_backend_netcf.c b/src/interface/interface_backend_netcf.c
index 65cb7eae62..06eb1ace08 100644
--- a/src/interface/interface_backend_netcf.c
+++ b/src/interface/interface_backend_netcf.c
@@ -89,9 +89,16 @@ virNetcfDriverStateDispose(void *obj)
 
 static int
 netcfStateInitialize(bool privileged,
+                     const char *root,
                      virStateInhibitCallback callback G_GNUC_UNUSED,
                      void *opaque G_GNUC_UNUSED)
 {
+    if (root != NULL) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("Driver does not support embedded mode"));
+        return -1;
+    }
+
     if (virNetcfDriverStateInitialize() < 0)
         return VIR_DRV_STATE_INIT_ERROR;
 
diff --git a/src/interface/interface_backend_udev.c b/src/interface/interface_backend_udev.c
index 7cc098eb33..e87b884c17 100644
--- a/src/interface/interface_backend_udev.c
+++ b/src/interface/interface_backend_udev.c
@@ -1145,11 +1145,18 @@ udevStateCleanup(void);
 
 static int
 udevStateInitialize(bool privileged,
+                    const char *root,
                     virStateInhibitCallback callback G_GNUC_UNUSED,
                     void *opaque G_GNUC_UNUSED)
 {
     int ret = VIR_DRV_STATE_INIT_ERROR;
 
+    if (root != NULL) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("Driver does not support embedded mode"));
+        return -1;
+    }
+
     if (VIR_ALLOC(driver) < 0)
         goto cleanup;
 
diff --git a/src/libvirt.c b/src/libvirt.c
index f1ffc97261..4de87cdecd 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -609,16 +609,36 @@ virRegisterStateDriver(virStateDriverPtr driver)
  * virStateInitialize:
  * @privileged: set to true if running with root privilege, false otherwise
  * @mandatory: set to true if all drivers must report success, not skipped
+ * @root: directory to use for embedded mode
  * @callback: callback to invoke to inhibit shutdown of the daemon
  * @opaque: data to pass to @callback
  *
  * Initialize all virtualization drivers.
  *
+ * Passing a non-NULL @root instructs the driver to run in embedded mode.
+ * Instead of using the compile time $prefix as the basis for directory
+ * paths, @root should be used instead. In addition any '/libvirt'
+ * component of the paths should be stripped.
+ *
+ * eg consider a build with prefix=/usr/local. A driver might use the
+ * locations
+ *
+ *    /usr/local/etc/libvirt/$DRIVER/
+ *    /usr/local/var/lib/libvirt/$DRIVER/
+ *    /usr/local/run/libvirt/$DRIVER/
+ *
+ * When run with @root, the locations should instead be
+ *
+ *    @root/etc/$DRIVER/
+ *    @root/var/lib/$DRIVER/
+ *    @root/run/$DRIVER/
+ *
  * Returns 0 if all succeed, -1 upon any failure.
  */
 int
 virStateInitialize(bool privileged,
                    bool mandatory,
+                   const char *root,
                    virStateInhibitCallback callback,
                    void *opaque)
 {
@@ -633,6 +653,7 @@ virStateInitialize(bool privileged,
             VIR_DEBUG("Running global init for %s state driver",
                       virStateDriverTab[i]->name);
             ret = virStateDriverTab[i]->stateInitialize(privileged,
+                                                        root,
                                                         callback,
                                                         opaque);
             VIR_DEBUG("State init result %d (mandatory=%d)", ret, mandatory);
diff --git a/src/libvirt_internal.h b/src/libvirt_internal.h
index 4a74dbc2af..00ef7aaf25 100644
--- a/src/libvirt_internal.h
+++ b/src/libvirt_internal.h
@@ -31,8 +31,10 @@ typedef void (*virStateInhibitCallback)(bool inhibit,
 
 int virStateInitialize(bool privileged,
                        bool mandatory,
+                       const char *root,
                        virStateInhibitCallback inhibit,
-                       void *opaque);
+                       void *opaque)
+    ATTRIBUTE_NONNULL(2);
 int virStateCleanup(void);
 int virStateReload(void);
 int virStateStop(void);
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index f021ec9c5d..85a1fc5de7 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -648,6 +648,7 @@ libxlAddDom0(libxlDriverPrivatePtr driver)
 
 static int
 libxlStateInitialize(bool privileged,
+                     const char *root,
                      virStateInhibitCallback callback G_GNUC_UNUSED,
                      void *opaque G_GNUC_UNUSED)
 {
@@ -656,6 +657,12 @@ libxlStateInitialize(bool privileged,
     char ebuf[1024];
     bool autostart = true;
 
+    if (root != NULL) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("Driver does not support embedded mode"));
+        return -1;
+    }
+
     if (!libxlDriverShouldLoad(privileged))
         return VIR_DRV_STATE_INIT_SKIPPED;
 
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 780c6ed4a2..47175d92b8 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -85,6 +85,7 @@ VIR_LOG_INIT("lxc.lxc_driver");
 
 
 static int lxcStateInitialize(bool privileged,
+                              const char *root,
                               virStateInhibitCallback callback,
                               void *opaque);
 static int lxcStateCleanup(void);
@@ -1526,12 +1527,19 @@ lxcSecurityInit(virLXCDriverConfigPtr cfg)
 
 
 static int lxcStateInitialize(bool privileged,
+                              const char *root,
                               virStateInhibitCallback callback G_GNUC_UNUSED,
                               void *opaque G_GNUC_UNUSED)
 {
     virLXCDriverConfigPtr cfg = NULL;
     bool autostart = true;
 
+    if (root != NULL) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("Driver does not support embedded mode"));
+        return -1;
+    }
+
     /* Check that the user is root, silently disable if not */
     if (!privileged) {
         VIR_INFO("Not running privileged, disabling driver");
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index c9c45df758..b66135f2d9 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -702,6 +702,7 @@ firewalld_dbus_filter_bridge(DBusConnection *connection G_GNUC_UNUSED,
  */
 static int
 networkStateInitialize(bool privileged,
+                       const char *root,
                        virStateInhibitCallback callback G_GNUC_UNUSED,
                        void *opaque G_GNUC_UNUSED)
 {
@@ -713,6 +714,12 @@ networkStateInitialize(bool privileged,
     DBusConnection *sysbus = NULL;
 #endif
 
+    if (root != NULL) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("Driver does not support embedded mode"));
+        return -1;
+    }
+
     if (VIR_ALLOC(network_driver) < 0)
         goto error;
 
diff --git a/src/node_device/node_device_hal.c b/src/node_device/node_device_hal.c
index 4cef7c2c12..c3ca310bb7 100644
--- a/src/node_device/node_device_hal.c
+++ b/src/node_device/node_device_hal.c
@@ -580,6 +580,7 @@ device_prop_modified(LibHalContext *ctx G_GNUC_UNUSED,
 
 static int
 nodeStateInitialize(bool privileged G_GNUC_UNUSED,
+                    const char *root,
                     virStateInhibitCallback callback G_GNUC_UNUSED,
                     void *opaque G_GNUC_UNUSED)
 {
@@ -591,6 +592,12 @@ nodeStateInitialize(bool privileged G_GNUC_UNUSED,
     DBusConnection *sysbus;
     DBusError err;
 
+    if (root != NULL) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("Driver does not support embedded mode"));
+        return -1;
+    }
+
     /* Ensure caps_tbl is sorted by capability name */
     qsort(caps_tbl, G_N_ELEMENTS(caps_tbl), sizeof(caps_tbl[0]),
           cmpstringp);
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
index 4b33dc25d8..396763fa29 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -1781,6 +1781,7 @@ udevPCITranslateInit(bool privileged G_GNUC_UNUSED)
 
 static int
 nodeStateInitialize(bool privileged,
+                    const char *root,
                     virStateInhibitCallback callback G_GNUC_UNUSED,
                     void *opaque G_GNUC_UNUSED)
 {
@@ -1788,6 +1789,12 @@ nodeStateInitialize(bool privileged,
     struct udev *udev = NULL;
     virThread enumThread;
 
+    if (root != NULL) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("Driver does not support embedded mode"));
+        return -1;
+    }
+
     if (VIR_ALLOC(driver) < 0)
         return VIR_DRV_STATE_INIT_ERROR;
 
diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c
index cc3ce98cc5..1c407727db 100644
--- a/src/nwfilter/nwfilter_driver.c
+++ b/src/nwfilter/nwfilter_driver.c
@@ -177,11 +177,18 @@ virNWFilterTriggerRebuildImpl(void *opaque)
  */
 static int
 nwfilterStateInitialize(bool privileged,
+                        const char *root,
                         virStateInhibitCallback callback G_GNUC_UNUSED,
                         void *opaque G_GNUC_UNUSED)
 {
     DBusConnection *sysbus = NULL;
 
+    if (root != NULL) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("Driver does not support embedded mode"));
+        return -1;
+    }
+
     if (virDBusHasSystemBus() &&
         !(sysbus = virDBusGetSystemBus()))
         return VIR_DRV_STATE_INIT_ERROR;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1fc662b3c8..56d420f608 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -631,6 +631,7 @@ qemuDomainFindMaxID(virDomainObjPtr vm,
  */
 static int
 qemuStateInitialize(bool privileged,
+                    const char *root,
                     virStateInhibitCallback callback,
                     void *opaque)
 {
@@ -644,6 +645,12 @@ qemuStateInitialize(bool privileged,
     const char *defsecmodel = NULL;
     g_autofree virSecurityManagerPtr *sec_managers = NULL;
 
+    if (root != NULL) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("Driver does not support embedded mode"));
+        return -1;
+    }
+
     if (VIR_ALLOC(qemu_driver) < 0)
         return VIR_DRV_STATE_INIT_ERROR;
 
diff --git a/src/remote/remote_daemon.c b/src/remote/remote_daemon.c
index cd55b2c39e..34788fb9b5 100644
--- a/src/remote/remote_daemon.c
+++ b/src/remote/remote_daemon.c
@@ -834,6 +834,7 @@ static void daemonRunStateInit(void *opaque)
      * seriously delay OS bootup process */
     if (virStateInitialize(virNetDaemonIsPrivileged(dmn),
                            mandatory,
+                           NULL,
                            daemonInhibitCallback,
                            dmn) < 0) {
         VIR_ERROR(_("Driver state initialization failed"));
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index c11f73ab4d..9b60cc5161 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -235,6 +235,7 @@ static int remoteSplitURIScheme(virURIPtr uri,
 
 static int
 remoteStateInitialize(bool privileged G_GNUC_UNUSED,
+                      const char *root G_GNUC_UNUSED,
                       virStateInhibitCallback callback G_GNUC_UNUSED,
                       void *opaque G_GNUC_UNUSED)
 {
diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c
index c3c57a41c7..a31005c731 100644
--- a/src/secret/secret_driver.c
+++ b/src/secret/secret_driver.c
@@ -452,9 +452,16 @@ secretStateCleanup(void)
 
 static int
 secretStateInitialize(bool privileged,
+                      const char *root,
                       virStateInhibitCallback callback G_GNUC_UNUSED,
                       void *opaque G_GNUC_UNUSED)
 {
+    if (root != NULL) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("Driver does not support embedded mode"));
+        return -1;
+    }
+
     if (VIR_ALLOC(driver) < 0)
         return VIR_DRV_STATE_INIT_ERROR;
 
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index 0bb116cf08..2dd093a9da 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -250,6 +250,7 @@ storageDriverAutostart(void)
  */
 static int
 storageStateInitialize(bool privileged,
+                       const char *root,
                        virStateInhibitCallback callback G_GNUC_UNUSED,
                        void *opaque G_GNUC_UNUSED)
 {
@@ -257,6 +258,12 @@ storageStateInitialize(bool privileged,
     g_autofree char *rundir = NULL;
     bool autostart = true;
 
+    if (root != NULL) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("Driver does not support embedded mode"));
+        return -1;
+    }
+
     if (VIR_ALLOC(driver) < 0)
         return VIR_DRV_STATE_INIT_ERROR;
 
diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c
index bcdbb50404..e833f59235 100644
--- a/src/vz/vz_driver.c
+++ b/src/vz/vz_driver.c
@@ -4094,12 +4094,19 @@ vzStateCleanup(void)
 
 static int
 vzStateInitialize(bool privileged,
+                  const char *root,
                   virStateInhibitCallback callback G_GNUC_UNUSED,
                   void *opaque G_GNUC_UNUSED)
 {
     if (!privileged)
         return VIR_DRV_STATE_INIT_SKIPPED;
 
+    if (root != NULL) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("Driver does not support embedded mode"));
+        return -1;
+    }
+
     vz_driver_privileged = privileged;
 
     if (virFileMakePathWithMode(VZ_STATEDIR, S_IRWXU) < 0) {
-- 
2.23.0




More information about the libvir-list mailing list