~ubuntu-branches/ubuntu/raring/autofs5/raring

« back to all changes in this revision

Viewing changes to daemon/direct.c

  • Committer: Bazaar Package Importer
  • Author(s): Jan Christoph Nordholz
  • Date: 2009-03-09 01:16:48 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20090309011648-gjynlid883f0s2c4
Tags: 5.0.4-1
* New upstream version (5.0.4 plus patchset as of 2009/03/09).
  * Closes: #518728.
  * Remove dpatch 14, applied upstream.
* New dpatch 14 to avoid using the relatively young SOCK_CLOEXEC
  feature.
* Only invoke 'make clean' on clean target so ./configure isn't
  purged.
* Fix a typo in the postinst regarding the ucf conffile handling.
* Add 'set -e' to package maintenance scripts.
* Drop unnecessary /var/run/autofs from package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 * ----------------------------------------------------------------------- */
21
21
 
22
22
#include <dirent.h>
 
23
#include <libgen.h>
23
24
#include <fcntl.h>
24
25
#include <signal.h>
25
26
#include <stdio.h>
35
36
#include <sys/mount.h>
36
37
#include <sys/vfs.h>
37
38
#include <sched.h>
38
 
#include <pwd.h>
39
 
#include <grp.h>
40
39
 
41
40
#include "automount.h"
42
41
 
50
49
pthread_key_t key_mnt_offset_params;
51
50
pthread_once_t key_mnt_params_once = PTHREAD_ONCE_INIT;
52
51
 
53
 
static pthread_mutex_t ma_mutex = PTHREAD_MUTEX_INITIALIZER;
54
52
static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER;
55
53
 
56
54
static void key_mnt_params_destroy(void *arg)
88
86
 
89
87
int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me)
90
88
{
 
89
        struct ioctl_ops *ops = get_ioctl_ops();
91
90
        char buf[MAX_ERR_BUF];
92
91
        int ioctlfd, rv, left, retries;
93
92
 
106
105
                        return 1;
107
106
                }
108
107
                ioctlfd = me->ioctlfd;
109
 
        } else {
110
 
                int cl_flags;
111
 
 
112
 
                ioctlfd = open(me->key, O_RDONLY);
113
 
                if (ioctlfd != -1) {
114
 
                        if ((cl_flags = fcntl(ioctlfd, F_GETFD, 0)) != -1) {
115
 
                                cl_flags |= FD_CLOEXEC;
116
 
                                fcntl(ioctlfd, F_SETFD, cl_flags);
117
 
                        }
118
 
                }
119
 
        }
120
 
 
 
108
        } else
 
109
                ops->open(ap->logopt, &ioctlfd, me->dev, me->key);
121
110
 
122
111
        if (ioctlfd >= 0) {
123
 
                int status = 1;
 
112
                unsigned int status = 1;
124
113
 
125
 
                rv = ioctl(ioctlfd, AUTOFS_IOC_ASKUMOUNT, &status);
 
114
                rv = ops->askumount(ap->logopt, ioctlfd, &status);
126
115
                if (rv) {
127
116
                        char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
128
117
                        error(ap->logopt, "ioctl failed: %s", estr);
135
124
                                return 1;
136
125
                        } else {
137
126
                                me->ioctlfd = -1;
138
 
                                ioctl(ioctlfd, AUTOFS_IOC_CATATONIC, 0);
139
 
                                close(ioctlfd);
 
127
                                ops->catatonic(ap->logopt, ioctlfd);
 
128
                                ops->close(ap->logopt, ioctlfd);
140
129
                                goto force_umount;
141
130
                        }
142
131
                }
143
132
                me->ioctlfd = -1;
144
 
                ioctl(ioctlfd, AUTOFS_IOC_CATATONIC, 0);
145
 
                close(ioctlfd);
 
133
                ops->catatonic(ap->logopt, ioctlfd);
 
134
                ops->close(ap->logopt, ioctlfd);
146
135
        } else {
147
 
                char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
148
136
                error(ap->logopt,
149
137
                      "couldn't get ioctl fd for direct mount %s", me->key);
150
 
                debug(ap->logopt, "open: %s", estr);
151
138
                return 1;
152
139
        }
153
140
 
155
142
 
156
143
        retries = UMOUNT_RETRIES;
157
144
        while ((rv = umount(me->key)) == -1 && retries--) {
158
 
                struct timespec tm = {0, 100000000};
 
145
                struct timespec tm = {0, 200000000};
159
146
                if (errno != EBUSY)
160
147
                        break;
161
148
                nanosleep(&tm, NULL);
191
178
        } else
192
179
                info(ap->logopt, "umounted direct mount %s", me->key);
193
180
 
194
 
        if (!rv && me->dir_created) {
 
181
        if (!rv && me->flags & MOUNT_FLAG_DIR_CREATED) {
195
182
                if  (rmdir(me->key) == -1) {
196
183
                        char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
197
184
                        warn(ap->logopt, "failed to remove dir %s: %s",
219
206
 
220
207
        mnts = tree_make_mnt_tree(_PROC_MOUNTS, "/");
221
208
        pthread_cleanup_push(mnts_cleanup, mnts);
222
 
        pthread_cleanup_push(master_source_lock_cleanup, ap->entry);
223
 
        master_source_readlock(ap->entry);
224
209
        nc = ap->entry->master->nc;
225
210
        cache_readlock(nc);
226
211
        pthread_cleanup_push(cache_lock_cleanup, nc);
247
232
        }
248
233
        pthread_cleanup_pop(1);
249
234
        pthread_cleanup_pop(1);
250
 
        pthread_cleanup_pop(1);
251
235
 
252
236
        return 0;
253
237
}
275
259
                else
276
260
                        rv = umount2(mnt->path, MNT_DETACH);
277
261
                if (rv == -1) {
278
 
                        ret = 0;
279
262
                        debug(ap->logopt,
280
263
                              "can't unlink %s from mount tree", mnt->path);
281
264
 
287
270
 
288
271
                        case ENOENT:
289
272
                        case EFAULT:
 
273
                                ret = 0;
290
274
                                warn(ap->logopt, "bad path for mount");
291
275
                                break;
292
276
                        }
295
279
        return ret;
296
280
}
297
281
 
298
 
int do_mount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me)
 
282
static int unlink_active_mounts(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me)
299
283
{
300
 
        struct mnt_params *mp;
301
 
        time_t timeout = ap->exp_timeout;
302
 
        struct stat st;
303
 
        int status, ret, ioctlfd, cl_flags;
 
284
        struct ioctl_ops *ops = get_ioctl_ops();
304
285
        struct list_head list;
305
 
        const char *map_name;
306
286
 
307
287
        INIT_LIST_HEAD(&list);
308
288
 
313
293
 
314
294
                        save_ioctlfd = ioctlfd = me->ioctlfd;
315
295
 
316
 
                        if (ioctlfd == -1) {
317
 
                                ioctlfd = open(me->key, O_RDONLY);
318
 
                                if (ioctlfd != -1) {
319
 
                                        cl_flags = fcntl(ioctlfd, F_GETFD, 0);
320
 
                                        if (cl_flags != -1) {
321
 
                                                cl_flags |= FD_CLOEXEC;
322
 
                                                fcntl(ioctlfd, F_SETFD, cl_flags);
323
 
                                        }
324
 
                                }
325
 
                        }
 
296
                        if (ioctlfd == -1)
 
297
                                ops->open(ap->logopt,
 
298
                                          &ioctlfd, me->dev, me->key);
326
299
 
327
300
                        if (ioctlfd < 0) {
328
301
                                error(ap->logopt,
331
304
                                return 0;
332
305
                        }
333
306
 
334
 
                        ioctl(ioctlfd, AUTOFS_IOC_SETTIMEOUT, &tout);
 
307
                        ops->timeout(ap->logopt, ioctlfd, &tout);
335
308
 
336
309
                        if (save_ioctlfd == -1)
337
 
                                close(ioctlfd);
338
 
 
339
 
                        return 0;
340
 
                }
341
 
                if (!unlink_mount_tree(ap, &list)) {
342
 
                        debug(ap->logopt,
343
 
                              "already mounted as other than autofs "
344
 
                              "or failed to unlink entry in tree");
345
 
                        return -1;
346
 
                }
347
 
        }
