[Libguestfs] [nbdkit PATCH 2/9] server: Consolidate common backend tasks into new backend.c

Eric Blake eblake at redhat.com
Fri Aug 30 03:08:22 UTC 2019


Both plugin.c and filter.c add the same three fields on top of struct
backend, and use very similar code in initializing them.  Let's stop
the duplication, by moving those three fields into struct backend, and
creating a new backend.c for manipulating them.  In turn, we can drop
the backend->name() accessor in favor of just directly accessing the
name field.  This is a net reduction in lines of code (remember, the
diffstat is also counting comment additions, including license
boilerplate).

Signed-off-by: Eric Blake <eblake at redhat.com>
---
 server/internal.h  |  21 +++++++-
 server/Makefile.am |   3 +-
 server/backend.c   | 121 ++++++++++++++++++++++++++++++++++++++++++
 server/filters.c   | 129 +++++++++++----------------------------------
 server/main.c      |   2 +-
 server/plugins.c   | 102 ++++++++---------------------------
 6 files changed, 195 insertions(+), 183 deletions(-)
 create mode 100644 server/backend.c

diff --git a/server/internal.h b/server/internal.h
index a9692bbc..3af6ca16 100644
--- a/server/internal.h
+++ b/server/internal.h
@@ -242,6 +242,7 @@ extern void log_stderr_verror (const char *fs, va_list args)
 extern void log_syslog_verror (const char *fs, va_list args)
   __attribute__((__format__ (printf, 1, 0)));

+/* backend.c */
 struct backend {
   /* Next filter or plugin in the chain.  This is always NULL for
    * plugins and never NULL for filters.
@@ -255,9 +256,18 @@ struct backend {
    */
   size_t i;

+  /* A copy of the backend name that survives a dlclose. */
+  char *name;
+
+  /* The file the backend was loaded from. */
+  char *filename;
+
+  /* The dlopen handle for the backend. */
+  void *dl;
+
+  /* Backend callbacks. All are required. */
   void (*free) (struct backend *);
   int (*thread_model) (struct backend *);
-  const char *(*name) (struct backend *);
   const char *(*plugin_name) (struct backend *);
   void (*usage) (struct backend *);
   const char *(*version) (struct backend *);
@@ -298,6 +308,15 @@ struct backend {
                 uint64_t offset, uint32_t flags, int *err);
 };

+extern void backend_init (struct backend *b, struct backend *next, size_t index,
+                          const char *filename, void *dl, const char *type)
+  __attribute__((__nonnull__ (1, 4, 5, 6)));
+extern void backend_set_name (struct backend *b, const char *name,
+                              const char *type)
+  __attribute__((__nonnull__ (1, 3)));
+extern void backend_unload (struct backend *b, void (*unload) (void))
+  __attribute__((__nonnull__ (1)));
+
 /* plugins.c */
 extern struct backend *plugin_register (size_t index, const char *filename,
                                         void *dl, struct nbdkit_plugin *(*plugin_init) (void))
diff --git a/server/Makefile.am b/server/Makefile.am
index 29674866..a0417639 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -1,5 +1,5 @@
 # nbdkit
-# Copyright (C) 2013-2018 Red Hat Inc.
+# Copyright (C) 2013-2019 Red Hat Inc.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are
@@ -36,6 +36,7 @@ EXTRA_DIST = nbdkit.syms
 sbin_PROGRAMS = nbdkit

 nbdkit_SOURCES = \
+	backend.c \
 	background.c \
 	captive.c \
 	connections.c \
