summaryrefslogtreecommitdiff
path: root/multipathd
diff options
context:
space:
mode:
authorBenjamin Marzinski <bmarzins@redhat.com>2009-04-02 22:36:41 +0200
committerChristophe Varoqui <christophe.varoqui@free.fr>2009-04-02 22:36:41 +0200
commitbe6b014d785d0e6bc34d3a5f2ac531df8b3d8690 (patch)
treece765485441464f882033334df3af411b905d878 /multipathd
parent0a0319d381249760c71023edbe0ac9c093bb4a74 (diff)
downloadmultipath-tools-be6b014d785d0e6bc34d3a5f2ac531df8b3d8690.tar.gz
multipath-tools-be6b014d785d0e6bc34d3a5f2ac531df8b3d8690.tar.bz2
multipath-tools-be6b014d785d0e6bc34d3a5f2ac531df8b3d8690.zip
[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.
Diffstat (limited to 'multipathd')
-rw-r--r--multipathd/main.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/multipathd/main.c b/multipathd/main.c
index 9957f1f..a4ee10c 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -688,6 +688,9 @@ out:
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");
@@ -697,6 +700,9 @@ ueventloop (void * ap)
static void *
uxlsnrloop (void * ap)
{
+ block_signal(SIGUSR1, NULL);
+ block_signal(SIGHUP, NULL);
+
if (cli_init())
return NULL;
@@ -1007,6 +1013,7 @@ checkerloop (void *ap)
struct path *pp;
int count = 0;
unsigned int i;
+ sigset_t old;
mlockall(MCL_CURRENT | MCL_FUTURE);
vecs = (struct vectors *)ap;
@@ -1020,6 +1027,7 @@ checkerloop (void *ap)
}
while (1) {
+ block_signal(SIGHUP, &old);
pthread_cleanup_push(cleanup_lock, &vecs->lock);
lock(vecs->lock);
condlog(4, "tick");
@@ -1042,6 +1050,7 @@ checkerloop (void *ap)
}
lock_cleanup_pop(vecs->lock);
+ pthread_sigmask(SIG_SETMASK, &old, NULL);
sleep(1);
}
return NULL;
@@ -1358,6 +1367,7 @@ child (void * param)
/*
* exit path
*/
+ block_signal(SIGHUP, NULL);
lock(vecs->lock);
remove_maps_and_stop_waiters(vecs);
free_pathvec(vecs->pathvec, FREE_PATHS);