348
 
 
349
 
        if (me->ioctlfd != -1) {
350
 
                error(ap->logopt, "active direct mount %s", me->key);
351
 
                return -1;
 
310
                                ops->close(ap->logopt, ioctlfd);
 
311
 
 
312
                        return 0;
 
313
                }
 
314
        }
 
315
 
 
316
        if (!unlink_mount_tree(ap, &list)) {
 
317
                debug(ap->logopt,
 
318
                      "already mounted as other than autofs "
 
319
                      "or failed to unlink entry in tree");
 
320
                return 0;
 
321
        }
 
322
 
 
323
        return 1;
 
324
}
 
325
 
 
326
int do_mount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me)
 
327
{
 
328
        const char *str_direct = mount_type_str(t_direct);
 
329
        struct ioctl_ops *ops = get_ioctl_ops();
 
330
        struct mnt_params *mp;
 
331
        time_t timeout = ap->exp_timeout;
 
332
        struct stat st;
 
333
        int status, ret, ioctlfd;
 
334
        const char *map_name;
 
335
 
 
336
        /* Calculate the timeouts */
 
337
        ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
 
338
 
 
339
        if (ops->version) {
 
340
                ap->flags |= MOUNT_FLAG_REMOUNT;
 
341
                ret = try_remount(ap, me, t_direct);
 
342
                ap->flags &= ~MOUNT_FLAG_REMOUNT;
 
343
                if (ret == 1)
 
344
                        return 0;
 
345
                if (ret == 0)
 
346
                        return -1;
 
347
        } else {
 
348
                /*
 
349
                 * A return of 0 indicates we're re-reading the map.
 
350
                 * A return of 1 indicates we successfully unlinked
 
351
                 * the mount tree if there was one. A return of -1
 
352
                 * inducates we failed to unlink the mount tree so
 
353
                 * we have to return a failure.
 
354
                 */
 
355
                ret = unlink_active_mounts(ap, mnts, me);
 
356
                if (ret == -1 || ret == 0)
 
357
                        return ret;
 
358
 
 
359
                if (me->ioctlfd != -1) {
 
360
                        error(ap->logopt, "active direct mount %s", me->key);
 
361
                        return -1;
 
362
                }
352
363
        }
353
364
 
354
365
        status = pthread_once(&key_mnt_params_once, key_mnt_params_init);
374
385
        }
375
386
 
376
387
        if (!mp->options) {
377
 
                mp->options = make_options_string(ap->path, ap->kpipefd, "direct");
 
388
                mp->options = make_options_string(ap->path, ap->kpipefd, str_direct);
378
389
                if (!mp->options)
379
390
                        return 0;
380
391
        }
388
399
                }
389
400
                /* If we recieve an error, and it's EEXIST or EROFS we know
390
401
                   the directory was not created. */
391
 
                me->dir_created = 0;
 
402
                me->flags &= ~MOUNT_FLAG_DIR_CREATED;
392
403
        } else {
393
404
                /* No errors so the directory was successfully created */
394
 
                me->dir_created = 1;
 
405
                me->flags |= MOUNT_FLAG_DIR_CREATED;
395
406
        }
396
407
 
397
408
        map_name = me->mc->map->argv[0];
402
413
                goto out_err;
403
414
        }
404
415
 
405
 
        /* Root directory for ioctl()'s */
406
 
        ioctlfd = open(me->key, O_RDONLY);
407
 
        if (ioctlfd < 0) {
408
 
                crit(ap->logopt, "failed to create ioctl fd for %s", me->key);
409
 
                goto out_umount;
410
 
        }
411
 
 
412
 
        if ((cl_flags = fcntl(ioctlfd, F_GETFD, 0)) != -1) {
413
 
                cl_flags |= FD_CLOEXEC;
414
 
                fcntl(ioctlfd, F_SETFD, cl_flags);
415
 
        }
416
 
 
417
 
        /* Calculate the timeouts */
418
 
        ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
419
 
 
420
 
        ioctl(ioctlfd, AUTOFS_IOC_SETTIMEOUT, &timeout);
421
 
 
422
 
        if (ap->exp_timeout)
423
 
                info(ap->logopt,
424
 
                    "mounted direct mount on %s "
425
 
                    "with timeout %u, freq %u seconds", me->key,
426
 
                    (unsigned int) ap->exp_timeout,
427
 
                    (unsigned int) ap->exp_runfreq);
428
 
        else
429
 
                info(ap->logopt,
430
 
                     "mounted direct mount on %s with timeouts disabled",
431
 
                     me->key);
432
 
 
433
 
        ret = fstat(ioctlfd, &st);
 
416
        ret = stat(me->key, &st);
434
417
        if (ret == -1) {
435
418
                error(ap->logopt,
436
419
                      "failed to stat direct mount trigger %s", me->key);
437
 
                goto out_close;
438
 
        }
 
420
                goto out_umount;
 
421
        }
 
422
 
 
423
        ops->open(ap->logopt, &ioctlfd, st.st_dev, me->key);
 
424
        if (ioctlfd < 0) {
 
425
                crit(ap->logopt, "failed to create ioctl fd for %s", me->key);
 
426
                goto out_umount;
 
427
        }
 
428
 
 
429
        ops->timeout(ap->logopt, ioctlfd, &timeout);
 
430
        notify_mount_result(ap, me->key, str_direct);
439
431
        cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino);
440
 
 
441
 
        close(ioctlfd);
 
432
        ops->close(ap->logopt, ioctlfd);
442
433
 
443
434
        debug(ap->logopt, "mounted trigger %s", me->key);
444
435
 
445
436
        return 0;
446
437
 
447
 
out_close:
448
 
        close(ioctlfd);
449
438
out_umount:
450
439
        /* TODO: maybe force umount (-l) */
451
440
        umount(me->key);
452
441
out_err:
453
 
        if (me->dir_created)
 
442
        if (me->flags & MOUNT_FLAG_DIR_CREATED)
454
443
                rmdir(me->key);
455
444
 
456
445
        return -1;
482
471
        pthread_cleanup_push(master_source_lock_cleanup, ap->entry);
483
472
        master_source_readlock(ap->entry);
484
473
        nc = ap->entry->master->nc;
485
 
        cache_readlock(nc);
486
 
        pthread_cleanup_push(cache_lock_cleanup, nc);
487
474
        map = ap->entry->maps;
