diff options
author | Benjamin Marzinski <bmarzins@redhat.com> | 2009-04-02 22:36:41 +0200 |
---|---|---|
committer | Christophe Varoqui <christophe.varoqui@free.fr> | 2009-04-02 22:36:41 +0200 |
commit | be6b014d785d0e6bc34d3a5f2ac531df8b3d8690 (patch) | |
tree | ce765485441464f882033334df3af411b905d878 /multipathd | |
parent | 0a0319d381249760c71023edbe0ac9c093bb4a74 (diff) | |
download | multipath-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.c | 10 |
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); |