[Libguestfs] [nbdkit PATCH 1/2] filters: Add .export_description wrappers

Eric Blake eblake at redhat.com
Thu Aug 27 22:03:45 UTC 2020


When extracting an obvious subset of a larger container (ext2, gzip,
partition, tar, xz), it's fairly easy to add a nice updated
description for what the client is seeing.  Not all clients request
the description, but if you are worried about this leaking too much
information, it can be silenced with nbdkit-exportname-filter.

Signed-off-by: Eric Blake <eblake at redhat.com>

---
And maybe this is an excuse for adding nbdkit_[v]printf_intern()...
---
 filters/ext2/ext2.c           | 54 ++++++++++++++++++++++----------
 filters/gzip/gzip.c           | 40 ++++++++++++++++--------
 filters/partition/partition.c | 58 +++++++++++++++++++++++++----------
 filters/tar/tar.c             | 48 +++++++++++++++++++----------
 filters/xz/xz.c               | 43 ++++++++++++++++++--------
 5 files changed, 168 insertions(+), 75 deletions(-)

diff --git a/filters/ext2/ext2.c b/filters/ext2/ext2.c
index 75ac2c4c..7ad4a005 100644
--- a/filters/ext2/ext2.c
+++ b/filters/ext2/ext2.c
@@ -294,6 +294,25 @@ static int ext2_thread_model (void)
   return NBDKIT_THREAD_MODEL_SERIALIZE_CONNECTIONS;
 }

+/* Description. */
+static const char *
+ext2_export_description (struct nbdkit_next_ops *next_ops, void *nxdata,
+                         void *handle)
+{
+  struct handle *h = handle;
+  const char *fname = file ?: h->exportname;
+  const char *slash = fname[0] == '/' ? "" : "/";
+  const char *base = next_ops->export_description (nxdata);
+  CLEANUP_FREE char *desc = NULL;
+
+  if (base)
+    asprintf (&desc, "embedded '%s%s' from within ext2 image: %s",
+              slash, fname, base);
+  else
+    asprintf (&desc, "embedded '%s%s' from within ext2 image", slash, fname);
+  return nbdkit_strdup_intern (desc);
+}
+
 /* Get the disk size. */
 static int64_t
 ext2_get_size (struct nbdkit_next_ops *next_ops, void *nxdata, void *handle)