488
475
        while (map) {
489
476
                /*
496
483
                }
497
484
 
498
485
                mc = map->mc;
499
 
                pthread_cleanup_push(cache_lock_cleanup, mc);
500
 
                cache_readlock(mc);
501
486
                me = cache_enumerate(mc, NULL);
502
487
                while (me) {
503
488
                        ne = cache_lookup_distinct(nc, me->key);
525
510
 
526
511
                        me = cache_enumerate(mc, me);
527
512
                }
528
 
                pthread_cleanup_pop(1);
529
513
                map = map->next;
530
514
        }
531
515
        pthread_cleanup_pop(1);
532
516
        pthread_cleanup_pop(1);
533
 
        pthread_cleanup_pop(1);
534
517
 
535
518
        return 0;
536
519
}
537
520
 
538
521
int umount_autofs_offset(struct autofs_point *ap, struct mapent *me)
539
522
{
 
523
        struct ioctl_ops *ops = get_ioctl_ops();
540
524
        char buf[MAX_ERR_BUF];
541
 
        int ioctlfd, cl_flags, rv = 1, retries;
 
525
        int ioctlfd, rv = 1, retries;
542
526
 
543
527
        if (me->ioctlfd != -1) {
544
528
                if (is_mounted(_PATH_MOUNTED, me->key, MNTS_REAL)) {
555
539
                              me->key);
556
540
                        return 0;
557
541
                }
558
 
 
559
 
                ioctlfd = open(me->key, O_RDONLY);
560
 
                if (ioctlfd != -1) {
561
 
                        if ((cl_flags = fcntl(ioctlfd, F_GETFD, 0)) != -1) {
562
 
                                cl_flags |= FD_CLOEXEC;
563
 
                                fcntl(ioctlfd, F_SETFD, cl_flags);
564
 
                        }
565
 
                }
 
542
                ops->open(ap->logopt, &ioctlfd, me->dev, me->key);
566
543
        }
567
544
 
568
545
        if (ioctlfd >= 0) {
569
 
                int status = 1;
 
546
                unsigned int status = 1;
570
547
 
571
 
                rv = ioctl(ioctlfd, AUTOFS_IOC_ASKUMOUNT, &status);
 
548
                rv = ops->askumount(ap->logopt, ioctlfd, &status);
572
549
                if (rv) {
573
550
                        char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
574
551
                        logerr("ioctl failed: %s", estr);
575
552
                        return 1;
576
553
                } else if (!status) {
577
554
                        if (ap->state != ST_SHUTDOWN_FORCE) {
578
 
                                error(ap->logopt,
579
 
                                      "ask umount returned busy for %s",
580
 
                                      me->key);
 
555
                                if (ap->shutdown)
 
556
                                        error(ap->logopt,
 
557
                                             "ask umount returned busy for %s",
 
558
                                             me->key);
581
559
                                return 1;
582
560
                        } else {
583
561
                                me->ioctlfd = -1;
584
 
                                ioctl(ioctlfd, AUTOFS_IOC_CATATONIC, 0);
585
 
                                close(ioctlfd);
 
562
                                ops->catatonic(ap->logopt, ioctlfd);
 
563
                                ops->close(ap->logopt, ioctlfd);
586
564
                                goto force_umount;
587
565
                        }
588
566
                }
589
567
                me->ioctlfd = -1;
590
 
                ioctl(ioctlfd, AUTOFS_IOC_CATATONIC, 0);
591
 
                close(ioctlfd);
 
568
                ops->catatonic(ap->logopt, ioctlfd);
 
569
                ops->close(ap->logopt, ioctlfd);
592
570
        } else {
593
571
                struct stat st;
594
572
                char *estr;
609
587
 
610
588
        retries = UMOUNT_RETRIES;
611
589
        while ((rv = umount(me->key)) == -1 && retries--) {
612
 
                struct timespec tm = {0, 100000000};
 
590
                struct timespec tm = {0, 200000000};
613
591
                if (errno != EBUSY)
614
592
                        break;
615
593
                nanosleep(&tm, NULL);
641
619
        } else
642
620
                info(ap->logopt, "umounted offset mount %s", me->key);
643
621
 
644
 
        if (!rv && me->dir_created) {
 
622
        if (!rv && me->flags & MOUNT_FLAG_DIR_CREATED) {
645
623
                if  (rmdir(me->key) == -1) {
646
624
                        char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
647
625
                        warn(ap->logopt, "failed to remove dir %s: %s",
651
629
        return rv;
652
630
}
653
631
 
654
 
int mount_autofs_offset(struct autofs_point *ap, struct mapent *me)
 
632
int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char *root, const char *offset)
655
633
{
 
634
        const char *str_offset = mount_type_str(t_offset);
 
635
        struct ioctl_ops *ops = get_ioctl_ops();
656
636
        char buf[MAX_ERR_BUF];
657
637
        struct mnt_params *mp;
658
638
        time_t timeout = ap->exp_timeout;
659
639
        struct stat st;
660
 
        int ioctlfd, cl_flags, status, ret;
 
640
        int ioctlfd, status, ret;
661
641
        const char *type, *map_name = NULL;
662
 
 
663
 
        if (is_mounted(_PROC_MOUNTS, me->key, MNTS_AUTOFS)) {
664
 
                if (ap->state != ST_READMAP)
665
 
                        warn(ap->logopt,
666
 
                              "trigger %s already mounted", me->key);
667
 
                return 0;
668
 
        }
669
 
 
670
 
        if (me->ioctlfd != -1) {
671
 
                error(ap->logopt, "active offset mount %s", me->key);
672
 
                return -1;
 
642
        char mountpoint[PATH_MAX];
 
643
 
 
644
        if (ops->version && ap->flags & MOUNT_FLAG_REMOUNT) {
 
645
                ret = try_remount(ap, me, t_offset);
 
646
                if (ret == 1)
 
647
                        return MOUNT_OFFSET_OK;
 
648
                return MOUNT_OFFSET_FAIL;
 
649
        } else {
 
650
/*
 
651
                if (is_mounted(_PROC_MOUNTS, me->key, MNTS_AUTOFS)) {
 
652
                        if (ap->state != ST_READMAP)
 
653
                                warn(ap->logopt,
 
654
                                     "trigger %s already mounted", me->key);
 
655
                        return MOUNT_OFFSET_OK;
 
656
                }
 
657
*/
 
658
                if (me->ioctlfd != -1) {
 
659
                        error(ap->logopt, "active offset mount %s", me->key);
 
660
                        return MOUNT_OFFSET_FAIL;
 
661
                }
673
662
        }
674
663
 
675
664
        status = pthread_once(&key_mnt_params_once, key_mnt_params_init);
683
672
                        crit(ap->logopt,
684
673
                          "mnt_params value create failed for offset mount %s",
685
674
                          me->key);
686
 
                        return 0;
 
675
                        return MOUNT_OFFSET_OK;
687
676
                }
688
677
                mp->options = NULL;
689
678
 
695
684
        }
696
685
 
697
686
        if (!mp->options) {
698
 
                mp->options = make_options_string(ap->path, ap->kpipefd, "offset");
 
687
                mp->options = make_options_string(ap->path, ap->kpipefd, str_offset);
699
688
                if (!mp->options)
700
 
                        return 0;
 
689
                        return MOUNT_OFFSET_OK;
701
690
        }
702
691
 
 
692
        strcpy(mountpoint, root);
 
693
        strcat(mountpoint, offset);
 
694
 
703
695
        /* In case the directory doesn't exist, try to mkdir it */
704
 
        if (mkdir_path(me->key, 0555) < 0) {
 
696
        if (mkdir_path(mountpoint, 0555) < 0) {
705
697
                if (errno == EEXIST) {
 
698
                        /*
 
699
                         * If the mount point directory is a real mount
 
700
                         * and it isn't the root offset then it must be
 
701
                         * a mount that has been automatically mounted by
 
702
                         * the kernel NFS client.
 
703
                         */
 
704
                        if (me->multi != me &&
 
705
                            is_mounted(_PROC_MOUNTS, mountpoint, MNTS_REAL))
 
706
                                return MOUNT_OFFSET_IGNORE;
 
707
 
706
708
                        /* 
707
709
                         * If we recieve an error, and it's EEXIST
708
710
                         * we know the directory was not created.
709
711
                         */
710
 
                        me->dir_created = 0;
 
712
                        me->flags &= ~MOUNT_FLAG_DIR_CREATED;
711
713
                } else if (errno == EACCES) {
712
714
                        /*
713
715
                         * We require the mount point directory to exist when
720
722
                        char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
721
723
                        debug(ap->logopt,
722
724
                             "can't create mount directory: %s, %s",
723
 
                             me->key, estr);
724
 
                        return -1;
 
725
                             mountpoint, estr);
 
726
                        return MOUNT_OFFSET_FAIL;
725
727
                } else {
726
728
                        char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
727
729
                        crit(ap->logopt,
728
730
                             "failed to create mount directory: %s, %s",
729
 
                             me->key, estr);
730
 
                        return -1;
 
731
                             mountpoint, estr);
 
732
                        return MOUNT_OFFSET_FAIL;
731
733
                }
732
734
        } else {
733
735
                /* No errors so the directory was successfully created */
734
 
                me->dir_created = 1;
 
736
                me->flags |= MOUNT_FLAG_DIR_CREATED;
735
737
        }
736
738
 
737
739
        debug(ap->logopt,
738
740
              "calling mount -t autofs " SLOPPY " -o %s automount %s",
739
 
              mp->options, me->key);
 
741
              mp->options, mountpoint);
740
742
 
741
743
        type = ap->entry->maps->type;
742
744
        if (type && !strcmp(ap->entry->maps->type, "hosts")) {
748
750
        } else
749
751
                map_name = me->mc->map->argv[0];
750
752
 
751
 
        ret = mount(map_name, me->key, "autofs", MS_MGC_VAL, mp->options);
 
753
        ret = mount(map_name, mountpoint, "autofs", MS_MGC_VAL, mp->options);
752
754
        if (ret) {
753
 
                crit(ap->logopt, "failed to mount autofs path %s", me->key);
754
 
                goto out_err;
755
 
        }
756
 
 
757
 
        if (ret != 0) {
758
755
                crit(ap->logopt,
759
 
                     "failed to mount autofs offset trigger %s", me->key);
 
756
                     "failed to mount offset trigger %s at %s",
 
757
                     me->key, mountpoint);
760
758
                goto out_err;
761
759
        }
