Răsfoiți Sursa

totemknet: Add locking for log call

Knet callbacks may be called from different thread than main thread. If
this happens, log messages may be lost. Most prominent example is when
link goes up (logged by main thread) and host_change_callback_fn is
called.

Implemented solution is adding mutex for every log call in totemknet.

Signed-off-by: Jan Friesse <jfriesse@redhat.com>
Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
Jan Friesse 6 ani în urmă
părinte
comite
1cf1558fe7
1 a modificat fișierele cu 27 adăugiri și 3 ștergeri
  1. 27 3
      exec/totemknet.c

+ 27 - 3
exec/totemknet.c

@@ -51,6 +51,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <errno.h>
+#include <pthread.h>
 #include <sched.h>
 #include <time.h>
 #include <sys/time.h>
@@ -171,6 +172,8 @@ struct totemknet_instance {
 
 	int logpipes[2];
 	int knet_fd;
+
+	pthread_mutex_t log_mutex;
 #ifdef HAVE_LIBNOZZLE
 	char *nozzle_name;
 	char *nozzle_ipaddr;
@@ -203,20 +206,36 @@ static void log_flush_messages (
 
 static void totemknet_instance_initialize (struct totemknet_instance *instance)
 {
+	int res;
+
 	memset (instance, 0, sizeof (struct totemknet_instance));
+	res = pthread_mutex_init(&instance->log_mutex, NULL);
+	/*
+	 * There is not too much else what can be done.
+	 */
+	assert(res == 0);
 }
 
+#define knet_log_printf_lock(level, subsys, function, file, line, format, args...)	\
+do {											\
+	(void)pthread_mutex_lock(&instance->log_mutex);					\
+	instance->totemknet_log_printf (						\
+		level, subsys, function, file, line,					\
+		(const char *)format, ##args);						\
+	(void)pthread_mutex_unlock(&instance->log_mutex);				\
+} while (0);
+
 #define knet_log_printf(level, format, args...)		\
 do {							\
-        instance->totemknet_log_printf (		\
+        knet_log_printf_lock (				\
 		level, instance->totemknet_subsys_id,	\
                 __FUNCTION__, __FILE__, __LINE__,	\
 		(const char *)format, ##args);		\
 } while (0);
 
-#define libknet_log_printf(level, format, args...)		\
+#define libknet_log_printf(level, format, args...)	\
 do {							\
-        instance->totemknet_log_printf (		\
+        knet_log_printf_lock (				\
 		level, instance->knet_subsys_id,	\
                 __FUNCTION__, "libknet.h", __LINE__,	\
 		(const char *)format, ##args);		\
@@ -603,6 +622,11 @@ finalise_error:
 
 	log_flush_messages(instance);
 
+	/*
+	 * Error is deliberately ignored
+	 */
+	(void)pthread_mutex_destroy(&instance->log_mutex);
+
 	return (res);
 }