---
lib/Makefile.am | 3 ++
server/Makefile.am | 1 -
server/internal.h | 2 +-
server/log.c | 20 +------------
server/main.c | 7 +++++
server/nbdkit.syms | 4 ---
lib/lib.h | 41 +++++++++++++++++++++++++-
{server => lib}/debug.c | 6 ++--
lib/init.c | 17 ++++++++++-
lib/log.c | 59 +++++++++++++++++++++++++++++++++++++
lib/vfprintf.c | 65 +++++++++++++++++++++++++++++++++++++++++
lib/libnbdkit.syms | 4 +++
12 files changed, 199 insertions(+), 30 deletions(-)
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 268282af..6826269b 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -40,12 +40,15 @@ EXTRA_DIST = libnbdkit.syms
lib_LTLIBRARIES = libnbdkit.la
libnbdkit_la_SOURCES = \
+ debug.c \
extents.c \
init.c \
lib.h \
+ log.c \
parse.c \
password.c \
path.c \
+ vfprintf.c \
$(NULL)
libnbdkit_la_CPPFLAGS = \
diff --git a/server/Makefile.am b/server/Makefile.am
index 8448bc10..8d9ba0f0 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -41,7 +41,6 @@ nbdkit_SOURCES = \
captive.c \
connections.c \
crypto.c \
- debug.c \
debug-flags.c \
filters.c \
internal.h \
diff --git a/server/internal.h b/server/internal.h
index d412e500..a3f4d1f1 100644
--- a/server/internal.h
+++ b/server/internal.h
@@ -306,7 +306,7 @@ extern void apply_debug_flags (void *dl, const char *name);
extern void free_debug_flags (void);
/* log.c */
-extern void log_verror (const char *fs, va_list args);
+extern void do_nbdkit_verror (const char *fs, va_list args);
/* log-*.c */
extern void log_stderr_verror (const char *fs, va_list args)
diff --git a/server/log.c b/server/log.c
index 37de3dd2..3588c7cc 100644
--- a/server/log.c
+++ b/server/log.c
@@ -44,7 +44,7 @@
* Note: preserves the previous value of errno.
*/
void
-log_verror (const char *fs, va_list args)
+do_nbdkit_verror (const char *fs, va_list args)
{
switch (log_to) {
case LOG_TO_DEFAULT:
@@ -64,21 +64,3 @@ log_verror (const char *fs, va_list args)
break;
}
}
-
-/* Note: preserves the previous value of errno. */
-void
-nbdkit_verror (const char *fs, va_list args)
-{
- log_verror (fs, args);
-}
-
-/* Note: preserves the previous value of errno. */
-void
-nbdkit_error (const char *fs, ...)
-{
- va_list args;
-
- va_start (args, fs);
- nbdkit_verror (fs, args);
- va_end (args);
-}
diff --git a/server/main.c b/server/main.c
index b303146c..9fcb8e13 100644
--- a/server/main.c
+++ b/server/main.c
@@ -168,6 +168,13 @@ main (int argc, char *argv[])
size_t i;
const char *magic_config_key;
+ /* Initialize libnbdkit.so. This must be done very early. */
+ libnbdkit_private_init (PACKAGE_VERSION,
+ &verbose,
+ do_nbdkit_verror,
+ threadlocal_get_name,
+ threadlocal_get_instance_num);
+
/* Refuse to run if stdin/out/err are closed, whether or not -s is used. */
if (fcntl (STDERR_FILENO, F_GETFL) == -1) {
/* Nowhere we can report the error. Oh well. */
diff --git a/server/nbdkit.syms b/server/nbdkit.syms
index 56e5008e..ea46ac3e 100644
--- a/server/nbdkit.syms
+++ b/server/nbdkit.syms
@@ -34,15 +34,11 @@
{
global:
- nbdkit_debug;
- nbdkit_error;
nbdkit_export_name;
nbdkit_nanosleep;
nbdkit_peer_name;
nbdkit_set_error;
nbdkit_shutdown;
- nbdkit_vdebug;
- nbdkit_verror;
# -D server.* flags must be visible to nbdkit itself.
nbdkit_debug_*;
diff --git a/lib/lib.h b/lib/lib.h
index 2d7ca930..077bcdc6 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -38,11 +38,50 @@
#include <sys/types.h>
#include <sys/socket.h>
+typedef void (*do_nbdkit_verror_t) (const char *fs, va_list args);
+typedef const char *(*threadlocal_get_name_t) (void);
+typedef size_t (*threadlocal_get_instance_num_t) (void);
+
+#ifdef IN_NBDKIT_LIB
+
+/* After nbdkit_private_init is called, these global function pointers
+ * are set up to point back to the corresponding functions in the
+ * server.
+ */
+extern do_nbdkit_verror_t do_nbdkit_verror;
+extern threadlocal_get_name_t threadlocal_get_name;
+extern threadlocal_get_instance_num_t threadlocal_get_instance_num;
+
+/* And a pointer to the verbose flag. */
+extern bool *verbose;
+
+/* Replacement vfprintf. Awkwardly this is duplicated in server/ too. */
+#if !HAVE_VFPRINTF_PERCENT_M
+#include <stdio.h>
+#define vfprintf replace_vfprintf
+extern int replace_vfprintf (FILE *f, const char *fmt, va_list args)
+ __attribute__((__format__ (printf, 2, 0)));
+#endif
+
+/* Declare program_name. */
+#if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME == 1
+#include <errno.h>
+#define program_name program_invocation_short_name
+#else
+#define program_name "nbdkit"
+#endif
+
+#endif /* IN_NBDKIT_LIB */
+
/* Defines the private function which is used by the server to
* initialize libnbdkit.so at runtime. This ABI may change at any
* time, which is why nbdkit and the corresponding libnbdkit.so must
* always be shipped together.
*/
-extern void libnbdkit_private_init (const char *expected_version);
+extern void libnbdkit_private_init (const char *expected_version,
+ bool *verbose,
+ do_nbdkit_verror_t do_nbdkit_verror,
+ threadlocal_get_name_t threadlocal_get_name,
+ threadlocal_get_instance_num_t
threadlocal_get_instance_num);
#endif /* NBDKIT_LIB_H */
diff --git a/server/debug.c b/lib/debug.c
similarity index 98%
rename from server/debug.c
rename to lib/debug.c
index cf511945..261bd712 100644
--- a/server/debug.c
+++ b/lib/debug.c
@@ -38,7 +38,7 @@
#include <string.h>
#include <errno.h>
-#include "internal.h"
+#include "lib.h"
/* Called with flockfile (stderr) taken. */
static void
@@ -65,7 +65,7 @@ nbdkit_vdebug (const char *fs, va_list args)
{
int err = errno;
- if (!verbose)
+ if (!*verbose)
return;
flockfile (stderr);
prologue ();
@@ -85,7 +85,7 @@ nbdkit_debug (const char *fs, ...)
va_list args;
int err = errno;
- if (!verbose)
+ if (!*verbose)
return;
flockfile (stderr);
diff --git a/lib/init.c b/lib/init.c
index ef7eeb3d..172c265e 100644
--- a/lib/init.c
+++ b/lib/init.c
@@ -41,8 +41,16 @@
bool *verbose;
+do_nbdkit_verror_t do_nbdkit_verror;
+threadlocal_get_name_t threadlocal_get_name;
+threadlocal_get_instance_num_t threadlocal_get_instance_num;
+
void
-libnbdkit_private_init (const char *expected_version)
+libnbdkit_private_init (const char *expected_version,
+ bool *_verbose,
+ do_nbdkit_verror_t _do_nbdkit_verror,
+ threadlocal_get_name_t _threadlocal_get_name,
+ threadlocal_get_instance_num_t _threadlocal_get_instance_num)
{
if (strcmp (expected_version, PACKAGE_VERSION) != 0) {
fprintf (stderr,
@@ -50,4 +58,11 @@ libnbdkit_private_init (const char *expected_version)
"nbdkit and libnbdkit.so versions do not match\n");
abort ();
}
+
+ verbose = _verbose;
+
+ do_nbdkit_verror = _do_nbdkit_verror;
+
+ threadlocal_get_name = _threadlocal_get_name;
+ threadlocal_get_instance_num = _threadlocal_get_instance_num;
}
diff --git a/lib/log.c b/lib/log.c
new file mode 100644
index 00000000..f3955c0b
--- /dev/null
+++ b/lib/log.c
@@ -0,0 +1,59 @@
+/* nbdkit
+ * Copyright (C) 2013-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 <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+
+#include "lib.h"
+
+/* Note: preserves the previous value of errno. */
+void
+nbdkit_verror (const char *fs, va_list args)
+{
+ do_nbdkit_verror (fs, args);
+}
+
+/* Note: preserves the previous value of errno. */
+void
+nbdkit_error (const char *fs, ...)
+{
+ va_list args;
+
+ va_start (args, fs);
+ nbdkit_verror (fs, args);
+ va_end (args);
+}
diff --git a/lib/vfprintf.c b/lib/vfprintf.c
new file mode 100644
index 00000000..6e330a41
--- /dev/null
+++ b/lib/vfprintf.c
@@ -0,0 +1,65 @@
+/* nbdkit
+ * Copyright (C) 2013-2018 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 <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+
+#include "lib.h"
+
+#if !HAVE_VFPRINTF_PERCENT_M
+/* Work around lack of %m in BSD */
+#undef vfprintf
+
+/* Call the real vfprintf after first changing %m into strerror(errno). */
+int
+replace_vfprintf (FILE *f, const char *fmt, va_list args)
+{
+ char *repl = NULL;
+ char *p = strstr (fmt, "%m"); /* assume strstr doesn't touch errno */
+ int ret;
+
+ /* We only handle the first %m; if a user passes more than one, they
+ * deserve broken output.
+ */
+ if (p && asprintf (&repl, "%.*s%s%s", (int) (p - fmt), fmt,
strerror (errno),
+ p + 2) > 0)
+ fmt = repl;
+ ret = vfprintf (f, fmt, args);
+ free (repl);
+ return ret;
+}
+#endif
diff --git a/lib/libnbdkit.syms b/lib/libnbdkit.syms
index f4e80e42..96a6aa68 100644
--- a/lib/libnbdkit.syms
+++ b/lib/libnbdkit.syms
@@ -40,6 +40,8 @@
global:
nbdkit_absolute_path;
nbdkit_add_extent;
+ nbdkit_debug;
+ nbdkit_error;
nbdkit_extents_count;
nbdkit_extents_free;
nbdkit_extents_new;
@@ -58,6 +60,8 @@
nbdkit_parse_unsigned;
nbdkit_read_password;
nbdkit_realpath;
+ nbdkit_vdebug;
+ nbdkit_verror;
# Private function that must only be called by the server.
libnbdkit_private_init;
--
2.25.0