762
760
 
763
 
        /* Root directory for ioctl()'s */
764
 
        ioctlfd = open(me->key, O_RDONLY);
765
 
        if (ioctlfd < 0) {
766
 
                crit(ap->logopt, "failed to create ioctl fd for %s", me->key);
767
 
                goto out_umount;
768
 
        }
769
 
 
770
 
        if ((cl_flags = fcntl(ioctlfd, F_GETFD, 0)) != -1) {
771
 
                cl_flags |= FD_CLOEXEC;
772
 
                fcntl(ioctlfd, F_SETFD, cl_flags);
773
 
        }
774
 
 
775
 
        ioctl(ioctlfd, AUTOFS_IOC_SETTIMEOUT, &timeout);
776
 
 
777
 
        ret = fstat(ioctlfd, &st);
 
761
        ret = stat(mountpoint, &st);
778
762
        if (ret == -1) {
779
763
                error(ap->logopt,
780
 
                     "failed to stat direct mount trigger %s", me->key);
781
 
                goto out_close;
782
 
        }
783
 
 
 
764
                     "failed to stat direct mount trigger %s", mountpoint);
 
765
                goto out_umount;
 
766
        }
 
767
 
 
768
        ops->open(ap->logopt, &ioctlfd, st.st_dev, mountpoint);
 
769
        if (ioctlfd < 0) {
 
770
                crit(ap->logopt, "failed to create ioctl fd for %s", mountpoint);
 
771
                goto out_umount;
 
772
        }
 
773
 
 
774
        ops->timeout(ap->logopt, ioctlfd, &timeout);
 
775
        notify_mount_result(ap, mountpoint, str_offset);
784
776
        cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino);
785
 
 
786
 
        close(ioctlfd);
787
 
 
788
 
        debug(ap->logopt, "mounted trigger %s", me->key);
789
 
 
790
 
        return 0;
791
 
 
792
 
out_close:
793
 
        close(ioctlfd);
 
777
        ops->close(ap->logopt, ioctlfd);
 
778
 
 
779
        debug(ap->logopt, "mounted trigger %s at %s", me->key, mountpoint);
 
780
 
 
781
        return MOUNT_OFFSET_OK;
 
782
 
794
783
out_umount:
795
 
        umount(me->key);
 
784
        umount(mountpoint);
796
785
out_err:
797
 
        if (stat(me->key, &st) == 0 && me->dir_created)
798
 
                 rmdir_path(ap, me->key, st.st_dev);
799
 
 
800
 
        return -1;
801
 
}
802
 
 
803
 
static int expire_direct(int ioctlfd, const char *path, unsigned int when, unsigned int logopt)
804
 
{
805
 
        char buf[MAX_ERR_BUF];
806
 
        int ret, retries;
807
 
        struct stat st;
808
 
 
809
 
        if (fstat(ioctlfd, &st) == -1) {
810
 
                char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
811
 
                error(logopt, "fstat failed: %s", estr);
812
 
                return 0;
813
 
        }
814
 
 
815
 
        retries = (count_mounts(logopt, path, st.st_dev) + 1) * EXPIRE_RETRIES;
816
 
 
817
 
        while (retries--) {
818
 
                struct timespec tm = {0, 100000000};
819
 
 
820
 
                /* Ggenerate expire message for the mount. */
821
 
                ret = ioctl(ioctlfd, AUTOFS_IOC_EXPIRE_DIRECT, &when);
822
 
                if (ret == -1) {
823
 
                        /* Mount has gone away */
824
 
                        if (errno == EBADF || errno == EINVAL)
825
 
                                return 1;
826
 
 
827
 
                        /* Other than need to wait for the kernel ? */
828
 
                        if (errno != EAGAIN)
829
 
                                return 0;
830
 
                }
831
 
 
832
 
                nanosleep(&tm, NULL);
833
 
        }
834
 
 
835
 
        if (!ioctl(ioctlfd, AUTOFS_IOC_ASKUMOUNT, &ret)) {
836
 
                if (!ret)
837
 
                        return 0;
838
 
        }
839
 
 
840
 
        return 1;
 
786
        if (stat(mountpoint, &st) == 0 && me->flags & MOUNT_FLAG_DIR_CREATED)
 
787
                 rmdir_path(ap, mountpoint, st.st_dev);
 
788
 
 
789
        return MOUNT_OFFSET_FAIL;
841
790
}
842
791
 
843
792
void *expire_proc_direct(void *arg)
844
793
{
 
794
        struct ioctl_ops *ops = get_ioctl_ops();
845
795
        struct mnt_list *mnts = NULL, *next;
846
796
        struct list_head list, *p;
847
797
        struct expire_args *ea;
875
825
 
876
826
        left = 0;
877
827
 
 
828
        pthread_cleanup_push(mnts_cleanup, mnts);
878
829
        mnts = tree_make_mnt_tree(_PROC_MOUNTS, "/");
879
830
 
880
831
        /* Get a list of mounts select real ones and expire them if possible */
883
834
                ec.status = 0;
884
835
                return NULL;
885
836
        }
886
 
        pthread_cleanup_push(mnts_cleanup, mnts);
887
837
 