diff --git a/server/backend.c b/server/backend.c
new file mode 100644
index 00000000..c7ee2d05
--- /dev/null
+++ b/server/backend.c
@@ -0,0 +1,121 @@
+/* nbdkit
+ * Copyright (C) 2013-2019 Red Hat Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Red Hat nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <ctype.h>
+#include <dlfcn.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "internal.h"
+
+/* Helpers for registering a new backend. */
+
+void
+backend_init (struct backend *b, struct backend *next, size_t index,
+              const char *filename, void *dl, const char *type)
+{
+  b->next = next;
+  b->i = index;
+  b->filename = strdup (filename);
+  if (b->filename == NULL) {
+    perror ("strdup");
+    exit (EXIT_FAILURE);
+  }
+  b->dl = dl;
+
+  debug ("registering %s %s", type, filename);
+}
+
+void
+backend_set_name (struct backend *b, const char *name, const char *type)
+{
+  size_t i, len;
+
+  /* name is required. */
+  if (name == NULL) {
+    fprintf (stderr, "%s: %s: %s must have a .name field\n",
+             program_name, b->filename, type);
+    exit (EXIT_FAILURE);
+  }
+
+  len = strlen (name);
+  if (len == 0) {
+    fprintf (stderr, "%s: %s: %s.name field must not be empty\n",
+             program_name, b->filename, type);
+    exit (EXIT_FAILURE);
+  }
+  for (i = 0; i < len; ++i) {
+    unsigned char c = name[i];
+
+    if (!(isascii (c) && isalnum (c))) {
+      fprintf (stderr,
+               "%s: %s: %s.name ('%s') field "
+               "must contain only ASCII alphanumeric characters\n",
+               program_name, b->filename, type, name);
+      exit (EXIT_FAILURE);
+    }
+  }
+
+  /* Copy the module's name into local storage, so that name
+   * survives past unload.
+   */
+  b->name = strdup (name);
+  if (b->name == NULL) {
+    perror ("strdup");
+    exit (EXIT_FAILURE);
+  }
+
+  debug ("registered %s %s (name %s)", type, b->filename, b->name);
+}
+
+void
+backend_unload (struct backend *b, void (*unload) (void))
+{
+  /* Acquiring this lock prevents any other backend callbacks from running
+   * simultaneously.
+   */
+  lock_unload ();
+
+  debug ("%s: unload", b->name);
+  if (unload)
+    unload ();
+
+  if (DO_DLCLOSE)
+    dlclose (b->dl);
+  free (b->filename);
+
+  unlock_unload ();
+
+  free (b->name);
+}
diff --git a/server/filters.c b/server/filters.c
index 287c8747..1f76bf61 100644
--- a/server/filters.c
+++ b/server/filters.c
@@ -48,9 +48,6 @@
  */
 struct backend_filter {
   struct backend backend;
-  char *name;                   /* copy of filter.name */
-  char *filename;
-  void *dl;
   struct nbdkit_filter filter;
 };

@@ -70,22 +67,7 @@ filter_free (struct backend *b)

   b->next->free (b->next);

-  /* Acquiring this lock prevents any filter callbacks from running
-   * simultaneously.
-   */
-  lock_unload ();
-
-  debug ("%s: unload", f->name);
-  if (f->filter.unload)
-    f->filter.unload ();
-
-  if (DO_DLCLOSE)
-    dlclose (f->dl);
-  free (f->filename);
-
-  unlock_unload ();
-
-  free (f->name);
+  backend_unload (b, f->filter.unload);
   free (f);
 }

@@ -117,14 +99,6 @@ plugin_name (struct backend *b)
   return b->next->plugin_name (b->next);
 }

