FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Redhat > Device-mapper Development

 
 
LinkBack Thread Tools
 
Old 08-27-2008, 07:14 PM
 
Default multipath-tools libmultipath/lock.c libmultipa ...

CVSROOT: /cvs/dm
Module name: multipath-tools
Branch: RHEL5_FC6
Changes by: bmarzins@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&r 1=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
", __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);

--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
 

Thread Tools




All times are GMT. The time now is 08:14 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org