888
838
        list_for_each(p, &list) {
889
839
                next = list_entry(p, struct mnt_list, list);
892
842
                 * All direct mounts must be present in the map
893
843
                 * entry cache.
894
844
                 */
 
845
                pthread_cleanup_push(master_source_lock_cleanup, ap->entry);
 
846
                master_source_readlock(ap->entry);
895
847
                me = lookup_source_mapent(ap, next->path, LKP_DISTINCT);
 
848
                pthread_cleanup_pop(1);
896
849
                if (!me)
897
850
                        continue;
898
851
 
899
852
                if (!strcmp(next->fs_type, "autofs")) {
900
853
                        struct stat st;
901
 
                        struct statfs fs;
902
854
                        int ioctlfd;
903
855
 
904
856
                        cache_unlock(me->mc);
919
871
                                continue;
920
872
                        }
921
873
 
922
 
                        if (statfs(next->path, &fs) == -1) {
923
 
                                pthread_setcancelstate(cur_state, NULL);
924
 
                                warn(ap->logopt,
925
 
                                    "fstatfs failed for %s", next->path);
926
 
                                continue;
927
 
                        }
928
 
 
929
 
                        if (fs.f_type != (__SWORD_TYPE) AUTOFS_SUPER_MAGIC) {
 
874
                        /* It's got a mount, deal with in the outer loop */
 
875
                        if (tree_is_mounted(mnts, me->key, MNTS_REAL)) {
930
876
                                pthread_setcancelstate(cur_state, NULL);
931
877
                                continue;
932
878
                        }
944
890
                         */
945
891
 
946
892
                        /* Offsets always have a real mount at their base */
 
893
                        cache_writelock(me->mc);
947
894
                        if (strstr(next->opts, "offset")) {
948
 
                                close(me->ioctlfd);
 
895
                                ops->close(ap->logopt, me->ioctlfd);
949
896
                                me->ioctlfd = -1;
 
897
                                cache_unlock(me->mc);
950
898
                                pthread_setcancelstate(cur_state, NULL);
951
899
                                continue;
952
900
                        }
 
901
                        cache_unlock(me->mc);
953
902
 
954
903
                        ioctlfd = me->ioctlfd;
955
904
 
956
 
                        ret = expire_direct(ioctlfd, next->path, now, ap->logopt);
957
 
                        if (!ret) {
 
905
                        ret = ops->expire(ap->logopt, ioctlfd, next->path, now);
 
906
                        if (ret) {
958
907
                                left++;
959
908
                                pthread_setcancelstate(cur_state, NULL);
960
909
                                continue;
961
910
                        }
962
911
 
 
912
                        cache_writelock(me->mc);
963
913
                        if (me->ioctlfd != -1 && 
964
914
                            fstat(ioctlfd, &st) != -1 &&
965
915
                            !count_mounts(ap->logopt, next->path, st.st_dev)) {
966
 
                                close(ioctlfd);
 
916
                                ops->close(ap->logopt, ioctlfd);
967
917
                                me->ioctlfd = -1;
968
918
                        }
 
919
                        cache_unlock(me->mc);
969
920
 
970
921
                        pthread_setcancelstate(cur_state, NULL);
971
922
                        continue;
986
937
                debug(ap->logopt, "send expire to trigger %s", next->path);
987
938
 
988
939
                pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
989
 
                ret = expire_direct(ioctlfd, next->path, now, ap->logopt);
990
 
                if (!ret)
 
940
                ret = ops->expire(ap->logopt, ioctlfd, next->path, now);
 
941
                if (ret)
991
942
                        left++;
992
943
                pthread_setcancelstate(cur_state, NULL);
993
944
        }
1018
969
 
1019
970
static void expire_send_fail(void *arg)
1020
971
{
 
972
        struct ioctl_ops *ops = get_ioctl_ops();
1021
973
        struct pending_args *mt = arg;
1022
 
        send_fail(mt->ap->logopt, mt->ioctlfd, mt->wait_queue_token);
 
974
        struct autofs_point *ap = mt->ap;
 
975
        ops->send_fail(ap->logopt,
 
976
                       mt->ioctlfd, mt->wait_queue_token, -ENOENT);
1023
977
}
1024
978
 
1025
979
static void free_pending_args(void *arg)
1037
991
 
1038
992
static void *do_expire_direct(void *arg)
1039
993
{
1040
 
        struct pending_args *mt;
 
994
        struct ioctl_ops *ops = get_ioctl_ops();
 
995
        struct pending_args *args, mt;
1041
996
        struct autofs_point *ap;
1042
997
        size_t len;
1043
998
        int status, state;
1044
999
 
1045
 
        mt = (struct pending_args *) arg;
 
1000
        args = (struct pending_args *) arg;
1046
1001
 
1047
1002
        status = pthread_mutex_lock(&ea_mutex);
1048
1003
        if (status)
1049
1004
                fatal(status);
1050
1005
 
1051
 
        ap = mt->ap;
1052
 
 
1053
 
        mt->signaled = 1;
1054
 
        status = pthread_cond_signal(&mt->cond);
 
1006
        memcpy(&mt, args, sizeof(struct pending_args));
 
1007
 
 
1008
        ap = mt.ap;
 
1009
 
 
1010
        args->signaled = 1;
 
1011
        status = pthread_cond_signal(&args->cond);
1055
1012
        if (status)
1056
1013
                fatal(status);
1057
1014
 
1058
1015
        expire_mutex_unlock(NULL);
1059
1016
 
1060
 
        pthread_cleanup_push(free_pending_args, mt);
1061
 
        pthread_cleanup_push(pending_cond_destroy, mt);
1062
 
        pthread_cleanup_push(expire_send_fail, mt);
 
1017
        pthread_cleanup_push(expire_send_fail, &mt);
1063
1018
 
1064
 
        len = _strlen(mt->name, KEY_MAX_LEN);
 
1019
        len = _strlen(mt.name, KEY_MAX_LEN);
1065
1020
        if (!len) {
1066
 
                warn(ap->logopt, "direct key path too long %s", mt->name);
 
1021
                warn(ap->logopt, "direct key path too long %s", mt.name);
1067
1022
                /* TODO: force umount ?? */
1068
1023
                pthread_exit(NULL);
1069
1024
        }
1070
1025
 
1071
 
        status = do_expire(ap, mt->name, len);
 
1026
        status = do_expire(ap, mt.name, len);
1072
1027
        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
1073
1028
        if (status)
1074
 
                send_fail(ap->logopt, mt->ioctlfd, mt->wait_queue_token);
 
1029
                ops->send_fail(ap->logopt,
 
1030
                               mt.ioctlfd, mt.wait_queue_token, -ENOENT);
1075
1031
        else {
1076
1032
                struct mapent *me;
1077
 
                cache_readlock(mt->mc);
1078
 
                me = cache_lookup_distinct(mt->mc, mt->name);
 
1033
                cache_writelock(mt.mc);
 
1034
                me = cache_lookup_distinct(mt.mc, mt.name);
1079
1035
                me->ioctlfd = -1;
1080
 
                cache_unlock(mt->mc);
1081
 
                send_ready(ap->logopt, mt->ioctlfd, mt->wait_queue_token);
1082
 
                close(mt->ioctlfd);
 
1036
                cache_unlock(mt.mc);
 
1037
                ops->send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token);
 
1038
                ops->close(ap->logopt, mt.ioctlfd);
1083
1039
        }
1084
1040
        pthread_setcancelstate(state, NULL);
1085
1041
 
1086
1042
        pthread_cleanup_pop(0);
1087
 
        pthread_cleanup_pop(1);
1088
 
        pthread_cleanup_pop(1);
1089
1043
 
1090
1044
        return NULL;
1091
1045
}
1092
1046
 
1093
1047
int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_direct_t *pkt)
1094
1048
{
 
1049
        struct ioctl_ops *ops = get_ioctl_ops();
1095
1050
        struct map_source *map;
1096
1051
        struct mapent_cache *mc = NULL;
1097
1052
        struct mapent *me = NULL;
1098
1053
        struct pending_args *mt;
1099
1054
        char buf[MAX_ERR_BUF];
1100
1055
        pthread_t thid;
 
1056
        struct timespec wait;
 
1057
        struct timeval now;
1101
1058
        int status, state;
1102
1059
 
1103
1060
        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
1112
1069
         * and since it got mounted we have to trust that
1113
1070
         * there is an entry in the cache.
1114
1071
         */
1115
 
        master_source_readlock(ap->entry);
 
1072
        master_source_writelock(ap->entry);
1116
1073
        map = ap->entry->maps;
1117
1074
        while (map) {
1118
1075
                mc = map->mc;
1123
1080
                cache_unlock(mc);
1124
1081
                map = map->next;
1125
1082
        }
1126
 
        master_source_unlock(ap->entry);
1127
1083
 
1128
1084
        if (!me) {
1129
1085
                /*
1132
1088
                 */
1133
1089
                crit(ap->logopt, "can't find map entry for (%lu,%lu)",
1134
1090
                    (unsigned long) pkt->dev, (unsigned long) pkt->ino);
 
1091
                master_source_unlock(ap->entry);
 
1092
                master_mutex_unlock();
1135
1093
                pthread_setcancelstate(state, NULL);
1136
1094
                return 1;
1137
1095
        }
1138
1096
 
 
1097
        /* Can't expire it if it isn't mounted */
 
1098
        if (me->ioctlfd == -1) {
 
1099
                int ioctlfd;
 
1100
                ops->open(ap->logopt, &ioctlfd, me->dev, me->key);
 
1101
                if (ioctlfd == -1) {
 
1102
                        crit(ap->logopt, "can't open ioctlfd for %s",
 
1103
                             me->key);
 
1104
                        pthread_setcancelstate(state, NULL);
 
1105
                        return 1;
 
1106
                }
 
1107
                ops->send_ready(ap->logopt, ioctlfd, pkt->wait_queue_token);
 
1108
                ops->close(ap->logopt, ioctlfd);
 
1109
                cache_unlock(mc);
 
1110
                master_source_unlock(ap->entry);
 
1111
                pthread_setcancelstate(state, NULL);
 
1112
                return 0;
 
1113
        }
1139
1114
 
1140
1115
        mt = malloc(sizeof(struct pending_args));
1141
1116
        if (!mt) {
1142
1117
                char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
1143
1118
                error(ap->logopt, "malloc: %s", estr);
1144
 
                send_fail(ap->logopt, me->ioctlfd, pkt->wait_queue_token);
 
1119
                ops->send_fail(ap->logopt,
 
1120
                               me->ioctlfd, pkt->wait_queue_token, -ENOMEM);
1145
1121
                cache_unlock(mc);
 
1122
                master_source_unlock(ap->entry);
1146
1123
                pthread_setcancelstate(state, NULL);
1147
1124
                return 1;
1148
1125
        }
1170
1147
        status = pthread_create(&thid, &thread_attr, do_expire_direct, mt);
1171
1148
        if (status) {
1172
1149
                error(ap->logopt, "expire thread create failed");
1173
 
                send_fail(ap->logopt, mt->ioctlfd, pkt->wait_queue_token);
 
1150
                ops->send_fail(ap->logopt,
 
1151
                               mt->ioctlfd, pkt->wait_queue_token, -status);
1174
1152
                cache_unlock(mc);
 
1153
                master_source_unlock(ap->entry);
1175
1154
                expire_mutex_unlock(NULL);
1176
1155
                pending_cond_destroy(mt);
1177
1156
                free_pending_args(mt);
1180
1159
        }
1181
1160
 
1182
1161
        cache_unlock(mc);
 
1162
        master_source_unlock(ap->entry);
1183
1163
 
 
1164
        pthread_cleanup_push(free_pending_args, mt);
 
1165
        pthread_cleanup_push(pending_cond_destroy, mt);
1184
1166
        pthread_cleanup_push(expire_mutex_unlock, NULL);
1185
1167
        pthread_setcancelstate(state, NULL);
1186
1168
 
1187
1169
        mt->signaled = 0;
1188
1170
        while (!mt->signaled) {
 
1171
                gettimeofday(&now, NULL);
 
1172
                wait.tv_sec = now.tv_sec + 2;
 
1173
                wait.tv_nsec = now.tv_usec * 1000;
1189
1174
                status = pthread_cond_wait(&mt->cond, &ea_mutex);
1190
 
                if (status)
 
1175
                if (status && status != ETIMEDOUT)
1191
1176
                        fatal(status);
1192
1177
        }
1193
1178
 
1194
1179
        pthread_cleanup_pop(1);
 
1180
        pthread_cleanup_pop(1);
 
1181
        pthread_cleanup_pop(1);
1195
1182
 
1196
1183
        return 0;
1197
1184
}
1198
1185
 
