158 lines
3.7 KiB
Diff
158 lines
3.7 KiB
Diff
|
From 453a7611b625fc6f306a47ccc61bf3b83d75e522 Mon Sep 17 00:00:00 2001
|
||
|
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||
|
Date: Thu, 5 Aug 2021 10:13:53 +0100
|
||
|
Subject: [PATCH] server: Make debug messages atomic
|
||
|
|
||
|
Previously we used flockfile around the separate fprintf statements
|
||
|
used to emit debug messages. However this does not make debug
|
||
|
messages atomic (only atomic with respect to other nbdkit threads).
|
||
|
It's easy to see this in strace:
|
||
|
|
||
|
1915655 write(2, "nbdkit: ", 8) = 8
|
||
|
1915655 write(2, "debug: ", 7) = 7
|
||
|
1915655 write(2, "nbdkit 1.27.3 (nbdkit-1.27.3-1.f"..., 36) = 36
|
||
|
1915655 write(2, "\n", 1) = 1
|
||
|
|
||
|
We require open_memstream already, so use this to print messages to a
|
||
|
string buffer which we can emit in a single write.
|
||
|
|
||
|
This fixes various tests which grep the log file looking for sentinel
|
||
|
messages. In particular a recent Fedora build failure in
|
||
|
test-nbdkit-backend-debug.sh was caused by this, but there are other
|
||
|
tests that fail occasionally for the same reason.
|
||
|
|
||
|
This change also tries harder to set errno correctly before expanding
|
||
|
the format string (for debug messages that contain %m).
|
||
|
|
||
|
Note that libnbd already emits atomic messages.
|
||
|
|
||
|
(cherry picked from commit 30eef3bf2d93b12072f91f95987bae33f9e3fe1a)
|
||
|
---
|
||
|
server/debug.c | 72 ++++++++++++++++++++++++++++++++------------------
|
||
|
1 file changed, 46 insertions(+), 26 deletions(-)
|
||
|
|
||
|
diff --git a/server/debug.c b/server/debug.c
|
||
|
index eede5e16..07710581 100644
|
||
|
--- a/server/debug.c
|
||
|
+++ b/server/debug.c
|
||
|
@@ -40,23 +40,22 @@
|
||
|
|
||
|
#include "internal.h"
|
||
|
|
||
|
-/* Called with flockfile (stderr) taken. */
|
||
|
static void
|
||
|
-prologue (void)
|
||
|
+prologue (FILE *fp)
|
||
|
{
|
||
|
const char *name = threadlocal_get_name ();
|
||
|
size_t instance_num = threadlocal_get_instance_num ();
|
||
|
|
||
|
- fprintf (stderr, "%s: ", program_name);
|
||
|
+ fprintf (fp, "%s: ", program_name);
|
||
|
|
||
|
if (name) {
|
||
|
- fprintf (stderr, "%s", name);
|
||
|
+ fprintf (fp, "%s", name);
|
||
|
if (instance_num > 0)
|
||
|
- fprintf (stderr, "[%zu]", instance_num);
|
||
|
- fprintf (stderr, ": ");
|
||
|
+ fprintf (fp, "[%zu]", instance_num);
|
||
|
+ fprintf (fp, ": ");
|
||
|
}
|
||
|
|
||
|
- fprintf (stderr, "debug: ");
|
||
|
+ fprintf (fp, "debug: ");
|
||
|
}
|
||
|
|
||
|
/* Note: preserves the previous value of errno. */
|
||
|
@@ -64,20 +63,30 @@ NBDKIT_DLL_PUBLIC void
|
||
|
nbdkit_vdebug (const char *fs, va_list args)
|
||
|
{
|
||
|
int err = errno;
|
||
|
+ CLEANUP_FREE char *str = NULL;
|
||
|
+ size_t len = 0;
|
||
|
+ FILE *fp;
|
||
|
|
||
|
if (!verbose)
|
||
|
return;
|
||
|
-#ifdef HAVE_FLOCKFILE
|
||
|
- flockfile (stderr);
|
||
|
-#endif
|
||
|
- prologue ();
|
||
|
|
||
|
- vfprintf (stderr, fs, args);
|
||
|
+ fp = open_memstream (&str, &len);
|
||
|
+ if (fp == NULL) {
|
||
|
+ /* Try to emit what we can. */
|
||
|
+ errno = err;
|
||
|
+ vfprintf (stderr, fs, args);
|
||
|
+ return;
|
||
|
+ }
|
||
|
|
||
|
- fprintf (stderr, "\n");
|
||
|
-#ifdef HAVE_FUNLOCKFILE
|
||
|
- funlockfile (stderr);
|
||
|
-#endif
|
||
|
+ prologue (fp);
|
||
|
+
|
||
|
+ errno = err;
|
||
|
+ vfprintf (fp, fs, args);
|
||
|
+
|
||
|
+ fprintf (fp, "\n");
|
||
|
+ fclose (fp);
|
||
|
+
|
||
|
+ fputs (str, stderr);
|
||
|
|
||
|
errno = err;
|
||
|
}
|
||
|
@@ -86,25 +95,36 @@ nbdkit_vdebug (const char *fs, va_list args)
|
||
|
NBDKIT_DLL_PUBLIC void
|
||
|
nbdkit_debug (const char *fs, ...)
|
||
|
{
|
||
|
+ int err = errno;
|
||
|
va_list args;
|
||
|
- int err = errno;
|
||
|
+ CLEANUP_FREE char *str = NULL;
|
||
|
+ size_t len = 0;
|
||
|
+ FILE *fp;
|
||
|
|
||
|
if (!verbose)
|
||
|
return;
|
||
|
|
||
|
-#ifdef HAVE_FLOCKFILE
|
||
|
- flockfile (stderr);
|
||
|
-#endif
|
||
|
- prologue ();
|
||
|
+ fp = open_memstream (&str, &len);
|
||
|
+ if (fp == NULL) {
|
||
|
+ /* Try to emit what we can. */
|
||
|
+ va_start (args, fs);
|
||
|
+ errno = err;
|
||
|
+ vfprintf (stderr, fs, args);
|
||
|
+ va_end (args);
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ prologue (fp);
|
||
|
|
||
|
va_start (args, fs);
|
||
|
- vfprintf (stderr, fs, args);
|
||
|
+ errno = err;
|
||
|
+ vfprintf (fp, fs, args);
|
||
|
va_end (args);
|
||
|
|
||
|
- fprintf (stderr, "\n");
|
||
|
-#ifdef HAVE_FUNLOCKFILE
|
||
|
- funlockfile (stderr);
|
||
|
-#endif
|
||
|
+ fprintf (fp, "\n");
|
||
|
+ fclose (fp);
|
||
|
+
|
||
|
+ fputs (str, stderr);
|
||
|
|
||
|
errno = err;
|
||
|
}
|
||
|
--
|
||
|
2.31.1
|
||
|
|