[Libguestfs] [PATCH nbdkit v2 2/3] iso: Implement this plugin using fileops (read-only).

Richard W.M. Jones
Thu, 09 Apr 2020 08:36:30 -0000

The plugin should now support pre-fetch and extents, although most ISO
images will be non-sparse so extents probably isn't that useful.
---
 plugins/iso/Makefile.am |  4 +-
 plugins/iso/iso.c       | 99 +++++++++++++++++++----------------------
 2 files changed, 48 insertions(+), 55 deletions(-)

diff --git a/plugins/iso/Makefile.am b/plugins/iso/Makefile.am
index a0fd337a..44ecbc8a 100644
--- a/plugins/iso/Makefile.am
+++ b/plugins/iso/Makefile.am
@@ -43,8 +43,9 @@ nbdkit_iso_plugin_la_SOURCES = \
 	$(NULL)

 nbdkit_iso_plugin_la_CPPFLAGS = \
-	-I$(top_srcdir)/common/utils \
 	-I$(top_srcdir)/include \
+	-I$(top_srcdir)/common/fileops \
+	-I$(top_srcdir)/common/utils \
 	-I. \
 	$(NULL)
 nbdkit_iso_plugin_la_CFLAGS = $(WARNINGS_CFLAGS)
@@ -53,6 +54,7 @@ nbdkit_iso_plugin_la_LDFLAGS = \
 	-Wl,--version-script=$(top_srcdir)/plugins/plugins.syms \
 	$(NULL)
 nbdkit_iso_plugin_la_LIBADD = \
+	$(top_builddir)/common/fileops/libfileops.la \
 	$(top_builddir)/common/utils/libutils.la \
 	$(NULL)

diff --git a/plugins/iso/iso.c b/plugins/iso/iso.c
index 92554ace..b8a4b5e3 100644
--- a/plugins/iso/iso.c
+++ b/plugins/iso/iso.c
@@ -39,9 +39,11 @@
 #include <sys/types.h>
 #include <sys/stat.h>

+#define NBDKIT_API_VERSION 2
 #include <nbdkit-plugin.h>

 #include "cleanup.h"
+#include "fileops.h"
 #include "utils.h"

 /* List of directories parsed from the command line. */
@@ -57,7 +59,7 @@ static const char *isoprog = ISOPROG;
 static const char *params = NULL;

 /* The temporary ISO. */
-static int fd = -1;
+static int iso_fd = -1;

 /* Construct the temporary ISO. */
 static int
@@ -80,8 +82,8 @@ make_iso (void)
     return -1;
   }

-  fd = mkstemp (template);
-  if (fd == -1) {
+  iso_fd = mkstemp (template);
+  if (iso_fd == -1) {
     nbdkit_error ("mkstemp: %s: %m", template);
     return -1;
   }
@@ -103,7 +105,7 @@ make_iso (void)
     shell_quote (dirs[i], fp);
   }
   /* Redirect output to the temporary file. */
-  fprintf (fp, " >&%d", fd);
+  fprintf (fp, " >&%d", iso_fd);

   if (fclose (fp) == EOF) {
     nbdkit_error ("memstream failed: %m");
@@ -128,8 +130,8 @@ iso_unload (void)
     free (dirs[i]);
   free (dirs);

-  if (fd >= 0)
-    close (fd);
+  if (iso_fd >= 0)
+    close (iso_fd);
 }

 static int
@@ -193,25 +195,43 @@ iso_get_ready (void)
 static void *
 iso_open (int readonly)
 {
-  return NBDKIT_HANDLE_NOT_NEEDED;
+  struct fileops *fops;
+  int fd;
+
+  fops = malloc (sizeof *fops);
+  if (fops == NULL) {
+    nbdkit_error ("malloc: %m");
+    return NULL;
+  }
+
+  /* Copy the fd because fileops needs to have its own file descriptor. */
+  fd = dup (iso_fd);
+  if (fd == -1) {
+    nbdkit_error ("dup: %m");
+    free (fops);
+    return NULL;
+  }
+
+  if (init_fileops (fd, fops) == -1) {
+    free (fops);
+    return NULL;
+  }
+
+  return fops;
+}
+
+/* Free up the per-connection handle. */
+static void
+iso_close (void *handle)
+{
+  struct fileops *fops = handle;
+
+  close_fileops (fops);
+  free (fops);
 }

 #define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL

-/* Get the file size. */
-static int64_t
-iso_get_size (void *handle)
-{
-  struct stat statbuf;
-
-  if (fstat (fd, &statbuf) == -1) {
-    nbdkit_error ("fstat: %m");
-    return -1;
-  }
-
-  return statbuf.st_size;
-}
-
 /* Serves the same data over multiple connections. */
 static int
 iso_can_multi_conn (void *handle)
@@ -219,35 +239,6 @@ iso_can_multi_conn (void *handle)
   return 1;
 }

-static int
-iso_can_cache (void *handle)
-{
-  /* Let nbdkit call pread to populate the file system cache. */
-  return NBDKIT_CACHE_EMULATE;
-}
-
-/* Read data from the file. */
-static int
-iso_pread (void *handle, void *buf, uint32_t count, uint64_t offset)
-{
-  while (count > 0) {
-    ssize_t r = pread (fd, buf, count, offset);
-    if (r == -1) {
-      nbdkit_error ("pread: %m");
-      return -1;
-    }
-    if (r == 0) {
-      nbdkit_error ("pread: unexpected end of file");
-      return -1;
-    }
-    buf += r;
-    count -= r;
-    offset += r;
-  }
-
-  return 0;
-}
-
 static struct nbdkit_plugin plugin = {
   .name              = "iso",
   .longname          = "nbdkit iso plugin",
@@ -259,11 +250,11 @@ static struct nbdkit_plugin plugin = {
   .magic_config_key  = "dir",
   .get_ready         = iso_get_ready,
   .open              = iso_open,
-  .get_size          = iso_get_size,
+  .close             = iso_close,
   .can_multi_conn    = iso_can_multi_conn,
-  .can_cache         = iso_can_cache,
-  .pread             = iso_pread,
-  .errno_is_preserved = 1,
+
+  /* This bulk of this plugin is implemented in common/fileops/fileops.c */
+  FILEOPS_READ_ONLY_CALLBACKS
 };

 NBDKIT_REGISTER_PLUGIN(plugin)
--
2.25.0