1199
1186
static void mount_send_fail(void *arg)
1200
1187
{
 
1188
        struct ioctl_ops *ops = get_ioctl_ops();
1201
1189
        struct pending_args *mt = arg;
1202
 
        send_fail(mt->ap->logopt, mt->ioctlfd, mt->wait_queue_token);
1203
 
        close(mt->ioctlfd);
 
1190
        struct autofs_point *ap = mt->ap;
 
1191
        ops->send_fail(ap->logopt, mt->ioctlfd, mt->wait_queue_token, -ENOENT);
 
1192
        ops->close(ap->logopt, mt->ioctlfd);
 
1193
}
 
1194
 
 
1195
static void pending_mutex_destroy(void *arg)
 
1196
{
 
1197
        struct pending_args *mt = (struct pending_args *) arg;
 
1198
        int status = pthread_mutex_destroy(&mt->mutex);
 
1199
        if (status)
 
1200
                fatal(status);
1204
1201
}
1205
1202
 
1206
1203
static void mount_mutex_unlock(void *arg)
1207
1204
{
1208
 
        int status = pthread_mutex_unlock(&ma_mutex);
 
1205
        struct pending_args *mt = (struct pending_args *) arg;
 
1206
        int status = pthread_mutex_unlock(&mt->mutex);
1209
1207
        if (status)
1210
1208
                fatal(status);
1211
1209
}
1212
1210
 
1213
1211
static void *do_mount_direct(void *arg)
1214
1212
{
1215
 
        struct pending_args *mt;
 
1213
        struct ioctl_ops *ops = get_ioctl_ops();
 
1214
        struct pending_args *args, mt;
1216
1215
        struct autofs_point *ap;
1217
 
        struct passwd pw;
1218
 
        struct passwd *ppw = &pw;
1219
 
        struct passwd **pppw = &ppw;
1220
 
        struct group gr;
1221
 
        struct group *pgr;
1222
 
        struct group **ppgr;
1223
 
        char *pw_tmp, *gr_tmp;
1224
 
        struct thread_stdenv_vars *tsv;
1225
 
        int tmplen, grplen;
1226
1216
        struct stat st;
1227
1217
        int status, state;
1228
1218
 
1229
 
        mt = (struct pending_args *) arg;
1230
 
 
1231
 
        status = pthread_mutex_lock(&ma_mutex);
1232
 
        if (status)
1233
 
                fatal(status);
1234
 
 
1235
 
        ap = mt->ap;
1236
 
 
1237
 
        mt->signaled = 1;
1238
 
        status = pthread_cond_signal(&mt->cond);
1239
 
        if (status)
1240
 
                fatal(status);
1241
 
 
1242
 
        mount_mutex_unlock(NULL);
1243
 
 
1244
 
        pthread_cleanup_push(free_pending_args, mt);
1245
 
        pthread_cleanup_push(pending_cond_destroy, mt);
1246
 
        pthread_cleanup_push(mount_send_fail, mt);
 
1219
        args = (struct pending_args *) arg;
 
1220
 
 
1221
        status = pthread_mutex_lock(&args->mutex);
 
1222
        if (status)
 
1223
                fatal(status);
 
1224
 
 
1225
        memcpy(&mt, args, sizeof(struct pending_args));
 
1226
 
 
1227
        ap = mt.ap;
 
1228
 
 
1229
        args->signaled = 1;
 
1230
        status = pthread_cond_signal(&args->cond);
 
1231
        if (status)
 
1232
                fatal(status);
 
1233
 
 
1234
        mount_mutex_unlock(args);
 
1235
 
 
1236
        pthread_cleanup_push(mount_send_fail, &mt);
1247
1237
 
1248
1238
        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
1249
1239
 
1250
 
        status = fstat(mt->ioctlfd, &st);
 
1240
        status = fstat(mt.ioctlfd, &st);
1251
1241
        if (status == -1) {
1252
1242
                error(ap->logopt,
1253
 
                      "can't stat direct mount trigger %s", mt->name);
 
1243
                      "can't stat direct mount trigger %s", mt.name);
 
1244
                ops->send_fail(ap->logopt,
 
1245
                               mt.ioctlfd, mt.wait_queue_token, -ENOENT);
 
1246
                ops->close(ap->logopt, mt.ioctlfd);
1254
1247
                pthread_setcancelstate(state, NULL);
1255
1248
                pthread_exit(NULL);
1256
1249
        }
1257
1250
 
1258
 
        status = stat(mt->name, &st);
1259
 
        if (!S_ISDIR(st.st_mode) || st.st_dev != mt->dev) {
 
1251
        status = stat(mt.name, &st);
 
1252
        if (!S_ISDIR(st.st_mode) || st.st_dev != mt.dev) {
1260
1253
                error(ap->logopt,
1261
1254
                     "direct trigger not valid or already mounted %s",
1262
 
                     mt->name);
 
1255
                     mt.name);
 
1256
                ops->send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token);
 
1257
                ops->close(ap->logopt, mt.ioctlfd);
1263
1258
                pthread_setcancelstate(state, NULL);
1264
1259
                pthread_exit(NULL);
1265
1260
        }
1266
1261
 
1267
1262
        pthread_setcancelstate(state, NULL);
1268
1263
 
1269
 
        info(ap->logopt, "attempting to mount entry %s", mt->name);
1270
 
 
1271
 
        /*
1272
 
         * Setup thread specific data values for macro
1273
 
         * substution in map entries during the mount.
1274
 
         * Best effort only as it must go ahead.
1275
 
         */
1276
 
 
1277
 
        tsv = malloc(sizeof(struct thread_stdenv_vars));
1278
 
        if (!tsv) 
1279
 
                goto cont;
1280
 
 
1281
 
        tsv->uid = mt->uid;
1282
 
        tsv->gid = mt->gid;
1283
 
 
1284
 
        /* Try to get passwd info */
1285
 
 
1286
 
        tmplen = sysconf(_SC_GETPW_R_SIZE_MAX);
1287
 
        if (tmplen < 0) {
1288
 
                error(ap->logopt, "failed to get buffer size for getpwuid_r");
1289
 
                free(tsv);
1290
 
                goto cont;
1291
 
        }
1292
 
 
1293
 
        pw_tmp = malloc(tmplen + 1);