@@ -412,23 +431,24 @@ ext2_flush (struct nbdkit_next_ops *next_ops, void *nxdata,
  */

 static struct nbdkit_filter filter = {
-  .name              = "ext2",
-  .longname          = "nbdkit ext2 filter",
-  .load              = ext2_load,
-  .unload            = ext2_unload,
-  .config            = ext2_config,
-  .config_complete   = ext2_config_complete,
-  .config_help       = ext2_config_help,
-  .thread_model      = ext2_thread_model,
-  .open              = ext2_open,
-  .prepare           = ext2_prepare,
-  .close             = ext2_close,
-  .can_fua           = ext2_can_fua,
-  .can_cache         = ext2_can_cache,
-  .get_size          = ext2_get_size,
-  .pread             = ext2_pread,
-  .pwrite            = ext2_pwrite,
-  .flush             = ext2_flush,
+  .name               = "ext2",
+  .longname           = "nbdkit ext2 filter",
+  .load               = ext2_load,
+  .unload             = ext2_unload,
+  .config             = ext2_config,
+  .config_complete    = ext2_config_complete,
+  .config_help        = ext2_config_help,
+  .thread_model       = ext2_thread_model,
+  .open               = ext2_open,
+  .prepare            = ext2_prepare,
+  .close              = ext2_close,
+  .can_fua            = ext2_can_fua,
+  .can_cache          = ext2_can_cache,
+  .export_description = ext2_export_description,
+  .get_size           = ext2_get_size,
+  .pread              = ext2_pread,
+  .pwrite             = ext2_pwrite,
+  .flush              = ext2_flush,
 };

 NBDKIT_REGISTER_FILTER(filter)
diff --git a/filters/gzip/gzip.c b/filters/gzip/gzip.c
index 929260bf..833ea937 100644
--- a/filters/gzip/gzip.c
+++ b/filters/gzip/gzip.c
@@ -287,6 +287,21 @@ gzip_can_cache (struct nbdkit_next_ops *next_ops, void *nxdata,
   return NBDKIT_CACHE_EMULATE;
 }

+/* Description. */
+static const char *
+gzip_export_description (struct nbdkit_next_ops *next_ops, void *nxdata,
+                         void *handle)
+{
+  const char *base = next_ops->export_description (nxdata);
+  CLEANUP_FREE char *desc = NULL;
+
+  if (base) {
+    asprintf (&desc, "expansion of gzip-compressed image: %s", base);
+    return nbdkit_strdup_intern (desc);
+  }
+  return "expansion of gzip-compressed image";
+}
+
 /* Get the file size. */
 static int64_t
 gzip_get_size (struct nbdkit_next_ops *next_ops, void *nxdata,
@@ -339,18 +354,19 @@ gzip_pread (struct nbdkit_next_ops *next_ops, void *nxdata,
 }

 static struct nbdkit_filter filter = {
-  .name              = "gzip",
-  .longname          = "nbdkit gzip filter",
-  .unload            = gzip_unload,
-  .thread_model      = gzip_thread_model,
-  .open              = gzip_open,
-  .prepare           = gzip_prepare,
-  .can_write         = gzip_can_write,
-  .can_extents       = gzip_can_extents,
-  .can_cache         = gzip_can_cache,
-  .prepare           = gzip_prepare,
-  .get_size          = gzip_get_size,
-  .pread             = gzip_pread,
+  .name               = "gzip",
+  .longname           = "nbdkit gzip filter",
+  .unload             = gzip_unload,
+  .thread_model       = gzip_thread_model,
+  .open               = gzip_open,
+  .prepare            = gzip_prepare,
+  .can_write          = gzip_can_write,
+  .can_extents        = gzip_can_extents,
+  .can_cache          = gzip_can_cache,
+  .prepare            = gzip_prepare,
+  .export_description = gzip_export_description,
+  .get_size           = gzip_get_size,
+  .pread              = gzip_pread,
 };

 NBDKIT_REGISTER_FILTER(filter)
diff --git a/filters/partition/partition.c b/filters/partition/partition.c
index 849f0cc7..bb83da7b 100644
--- a/filters/partition/partition.c
+++ b/filters/partition/partition.c
@@ -37,6 +37,7 @@
 #include <stdint.h>
 #include <string.h>
 #include <inttypes.h>
+#include <assert.h>

 #include <nbdkit-filter.h>

@@ -83,6 +84,7 @@ partition_config_complete (nbdkit_next_config_complete *next, void *nxdata)
 struct handle {
   int64_t offset;
   int64_t range;
+  const char *type;
 };

 /* Open a connection. */
@@ -139,13 +141,17 @@ partition_prepare (struct nbdkit_next_ops *next_ops, void *nxdata,

   /* Is it GPT? */
   if (size >= 2 * 34 * SECTOR_SIZE &&
-      memcmp (&lba01[SECTOR_SIZE], "EFI PART", 8) == 0)
+      memcmp (&lba01[SECTOR_SIZE], "EFI PART", 8) == 0) {
     r = find_gpt_partition (next_ops, nxdata, size, &lba01[SECTOR_SIZE],
                             &h->offset, &h->range);
+    h->type = "GPT";
+  }
   /* Is it MBR? */
-  else if (lba01[0x1fe] == 0x55 && lba01[0x1ff] == 0xAA)
+  else if (lba01[0x1fe] == 0x55 && lba01[0x1ff] == 0xAA) {
     r = find_mbr_partition (next_ops, nxdata, size, lba01,
                             &h->offset, &h->range);
+    h->type = "MBR";
+  }
   else {
     nbdkit_error ("disk does not contain MBR or GPT partition table signature");
     r = -1;
@@ -168,6 +174,23 @@ partition_prepare (struct nbdkit_next_ops *next_ops, void *nxdata,
   return 0;
 }

+/* Description. */
+static const char *
+partition_export_description (struct nbdkit_next_ops *next_ops, void *nxdata,
+                              void *handle)
+{
+  struct handle *h = handle;
+  const char *base = next_ops->export_description (nxdata);
+  CLEANUP_FREE char *desc = NULL;
+
+  assert (h->type);
+  if (base)
+    asprintf (&desc, "partition %d of %s disk: %s", partnum, h->type, base);
+  else
+    asprintf (&desc, "partition %d of %s disk", partnum, h->type);
+  return nbdkit_strdup_intern (desc);
+}
+
 /* Get the file size. */
 static int64_t
 partition_get_size (struct nbdkit_next_ops *next_ops, void *nxdata,
@@ -266,21 +289,22 @@ partition_cache (struct nbdkit_next_ops *next_ops, void *nxdata,
 }

 static struct nbdkit_filter filter = {
-  .name              = "partition",
-  .longname          = "nbdkit partition filter",
-  .config            = partition_config,
-  .config_complete   = partition_config_complete,
-  .config_help       = partition_config_help,
-  .open              = partition_open,
-  .prepare           = partition_prepare,
-  .close             = partition_close,
-  .get_size          = partition_get_size,
-  .pread             = partition_pread,
-  .pwrite            = partition_pwrite,
-  .trim              = partition_trim,
-  .zero              = partition_zero,
-  .extents           = partition_extents,
-  .cache             = partition_cache,
+  .name               = "partition",
+  .longname           = "nbdkit partition filter",
+  .config             = partition_config,
+  .config_complete    = partition_config_complete,
+  .config_help        = partition_config_help,
+  .open               = partition_open,
+  .prepare            = partition_prepare,
+  .close              = partition_close,
+  .export_description = partition_export_description,
+  .get_size           = partition_get_size,
+  .pread              = partition_pread,
+  .pwrite             = partition_pwrite,
+  .trim               = partition_trim,
+  .zero               = partition_zero,
+  .extents            = partition_extents,
+  .cache              = partition_cache,
 };

 NBDKIT_REGISTER_FILTER(filter)
diff --git a/filters/tar/tar.c b/filters/tar/tar.c
index cb42b918..090a2144 100644
--- a/filters/tar/tar.c
+++ b/filters/tar/tar.c
@@ -295,6 +295,21 @@ tar_prepare (struct nbdkit_next_ops *next_ops, void *nxdata,
   return 0;
 }

+/* Description. */
+static const char *
+tar_export_description (struct nbdkit_next_ops *next_ops, void *nxdata,
+                        void *handle)
+{
+  const char *base = next_ops->export_description (nxdata);
+  CLEANUP_FREE char *desc = NULL;
+
+  if (base)
+    asprintf (&desc, "embedded %s from within tar file: %s", entry, base);
+  else
+    asprintf (&desc, "embedded %s from within tar file", entry);
+  return nbdkit_strdup_intern (desc);
+}
+
 /* Get the file size. */
 static int64_t
 tar_get_size (struct nbdkit_next_ops *next_ops, void *nxdata,
@@ -395,22 +410,23 @@ tar_cache (struct nbdkit_next_ops *next_ops, void *nxdata,
 }

 static struct nbdkit_filter filter = {
-  .name              = "tar",
-  .longname          = "nbdkit tar filter",
-  .config            = tar_config,
-  .config_complete   = tar_config_complete,
-  .config_help       = tar_config_help,
-  .thread_model      = tar_thread_model,
-  .open              = tar_open,
-  .close             = tar_close,
-  .prepare           = tar_prepare,
-  .get_size          = tar_get_size,
-  .pread             = tar_pread,
-  .pwrite            = tar_pwrite,
-  .trim              = tar_trim,
-  .zero              = tar_zero,
-  .extents           = tar_extents,
-  .cache             = tar_cache,
+  .name               = "tar",
+  .longname           = "nbdkit tar filter",
+  .config             = tar_config,
+  .config_complete    = tar_config_complete,
+  .config_help        = tar_config_help,
+  .thread_model       = tar_thread_model,
+  .open               = tar_open,
+  .close              = tar_close,
+  .prepare            = tar_prepare,
+  .export_description = tar_export_description,
+  .get_size           = tar_get_size,
+  .pread              = tar_pread,
+  .pwrite             = tar_pwrite,
+  .trim               = tar_trim,
+  .zero               = tar_zero,
+  .extents            = tar_extents,
+  .cache              = tar_cache,
 };

 NBDKIT_REGISTER_FILTER(filter)
diff --git a/filters/xz/xz.c b/filters/xz/xz.c
index 26cfa959..2aa8c893 100644
--- a/filters/xz/xz.c
+++ b/filters/xz/xz.c
@@ -47,6 +47,7 @@

 #include "xzfile.h"
 #include "blkcache.h"
+#include "cleanup.h"

 static uint64_t maxblock = 512 * 1024 * 1024;
 static uint32_t maxdepth = 8;
@@ -156,6 +157,21 @@ xz_prepare (struct nbdkit_next_ops *next_ops, void *nxdata, void *handle,
   return 0;
 }

+/* Description. */
+static const char *
+xz_export_description (struct nbdkit_next_ops *next_ops, void *nxdata,
+                       void *handle)
+{
+  const char *base = next_ops->export_description (nxdata);
+  CLEANUP_FREE char *desc = NULL;
+
+  if (base) {
+    asprintf (&desc, "expansion of xz-compressed image: %s", base);
+    return nbdkit_strdup_intern (desc);
+  }
+  return "expansion of xz-compressed image";
+}
+
 /* Get the file size. */
 static int64_t
 xz_get_size (struct nbdkit_next_ops *next_ops, void *nxdata, void *handle)
@@ -245,19 +261,20 @@ static int xz_thread_model (void)
 }

 static struct nbdkit_filter filter = {
-  .name              = "xz",
-  .longname          = "nbdkit XZ filter",
-  .config            = xz_config,
-  .config_help       = xz_config_help,
-  .thread_model      = xz_thread_model,
-  .open              = xz_open,
-  .close             = xz_close,
-  .prepare           = xz_prepare,
-  .get_size          = xz_get_size,
-  .can_write         = xz_can_write,
-  .can_extents       = xz_can_extents,
-  .can_cache         = xz_can_cache,
-  .pread             = xz_pread,
+  .name               = "xz",
+  .longname           = "nbdkit XZ filter",
+  .config             = xz_config,
+  .config_help        = xz_config_help,
+  .thread_model       = xz_thread_model,
+  .open               = xz_open,
+  .close              = xz_close,
+  .prepare            = xz_prepare,
+  .export_description = xz_export_description,
+  .get_size           = xz_get_size,
+  .can_write          = xz_can_write,
+  .can_extents        = xz_can_extents,
+  .can_cache          = xz_can_cache,
+  .pread              = xz_pread,
 };

 NBDKIT_REGISTER_FILTER(filter)
-- 
2.28.0




More information about the Libguestfs mailing list