[dm-devel] multipath-tools libmultipath/lock.c libmultipa ...

bmarzins at sourceware.org bmarzins at sourceware.org
Wed Aug 27 19:14:59 UTC 2008


CVSROOT:	/cvs/dm
Module name:	multipath-tools
Branch: 	RHEL5_FC6
Changes by:	bmarzins at sourceware.org	2008-08-27 19:14:58

Modified files:
	libmultipath   : lock.c lock.h log_pthread.c waiter.c 
	multipathd     : main.c 

Log message:
	Fix a multipathd signal deadlock.  If multipathd is run with -v3, both the
	SIGHUP, and the SIGUSR1 signal handlers will log a message.  If a multipathd
	thread receives one of these signals while it has a log lock held, it deadlocks
	itself. Also, the SIGHUP handler will grab the vecs lock, so if any thread
	receives a SIGHUP while holding the vecs lock, it deadlocks itself.  This
	commit blocks the appropriate signals to guard against this.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/multipath-tools/libmultipath/lock.c.diff?cvsroot=dm&only_with_tag=RHEL5_FC6&r1=1.1&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/multipath-tools/libmultipath/lock.h.diff?cvsroot=dm&only_with_tag=RHEL5_FC6&r1=1.1&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/multipath-tools/libmultipath/log_pthread.c.diff?cvsroot=dm&only_with_tag=RHEL5_FC6&r1=1.1.2.1&r2=1.1.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/multipath-tools/libmultipath/waiter.c.diff?cvsroot=dm&only_with_tag=RHEL5_FC6&r1=1.1.2.1&r2=1.1.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/multipath-tools/multipathd/main.c.diff?cvsroot=dm&only_with_tag=RHEL5_FC6&r1=1.69.2.7&r2=1.69.2.8

--- multipath-tools/libmultipath/lock.c	2006/06/06 18:46:38	1.1
+++ multipath-tools/libmultipath/lock.c	2008/08/27 19:14:57	1.1.2.1
@@ -1,6 +1,15 @@
 #include <pthread.h>
+#include <signal.h>
 #include "lock.h"
 
+void block_signal(int signum, sigset_t *old)
+{
+	sigset_t set;
+	sigemptyset(&set);
+	sigaddset(&set, signum);
+	pthread_sigmask(SIG_BLOCK, &set, old);
+}	
+
 void cleanup_lock (void * data)
 {
 	unlock((pthread_mutex_t *)data);
--- multipath-tools/libmultipath/lock.h	2006/06/06 18:46:38	1.1
+++ multipath-tools/libmultipath/lock.h	2008/08/27 19:14:57	1.1.2.1
@@ -1,6 +1,8 @@
 #ifndef _LOCK_H
 #define _LOCK_H
 
+#include <signal.h>
+
 #ifdef LCKDBG
 #define lock(a) \
 	        fprintf(stderr, "%s:%s(%i) lock %p\n", __FILE__, __FUNCTION__, __LINE__, a); \
@@ -18,5 +20,6 @@
 #endif
 
 void cleanup_lock (void * data);
+void block_signal(int signum, sigset_t *old);
 
 #endif /* _LOCK_H */
--- multipath-tools/libmultipath/log_pthread.c	2007/06/15 19:03:02	1.1.2.1
+++ multipath-tools/libmultipath/log_pthread.c	2008/08/27 19:14:57	1.1.2.2
@@ -11,9 +11,15 @@
 
 #include "log_pthread.h"
 #include "log.h"
+#include "lock.h"
 
 void log_safe (int prio, const char * fmt, va_list ap)
 {
+	sigset_t old;
+
+	block_signal(SIGUSR1, &old);
+	block_signal(SIGHUP, NULL);
+
 	pthread_mutex_lock(logq_lock);
 	//va_start(ap, fmt);
 	log_enqueue(prio, fmt, ap);
@@ -23,6 +29,8 @@
 	pthread_mutex_lock(logev_lock);
 	pthread_cond_signal(logev_cond);
 	pthread_mutex_unlock(logev_lock);
+
+	pthread_sigmask(SIG_SETMASK, &old, NULL);
 }
 
 static void flush_logqueue (void)
--- multipath-tools/libmultipath/waiter.c	2007/06/15 19:03:02	1.1.2.1
+++ multipath-tools/libmultipath/waiter.c	2008/08/27 19:14:57	1.1.2.2
@@ -32,11 +32,13 @@
 
 void free_waiter (void *data)
 {
+	sigset_t old;
 	struct event_thread *wp = (struct event_thread *)data;
 
 	/*
 	 * indicate in mpp that the wp is already freed storage
 	 */
+	block_signal(SIGHUP, &old);
 	lock(wp->vecs->lock);
 
 	if (wp->mpp)
@@ -48,6 +50,7 @@
 		condlog(3, "free_waiter, mpp freed before wp=%p,", wp);
 
 	unlock(wp->vecs->lock);
+	pthread_sigmask(SIG_SETMASK, &old, NULL);
 
 	if (wp->dmt)
 		dm_task_destroy(wp->dmt);
--- multipath-tools/multipathd/main.c	2008/05/12 18:48:03	1.69.2.7
+++ multipath-tools/multipathd/main.c	2008/08/27 19:14:58	1.69.2.8
@@ -705,6 +705,9 @@
 static void *
 ueventloop (void * ap)
 {
+	block_signal(SIGUSR1, NULL);
+	block_signal(SIGHUP, NULL);
+
 	if (uevent_listen(&uev_trigger, ap))
 		fprintf(stderr, "error starting uevent listener");
 		
@@ -720,6 +723,9 @@
 	if (alloc_handlers())
 		return NULL;
 
+	block_signal(SIGUSR1, NULL);
+	block_signal(SIGHUP, NULL);
+
 	add_handler(LIST+PATHS, cli_list_paths);
 	add_handler(LIST+MAPS, cli_list_maps);
 	add_handler(LIST+MAPS+STATUS, cli_list_maps_status);
@@ -880,6 +886,7 @@
 	int count = 0;
 	int newstate;
 	unsigned int i;
+	sigset_t old;
 
 	mlockall(MCL_CURRENT | MCL_FUTURE);
 	vecs = (struct vectors *)ap;
@@ -893,6 +900,7 @@
 	}
 
 	while (1) {
+		block_signal(SIGHUP, &old);
 		pthread_cleanup_push(cleanup_lock, vecs->lock);
 		lock(vecs->lock);
 		condlog(4, "tick");
@@ -1051,6 +1059,7 @@
 		}
 		
 		lock_cleanup_pop(vecs->lock);
+		pthread_sigmask(SIG_SETMASK, &old, NULL);
 		sleep(1);
 	}
 	return NULL;
@@ -1532,6 +1541,7 @@
 	/*
 	 * exit path
 	 */
+	block_signal(SIGHUP, NULL);
 	lock(vecs->lock);
 	remove_maps(vecs, stop_waiter_thread);
 	free_pathvec(vecs->pathvec, FREE_PATHS);




More information about the dm-devel mailing list