-static const char *
-filter_name (struct backend *b)
-{
-  struct backend_filter *f = container_of (b, struct backend_filter, backend);
-
-  return f->name;
-}
-
 static const char *
 filter_version (struct backend *b)
 {
@@ -139,11 +113,11 @@ filter_usage (struct backend *b)
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
   const char *p;

-  printf ("filter: %s", f->name);
+  printf ("filter: %s", b->name);
   if (f->filter.longname)
     printf (" (%s)", f->filter.longname);
   printf ("\n");
-  printf ("(%s)\n", f->filename);
+  printf ("(%s)\n", b->filename);
   if (f->filter.description) {
     printf ("%s", f->filter.description);
     if ((p = strrchr (f->filter.description, '\n')) == NULL || p[1])
@@ -176,7 +150,7 @@ filter_config (struct backend *b, const char *key, const char *value)
   struct backend_filter *f = container_of (b, struct backend_filter, backend);

   debug ("%s: config key=%s, value=%s",
-         f->name, key, value);
+         b->name, key, value);

   if (f->filter.config) {
     if (f->filter.config (next_config, b->next, key, value) == -1)
@@ -199,7 +173,7 @@ filter_config_complete (struct backend *b)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);

-  debug ("%s: config_complete", f->name);
+  debug ("%s: config_complete", b->name);

   if (f->filter.config_complete) {
     if (f->filter.config_complete (next_config_complete, b->next) == -1)
@@ -233,7 +207,7 @@ filter_open (struct backend *b, struct connection *conn, int readonly)
   struct b_conn nxdata = { .b = b->next, .conn = conn };
   void *handle;

-  debug ("%s: open readonly=%d", f->name, readonly);
+  debug ("%s: open readonly=%d", b->name, readonly);

   if (f->filter.open) {
     handle = f->filter.open (next_open, &nxdata, readonly);
@@ -252,7 +226,7 @@ filter_close (struct backend *b, struct connection *conn)
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
   void *handle = connection_get_handle (conn, b->i);

-  debug ("%s: close", f->name);
+  debug ("%s: close", b->name);

   if (f->filter.close)
     f->filter.close (handle);
@@ -456,7 +430,7 @@ filter_prepare (struct backend *b, struct connection *conn)
   void *handle = connection_get_handle (conn, b->i);
   struct b_conn nxdata = { .b = b->next, .conn = conn };

-  debug ("%s: prepare", f->name);
+  debug ("%s: prepare", b->name);

   /* Call these in order starting from the filter closest to the
    * plugin.
@@ -478,7 +452,7 @@ filter_finalize (struct backend *b, struct connection *conn)
   void *handle = connection_get_handle (conn, b->i);
   struct b_conn nxdata = { .b = b->next, .conn = conn };

-  debug ("%s: finalize", f->name);
+  debug ("%s: finalize", b->name);

   /* Call these in reverse order to .prepare above, starting from the
    * filter furthest away from the plugin.
@@ -497,7 +471,7 @@ filter_get_size (struct backend *b, struct connection *conn)
   void *handle = connection_get_handle (conn, b->i);
   struct b_conn nxdata = { .b = b->next, .conn = conn };

-  debug ("%s: get_size", f->name);
+  debug ("%s: get_size", b->name);

   if (f->filter.get_size)
     return f->filter.get_size (&next_ops, &nxdata, handle);
@@ -512,7 +486,7 @@ filter_can_write (struct backend *b, struct connection *conn)
   void *handle = connection_get_handle (conn, b->i);
   struct b_conn nxdata = { .b = b->next, .conn = conn };

-  debug ("%s: can_write", f->name);
+  debug ("%s: can_write", b->name);

   if (f->filter.can_write)
     return f->filter.can_write (&next_ops, &nxdata, handle);
@@ -527,7 +501,7 @@ filter_can_flush (struct backend *b, struct connection *conn)
   void *handle = connection_get_handle (conn, b->i);
   struct b_conn nxdata = { .b = b->next, .conn = conn };

-  debug ("%s: can_flush", f->name);
+  debug ("%s: can_flush", b->name);

   if (f->filter.can_flush)
     return f->filter.can_flush (&next_ops, &nxdata, handle);
@@ -542,7 +516,7 @@ filter_is_rotational (struct backend *b, struct connection *conn)
   void *handle = connection_get_handle (conn, b->i);
   struct b_conn nxdata = { .b = b->next, .conn = conn };

-  debug ("%s: is_rotational", f->name);
+  debug ("%s: is_rotational", b->name);

   if (f->filter.is_rotational)
     return f->filter.is_rotational (&next_ops, &nxdata, handle);
@@ -557,7 +531,7 @@ filter_can_trim (struct backend *b, struct connection *conn)
   void *handle = connection_get_handle (conn, b->i);
   struct b_conn nxdata = { .b = b->next, .conn = conn };

-  debug ("%s: can_trim", f->name);
+  debug ("%s: can_trim", b->name);

   if (f->filter.can_trim)
     return f->filter.can_trim (&next_ops, &nxdata, handle);
@@ -572,7 +546,7 @@ filter_can_zero (struct backend *b, struct connection *conn)
   void *handle = connection_get_handle (conn, b->i);
   struct b_conn nxdata = { .b = b->next, .conn = conn };

-  debug ("%s: can_zero", f->name);
+  debug ("%s: can_zero", b->name);

   if (f->filter.can_zero)
     return f->filter.can_zero (&next_ops, &nxdata, handle);
@@ -587,7 +561,7 @@ filter_can_extents (struct backend *b, struct connection *conn)
   void *handle = connection_get_handle (conn, b->i);
   struct b_conn nxdata = { .b = b->next, .conn = conn };

-  debug ("%s: can_extents", f->name);
+  debug ("%s: can_extents", b->name);

   if (f->filter.can_extents)
     return f->filter.can_extents (&next_ops, &nxdata, handle);
@@ -602,7 +576,7 @@ filter_can_fua (struct backend *b, struct connection *conn)
   void *handle = connection_get_handle (conn, b->i);
   struct b_conn nxdata = { .b = b->next, .conn = conn };

-  debug ("%s: can_fua", f->name);
+  debug ("%s: can_fua", b->name);

   if (f->filter.can_fua)
     return f->filter.can_fua (&next_ops, &nxdata, handle);
@@ -617,7 +591,7 @@ filter_can_multi_conn (struct backend *b, struct connection *conn)
   void *handle = connection_get_handle (conn, b->i);
   struct b_conn nxdata = { .b = b->next, .conn = conn };

-  debug ("%s: can_multi_conn", f->name);
+  debug ("%s: can_multi_conn", b->name);

   if (f->filter.can_multi_conn)
     return f->filter.can_multi_conn (&next_ops, &nxdata, handle);
@@ -632,7 +606,7 @@ filter_can_cache (struct backend *b, struct connection *conn)
   void *handle = connection_get_handle (conn, b->i);
   struct b_conn nxdata = { .b = b->next, .conn = conn };

-  debug ("%s: can_cache", f->name);
+  debug ("%s: can_cache", b->name);

   if (f->filter.can_cache)
     return f->filter.can_cache (&next_ops, &nxdata, handle);
@@ -652,7 +626,7 @@ filter_pread (struct backend *b, struct connection *conn,
   assert (flags == 0);

   debug ("%s: pread count=%" PRIu32 " offset=%" PRIu64 " flags=0x%" PRIx32,
-         f->name, count, offset, flags);
+         b->name, count, offset, flags);

   if (f->filter.pread)
     return f->filter.pread (&next_ops, &nxdata, handle,
@@ -673,7 +647,7 @@ filter_pwrite (struct backend *b, struct connection *conn,
   assert (!(flags & ~NBDKIT_FLAG_FUA));

   debug ("%s: pwrite count=%" PRIu32 " offset=%" PRIu64 " flags=0x%" PRIx32,
-         f->name, count, offset, flags);
+         b->name, count, offset, flags);

   if (f->filter.pwrite)
     return f->filter.pwrite (&next_ops, &nxdata, handle,
@@ -692,7 +666,7 @@ filter_flush (struct backend *b, struct connection *conn, uint32_t flags,

   assert (flags == 0);

-  debug ("%s: flush flags=0x%" PRIx32, f->name, flags);
+  debug ("%s: flush flags=0x%" PRIx32, b->name, flags);

   if (f->filter.flush)
     return f->filter.flush (&next_ops, &nxdata, handle, flags, err);
@@ -712,7 +686,7 @@ filter_trim (struct backend *b, struct connection *conn,
   assert (flags == 0);

   debug ("%s: trim count=%" PRIu32 " offset=%" PRIu64 " flags=0x%" PRIx32,
-         f->name, count, offset, flags);
+         b->name, count, offset, flags);

   if (f->filter.trim)
     return f->filter.trim (&next_ops, &nxdata, handle, count, offset, flags,
@@ -732,7 +706,7 @@ filter_zero (struct backend *b, struct connection *conn,
   assert (!(flags & ~(NBDKIT_FLAG_MAY_TRIM | NBDKIT_FLAG_FUA)));

   debug ("%s: zero count=%" PRIu32 " offset=%" PRIu64 " flags=0x%" PRIx32,
-         f->name, count, offset, flags);
+         b->name, count, offset, flags);

   if (f->filter.zero)
     return f->filter.zero (&next_ops, &nxdata, handle,
@@ -753,7 +727,7 @@ filter_extents (struct backend *b, struct connection *conn,
   assert (!(flags & ~NBDKIT_FLAG_REQ_ONE));

   debug ("%s: extents count=%" PRIu32 " offset=%" PRIu64 " flags=0x%" PRIx32,
-         f->name, count, offset, flags);
+         b->name, count, offset, flags);

   if (f->filter.extents)
     return f->filter.extents (&next_ops, &nxdata, handle,
@@ -776,7 +750,7 @@ filter_cache (struct backend *b, struct connection *conn,
   assert (flags == 0);

   debug ("%s: cache count=%" PRIu32 " offset=%" PRIu64 " flags=0x%" PRIx32,
-         f->name, count, offset, flags);
+         b->name, count, offset, flags);

   if (f->filter.cache)
     return f->filter.cache (&next_ops, &nxdata, handle,
@@ -788,7 +762,6 @@ filter_cache (struct backend *b, struct connection *conn,
 static struct backend filter_functions = {
   .free = filter_free,
   .thread_model = filter_thread_model,
-  .name = filter_name,
   .plugin_name = plugin_name,
   .usage = filter_usage,
   .version = filter_version,
@@ -826,7 +799,6 @@ filter_register (struct backend *next, size_t index, const char *filename,
 {
   struct backend_filter *f;
   const struct nbdkit_filter *filter;
-  size_t i, len;
   union overlay {
     const char *str;
     unsigned int api;
@@ -834,19 +806,12 @@ filter_register (struct backend *next, size_t index, const char *filename,

   f = calloc (1, sizeof *f);
   if (f == NULL) {
-  out_of_memory:
     perror ("strdup");
     exit (EXIT_FAILURE);
   }

   f->backend = filter_functions;
-  f->backend.next = next;
-  f->backend.i = index;
-  f->filename = strdup (filename);
-  if (f->filename == NULL) goto out_of_memory;
-  f->dl = dl;
-
-  debug ("registering filter %s", filename);
+  backend_init (&f->backend, next, index, filename, dl, "filter");

   /* Call the initialization function which returns the address of the
    * filter's own 'struct nbdkit_filter'.
@@ -888,47 +853,13 @@ filter_register (struct backend *next, size_t index, const char *filename,

   f->filter = *filter;

-  /* Only filter.name is required. */
-  if (f->filter.name == NULL) {
-    fprintf (stderr, "%s: %s: filter must have a .name field\n",
-             program_name, filename);
-    exit (EXIT_FAILURE);
-  }
-
-  len = strlen (f->filter.name);
-  if (len == 0) {
-    fprintf (stderr, "%s: %s: filter.name field must not be empty\n",
-             program_name, filename);
-    exit (EXIT_FAILURE);
-  }
-  for (i = 0; i < len; ++i) {
-    if (!((f->filter.name[i] >= '0' && f->filter.name[i] <= '9') ||
-          (f->filter.name[i] >= 'a' && f->filter.name[i] <= 'z') ||
-          (f->filter.name[i] >= 'A' && f->filter.name[i] <= 'Z'))) {
-      fprintf (stderr,
-               "%s: %s: filter.name ('%s') field "
-               "must contain only ASCII alphanumeric characters\n",
-               program_name, filename, f->filter.name);
-      exit (EXIT_FAILURE);
-    }
-  }
-
-  /* Copy the module's name into local storage, so that filter.name
-   * survives past unload.
-   */
-  f->name = strdup (f->filter.name);
-  if (f->name == NULL) {
-    perror ("strdup");
-    exit (EXIT_FAILURE);
-  }
-
-  debug ("registered filter %s (name %s)", f->filename, f->name);
+  backend_set_name (&f->backend, f->filter.name, "filter");

   /* Set debug flags before calling load. */
-  set_debug_flags (dl, f->name);
+  set_debug_flags (dl, f->backend.name);

   /* Call the on-load callback if it exists. */
-  debug ("%s: load", f->name);
+  debug ("%s: load", f->backend.name);
   if (f->filter.load)
     f->filter.load ();

diff --git a/server/main.c b/server/main.c
index 124e19b7..6999818c 100644
--- a/server/main.c
+++ b/server/main.c
@@ -602,7 +602,7 @@ main (int argc, char *argv[])

     display_version ();
     for_each_backend (b) {
-      printf ("%s", b->name (b));
+      printf ("%s", b->name);
       if ((v = b->version (b)) != NULL)
         printf (" %s", v);
       printf ("\n");
diff --git a/server/plugins.c b/server/plugins.c
index 34cc3cb5..0f70ede0 100644
--- a/server/plugins.c
+++ b/server/plugins.c
@@ -54,9 +54,6 @@
  */
 struct backend_plugin {
   struct backend backend;
-  char *name;                   /* copy of plugin.name */
-  char *filename;
-  void *dl;
   struct nbdkit_plugin plugin;
 };

@@ -65,22 +62,7 @@ plugin_free (struct backend *b)
 {
   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);

-  /* Acquiring this lock prevents any plugin callbacks from running
-   * simultaneously.
-   */
-  lock_unload ();
-
-  debug ("%s: unload", p->name);
-  if (p->plugin.unload)
-    p->plugin.unload ();
-
-  if (DO_DLCLOSE)
-    dlclose (p->dl);
-  free (p->filename);
-
-  unlock_unload ();
-
-  free (p->name);
+  backend_unload (b, p->plugin.unload);
   free (p);
 }

@@ -113,9 +95,7 @@ plugin_thread_model (struct backend *b)
 static const char *
 plugin_name (struct backend *b)
 {
-  struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
-
-  return p->name;
+  return b->name;
 }

 static void
@@ -124,11 +104,11 @@ plugin_usage (struct backend *b)
   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
   const char *t;

-  printf ("plugin: %s", p->name);
+  printf ("plugin: %s", b->name);
   if (p->plugin.longname)
     printf (" (%s)", p->plugin.longname);
   printf ("\n");
-  printf ("(%s)\n", p->filename);
+  printf ("(%s)\n", b->filename);
   if (p->plugin.description) {
     printf ("%s", p->plugin.description);
     if ((t = strrchr (p->plugin.description, '\n')) == NULL || t[1])
@@ -156,11 +136,11 @@ plugin_dump_fields (struct backend *b)
   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
   char *path;

-  path = nbdkit_realpath (p->filename);
+  path = nbdkit_realpath (b->filename);
   printf ("path=%s\n", path);
   free (path);

-  printf ("name=%s\n", p->name);
+  printf ("name=%s\n", b->name);
   if (p->plugin.version)
     printf ("version=%s\n", p->plugin.version);

@@ -220,14 +200,14 @@ plugin_config (struct backend *b, const char *key, const char *value)
 {
   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);

-  debug ("%s: config key=%s, value=%s", p->name, key, value);
+  debug ("%s: config key=%s, value=%s", b->name, key, value);

   if (p->plugin.config == NULL) {
     fprintf (stderr,
              "%s: %s: this plugin does not need command line configuration\n"
              "Try using: %s --help %s\n",
-             program_name, p->filename,
-             program_name, p->filename);
+             program_name, b->filename,
+             program_name, b->filename);
     exit (EXIT_FAILURE);
   }

@@ -240,7 +220,7 @@ plugin_config_complete (struct backend *b)
 {
   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);

-  debug ("%s: config_complete", p->name);
+  debug ("%s: config_complete", b->name);

   if (!p->plugin.config_complete)
     return;
@@ -266,7 +246,7 @@ plugin_open (struct backend *b, struct connection *conn, int readonly)
   assert (connection_get_handle (conn, 0) == NULL);
   assert (p->plugin.open != NULL);

-  debug ("%s: open readonly=%d", p->name, readonly);
+  debug ("%s: open readonly=%d", b->name, readonly);

   handle = p->plugin.open (readonly);
   if (!handle)
@@ -744,7 +724,6 @@ plugin_cache (struct backend *b, struct connection *conn,
 static struct backend plugin_functions = {
   .free = plugin_free,
   .thread_model = plugin_thread_model,
-  .name = plugin_name,
   .plugin_name = plugin_name,
   .usage = plugin_usage,
   .version = plugin_version,
@@ -782,23 +761,16 @@ plugin_register (size_t index, const char *filename,
 {
   struct backend_plugin *p;
   const struct nbdkit_plugin *plugin;
-  size_t i, len, size;
+  size_t size;

   p = malloc (sizeof *p);
   if (p == NULL) {
-  out_of_memory:
     perror ("strdup");
     exit (EXIT_FAILURE);
   }

   p->backend = plugin_functions;
-  p->backend.next = NULL;
-  p->backend.i = index;
-  p->filename = strdup (filename);
-  if (p->filename == NULL) goto out_of_memory;
-  p->dl = dl;
-
-  debug ("registering plugin %s", p->filename);
+  backend_init (&p->backend, NULL, index, filename, dl, "plugin");

   /* Call the initialization function which returns the address of the
    * plugin's own 'struct nbdkit_plugin'.
@@ -806,7 +778,7 @@ plugin_register (size_t index, const char *filename,
   plugin = plugin_init ();
   if (!plugin) {
     fprintf (stderr, "%s: %s: plugin registration function failed\n",
-             program_name, p->filename);
+             program_name, filename);
     exit (EXIT_FAILURE);
   }

@@ -815,7 +787,7 @@ plugin_register (size_t index, const char *filename,
     fprintf (stderr,
              "%s: %s: plugin is incompatible with this version of nbdkit "
              "(_api_version = %d)\n",
-             program_name, p->filename, plugin->_api_version);
+             program_name, filename, plugin->_api_version);
     exit (EXIT_FAILURE);
   }

@@ -833,61 +805,29 @@ plugin_register (size_t index, const char *filename,
   /* Check for the minimum fields which must exist in the
    * plugin struct.
    */
-  if (p->plugin.name == NULL) {
-    fprintf (stderr, "%s: %s: plugin must have a .name field\n",
-             program_name, p->filename);
-    exit (EXIT_FAILURE);
-  }
   if (p->plugin.open == NULL) {
     fprintf (stderr, "%s: %s: plugin must have a .open callback\n",
-             program_name, p->filename);
+             program_name, filename);
     exit (EXIT_FAILURE);
   }
   if (p->plugin.get_size == NULL) {
     fprintf (stderr, "%s: %s: plugin must have a .get_size callback\n",
-             program_name, p->filename);
+             program_name, filename);
     exit (EXIT_FAILURE);
   }
   if (p->plugin.pread == NULL && p->plugin._pread_old == NULL) {
     fprintf (stderr, "%s: %s: plugin must have a .pread callback\n",
-             program_name, p->filename);
+             program_name, filename);
     exit (EXIT_FAILURE);
   }

-  len = strlen (p->plugin.name);
-  if (len == 0) {
-    fprintf (stderr, "%s: %s: plugin.name field must not be empty\n",
-             program_name, p->filename);
-    exit (EXIT_FAILURE);
-  }
-  for (i = 0; i < len; ++i) {
-    if (!((p->plugin.name[i] >= '0' && p->plugin.name[i] <= '9') ||
-          (p->plugin.name[i] >= 'a' && p->plugin.name[i] <= 'z') ||
-          (p->plugin.name[i] >= 'A' && p->plugin.name[i] <= 'Z'))) {
-      fprintf (stderr,
-               "%s: %s: plugin.name ('%s') field "
-               "must contain only ASCII alphanumeric characters\n",
-               program_name, p->filename, p->plugin.name);
-      exit (EXIT_FAILURE);
-    }
-  }
-
-  /* Copy the module's name into local storage, so that plugin.name
-   * survives past unload.
-   */
-  p->name = strdup (p->plugin.name);
-  if (p->name == NULL) {
-    perror ("strdup");
-    exit (EXIT_FAILURE);
-  }
-
-  debug ("registered plugin %s (name %s)", p->filename, p->name);
+  backend_set_name (&p->backend, p->plugin.name, "plugin");

   /* Set debug flags before calling load. */
-  set_debug_flags (dl, p->name);
+  set_debug_flags (dl, p->backend.name);

   /* Call the on-load callback if it exists. */
-  debug ("%s: load", p->name);
+  debug ("%s: load", p->backend.name);
   if (p->plugin.load)
     p->plugin.load ();

-- 
2.21.0




More information about the Libguestfs mailing list