[libvirt PATCH v3 05/18] qemu: implement basic virFileCache for nbdkit caps

Jonathon Jongsma posted 18 patches 3 years, 3 months ago
There is a newer version of this series
[libvirt PATCH v3 05/18] qemu: implement basic virFileCache for nbdkit caps
Posted by Jonathon Jongsma 3 years, 3 months ago
Preparatory step for caching nbdkit capabilities. This patch implements
the newData and isValid virFileCacheHandlers callback functions.

Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
---
 src/qemu/qemu_nbdkit.c | 93 +++++++++++++++++++++++++++++++++++++++++-
 src/qemu/qemu_nbdkit.h |  4 ++
 2 files changed, 96 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_nbdkit.c b/src/qemu/qemu_nbdkit.c
index 5de1021d89..9ab048e9e1 100644
--- a/src/qemu/qemu_nbdkit.c
+++ b/src/qemu/qemu_nbdkit.c
@@ -202,7 +202,7 @@ qemuNbdkitGetDirMtime(const char *moddir)
 }
 
 
-G_GNUC_UNUSED static void
+static void
 qemuNbdkitCapsQuery(qemuNbdkitCaps *caps)
 {
     struct stat st;
@@ -241,3 +241,94 @@ qemuNbdkitCapsSet(qemuNbdkitCaps *nbdkitCaps,
 {
     ignore_value(virBitmapSetBit(nbdkitCaps->flags, flag));
 }
+
+
+static bool
+virNbkditCapsCheckModdir(const char *moddir,
+                         time_t expectedMtime)
+{
+    time_t mtime = qemuNbdkitGetDirMtime(moddir);
+
+    if (mtime != expectedMtime) {
+        VIR_DEBUG("Outdated capabilities for nbdkit: module "
+                  "directory '%s' changed (%lld vs %lld)",
+                  moddir,
+                  (long long)mtime, (long long)expectedMtime);
+        return false;
+    }
+    return true;
+}
+
+
+static bool
+virNbdkitCapsIsValid(void *data,
+                     void *privData G_GNUC_UNUSED)
+{
+    qemuNbdkitCaps *nbdkitCaps = data;
+    struct stat st;
+
+    if (!nbdkitCaps->path)
+        return true;
+
+    if (!virNbkditCapsCheckModdir(NBDKIT_PLUGINDIR, nbdkitCaps->pluginDirMtime))
+        return false;
+    if (!virNbkditCapsCheckModdir(NBDKIT_FILTERDIR, nbdkitCaps->filterDirMtime))
+        return false;
+
+    if (nbdkitCaps->libvirtCtime != virGetSelfLastChanged() ||
+        nbdkitCaps->libvirtVersion != LIBVIR_VERSION_NUMBER) {
+        VIR_DEBUG("Outdated capabilities for '%s': libvirt changed "
+                  "(%lld vs %lld, %lu vs %lu)",
+                  nbdkitCaps->path,
+                  (long long)nbdkitCaps->libvirtCtime,
+                  (long long)virGetSelfLastChanged(),
+                  (unsigned long)nbdkitCaps->libvirtVersion,
+                  (unsigned long)LIBVIR_VERSION_NUMBER);
+        return false;
+    }
+
+    if (stat(nbdkitCaps->path, &st) < 0) {
+        VIR_DEBUG("Failed to stat nbdkit binary '%s': %s",
+                  nbdkitCaps->path,
+                  g_strerror(errno));
+        return false;
+    }
+
+    if (st.st_ctime != nbdkitCaps->ctime) {
+        VIR_DEBUG("Outdated capabilities for '%s': nbdkit binary changed "
+                  "(%lld vs %lld)",
+                  nbdkitCaps->path,
+                  (long long)st.st_ctime, (long long)nbdkitCaps->ctime);
+        return false;
+    }
+
+    return true;
+}
+
+
+static void*
+virNbdkitCapsNewData(const char *binary,
+                     void *privData G_GNUC_UNUSED)
+{
+    qemuNbdkitCaps *caps = qemuNbdkitCapsNew(binary);
+    qemuNbdkitCapsQuery(caps);
+
+    return caps;
+}
+
+
+virFileCacheHandlers nbdkitCapsCacheHandlers = {
+    .isValid = virNbdkitCapsIsValid,
+    .newData = virNbdkitCapsNewData,
+    .loadFile = NULL,
+    .saveFile = NULL,
+    .privFree = NULL,
+};
+
+
+virFileCache*
+qemuNbdkitCapsCacheNew(const char *cachedir)
+{
+    g_autofree char *dir = g_build_filename(cachedir, "nbdkitcapabilities", NULL);
+    return virFileCacheNew(dir, "xml", &nbdkitCapsCacheHandlers);
+}
diff --git a/src/qemu/qemu_nbdkit.h b/src/qemu/qemu_nbdkit.h
index 8ffb0f7044..f6cbedaa94 100644
--- a/src/qemu/qemu_nbdkit.h
+++ b/src/qemu/qemu_nbdkit.h
@@ -23,6 +23,7 @@
 
 #include "internal.h"
 #include "virenum.h"
+#include "virfilecache.h"
 
 typedef struct _qemuNbdkitCaps qemuNbdkitCaps;
 
@@ -40,6 +41,9 @@ VIR_ENUM_DECL(qemuNbdkitCaps);
 qemuNbdkitCaps *
 qemuNbdkitCapsNew(const char *path);
 
+virFileCache *
+qemuNbdkitCapsCacheNew(const char *cachedir);
+
 bool
 qemuNbdkitCapsGet(qemuNbdkitCaps *nbdkitCaps,
                   qemuNbdkitCapsFlags flag);
-- 
2.37.3
Re: [libvirt PATCH v3 05/18] qemu: implement basic virFileCache for nbdkit caps
Posted by Peter Krempa 3 years, 2 months ago
On Thu, Oct 20, 2022 at 16:58:56 -0500, Jonathon Jongsma wrote:
> Preparatory step for caching nbdkit capabilities. This patch implements
> the newData and isValid virFileCacheHandlers callback functions.
> 
> Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
> ---
>  src/qemu/qemu_nbdkit.c | 93 +++++++++++++++++++++++++++++++++++++++++-
>  src/qemu/qemu_nbdkit.h |  4 ++
>  2 files changed, 96 insertions(+), 1 deletion(-)
> 
> diff --git a/src/qemu/qemu_nbdkit.c b/src/qemu/qemu_nbdkit.c
> index 5de1021d89..9ab048e9e1 100644
> --- a/src/qemu/qemu_nbdkit.c
> +++ b/src/qemu/qemu_nbdkit.c
> @@ -202,7 +202,7 @@ qemuNbdkitGetDirMtime(const char *moddir)
>  }
>  
>  
> -G_GNUC_UNUSED static void
> +static void
>  qemuNbdkitCapsQuery(qemuNbdkitCaps *caps)
>  {
>      struct stat st;
> @@ -241,3 +241,94 @@ qemuNbdkitCapsSet(qemuNbdkitCaps *nbdkitCaps,
>  {
>      ignore_value(virBitmapSetBit(nbdkitCaps->flags, flag));
>  }
> +
> +
> +static bool
> +virNbkditCapsCheckModdir(const char *moddir,
> +                         time_t expectedMtime)
> +{
> +    time_t mtime = qemuNbdkitGetDirMtime(moddir);
> +
> +    if (mtime != expectedMtime) {
> +        VIR_DEBUG("Outdated capabilities for nbdkit: module "
> +                  "directory '%s' changed (%lld vs %lld)",

Preferrably don't use linebreaks in debug/error messages for better
greppability even if it exceeds the "recomended" line lenght. (more
instances in this patch).

Reviewed-by: Peter Krempa <pkrempa@redhat.com>