Merge lp:~serge-hallyn/ubuntu/natty/multipath-tools/free_waiter-race into lp:ubuntu/natty/multipath-tools

Proposed by Serge Hallyn
Status: Merged
Merged at revision: 37
Proposed branch: lp:~serge-hallyn/ubuntu/natty/multipath-tools/free_waiter-race
Merge into: lp:ubuntu/natty/multipath-tools
Diff against target: 247 lines (+227/-0)
3 files modified
debian/changelog (+7/-0)
debian/patches/1004--race-condition-fix-with-free_waiter-threads-during-shutdown.patch (+219/-0)
debian/patches/series (+1/-0)
To merge this branch: bzr merge lp:~serge-hallyn/ubuntu/natty/multipath-tools/free_waiter-race
Reviewer Review Type Date Requested Status
Dustin Kirkland  Pending
Review via email: mp+49144@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2011-02-09 12:45:34 +0000
3+++ debian/changelog 2011-02-09 21:53:14 +0000
4@@ -1,3 +1,10 @@
5+multipath-tools (0.4.8-14ubuntu9) natty; urgency=low
6+
7+ * Fix segv caused by race condition with free_waiter threads during
8+ shutdown, using backport from upstream. (LP: #713237)
9+
10+ -- dann frazier <dann.frazier@canonical.com> Thu, 03 Feb 2011 16:37:10 -0700
11+
12 multipath-tools (0.4.8-14ubuntu8) natty; urgency=low
13
14 * Fix segv on shutdown when log buffer is empty, using patch cherry-picked
15
16=== added file 'debian/patches/1004--race-condition-fix-with-free_waiter-threads-during-shutdown.patch'
17--- debian/patches/1004--race-condition-fix-with-free_waiter-threads-during-shutdown.patch 1970-01-01 00:00:00 +0000
18+++ debian/patches/1004--race-condition-fix-with-free_waiter-threads-during-shutdown.patch 2011-02-09 21:53:14 +0000
19@@ -0,0 +1,219 @@
20+Description: Race-condition fix with free_waiter threads during shutdown.
21+Author: Konrad Rzeszutek <konrad@virtualiron.com>
22+Origin: upstream, http://www.spinics.net/lists/dm-devel/msg08911.html, commit a403f57b991f3be7c7ea6250d95fad1554c9d6ca
23+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/multipath-tools/+bug/713237
24+
25+Index: fix-segv/libmultipath/lock.c
26+===================================================================
27+--- fix-segv.orig/libmultipath/lock.c 2011-02-03 16:36:19.803282771 -0700
28++++ fix-segv/libmultipath/lock.c 2011-02-03 16:58:16.483280080 -0700
29+@@ -1,8 +1,8 @@
30+ #include <pthread.h>
31+ #include "lock.h"
32+-
33++#include <stdio.h>
34+ void cleanup_lock (void * data)
35+ {
36+- unlock((pthread_mutex_t *)data);
37++ unlock ((*(struct mutex_lock *)data));
38+ }
39+
40+Index: fix-segv/libmultipath/lock.h
41+===================================================================
42+--- fix-segv.orig/libmultipath/lock.h 2011-02-03 16:36:19.791279834 -0700
43++++ fix-segv/libmultipath/lock.h 2011-02-03 16:58:38.403579621 -0700
44+@@ -1,19 +1,30 @@
45+ #ifndef _LOCK_H
46+ #define _LOCK_H
47+
48++#include <pthread.h>
49++
50++/*
51++ * Wrapper for the mutex. Includes a ref-count to keep
52++ * track of how many there are out-standing threads blocking
53++ * on a mutex. */
54++struct mutex_lock {
55++ pthread_mutex_t *mutex;
56++ int depth;
57++};
58++
59+ #ifdef LCKDBG
60+ #define lock(a) \
61+- fprintf(stderr, "%s:%s(%i) lock %p\n", __FILE__, __FUNCTION__, __LINE__, a); \
62+- pthread_mutex_lock(a)
63++ fprintf(stderr, "%s:%s(%i) lock %p depth: %d (%ld)\n", __FILE__, __FUNCTION__, __LINE__, a.mutex, a.depth, pthread_self()); \
64++ a.depth++; pthread_mutex_lock(a.mutex)
65+ #define unlock(a) \
66+- fprintf(stderr, "%s:%s(%i) unlock %p\n", __FILE__, __FUNCTION__, __LINE__, a); \
67+- pthread_mutex_unlock(a)
68++ fprintf(stderr, "%s:%s(%i) unlock %p depth: %d (%ld)\n", __FILE__, __FUNCTION__, __LINE__, a.mutex, a.depth, pthread_self()); \
69++ a.depth--; pthread_mutex_unlock(a.mutex)
70+ #define lock_cleanup_pop(a) \
71+- fprintf(stderr, "%s:%s(%i) unlock %p\n", __FILE__, __FUNCTION__, __LINE__, a); \
72+- pthread_cleanup_pop(1);
73++ fprintf(stderr, "%s:%s(%i) unlock %p depth: %d (%ld)\n", __FILE__, __FUNCTION__, __LINE__, a.mutex, a.depth, pthread_self()); \
74++ pthread_cleanup_pop(1);
75+ #else
76+-#define lock(a) pthread_mutex_lock(a)
77+-#define unlock(a) pthread_mutex_unlock(a)
78++#define lock(a) a.depth++; pthread_mutex_lock(a.mutex)
79++#define unlock(a) a.depth--; pthread_mutex_unlock(a.mutex)
80+ #define lock_cleanup_pop(a) pthread_cleanup_pop(1);
81+ #endif
82+
83+Index: fix-segv/libmultipath/structs_vec.h
84+===================================================================
85+--- fix-segv.orig/libmultipath/structs_vec.h 2011-02-03 16:36:19.787281481 -0700
86++++ fix-segv/libmultipath/structs_vec.h 2011-02-03 16:58:16.487280599 -0700
87+@@ -1,9 +1,15 @@
88+ #ifndef _STRUCTS_VEC_H
89+ #define _STRUCTS_VEC_H
90+
91++#include "lock.h"
92++/*
93++struct mutex_lock {
94++ pthread_mutex_t *mutex;
95++ int depth;
96++}; */
97+ struct vectors {
98+ #if DAEMON
99+- pthread_mutex_t *lock;
100++ struct mutex_lock lock; /* defined in lock.h */
101+ #endif
102+ vector pathvec;
103+ vector mpvec;
104+Index: fix-segv/libmultipath/waiter.c
105+===================================================================
106+--- fix-segv.orig/libmultipath/waiter.c 2011-02-03 16:36:19.795279169 -0700
107++++ fix-segv/libmultipath/waiter.c 2011-02-03 16:58:16.487280599 -0700
108+@@ -45,7 +45,10 @@
109+ */
110+ wp->mpp->waiter = NULL;
111+ else
112+- condlog(3, "free_waiter, mpp freed before wp=%p,", wp);
113++ /*
114++ * This is OK condition during shutdown.
115++ */
116++ condlog(3, "free_waiter, mpp freed before wp=%p (%s).", wp, wp->mapname);
117+
118+ unlock(wp->vecs->lock);
119+
120+@@ -58,13 +61,16 @@
121+ void stop_waiter_thread (struct multipath *mpp, struct vectors *vecs)
122+ {
123+ struct event_thread *wp = (struct event_thread *)mpp->waiter;
124++ pthread_t thread;
125+
126+ if (!wp) {
127+ condlog(3, "%s: no waiter thread", mpp->alias);
128+ return;
129+ }
130+- condlog(2, "%s: stop event checker thread", wp->mapname);
131+- pthread_kill((pthread_t)wp->thread, SIGUSR1);
132++ thread = wp->thread;
133++ condlog(2, "%s: stop event checker thread (%lu)", wp->mapname, thread);
134++
135++ pthread_kill(thread, SIGUSR1);
136+ }
137+
138+ static sigset_t unblock_signals(void)
139+@@ -148,7 +154,7 @@
140+ * 4) a path reinstate : nothing to do
141+ * 5) a switch group : nothing to do
142+ */
143+- pthread_cleanup_push(cleanup_lock, waiter->vecs->lock);
144++ pthread_cleanup_push(cleanup_lock, &waiter->vecs->lock);
145+ lock(waiter->vecs->lock);
146+ r = update_multipath(waiter->vecs, waiter->mapname);
147+ lock_cleanup_pop(waiter->vecs->lock);
148+Index: fix-segv/multipath/main.c
149+===================================================================
150+--- fix-segv.orig/multipath/main.c 2011-02-03 16:36:19.819283822 -0700
151++++ fix-segv/multipath/main.c 2011-02-03 16:58:16.495278814 -0700
152+@@ -419,6 +419,7 @@
153+ condlog(3, "restart multipath configuration process");
154+
155+ out:
156++
157+ sysfs_cleanup();
158+ free_config(conf);
159+ dm_lib_release();
160+Index: fix-segv/multipathd/main.c
161+===================================================================
162+--- fix-segv.orig/multipathd/main.c 2011-02-03 16:58:16.463280045 -0700
163++++ fix-segv/multipathd/main.c 2011-02-03 16:58:16.499281808 -0700
164+@@ -591,7 +591,7 @@
165+ *len = 0;
166+ vecs = (struct vectors *)trigger_data;
167+
168+- pthread_cleanup_push(cleanup_lock, vecs->lock);
169++ pthread_cleanup_push(cleanup_lock, &vecs->lock);
170+ lock(vecs->lock);
171+
172+ r = parse_cmd(str, reply, len, vecs);
173+@@ -744,9 +744,9 @@
174+ condlog(3, "unlink pidfile");
175+ unlink(DEFAULT_PIDFILE);
176+
177+- lock(&exit_mutex);
178++ pthread_mutex_lock(&exit_mutex);
179+ pthread_cond_signal(&exit_cond);
180+- unlock(&exit_mutex);
181++ pthread_mutex_unlock(&exit_mutex);
182+
183+ return status;
184+ }
185+@@ -879,7 +879,7 @@
186+ }
187+
188+ while (1) {
189+- pthread_cleanup_push(cleanup_lock, vecs->lock);
190++ pthread_cleanup_push(cleanup_lock, &vecs->lock);
191+ lock(vecs->lock);
192+ condlog(4, "tick");
193+
194+@@ -1153,13 +1153,14 @@
195+ if (!vecs)
196+ return NULL;
197+
198+- vecs->lock =
199++ vecs->lock.mutex =
200+ (pthread_mutex_t *)MALLOC(sizeof(pthread_mutex_t));
201+
202+- if (!vecs->lock)
203++ if (!vecs->lock.mutex)
204+ goto out;
205+
206+- pthread_mutex_init(vecs->lock, NULL);
207++ pthread_mutex_init(vecs->lock.mutex, NULL);
208++ vecs->lock.depth = 0;
209+
210+ return vecs;
211+
212+@@ -1307,7 +1308,6 @@
213+ condlog(0, "failure during configuration");
214+ exit(1);
215+ }
216+-
217+ /*
218+ * start threads
219+ */
220+@@ -1341,9 +1341,15 @@
221+ free_polls();
222+
223+ unlock(vecs->lock);
224+- pthread_mutex_destroy(vecs->lock);
225+- FREE(vecs->lock);
226+- vecs->lock = NULL;
227++ /* Now all the waitevent threads will start rushing in. */
228++ while (vecs->lock.depth > 0) {
229++ sleep (1); /* This is weak. */
230++ condlog(3,"Have %d wait event checkers threads to de-alloc, waiting..\n", vecs->lock.depth);
231++ }
232++ pthread_mutex_destroy(vecs->lock.mutex);
233++ FREE(vecs->lock.mutex);
234++ vecs->lock.depth = 0;
235++ vecs->lock.mutex = NULL;
236+ FREE(vecs);
237+ vecs = NULL;
238+ free_config(conf);
239
240=== modified file 'debian/patches/series'
241--- debian/patches/series 2011-02-01 21:45:14 +0000
242+++ debian/patches/series 2011-02-09 21:53:14 +0000
243@@ -14,3 +14,4 @@
244 1001--intel-mpath-prio-alua.patch
245 1002--Fix-for-uevent-devpath-handling.patch
246 1003--multipathd-crash-on-shutdown.patch
247+1004--race-condition-fix-with-free_waiter-threads-during-shutdown.patch

Subscribers

People subscribed via source and target branches

to all changes: