]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
use a UNIX file descriptor instead of FILE* for the trace file
authorAlain Spineux <alain@baculasystems.com>
Wed, 31 Aug 2022 14:23:54 +0000 (16:23 +0200)
committerEric Bollengier <eric@baculasystems.com>
Thu, 14 Sep 2023 11:56:59 +0000 (13:56 +0200)
- avoid the double buffering that can be responsible for undesirable
  mix of debug message
- there is no justification for the use of a FILE*
  - every fputs() is followed by a fflush()
- Note from "man 2 open" concurrent write() to NFS using O_APPEND may lead to
  lead to corrupted files

bacula/src/lib/message.c
bacula/src/lib/message.h

index 7223de13226c26597984e4fb3916f56046722a16..ad20fc910adf7b68d6fc2a1f3f57a8edd29e2f30 100644 (file)
@@ -82,7 +82,7 @@ static pthread_mutex_t fides_mutex = PTHREAD_MUTEX_INITIALIZER;
 static MSGS *daemon_msgs;              /* global messages */
 static void (*message_callback)(int type, char *msg) = NULL;
 #define MAX_TRACE_PATH  200
-static FILE *trace_fd = NULL;
+static int trace_fd = -1;
 static char trace_path[MAX_TRACE_PATH] = {0};
 
 #if defined(HAVE_WIN32)
@@ -211,8 +211,8 @@ void set_debug_flags(char *options)
 
       case 'c':
          /* truncate the trace file */
-         if (trace && trace_fd) {
-            ftruncate(fileno(trace_fd), 0);
+         if (trace && trace_fd != -1) {
+            ftruncate(trace_fd, 0);
          }
          break;
 
@@ -787,9 +787,9 @@ void term_msg()
       free(exename);
       exename = NULL;
    }
-   if (trace_fd) {
-      fclose(trace_fd);
-      trace_fd = NULL;
+   if (trace_fd != -1) {
+      close(trace_fd);
+      trace_fd = -1;
       trace = false;
    }
    working_directory = NULL;
@@ -1115,12 +1115,19 @@ const char *get_basename(const char *pathname)
 /* open trace file in working directory if not already open */
 static inline void open_trace_file()
 {
-   if (!trace_fd) {
+   if (trace_fd == -1) {
       bsnprintf(trace_path, sizeof(trace_path), "%s/%s.trace", working_directory ? working_directory : ".", my_name);
-      trace_fd = bfopen(trace_path, "a+b");
+      trace_fd = open(trace_path, O_RDWR | O_CREAT | O_APPEND, 0600);
    }
 }
 
+static void close_trace_file()
+{
+   int ltrace_fd = trace_fd;
+   trace_fd = -1;
+   close(ltrace_fd);
+}
+
 /* If the working directory or my_name has changed then close the trace file.
  * Next write will reopen it at the new location
  * use safe = true for reload when the daemon is multi threaded,
@@ -1129,21 +1136,13 @@ static inline void open_trace_file()
  */
 void update_trace_file_location(bool safe)
 {
-   if (trace_fd) {
+   if (trace_fd != -1) {
       char fn[MAX_TRACE_PATH];
       bsnprintf(fn, sizeof(fn), "%s/%s.trace", working_directory ? working_directory : ".", my_name);
       if (strcmp(trace_path, fn) != 0) {
          /* the trace file must be reopen at its new location */
-         if (safe) {
-            /* cheap safety, TODO use mutex instead */
-            FILE *ltrace_fd = trace_fd;
-            trace_fd = NULL;
-            bmicrosleep(0, 100000);         /* yield to prevent seg faults */
-            fclose(ltrace_fd);
-         } else {
-            fclose(trace_fd);
-            trace_fd = NULL;
-         }
+         close_trace_file();
+         /* will be reopen by next output */
       }
    }
 }
@@ -1159,9 +1158,8 @@ static void pt_out(char *buf)
      */
     if (trace) {
        open_trace_file();
-       if (trace_fd) {
-          fputs(buf, trace_fd);
-          fflush(trace_fd);
+       if (trace_fd != -1) {
+          write(trace_fd, buf, strlen(buf));
           return;
        } else {
           /* Some problem, turn off tracing */
@@ -1249,11 +1247,8 @@ void set_trace(int trace_flag)
    } else {
       trace = false;
    }
-   if (!trace && trace_fd) {
-      FILE *ltrace_fd = trace_fd;
-      trace_fd = NULL;
-      bmicrosleep(0, 100000);         /* yield to prevent seg faults */
-      fclose(ltrace_fd);
+   if (!trace && trace_fd != -1) {
+      close_trace_file();
    }
 }
 
@@ -1265,7 +1260,7 @@ void set_trace(int trace_flag)
  * In your tools be careful to no call any function that here in messages.c
  * that modify "trace" or close() or re-open() trace_fd
  */
-void set_trace_for_tools(FILE *new_trace_fd)
+void set_trace_for_tools(int new_trace_fd)
 {
    // don't call fclose(trace_fd) here
    trace = true;
@@ -1449,9 +1444,8 @@ t_msg(const char *file, int line, int64_t level, const char *fmt,...)
        va_start(arg_ptr, fmt);
        bvsnprintf(buf+len, sizeof(buf)-len, (char *)fmt, arg_ptr);
        va_end(arg_ptr);
-       if (trace_fd != NULL) {
-           fputs(buf, trace_fd);
-           fflush(trace_fd);
+       if (trace_fd != -1) {
+          write(trace_fd, buf, strlen(buf));
        }
    }
 }
index 4e98047a8994944665acf5ed12980285ffb580e3..b04e5692122aeb2ba42f911ac86282aa5090d255 100644 (file)
@@ -197,7 +197,7 @@ bool get_trace(void);
 void set_debug_flags(char *options);
 const char *get_basename(const char *pathname);
 bool is_message_type_set(JCR *jcr, int type);
-void set_trace_for_tools(FILE *new_trace_fd); // called by Bacula's tools only
+void set_trace_for_tools(int new_trace_fd); // called by Bacula's tools only
 void update_trace_file_location(bool safe);
 char *build_connecting_info_log(const char *daemon, const char *name, const char *addr, int port, bool tls, POOLMEM *&buf);