1294
 
        if (!pw_tmp) {
1295
 
                error(ap->logopt, "failed to malloc buffer for getpwuid_r");
1296
 
                free(tsv);
1297
 
                goto cont;
1298
 
        }
1299
 
 
1300
 
        status = getpwuid_r(mt->uid, ppw, pw_tmp, tmplen, pppw);
1301
 
        if (status || !ppw) {
1302
 
                error(ap->logopt, "failed to get passwd info from getpwuid_r");
1303
 
                free(tsv);
1304
 
                free(pw_tmp);
1305
 
                goto cont;
1306
 
        }
1307
 
 
1308
 
        tsv->user = strdup(pw.pw_name);
1309
 
        if (!tsv->user) {
1310
 
                error(ap->logopt, "failed to malloc buffer for user");
1311
 
                free(tsv);
1312
 
                free(pw_tmp);
1313
 
                goto cont;
1314
 
        }
1315
 
 
1316
 
        tsv->home = strdup(pw.pw_dir);
1317
 
        if (!tsv->user) {
1318
 
                error(ap->logopt, "failed to malloc buffer for home");
1319
 
                free(pw_tmp);
1320
 
                free(tsv->user);
1321
 
                free(tsv);
1322
 
                goto cont;
1323
 
        }
1324
 
 
1325
 
        free(pw_tmp);
1326
 
 
1327
 
        /* Try to get group info */
1328
 
 
1329
 
        grplen = sysconf(_SC_GETGR_R_SIZE_MAX);
1330
 
        if (tmplen < 0) {
1331
 
                error(ap->logopt, "failed to get buffer size for getgrgid_r");
1332
 
                free(tsv->user);
1333
 
                free(tsv->home);
1334
 
                free(tsv);
1335
 
                goto cont;
1336
 
        }
1337
 
 
1338
 
        gr_tmp = NULL;
1339
 
        tmplen = grplen;
1340
 
        while (1) {
1341
 
                char *tmp = realloc(gr_tmp, tmplen + 1);
1342
 
                if (!tmp) {
1343
 
                        error(ap->logopt, "failed to malloc buffer for getgrgid_r");
1344
 
                        if (gr_tmp)
1345
 
                                free(gr_tmp);
1346
 
                        free(tsv->user);
1347
 
                        free(tsv->home);
1348
 
                        free(tsv);
1349
 
                        goto cont;
1350
 
                }
1351
 
                gr_tmp = tmp;
1352
 
                pgr = &gr;
1353
 
                ppgr = &pgr;
1354
 
                status = getgrgid_r(mt->gid, pgr, gr_tmp, tmplen, ppgr);
1355
 
                if (status != ERANGE)
1356
 
                        break;
1357
 
                tmplen += grplen;
1358
 
        }
1359
 
 
1360
 
        if (status || !pgr) {
1361
 
                error(ap->logopt, "failed to get group info from getgrgid_r");
1362
 
                free(tsv->user);
1363
 
                free(tsv->home);
1364
 
                free(tsv);
1365
 
                free(gr_tmp);
1366
 
                goto cont;
1367
 
        }
1368
 
 
1369
 
        tsv->group = strdup(gr.gr_name);
1370
 
        if (!tsv->group) {
1371
 
                error(ap->logopt, "failed to malloc buffer for group");
1372
 
                free(tsv->user);
1373
 
                free(tsv->home);
1374
 
                free(tsv);
1375
 
                free(gr_tmp);
1376
 
                goto cont;
1377
 
        }
1378
 
 
1379
 
        free(gr_tmp);
1380
 
 
1381
 
        status = pthread_setspecific(key_thread_stdenv_vars, tsv);
1382
 
        if (status) {
1383
 
                error(ap->logopt, "failed to set stdenv thread var");
1384
 
                free(tsv->group);
1385
 
                free(tsv->user);
1386
 
                free(tsv->home);
1387
 
                free(tsv);
1388
 
        }
1389
 
 
1390
 
cont:
1391
 
        status = lookup_nss_mount(ap, NULL, mt->name, strlen(mt->name));
 
1264
        info(ap->logopt, "attempting to mount entry %s", mt.name);
 
1265
 
 
1266
        set_tsd_user_vars(ap->logopt, mt.uid, mt.gid);
 
1267
 
 
1268
        status = lookup_nss_mount(ap, NULL, mt.name, mt.len);
1392
1269
        /*
1393
1270
         * Direct mounts are always a single mount. If it fails there's
1394
1271
         * nothing to undo so just complain
1396
1273
        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
1397
1274
        if (status) {
1398
1275
                struct mapent *me;
1399
 
                int real_mount, set_fd;
1400
 
                cache_readlock(mt->mc);
1401
 
                me = cache_lookup_distinct(mt->mc, mt->name);
1402
 
                real_mount = is_mounted(_PATH_MOUNTED, me->key, MNTS_REAL);
1403
 
                set_fd = (real_mount || me->multi == me);
1404
 
                cache_unlock(mt->mc);
1405
 
                if (set_fd) {
1406
 
                        me->ioctlfd = mt->ioctlfd;
1407
 
                        send_ready(ap->logopt, mt->ioctlfd, mt->wait_queue_token);
1408
 
                } else {
1409
 
                        send_ready(ap->logopt, mt->ioctlfd, mt->wait_queue_token);
1410
 
                        close(mt->ioctlfd);
 
1276
                struct statfs fs;
 
1277
                unsigned int close_fd = 0;
 
1278
 
 
1279
                if (statfs(mt.name, &fs) == -1 ||
 
1280
                   (fs.f_type == AUTOFS_SUPER_MAGIC &&
 
1281
                    !master_find_submount(ap, mt.name)))
 
1282
                        close_fd = 1;
 
1283
                cache_writelock(mt.mc);
 
1284
                if ((me = cache_lookup_distinct(mt.mc, mt.name))) {
 
1285
                        /*
 
1286
                         * Careful here, we need to leave the file handle open
 
1287
                         * for direct mount multi-mounts with no real mount at
 
1288
                         * their base so they will be expired.
 
1289
                         */
 
1290
                        if (close_fd && me == me->multi)
 
1291
                                close_fd = 0;
 
1292
                        if (!close_fd)
 
1293
                                me->ioctlfd = mt.ioctlfd;
1411
1294
                }
1412
 
                info(ap->logopt, "mounted %s", mt->name);
 
1295
                ops->send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token);
 
1296
                cache_unlock(mt.mc);
 
1297
                if (close_fd)
 
1298
                        ops->close(ap->logopt, mt.ioctlfd);
 
1299
                info(ap->logopt, "mounted %s", mt.name);
1413
1300
        } else {
1414
 
                send_fail(mt->ap->logopt, mt->ioctlfd, mt->wait_queue_token);
1415
 
                close(mt->ioctlfd);
1416
 
                info(ap->logopt, "failed to mount %s", mt->name);
 
1301
                /* TODO: get mount return status from lookup_nss_mount */
 
1302
                ops->send_fail(ap->logopt,
 
1303
                               mt.ioctlfd, mt.wait_queue_token, -ENOENT);
 
1304
                ops->close(ap->logopt, mt.ioctlfd);
 
1305
                info(ap->logopt, "failed to mount %s", mt.name);
1417
1306
        }
1418
1307
        pthread_setcancelstate(state, NULL);
1419
1308
 
1420
1309
        pthread_cleanup_pop(0);
1421
 
        pthread_cleanup_pop(1);
1422
 
        pthread_cleanup_pop(1);
1423
1310
 
1424
1311
        return NULL;
1425
1312
}
1426
1313
 
