[Libguestfs] [PATCH nbdkit 5/7] cache: Implement cache-on-read=/PATH

Richard W.M. Jones rjones at redhat.com
Mon Jul 26 17:28:58 UTC 2021


For virt-v2v we will need to be able to turn cache-on-read on while
performing inspection and modification of the guest, and later off
when doing the bulk copy.  To do that allow the cache-on-read
parameter to refer to a path where the existence of the path toggles
the feature.

(We could restart nbdkit between these phases, but this change avoids
doing that.)
---
 filters/cache/nbdkit-cache-filter.pod | 11 ++++++++-
 filters/cache/cache.h                 | 10 ++++++--
 filters/cache/blk.c                   |  2 +-
 filters/cache/cache.c                 | 33 ++++++++++++++++++++-------
 4 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/filters/cache/nbdkit-cache-filter.pod b/filters/cache/nbdkit-cache-filter.pod
index 34fd0b29..2ac307e0 100644
--- a/filters/cache/nbdkit-cache-filter.pod
+++ b/filters/cache/nbdkit-cache-filter.pod
@@ -8,7 +8,7 @@ nbdkit-cache-filter - nbdkit caching filter
                               [cache-max-size=SIZE]
                               [cache-high-threshold=N]
                               [cache-low-threshold=N]
-                              [cache-on-read=true|false]
+                              [cache-on-read=true|false|/PATH]
                               [plugin-args...]
 
 =head1 DESCRIPTION
@@ -87,6 +87,15 @@ the plugin.
 
 Do not cache read requests (this is the default).
 
+=item B<cache-on-read=/PATH>
+
+(nbdkit E<ge> 1.28)
+
+When F</PATH> (which must be an absolute path) exists, this behaves
+like C<cache-on-read=true>, and when it does not exist like
+C<cache-on-read=false>.  This allows you to control the cache-on-read
+behaviour while nbdkit is running.
+
 =back
 
 =head1 CACHE MAXIMUM SIZE
diff --git a/filters/cache/cache.h b/filters/cache/cache.h
index 2b72221f..a559adef 100644
--- a/filters/cache/cache.h
+++ b/filters/cache/cache.h
@@ -49,7 +49,13 @@ extern unsigned blksize;
 extern int64_t max_size;
 extern unsigned hi_thresh, lo_thresh;
 
-/* Cache read requests. */
-extern bool cache_on_read;
+/* Cache on read mode. */
+extern enum cor_mode {
+  COR_OFF,
+  COR_ON,
+  COR_PATH,
+} cor_mode;
+extern const char *cor_path;
+extern bool cache_on_read (void);
 
 #endif /* NBDKIT_CACHE_H */
diff --git a/filters/cache/blk.c b/filters/cache/blk.c
index 42bd3779..19f79605 100644
--- a/filters/cache/blk.c
+++ b/filters/cache/blk.c
@@ -244,7 +244,7 @@ _blk_read_multiple (nbdkit_next *next,
     memset (block + n, 0, tail);
 
     /* If cache-on-read, copy the blocks to the cache. */
-    if (cache_on_read) {
+    if (cache_on_read ()) {
       if (cache_debug_verbose)
         nbdkit_debug ("cache: cache-on-read block %" PRIu64
                       " (offset %" PRIu64 ")",
diff --git a/filters/cache/cache.c b/filters/cache/cache.c
index 9c081948..8af52106 100644
--- a/filters/cache/cache.c
+++ b/filters/cache/cache.c
@@ -74,7 +74,8 @@ unsigned blksize;
 enum cache_mode cache_mode = CACHE_MODE_WRITEBACK;
 int64_t max_size = -1;
 unsigned hi_thresh = 95, lo_thresh = 80;
-bool cache_on_read = false;
+enum cor_mode cor_mode = COR_OFF;
+const char *cor_path;
 
 static int cache_flush (nbdkit_next *next, void *handle, uint32_t flags,
                         int *err);
@@ -161,12 +162,16 @@ cache_config (nbdkit_next_config *next, nbdkit_backend *nxdata,
   }
 #endif /* !HAVE_CACHE_RECLAIM */
   else if (strcmp (key, "cache-on-read") == 0) {
-    int r;
-
-    r = nbdkit_parse_bool (value);
-    if (r == -1)
-      return -1;
-    cache_on_read = r;
+    if (value[0] == '/') {
+      cor_path = value;
+      cor_mode = COR_PATH;
+    }
+    else {
+      int r = nbdkit_parse_bool (value);
+      if (r == -1)
+        return -1;
+      cor_mode = r ? COR_ON : COR_OFF;
+    }
     return 0;
   }
   else {
@@ -177,7 +182,7 @@ cache_config (nbdkit_next_config *next, nbdkit_backend *nxdata,
 #define cache_config_help_common \
   "cache=MODE                Set cache MODE, one of writeback (default),\n" \
   "                          writethrough, or unsafe.\n" \
-  "cache-on-read=BOOL        Set to true to cache on reads (default false).\n"
+  "cache-on-read=BOOL|/PATH  Set to true to cache on reads (default false).\n"
 #ifndef HAVE_CACHE_RECLAIM
 #define cache_config_help cache_config_help_common
 #else
@@ -187,6 +192,18 @@ cache_config (nbdkit_next_config *next, nbdkit_backend *nxdata,
   "cache-low-threshold=PCT   Percentage of max size where reclaim ends.\n"
 #endif
 
+/* Decide if cache-on-read is currently on or off. */
+bool
+cache_on_read (void)
+{
+  switch (cor_mode) {
+  case COR_ON: return true;
+  case COR_OFF: return false;
+  case COR_PATH: return access (cor_path, F_OK) == 0;
+  default: abort ();
+  }
+}
+
 static int
 cache_config_complete (nbdkit_next_config_complete *next,
                        nbdkit_backend *nxdata)
-- 
2.32.0




More information about the Libguestfs mailing list