[Libguestfs] [PATCH nbdkit 5/9 patch split 4/5] server: Move debug and error functions to libnbdkit.so

Richard W.M. Jones rjones at redhat.com
Thu Mar 26 20:13:22 UTC 2020


---
 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




More information about the Libguestfs mailing list