瀏覽代碼

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 年之前
父節點
當前提交
1cf1558fe7
共有 1 個文件被更改,包括 27 次插入3 次删除
  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);
 }