File multipath-tools-close-race-window-in-uevent-processing of Package multipath-tools

From db8978316293c190109a23b5169a1215799039e7 Mon Sep 17 00:00:00 2001
From: Hannes Reinecke <hare@suse.de>
Date: Thu, 26 Feb 2009 12:22:49 +0100
Subject: [PATCH] Close race windows in uevent processing

When using separate mutexes for condition and queue changes we
always have a race condition between dropping the first and
acquiring the second. So get rid of one of them and use one
mutex for both, signalling and queue changes.

References: bnc#478874

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 libmultipath/uevent.c |   23 ++++++++---------------
 1 files changed, 8 insertions(+), 15 deletions(-)

diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c
index 86d5d11..64eb6b0 100644
--- a/libmultipath/uevent.c
+++ b/libmultipath/uevent.c
@@ -49,16 +49,18 @@ typedef int (uev_trigger)(struct uevent *, void * trigger_data);
 pthread_t uevq_thr;
 LIST_HEAD(uevq);
 pthread_mutex_t uevq_lock, *uevq_lockp = &uevq_lock;
-pthread_mutex_t uevc_lock, *uevc_lockp = &uevc_lock;
 pthread_cond_t  uev_cond,  *uev_condp  = &uev_cond;
-uev_trigger *my_uev_trigger;
-void * my_trigger_data;
+static uev_trigger *my_uev_trigger;
+static void * my_trigger_data;
 
 struct uevent * alloc_uevent (void)
 {
 	return (struct uevent *)MALLOC(sizeof(struct uevent));
 }
 
+/*
+ * Called with uevq_lockp held
+ */
 void
 service_uevq(void)
 {
@@ -91,11 +93,7 @@ uevq_thread(void * et)
 		 * so make sure we only wait if we have to.
 		 */
 		if (list_empty(&uevq)) {
-			pthread_mutex_unlock(uevq_lockp);
-			pthread_mutex_lock(uevc_lockp);
-			pthread_cond_wait(uev_condp, uevc_lockp);
-			pthread_mutex_unlock(uevc_lockp);
-			pthread_mutex_lock(uevq_lockp);
+			pthread_cond_wait(uev_condp, uevq_lockp);
 		}
 		service_uevq();
 		pthread_mutex_unlock(uevq_lockp);
@@ -128,7 +126,6 @@ int uevent_listen(int (*uev_trigger)(struct uevent *, void * trigger_data),
 	INIT_LIST_HEAD(&uevq);
 
 	pthread_mutex_init(uevq_lockp, NULL);
-	pthread_mutex_init(uevc_lockp, NULL);
 	pthread_cond_init(uev_condp, NULL);
 
 	pthread_attr_init(&attr);
@@ -274,12 +271,9 @@ int uevent_listen(int (*uev_trigger)(struct uevent *, void * trigger_data),
 		 * Queue uevent and poke service pthread.
 		 */
 		pthread_mutex_lock(uevq_lockp);
-		list_add(&uev->node, &uevq);
-		pthread_mutex_unlock(uevq_lockp);
-
-		pthread_mutex_lock(uevc_lockp);
+		list_add_tail(&uev->node, &uevq);
 		pthread_cond_signal(uev_condp);
-		pthread_mutex_unlock(uevc_lockp);
+		pthread_mutex_unlock(uevq_lockp);
 	}
 
 exit:
@@ -290,7 +284,6 @@ exit:
 	pthread_mutex_unlock(uevq_lockp);
 
 	pthread_mutex_destroy(uevq_lockp);
-	pthread_mutex_destroy(uevc_lockp);
 	pthread_cond_destroy(uev_condp);
 
 	return 1;
-- 
1.6.0.2

openSUSE Build Service is sponsored by