1427
1314
int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_direct_t *pkt)
1428
1315
{
 
1316
        struct ioctl_ops *ops = get_ioctl_ops();
1429
1317
        struct map_source *map;
1430
1318
        struct mapent_cache *mc = NULL;
1431
1319
        struct mapent *me = NULL;
1433
1321
        struct pending_args *mt;
1434
1322
        char buf[MAX_ERR_BUF];
1435
1323
        int status = 0;
1436
 
        int ioctlfd, cl_flags, state;
 
1324
        struct timespec wait;
 
1325
        struct timeval now;
 
1326
        int ioctlfd, len, state;
1437
1327
 
1438
1328
        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
1439
1329
 
1440
 
        master_source_readlock(ap->entry);
 
1330
        master_mutex_lock();
 
1331
 
 
1332
        /*
 
1333
         * If our parent is a direct or offset mount that has been
 
1334
         * covered by a mount and another lookup occurs after the
 
1335
         * mount but before the device and inode are set in the
 
1336
         * cache entry we will not be able to find the mapent. So
 
1337
         * we must take the source writelock to ensure the parent
 
1338
         * has mount is complete before we look for the entry.
 
1339
         */
 
1340
        master_source_writelock(ap->entry);
1441
1341
        map = ap->entry->maps;
1442
1342
        while (map) {
1443
1343
                /*
1457
1357
                cache_unlock(mc);
1458
1358
                map = map->next;
1459
1359
        }
1460
 
        master_source_unlock(ap->entry);
1461
1360
 
1462
1361
        if (!me) {
1463
1362
                /*
1466
1365
                 */
1467
1366
                logerr("can't find map entry for (%lu,%lu)",
1468
1367
                    (unsigned long) pkt->dev, (unsigned long) pkt->ino);
 
1368
                master_source_unlock(ap->entry);
1469
1369
                pthread_setcancelstate(state, NULL);
1470
1370
                return 1;
1471
1371
        }
1475
1375
                ioctlfd = me->ioctlfd;
1476
1376
                me->ioctlfd = -1;
1477
1377
        } else
1478
 
                ioctlfd = open(me->key, O_RDONLY);
 
1378
                ops->open(ap->logopt, &ioctlfd, me->dev, me->key);
1479
1379
 
1480
1380
        if (ioctlfd == -1) {
1481
1381
                cache_unlock(mc);
 
1382
                master_source_unlock(ap->entry);
 
1383
                master_mutex_unlock();
1482
1384
                pthread_setcancelstate(state, NULL);
1483
1385
                crit(ap->logopt, "failed to create ioctl fd for %s", me->key);
1484
1386
                /* TODO:  how do we clear wait q in kernel ?? */
1485
1387
                return 1;
1486
1388
        }
1487
1389
 
1488
 
        if ((cl_flags = fcntl(ioctlfd, F_GETFD, 0)) != -1) {
1489
 
                cl_flags |= FD_CLOEXEC;
1490
 
                fcntl(ioctlfd, F_SETFD, cl_flags);
1491
 
        }
1492
 
 
1493
1390
        debug(ap->logopt, "token %ld, name %s, request pid %u",
1494
1391
                  (unsigned long) pkt->wait_queue_token, me->key, pkt->pid);
1495
1392
 
1496
1393
        /* Ignore packet if we're trying to shut down */
1497
 
        if (ap->shutdown ||
1498
 
            ap->state == ST_SHUTDOWN_FORCE ||
1499
 
            ap->state == ST_SHUTDOWN) {
1500
 
                send_fail(ap->logopt, ioctlfd, pkt->wait_queue_token);
1501
 
                close(ioctlfd);
1502
 
                cache_unlock(mc);
 
1394
        if (ap->shutdown || ap->state == ST_SHUTDOWN_FORCE) {
 
1395
                ops->send_fail(ap->logopt,
 
1396
                               ioctlfd, pkt->wait_queue_token, -ENOENT);
 
1397
                ops->close(ap->logopt, ioctlfd);
 
1398
                cache_unlock(mc);
 
1399
                master_source_unlock(ap->entry);
 
1400
                master_mutex_unlock();
 
1401
                pthread_setcancelstate(state, NULL);
 
1402
                return 1;
 
1403
        }
 
1404
 
 
1405
        len = strlen(me->key);
 
1406
        if (len >= PATH_MAX) {
 
1407
                error(ap->logopt, "direct mount path too long %s", me->key);
 
1408
                ops->send_fail(ap->logopt,
 
1409
                               ioctlfd, pkt->wait_queue_token, -ENAMETOOLONG);
 
1410
                ops->close(ap->logopt, ioctlfd);
 
1411
                cache_unlock(mc);
 
1412
                master_source_unlock(ap->entry);
 
1413
                master_mutex_unlock();
1503
1414
                pthread_setcancelstate(state, NULL);
1504
1415
                return 1;
1505
1416
        }
1508
1419
        if (!mt) {
1509
1420
                char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
1510
1421
                error(ap->logopt, "malloc: %s", estr);
1511
 
                send_fail(ap->logopt, ioctlfd, pkt->wait_queue_token);
1512
 
                close(ioctlfd);
 
1422
                ops->send_fail(ap->logopt,
 
1423
                               ioctlfd, pkt->wait_queue_token, -ENOMEM);
 
1424
                ops->close(ap->logopt, ioctlfd);
1513
1425
                cache_unlock(mc);
 
1426
                master_source_unlock(ap->entry);
 
1427
                master_mutex_unlock();
1514
1428
                pthread_setcancelstate(state, NULL);
1515
1429
                return 1;
1516
1430
        }
1520
1434
        if (status)
1521
1435
                fatal(status);
1522
1436
 
1523
 
        status = pthread_mutex_lock(&ma_mutex);
 
1437
        status = pthread_mutex_init(&mt->mutex, NULL);
 
1438
        if (status)
 
1439
                fatal(status);
 
1440
 
 
1441
        status = pthread_mutex_lock(&mt->mutex);
1524
1442
        if (status)
1525
1443
                fatal(status);
1526
1444
 
1528
1446
        mt->ioctlfd = ioctlfd;
1529
1447
        mt->mc = mc;
1530
1448
        strcpy(mt->name, me->key);
 
1449
        mt->len = len;
1531
1450
        mt->dev = me->dev;
1532
1451
        mt->type = NFY_MOUNT;
1533
1452
        mt->uid = pkt->uid;
1537
1456
        status = pthread_create(&thid, &thread_attr, do_mount_direct, mt);
1538
1457
        if (status) {
1539
1458
                error(ap->logopt, "missing mount thread create failed");
1540
 
                send_fail(ap->logopt, ioctlfd, pkt->wait_queue_token);
1541
 
                close(ioctlfd);
 
1459
                ops->send_fail(ap->logopt,
 
1460
                               ioctlfd, pkt->wait_queue_token, -status);
 
1461
                ops->close(ap->logopt, ioctlfd);
1542
1462
                cache_unlock(mc);
1543
 
                mount_mutex_unlock(NULL);
 
1463
                master_source_unlock(ap->entry);
 
1464
                master_mutex_unlock();
 
1465
                mount_mutex_unlock(mt);
1544
1466
                pending_cond_destroy(mt);
 
1467
                pending_mutex_destroy(mt);
1545
1468
                free_pending_args(mt);
1546
1469
                pthread_setcancelstate(state, NULL);
1547
1470
                return 1;
1548
1471
        }
1549
1472
 
1550
1473
        cache_unlock(mc);
1551
 
        pthread_cleanup_push(mount_mutex_unlock, NULL);
 
1474
        master_source_unlock(ap->entry);
 
1475
 
 
1476
        master_mutex_unlock();
 
1477
 
 
1478
        pthread_cleanup_push(free_pending_args, mt);
 
1479
        pthread_cleanup_push(pending_mutex_destroy, mt);
 
1480
        pthread_cleanup_push(pending_cond_destroy, mt);
 
1481
        pthread_cleanup_push(mount_mutex_unlock, mt);
1552
1482
        pthread_setcancelstate(state, NULL);
1553
1483
 
1554
1484
        mt->signaled = 0;
1555
1485
        while (!mt->signaled) {
1556
 
                status = pthread_cond_wait(&mt->cond, &ma_mutex);
1557
 
                if (status)
 
1486
                gettimeofday(&now, NULL);
 
1487
                wait.tv_sec = now.tv_sec + 2;
 
1488
                wait.tv_nsec = now.tv_usec * 1000;
 
1489
                status = pthread_cond_timedwait(&mt->cond, &mt->mutex, &wait);
 
1490
                if (status && status != ETIMEDOUT)
1558
1491
                        fatal(status);
1559
1492
        }
1560
1493
 
1561
1494
        pthread_cleanup_pop(1);
 
1495
        pthread_cleanup_pop(1);
 
1496
        pthread_cleanup_pop(1);
 
1497
        pthread_cleanup_pop(1);
1562
1498
 
1563
1499
        return 0;
1564
1500
}