1 autofs-5.0.4 - library reload fix update
3 From: Ian Kent <raven@themaw.net>
5 We still have a problem with libxml2 being unloaded before its thread
6 specific data destructor is called. This is due to the main thread
7 exiting (closing the handle we hold open to prevent this) before all
8 the mount handling threads have actually completed. This patch makes
9 the mount handling threads joinable (and joins with them as they exit)
10 to ensure that the mount handling threads have completed before allowing
11 the main thread to complete.
14 daemon/automount.c | 35 +++++++++++++++++++++++------------
15 daemon/direct.c | 7 ++++---
16 daemon/indirect.c | 7 ++++---
17 daemon/state.c | 7 ++++---
18 include/master.h | 3 +++
19 lib/master.c | 38 ++++++++++++++++++++++++++++++++++----
20 modules/mount_autofs.c | 4 ++--
21 7 files changed, 74 insertions(+), 27 deletions(-)
24 diff --git a/daemon/automount.c b/daemon/automount.c
25 index e120f50..f04273f 100644
26 --- a/daemon/automount.c
27 +++ b/daemon/automount.c
28 @@ -69,8 +69,9 @@ static size_t kpkt_len;
29 /* Does kernel know about SOCK_CLOEXEC and friends */
30 static int cloexec_works = 0;
32 -/* Attribute to create detached thread */
33 -pthread_attr_t thread_attr;
34 +/* Attributes for creating detached and joinable threads */
35 +pthread_attr_t th_attr;
36 +pthread_attr_t th_attr_detached;
38 struct master_readmap_cond mrc = {
39 PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, NULL, 0, 0, 0, 0};
40 @@ -1192,7 +1193,7 @@ static pthread_t do_signals(struct master *master, int sig)
44 - status = pthread_create(&thid, &thread_attr, do_notify_state, &r_sig);
45 + status = pthread_create(&thid, &th_attr_detached, do_notify_state, &r_sig);
48 "mount state notify thread create failed");
49 @@ -1281,7 +1282,7 @@ static int do_hup_signal(struct master *master, time_t age)
53 - status = pthread_create(&thid, &thread_attr, do_read_master, NULL);
54 + status = pthread_create(&thid, &th_attr_detached, do_read_master, NULL);
57 "master read map thread create failed");
58 @@ -1327,7 +1328,7 @@ static void *statemachine(void *arg)
62 - if (master_list_empty(master_list))
63 + if (master_done(master_list))
66 do_signals(master_list, sig);
67 @@ -1448,8 +1449,6 @@ static void handle_mounts_cleanup(void *arg)
68 master_mutex_unlock();
70 destroy_logpri_fifo(ap);
71 - master_free_mapent_sources(ap->entry, 1);
72 - master_free_mapent(ap->entry);
75 if (rmdir(path) == -1) {
76 @@ -1461,8 +1460,12 @@ static void handle_mounts_cleanup(void *arg)
78 info(logopt, "shut down path %s", path);
80 - /* If we are the last tell the state machine to shutdown */
81 - if (!submount && master_list_empty(master_list))
83 + * If we are not a submount send a signal to the signal handler
84 + * so it can join with any completed handle_mounts() threads and
85 + * perform final cleanup.
88 pthread_kill(state_mach_thid, SIGTERM);
91 @@ -1980,7 +1983,15 @@ int main(int argc, char *argv[])
95 - if (pthread_attr_init(&thread_attr)) {
96 + if (pthread_attr_init(&th_attr)) {
97 + logerr("%s: failed to init thread attribute struct!",
99 + close(start_pipefd[1]);
100 + release_flag_file();
104 + if (pthread_attr_init(&th_attr_detached)) {
105 logerr("%s: failed to init thread attribute struct!",
107 close(start_pipefd[1]);
108 @@ -1989,7 +2000,7 @@ int main(int argc, char *argv[])
111 if (pthread_attr_setdetachstate(
112 - &thread_attr, PTHREAD_CREATE_DETACHED)) {
113 + &th_attr_detached, PTHREAD_CREATE_DETACHED)) {
114 logerr("%s: failed to set detached thread attribute!",
116 close(start_pipefd[1]);
117 @@ -1999,7 +2010,7 @@ int main(int argc, char *argv[])
119 #ifdef _POSIX_THREAD_ATTR_STACKSIZE
120 if (pthread_attr_setstacksize(
121 - &thread_attr, PTHREAD_STACK_MIN*64)) {
122 + &th_attr_detached, PTHREAD_STACK_MIN*64)) {
123 logerr("%s: failed to set stack size thread attribute!",
125 close(start_pipefd[1]);
126 diff --git a/daemon/direct.c b/daemon/direct.c
127 index c0243c4..d9dda3d 100644
128 --- a/daemon/direct.c
129 +++ b/daemon/direct.c
132 #include "automount.h"
134 -extern pthread_attr_t thread_attr;
135 +/* Attribute to create detached thread */
136 +extern pthread_attr_t th_attr_detached;
140 @@ -1142,7 +1143,7 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
141 debug(ap->logopt, "token %ld, name %s",
142 (unsigned long) pkt->wait_queue_token, mt->name);
144 - status = pthread_create(&thid, &thread_attr, do_expire_direct, mt);
145 + status = pthread_create(&thid, &th_attr_detached, do_expire_direct, mt);
147 error(ap->logopt, "expire thread create failed");
148 ops->send_fail(ap->logopt,
149 @@ -1451,7 +1452,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
151 mt->wait_queue_token = pkt->wait_queue_token;
153 - status = pthread_create(&thid, &thread_attr, do_mount_direct, mt);
154 + status = pthread_create(&thid, &th_attr_detached, do_mount_direct, mt);
156 error(ap->logopt, "missing mount thread create failed");
157 ops->send_fail(ap->logopt,
158 diff --git a/daemon/indirect.c b/daemon/indirect.c
159 index 9d3745c..0721707 100644
160 --- a/daemon/indirect.c
161 +++ b/daemon/indirect.c
164 #include "automount.h"
166 -extern pthread_attr_t thread_attr;
167 +/* Attribute to create detached thread */
168 +extern pthread_attr_t th_attr_detached;
170 static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER;
172 @@ -647,7 +648,7 @@ int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_
174 mt->wait_queue_token = pkt->wait_queue_token;
176 - status = pthread_create(&thid, &thread_attr, do_expire_indirect, mt);
177 + status = pthread_create(&thid, &th_attr_detached, do_expire_indirect, mt);
179 error(ap->logopt, "expire thread create failed");
180 ops->send_fail(ap->logopt,
181 @@ -835,7 +836,7 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin
183 mt->wait_queue_token = pkt->wait_queue_token;
185 - status = pthread_create(&thid, &thread_attr, do_mount_indirect, mt);
186 + status = pthread_create(&thid, &th_attr_detached, do_mount_indirect, mt);
188 error(ap->logopt, "expire thread create failed");
189 ops->send_fail(ap->logopt,
190 diff --git a/daemon/state.c b/daemon/state.c
191 index 87c16a6..cd63be1 100644
196 #include "automount.h"
198 -extern pthread_attr_t thread_attr;
199 +/* Attribute to create detached thread */
200 +extern pthread_attr_t th_attr_detached;
204 @@ -292,7 +293,7 @@ static enum expire expire_proc(struct autofs_point *ap, int now)
206 expire = expire_proc_direct;
208 - status = pthread_create(&thid, &thread_attr, expire, ea);
209 + status = pthread_create(&thid, &th_attr_detached, expire, ea);
212 "expire thread create for %s failed", ap->path);
213 @@ -519,7 +520,7 @@ static unsigned int st_readmap(struct autofs_point *ap)
217 - status = pthread_create(&thid, &thread_attr, do_readmap, ra);
218 + status = pthread_create(&thid, &th_attr_detached, do_readmap, ra);
220 error(ap->logopt, "read map thread create failed");
221 st_readmap_cleanup(ra);
222 diff --git a/include/master.h b/include/master.h
223 index 6d801a9..c519e97 100644
224 --- a/include/master.h
225 +++ b/include/master.h
226 @@ -48,6 +48,7 @@ struct master_mapent {
227 struct map_source *maps;
228 struct autofs_point *ap;
229 struct list_head list;
230 + struct list_head join;
234 @@ -61,6 +62,7 @@ struct master {
236 struct mapent_cache *nc;
237 struct list_head mounts;
238 + struct list_head completed;
241 /* From the yacc master map parser */
242 @@ -109,6 +111,7 @@ void master_notify_state_change(struct master *, int);
243 int master_mount_mounts(struct master *, time_t, int);
244 extern inline unsigned int master_get_logopt(void);
245 int master_list_empty(struct master *);
246 +int master_done(struct master *);
247 int master_kill(struct master *);
250 diff --git a/lib/master.c b/lib/master.c
251 index e1cc062..762094f 100644
254 @@ -32,8 +32,8 @@ struct master *master_list = NULL;
256 extern long global_negative_timeout;
258 -/* Attribute to create detached thread */
259 -extern pthread_attr_t thread_attr;
260 +/* Attribute to create a joinable thread */
261 +extern pthread_attr_t th_attr;
263 extern struct startup_cond suc;
265 @@ -704,11 +704,16 @@ void master_add_mapent(struct master *master, struct master_mapent *entry)
267 void master_remove_mapent(struct master_mapent *entry)
269 + struct master *master = entry->master;
271 if (entry->ap->submount)
274 - if (!list_empty(&entry->list))
275 + if (!list_empty(&entry->list)) {
276 list_del_init(&entry->list);
277 + list_add(&entry->join, &master->completed);
283 @@ -786,6 +791,7 @@ struct master *master_new(const char *name, unsigned int timeout, unsigned int g
284 master->logopt = master->default_logging;
286 INIT_LIST_HEAD(&master->mounts);
287 + INIT_LIST_HEAD(&master->completed);
291 @@ -993,7 +999,7 @@ static int master_do_mount(struct master_mapent *entry)
293 debug(ap->logopt, "mounting %s", entry->path);
295 - status = pthread_create(&thid, &thread_attr, handle_mounts, &suc);
296 + status = pthread_create(&thid, &th_attr, handle_mounts, &suc);
299 "failed to create mount handler thread for %s",
300 @@ -1170,6 +1176,30 @@ int master_list_empty(struct master *master)
304 +int master_done(struct master *master)
306 + struct list_head *head, *p;
307 + struct master_mapent *entry;
310 + master_mutex_lock();
311 + head = &master->completed;
313 + while (p != head) {
314 + entry = list_entry(p, struct master_mapent, join);
316 + list_del(&entry->join);
317 + pthread_join(entry->thid, NULL);
318 + master_free_mapent_sources(entry, 1);
319 + master_free_mapent(entry);
321 + if (list_empty(&master->mounts))
323 + master_mutex_unlock();
328 inline unsigned int master_get_logopt(void)
330 return master_list ? master_list->logopt : LOGOPT_NONE;
331 diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c
332 index 82a5ef3..44fc043 100644
333 --- a/modules/mount_autofs.c
334 +++ b/modules/mount_autofs.c
336 #define MODPREFIX "mount(autofs): "
338 /* Attribute to create detached thread */
339 -extern pthread_attr_t thread_attr;
340 +extern pthread_attr_t th_attr_detached;
341 extern struct startup_cond suc;
343 int mount_version = AUTOFS_MOUNT_VERSION; /* Required by protocol */
344 @@ -235,7 +235,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
348 - if (pthread_create(&thid, &thread_attr, handle_mounts, &suc)) {
349 + if (pthread_create(&thid, &th_attr_detached, handle_mounts, &suc)) {
352 "failed to create mount handler thread for %s",