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 <[email protected]> --- 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 _______________________________________________ Libguestfs mailing list [email protected] https://www.redhat.com/mailman/listinfo/libguestfs
