[Libguestfs] [nbdkit PATCH v2 1/5] server: Add exports list functions

Eric Blake eblake at redhat.com
Thu Aug 6 02:25:18 UTC 2020


Add exports.c for manipulating an exports list, borrowing heavily from
similar code in managing an extents list.  The new functions are
exposed through nbdkit-filter.h, because filters will eventually need
a way to grab the export list from a plugin, but actually wiring that
up will be in a later patch.  For now, we enforce string length but
not strict UTF-8 content.

Signed-off-by: Eric Blake <eblake at redhat.com>
---
 include/nbdkit-common.h       |   4 +
 include/nbdkit-filter.h       |  12 +++
 server/Makefile.am            |   2 +
 common/utils/cleanup.h        |   3 +
 server/exports.c              | 149 ++++++++++++++++++++++++++++++++++
 server/nbdkit.syms            |   5 ++
 common/utils/cleanup-nbdkit.c |   6 ++
 7 files changed, 181 insertions(+)
 create mode 100644 server/exports.c

diff --git a/include/nbdkit-common.h b/include/nbdkit-common.h
index 671cd4a4..d38b37d2 100644
--- a/include/nbdkit-common.h
+++ b/include/nbdkit-common.h
@@ -117,6 +117,10 @@ struct nbdkit_extents;
 extern int nbdkit_add_extent (struct nbdkit_extents *,
                               uint64_t offset, uint64_t length, uint32_t type);

+struct nbdkit_exports;
+extern int nbdkit_add_export (struct nbdkit_exports *,
+                              const char *name, const char *description);
+
 /* A static non-NULL pointer which can be used when you don't need a
  * per-connection handle.
  */
diff --git a/include/nbdkit-filter.h b/include/nbdkit-filter.h
index cec12db7..01ff3dce 100644
--- a/include/nbdkit-filter.h
+++ b/include/nbdkit-filter.h
@@ -123,6 +123,18 @@ extern int nbdkit_extents_aligned (struct nbdkit_next_ops *next_ops,
                                    uint32_t flags, uint32_t align,
                                    struct nbdkit_extents *extents, int *err);

+/* Export functions. */
+struct nbdkit_export {
+  char *name;
+  char *description;
+};
+
+extern struct nbdkit_exports *nbdkit_exports_new (int default_only);
+extern void nbdkit_exports_free (struct nbdkit_exports *);
+extern size_t nbdkit_exports_count (const struct nbdkit_exports *);
+extern const struct nbdkit_export nbdkit_get_export (const struct nbdkit_exports *,
+                                                     size_t);
+
 /* Filter struct. */
 struct nbdkit_filter {
   /* Do not set these fields directly; use NBDKIT_REGISTER_FILTER.
diff --git a/server/Makefile.am b/server/Makefile.am
index 4c789934..58b22341 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -43,6 +43,7 @@ nbdkit_SOURCES = \
 	crypto.c \
 	debug.c \
 	debug-flags.c \
+	exports.c \
 	extents.c \
 	filters.c \
 	internal.h \
@@ -139,6 +140,7 @@ check_PROGRAMS = test-public
 test_public_SOURCES = \
 	test-public.c \
 	public.c \
+	exports.c \
 	extents.c \
 	$(NULL)
 test_public_CPPFLAGS = \
diff --git a/common/utils/cleanup.h b/common/utils/cleanup.h
index bcb65f7b..6b59556b 100644
--- a/common/utils/cleanup.h
+++ b/common/utils/cleanup.h
@@ -76,5 +76,8 @@ extern void cleanup_rwlock_unlock (pthread_rwlock_t **ptr);
 struct nbdkit_extents;
 extern void cleanup_extents_free (struct nbdkit_extents **ptr);
 #define CLEANUP_EXTENTS_FREE __attribute__((cleanup (cleanup_extents_free)))
+struct nbdkit_exports;
+extern void cleanup_exports_free (struct nbdkit_exports **ptr);
+#define CLEANUP_EXPORTS_FREE __attribute__((cleanup (cleanup_exports_free)))

 #endif /* NBDKIT_CLEANUP_H */
diff --git a/server/exports.c b/server/exports.c
new file mode 100644
index 00000000..3f819622
--- /dev/null
+++ b/server/exports.c
@@ -0,0 +1,149 @@
+/* nbdkit
+ * Copyright (C) 2019-2020 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 <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "vector.h"
+
+#include "internal.h"
+
+/* Cap nr_exports to avoid sending over-large replies to the client,
+ * and to avoid a plugin with large list consuming too much memory.
+ */
+#define MAX_EXPORTS 10000
+
+/* Appendable list of exports. */
+DEFINE_VECTOR_TYPE(exports, struct nbdkit_export);
+
+struct nbdkit_exports {
+  exports exports;
+
+  bool default_only;
+};
+
+struct nbdkit_exports *
+nbdkit_exports_new (int default_only)
+{
+  struct nbdkit_exports *r;
+
+  r = malloc (sizeof *r);
+  if (r == NULL) {
+    nbdkit_error ("nbdkit_exports_new: malloc: %m");
+    return NULL;
+  }
+  r->exports = (exports) empty_vector;
+  r->default_only = default_only != 0;
+  return r;
+}
+
+static void
+nbdkit_export_clear (struct nbdkit_export exp)
+{
+  free (exp.name);
+  free (exp.description);
+}
+
+void
+nbdkit_exports_free (struct nbdkit_exports *exps)
+{
+  if (exps) {
+    exports_iter (&exps->exports, nbdkit_export_clear);
+    free (exps->exports.ptr);
+    free (exps);
+  }
+}
+
+size_t
+nbdkit_exports_count (const struct nbdkit_exports *exps)
+{
+  return exps->exports.size;
+}
+
+const struct nbdkit_export
+nbdkit_get_export (const struct nbdkit_exports *exps, size_t i)
+{
+  assert (i < exps->exports.size);
+  return exps->exports.ptr[i];
+}
+
+int
+nbdkit_add_export (struct nbdkit_exports *exps,
+                   const char *name, const char *description)
+{
+  struct nbdkit_export e = { NULL, NULL };
+
+  if (exps->default_only && exps->exports.size == 1)
+    return 0;
+
+  if (exps->exports.size == MAX_EXPORTS) {
+    nbdkit_error ("nbdkit_add_export: too many exports");
+    errno = EINVAL;
+    return -1;
+  }
+  if (strlen (name) > NBD_MAX_STRING ||
+      (description && strlen (description) > NBD_MAX_STRING)) {
+    nbdkit_error ("nbdkit_add_export: string too long");
+    errno = EINVAL;
+    return -1;
+  }
+
+  e.name = strdup (name);
+  if (e.name == NULL) {
+    nbdkit_error ("nbdkit_add_export: strdup: %m");
+    return -1;
+  }
+  if (description) {
+    e.description = strdup (description);
+    if (e.description == NULL) {
+      nbdkit_error ("nbdkit_add_export: strdup: %m");
+      free (e.name);
+      errno = ENOMEM;
+      return -1;
+    }
+  }
+
+  if (exports_append (&exps->exports, e) == -1) {
+    nbdkit_error ("nbdkit_add_export: realloc: %m");
+    free (e.name);
+    free (e.description);
+    errno = ENOMEM;
+    return -1;
+  }
+
+  return 0;
+}
diff --git a/server/nbdkit.syms b/server/nbdkit.syms
index d62ad484..6cc6ed32 100644
--- a/server/nbdkit.syms
+++ b/server/nbdkit.syms
@@ -39,10 +39,15 @@
   # The functions we want plugins and filters to call.
   global:
     nbdkit_absolute_path;
+    nbdkit_add_export;
     nbdkit_add_extent;
     nbdkit_debug;
     nbdkit_error;
     nbdkit_export_name;
+    nbdkit_exports_count;
+    nbdkit_exports_free;
+    nbdkit_exports_new;
+    nbdkit_get_export;
     nbdkit_extents_aligned;
     nbdkit_extents_count;
     nbdkit_extents_free;
diff --git a/common/utils/cleanup-nbdkit.c b/common/utils/cleanup-nbdkit.c
index aaaf14a0..e7553c73 100644
--- a/common/utils/cleanup-nbdkit.c
+++ b/common/utils/cleanup-nbdkit.c
@@ -43,3 +43,9 @@ cleanup_extents_free (struct nbdkit_extents **ptr)
 {
   nbdkit_extents_free (*ptr);
 }
+
+void
+cleanup_exports_free (struct nbdkit_exports **ptr)
+{
+  nbdkit_exports_free (*ptr);
+}
-- 
2.28.0




More information about the Libguestfs mailing list