]> git.pld-linux.org Git - packages/autofs.git/blob - autofs-5.0.4-library-reload-fix-update.patch
- import latest patchset.
[packages/autofs.git] / autofs-5.0.4-library-reload-fix-update.patch
1 autofs-5.0.4 - library reload fix update
2
3 From: Ian Kent <raven@themaw.net>
4
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.
12 ---
13
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(-)
22
23
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;
31  
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;
37  
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)
41         if (status)
42                 fatal(status);
43  
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);
46         if (status) {
47                 error(master->logopt,
48                       "mount state notify thread create failed");
49 @@ -1281,7 +1282,7 @@ static int do_hup_signal(struct master *master, time_t age)
50  
51         master->reading = 1;
52  
53 -       status = pthread_create(&thid, &thread_attr, do_read_master, NULL);
54 +       status = pthread_create(&thid, &th_attr_detached, do_read_master, NULL);
55         if (status) {
56                 error(logopt,
57                       "master read map thread create failed");
58 @@ -1327,7 +1328,7 @@ static void *statemachine(void *arg)
59                 case SIGTERM:
60                 case SIGINT:
61                 case SIGUSR2:
62 -                       if (master_list_empty(master_list))
63 +                       if (master_done(master_list))
64                                 return NULL;
65                 case SIGUSR1:
66                         do_signals(master_list, sig);
67 @@ -1448,8 +1449,6 @@ static void handle_mounts_cleanup(void *arg)
68         master_mutex_unlock();
69  
70         destroy_logpri_fifo(ap);
71 -       master_free_mapent_sources(ap->entry, 1);
72 -       master_free_mapent(ap->entry);
73  
74         if (clean) {
75                 if (rmdir(path) == -1) {
76 @@ -1461,8 +1460,12 @@ static void handle_mounts_cleanup(void *arg)
77  
78         info(logopt, "shut down path %s", path);
79  
80 -       /* If we are the last tell the state machine to shutdown */
81 -       if (!submount && master_list_empty(master_list))
82 +       /*
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.
86 +        */
87 +       if (!submount)
88                 pthread_kill(state_mach_thid, SIGTERM);
89         
90         return;
91 @@ -1980,7 +1983,15 @@ int main(int argc, char *argv[])
92                 exit(1);
93         }
94  
95 -       if (pthread_attr_init(&thread_attr)) {
96 +       if (pthread_attr_init(&th_attr)) {
97 +               logerr("%s: failed to init thread attribute struct!",
98 +                    program);
99 +               close(start_pipefd[1]);
100 +               release_flag_file();
101 +               exit(1);
102 +       }
103 +
104 +       if (pthread_attr_init(&th_attr_detached)) {
105                 logerr("%s: failed to init thread attribute struct!",
106                      program);
107                 close(start_pipefd[1]);
108 @@ -1989,7 +2000,7 @@ int main(int argc, char *argv[])
109         }
110  
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!",
115                      program);
116                 close(start_pipefd[1]);
117 @@ -1999,7 +2010,7 @@ int main(int argc, char *argv[])
118  
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!",
124                        program);
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
130 @@ -37,7 +37,8 @@
131  
132  #include "automount.h"
133  
134 -extern pthread_attr_t thread_attr;
135 +/* Attribute to create detached thread */
136 +extern pthread_attr_t th_attr_detached;
137  
138  struct mnt_params {
139         char *options;
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);
143  
144 -       status = pthread_create(&thid, &thread_attr, do_expire_direct, mt);
145 +       status = pthread_create(&thid, &th_attr_detached, do_expire_direct, mt);
146         if (status) {
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_
150         mt->gid = pkt->gid;
151         mt->wait_queue_token = pkt->wait_queue_token;
152  
153 -       status = pthread_create(&thid, &thread_attr, do_mount_direct, mt);
154 +       status = pthread_create(&thid, &th_attr_detached, do_mount_direct, mt);
155         if (status) {
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
162 @@ -36,7 +36,8 @@
163  
164  #include "automount.h"
165  
166 -extern pthread_attr_t thread_attr;
167 +/* Attribute to create detached thread */
168 +extern pthread_attr_t th_attr_detached;
169  
170  static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER;
171  
172 @@ -647,7 +648,7 @@ int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_
173         mt->len = pkt->len;
174         mt->wait_queue_token = pkt->wait_queue_token;
175  
176 -       status = pthread_create(&thid, &thread_attr, do_expire_indirect, mt);
177 +       status = pthread_create(&thid, &th_attr_detached, do_expire_indirect, mt);
178         if (status) {
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
182         mt->gid = pkt->gid;
183         mt->wait_queue_token = pkt->wait_queue_token;
184  
185 -       status = pthread_create(&thid, &thread_attr, do_mount_indirect, mt);
186 +       status = pthread_create(&thid, &th_attr_detached, do_mount_indirect, mt);
187         if (status) {
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
192 --- a/daemon/state.c
193 +++ b/daemon/state.c
194 @@ -16,7 +16,8 @@
195  
196  #include "automount.h"
197  
198 -extern pthread_attr_t thread_attr;
199 +/* Attribute to create detached thread */
200 +extern pthread_attr_t th_attr_detached;
201  
202  struct state_queue {
203         pthread_t thid;
204 @@ -292,7 +293,7 @@ static enum expire expire_proc(struct autofs_point *ap, int now)
205         else
206                 expire = expire_proc_direct;
207  
208 -       status = pthread_create(&thid, &thread_attr, expire, ea);
209 +       status = pthread_create(&thid, &th_attr_detached, expire, ea);
210         if (status) {
211                 error(ap->logopt,
212                       "expire thread create for %s failed", ap->path);
213 @@ -519,7 +520,7 @@ static unsigned int st_readmap(struct autofs_point *ap)
214         ra->ap = ap;
215         ra->now = now;
216  
217 -       status = pthread_create(&thid, &thread_attr, do_readmap, ra);
218 +       status = pthread_create(&thid, &th_attr_detached, do_readmap, ra);
219         if (status) {
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;
231  };
232  
233  struct master {
234 @@ -61,6 +62,7 @@ struct master {
235         unsigned int logopt;
236         struct mapent_cache *nc;
237         struct list_head mounts;
238 +       struct list_head completed;
239  };
240  
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 *);
248  
249  #endif
250 diff --git a/lib/master.c b/lib/master.c
251 index e1cc062..762094f 100644
252 --- a/lib/master.c
253 +++ b/lib/master.c
254 @@ -32,8 +32,8 @@ struct master *master_list = NULL;
255  
256  extern long global_negative_timeout;
257  
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;
262  
263  extern struct startup_cond suc;
264  
265 @@ -704,11 +704,16 @@ void master_add_mapent(struct master *master, struct master_mapent *entry)
266  
267  void master_remove_mapent(struct master_mapent *entry)
268  {
269 +       struct master *master = entry->master;
270 +
271         if (entry->ap->submount)
272                 return;
273  
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);
278 +       }
279 +
280         return;
281  }
282  
283 @@ -786,6 +791,7 @@ struct master *master_new(const char *name, unsigned int timeout, unsigned int g
284         master->logopt = master->default_logging;
285  
286         INIT_LIST_HEAD(&master->mounts);
287 +       INIT_LIST_HEAD(&master->completed);
288  
289         return master;
290  }
291 @@ -993,7 +999,7 @@ static int master_do_mount(struct master_mapent *entry)
292  
293         debug(ap->logopt, "mounting %s", entry->path);
294  
295 -       status = pthread_create(&thid, &thread_attr, handle_mounts, &suc);
296 +       status = pthread_create(&thid, &th_attr, handle_mounts, &suc);
297         if (status) {
298                 crit(ap->logopt,
299                      "failed to create mount handler thread for %s",
300 @@ -1170,6 +1176,30 @@ int master_list_empty(struct master *master)
301         return res;
302  }
303  
304 +int master_done(struct master *master)
305 +{
306 +       struct list_head *head, *p;
307 +       struct master_mapent *entry;
308 +       int res = 0;
309 +
310 +       master_mutex_lock();
311 +       head = &master->completed;
312 +       p = head->next;
313 +       while (p != head) {
314 +               entry = list_entry(p, struct master_mapent, join);
315 +               p = p->next;
316 +               list_del(&entry->join);
317 +               pthread_join(entry->thid, NULL);
318 +               master_free_mapent_sources(entry, 1);
319 +               master_free_mapent(entry);
320 +       }
321 +       if (list_empty(&master->mounts))
322 +               res = 1;
323 +       master_mutex_unlock();
324 +
325 +       return res;
326 +}
327 +
328  inline unsigned int master_get_logopt(void)
329  {
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
335 @@ -30,7 +30,7 @@
336  #define MODPREFIX "mount(autofs): "
337  
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;
342  
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,
345         suc.done = 0;
346         suc.status = 0;
347  
348 -       if (pthread_create(&thid, &thread_attr, handle_mounts, &suc)) {
349 +       if (pthread_create(&thid, &th_attr_detached, handle_mounts, &suc)) {
350                 crit(ap->logopt,
351                      MODPREFIX
352                      "failed to create mount handler thread for %s",
This page took 0.101539 seconds and 3 git commands to generate.