Ver Fonte

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 há 6 anos atrás
pai
commit
1cf1558fe7
1 ficheiros alterados com 27 adições e 3 exclusões
  1. 27 3
      exec/totemknet.c

+ 27 - 3
exec/totemknet.c

@@ -51,6 +51,7 @@
 #include <stdlib.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdio.h>
 #include <errno.h>
 #include <errno.h>
+#include <pthread.h>
 #include <sched.h>
 #include <sched.h>
 #include <time.h>
 #include <time.h>
 #include <sys/time.h>
 #include <sys/time.h>
@@ -171,6 +172,8 @@ struct totemknet_instance {
 
 
 	int logpipes[2];
 	int logpipes[2];
 	int knet_fd;
 	int knet_fd;
+
+	pthread_mutex_t log_mutex;
 #ifdef HAVE_LIBNOZZLE
 #ifdef HAVE_LIBNOZZLE
 	char *nozzle_name;
 	char *nozzle_name;
 	char *nozzle_ipaddr;
 	char *nozzle_ipaddr;
@@ -203,20 +206,36 @@ static void log_flush_messages (
 
 
 static void totemknet_instance_initialize (struct totemknet_instance *instance)
 static void totemknet_instance_initialize (struct totemknet_instance *instance)
 {
 {
+	int res;
+
 	memset (instance, 0, sizeof (struct totemknet_instance));
 	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...)		\
 #define knet_log_printf(level, format, args...)		\
 do {							\
 do {							\
-        instance->totemknet_log_printf (		\
+        knet_log_printf_lock (				\
 		level, instance->totemknet_subsys_id,	\
 		level, instance->totemknet_subsys_id,	\
                 __FUNCTION__, __FILE__, __LINE__,	\
                 __FUNCTION__, __FILE__, __LINE__,	\
 		(const char *)format, ##args);		\
 		(const char *)format, ##args);		\
 } while (0);
 } while (0);
 
 
-#define libknet_log_printf(level, format, args...)		\
+#define libknet_log_printf(level, format, args...)	\
 do {							\
 do {							\
-        instance->totemknet_log_printf (		\
+        knet_log_printf_lock (				\
 		level, instance->knet_subsys_id,	\
 		level, instance->knet_subsys_id,	\
                 __FUNCTION__, "libknet.h", __LINE__,	\
                 __FUNCTION__, "libknet.h", __LINE__,	\
 		(const char *)format, ##args);		\
 		(const char *)format, ##args);		\
@@ -603,6 +622,11 @@ finalise_error:
 
 
 	log_flush_messages(instance);
 	log_flush_messages(instance);
 
 
+	/*
+	 * Error is deliberately ignored
+	 */
+	(void)pthread_mutex_destroy(&instance->log_mutex);
+
 	return (res);
 	return (res);
 }
 }