]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Add functions for determining nbdkit availability
authorJonathon Jongsma <jjongsma@redhat.com>
Tue, 5 Jul 2022 20:40:16 +0000 (15:40 -0500)
committerJonathon Jongsma <jjongsma@redhat.com>
Tue, 19 Sep 2023 19:28:49 +0000 (14:28 -0500)
In future commits, we will optionally use nbdkit to serve some remote
disk sources. This patch queries to see whether nbdkit is installed on
the host and queries it for capabilities. The data will be used in later
commits.

Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
src/qemu/meson.build
src/qemu/qemu_conf.h
src/qemu/qemu_nbdkit.c [new file with mode: 0644]
src/qemu/qemu_nbdkit.h [new file with mode: 0644]

index c8806bbc36a9266110d67cb98dfb9ebe8d4f0851..9be69961958f6ce6479725e7f63f944307cbca68 100644 (file)
@@ -28,6 +28,7 @@ qemu_driver_sources = [
   'qemu_monitor_json.c',
   'qemu_monitor_text.c',
   'qemu_namespace.c',
+  'qemu_nbdkit.c',
   'qemu_passt.c',
   'qemu_process.c',
   'qemu_qapi.c',
index 11c740d28fd854c0576ddad7ccac8e2e4780472d..4f610d86a17399964e93c2a2137ae0da5a28bb0b 100644 (file)
@@ -36,6 +36,7 @@
 #include "virthreadpool.h"
 #include "locking/lock_manager.h"
 #include "qemu_capabilities.h"
+#include "qemu_nbdkit.h"
 #include "virclosecallbacks.h"
 #include "virhostdev.h"
 #include "virfile.h"
diff --git a/src/qemu/qemu_nbdkit.c b/src/qemu/qemu_nbdkit.c
new file mode 100644 (file)
index 0000000..e4e8fd5
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * qemu_nbdkit.c: helpers for using nbdkit
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <config.h>
+#include <glib.h>
+
+#include "vircommand.h"
+#include "virerror.h"
+#include "virlog.h"
+#include "virpidfile.h"
+#include "virutil.h"
+#include "qemu_block.h"
+#include "qemu_conf.h"
+#include "qemu_domain.h"
+#include "qemu_extdevice.h"
+#include "qemu_nbdkit.h"
+#include "qemu_security.h"
+
+#include <fcntl.h>
+
+#define VIR_FROM_THIS VIR_FROM_QEMU
+
+VIR_LOG_INIT("qemu.nbdkit");
+
+VIR_ENUM_IMPL(qemuNbdkitCaps,
+    QEMU_NBDKIT_CAPS_LAST,
+    /* 0 */
+    "plugin-curl", /* QEMU_NBDKIT_CAPS_PLUGIN_CURL */
+    "plugin-ssh", /* QEMU_NBDKIT_CAPS_PLUGIN_SSH */
+    "filter-readahead", /* QEMU_NBDKIT_CAPS_FILTER_READAHEAD */
+);
+
+struct _qemuNbdkitCaps {
+    GObject parent;
+
+    char *path;
+    char *version;
+
+    virBitmap *flags;
+};
+G_DEFINE_TYPE(qemuNbdkitCaps, qemu_nbdkit_caps, G_TYPE_OBJECT);
+
+
+static void
+qemuNbdkitCheckCommandCap(qemuNbdkitCaps *nbdkit,
+                          virCommand *cmd,
+                          qemuNbdkitCapsFlags cap)
+{
+    if (virCommandRun(cmd, NULL) != 0)
+        return;
+
+    VIR_DEBUG("Setting nbdkit capability %i", cap);
+    ignore_value(virBitmapSetBit(nbdkit->flags, cap));
+}
+
+
+static void
+qemuNbdkitQueryFilter(qemuNbdkitCaps *nbdkit,
+                      const char *filter,
+                      qemuNbdkitCapsFlags cap)
+{
+    g_autoptr(virCommand) cmd = virCommandNewArgList(nbdkit->path,
+                                                     "--version",
+                                                     NULL);
+
+    virCommandAddArgPair(cmd, "--filter", filter);
+
+    /* use null plugin to check for filter */
+    virCommandAddArg(cmd, "null");
+
+    qemuNbdkitCheckCommandCap(nbdkit, cmd, cap);
+}
+
+
+static void
+qemuNbdkitQueryPlugin(qemuNbdkitCaps *nbdkit,
+                      const char *plugin,
+                      qemuNbdkitCapsFlags cap)
+{
+    g_autoptr(virCommand) cmd = virCommandNewArgList(nbdkit->path,
+                                                     plugin,
+                                                     "--version",
+                                                     NULL);
+
+    qemuNbdkitCheckCommandCap(nbdkit, cmd, cap);
+}
+
+
+static void
+qemuNbdkitCapsQueryPlugins(qemuNbdkitCaps *nbdkit)
+{
+    qemuNbdkitQueryPlugin(nbdkit, "curl", QEMU_NBDKIT_CAPS_PLUGIN_CURL);
+    qemuNbdkitQueryPlugin(nbdkit, "ssh", QEMU_NBDKIT_CAPS_PLUGIN_SSH);
+}
+
+
+static void
+qemuNbdkitCapsQueryFilters(qemuNbdkitCaps *nbdkit)
+{
+    qemuNbdkitQueryFilter(nbdkit, "readahead",
+                          QEMU_NBDKIT_CAPS_FILTER_READAHEAD);
+}
+
+
+static int
+qemuNbdkitCapsQueryVersion(qemuNbdkitCaps *nbdkit)
+{
+    g_autoptr(virCommand) cmd = virCommandNewArgList(nbdkit->path,
+                                                     "--version",
+                                                     NULL);
+
+    virCommandSetOutputBuffer(cmd, &nbdkit->version);
+
+    if (virCommandRun(cmd, NULL) != 0)
+        return -1;
+
+    VIR_DEBUG("Got nbdkit version %s", nbdkit->version);
+    return 0;
+}
+
+
+static void
+qemuNbdkitCapsFinalize(GObject *object)
+{
+    qemuNbdkitCaps *nbdkit = QEMU_NBDKIT_CAPS(object);
+
+    g_clear_pointer(&nbdkit->path, g_free);
+    g_clear_pointer(&nbdkit->version, g_free);
+    g_clear_pointer(&nbdkit->flags, virBitmapFree);
+
+    G_OBJECT_CLASS(qemu_nbdkit_caps_parent_class)->finalize(object);
+}
+
+
+void
+qemu_nbdkit_caps_init(qemuNbdkitCaps *caps)
+{
+    caps->flags = virBitmapNew(QEMU_NBDKIT_CAPS_LAST);
+    caps->version = NULL;
+}
+
+
+static void
+qemu_nbdkit_caps_class_init(qemuNbdkitCapsClass *klass)
+{
+    GObjectClass *obj = G_OBJECT_CLASS(klass);
+
+    obj->finalize = qemuNbdkitCapsFinalize;
+}
+
+
+qemuNbdkitCaps *
+qemuNbdkitCapsNew(const char *path)
+{
+    qemuNbdkitCaps *caps = g_object_new(QEMU_TYPE_NBDKIT_CAPS, NULL);
+    caps->path = g_strdup(path);
+
+    return caps;
+}
+
+
+G_GNUC_UNUSED static void
+qemuNbdkitCapsQuery(qemuNbdkitCaps *caps)
+{
+    qemuNbdkitCapsQueryPlugins(caps);
+    qemuNbdkitCapsQueryFilters(caps);
+    qemuNbdkitCapsQueryVersion(caps);
+}
+
+
+bool
+qemuNbdkitCapsGet(qemuNbdkitCaps *nbdkitCaps,
+                  qemuNbdkitCapsFlags flag)
+{
+    return virBitmapIsBitSet(nbdkitCaps->flags, flag);
+}
+
+
+void
+qemuNbdkitCapsSet(qemuNbdkitCaps *nbdkitCaps,
+                  qemuNbdkitCapsFlags flag)
+{
+    ignore_value(virBitmapSetBit(nbdkitCaps->flags, flag));
+}
diff --git a/src/qemu/qemu_nbdkit.h b/src/qemu/qemu_nbdkit.h
new file mode 100644 (file)
index 0000000..e191e1f
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * qemu_nbdkit.h: helpers for using nbdkit
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#pragma once
+
+#include "internal.h"
+#include "virenum.h"
+
+typedef struct _qemuNbdkitCaps qemuNbdkitCaps;
+
+typedef enum {
+    /* 0 */
+    QEMU_NBDKIT_CAPS_PLUGIN_CURL,
+    QEMU_NBDKIT_CAPS_PLUGIN_SSH,
+    QEMU_NBDKIT_CAPS_FILTER_READAHEAD,
+
+    QEMU_NBDKIT_CAPS_LAST,
+} qemuNbdkitCapsFlags;
+
+VIR_ENUM_DECL(qemuNbdkitCaps);
+
+qemuNbdkitCaps *
+qemuNbdkitCapsNew(const char *path);
+
+bool
+qemuNbdkitCapsGet(qemuNbdkitCaps *nbdkitCaps,
+                  qemuNbdkitCapsFlags flag);
+
+void
+qemuNbdkitCapsSet(qemuNbdkitCaps *nbdkitCaps,
+                  qemuNbdkitCapsFlags flag);
+
+#define QEMU_TYPE_NBDKIT_CAPS qemu_nbdkit_caps_get_type()
+G_DECLARE_FINAL_TYPE(qemuNbdkitCaps, qemu_nbdkit_caps, QEMU, NBDKIT_CAPS, GObject);