1
/* ----------------------------------------------------------------------- *
3
* indirect.c - Linux automounter indirect mount handling
5
* Copyright 1997 Transmeta Corporation - All Rights Reserved
6
* Copyright 1999-2000 Jeremy Fitzhardinge <jeremy@goop.org>
7
* Copyright 2001-2005 Ian Kent <raven@themaw.net>
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
12
* USA; either version 2 of the License, or (at your option) any later
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
20
* ----------------------------------------------------------------------- */
29
#include <sys/ioctl.h>
30
#include <sys/types.h>
34
#include <sys/mount.h>
39
#include "automount.h"
41
extern pthread_attr_t thread_attr;
43
static pthread_mutex_t ma_mutex = PTHREAD_MUTEX_INITIALIZER;
44
static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER;
46
static int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts)
48
struct mnt_list *this;
50
pid_t pgrp = getpgrp();
53
sprintf(spgrp, "pgrp=%d", pgrp);
58
if (strstr(this->opts, spgrp)) {
63
if (strcmp(this->fs_type, "autofs"))
64
rv = spawn_umount(ap->logopt, "-l", this->path, NULL);
66
rv = umount2(this->path, MNT_DETACH);
70
"can't unlink %s from mount tree", this->path);
75
"bad superblock or not mounted");
80
warn(ap->logopt, "bad path for mount");
89
static int do_mount_autofs_indirect(struct autofs_point *ap)
91
time_t timeout = ap->exp_timeout;
93
const char *type, *map_name = NULL;
95
struct mnt_list *mnts;
98
mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 1);
100
ret = unlink_mount_tree(ap, mnts);
104
"already mounted as other than autofs "
105
"or failed to unlink entry in tree");
110
options = make_options_string(ap->path, ap->kpipefd, NULL);
114
/* In case the directory doesn't exist, try to mkdir it */
115
if (mkdir_path(ap->path, 0555) < 0) {
116
if (errno != EEXIST && errno != EROFS) {
118
"failed to create autofs directory %s",
122
/* If we recieve an error, and it's EEXIST or EROFS we know
123
the directory was not created. */
126
/* No errors so the directory was successfully created */
130
type = ap->entry->maps->type;
131
if (type && !strcmp(ap->entry->maps->type, "hosts")) {
132
char *tmp = alloca(7);
134
strcpy(tmp, "-hosts");
135
map_name = (const char *) tmp;
138
map_name = ap->entry->maps->argv[0];
140
ret = mount(map_name, ap->path, "autofs", MS_MGC_VAL, options);
142
crit(ap->logopt, "failed to mount autofs path %s", ap->path);
150
/* Root directory for ioctl()'s */
151
ap->ioctlfd = open(ap->path, O_RDONLY);
152
if (ap->ioctlfd < 0) {
154
"failed to create ioctl fd for autofs path %s", ap->path);
158
if ((cl_flags = fcntl(ap->ioctlfd, F_GETFD, 0)) != -1) {
159
cl_flags |= FD_CLOEXEC;
160
fcntl(ap->ioctlfd, F_SETFD, cl_flags);
163
ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
165
ioctl(ap->ioctlfd, AUTOFS_IOC_SETTIMEOUT, &timeout);
169
"mounted indirect mount on %s "
170
"with timeout %u, freq %u seconds", ap->path,
171
(unsigned int) ap->exp_timeout,
172
(unsigned int) ap->exp_runfreq);
175
"mounted indirect mount on %s with timeouts disabled",
178
fstat(ap->ioctlfd, &st);
179
ap->dev = st.st_dev; /* Device number for mount point checks */
187
rmdir_path(ap, ap->path, ap->dev);
191
close(ap->state_pipe[0]);
192
close(ap->state_pipe[1]);
199
int mount_autofs_indirect(struct autofs_point *ap)
201
time_t now = time(NULL);
205
/* TODO: read map, determine map type is OK */
206
if (lookup_nss_read_map(ap, NULL, now))
207
lookup_prune_cache(ap, now);
209
error(ap->logopt, "failed to read map for %s", ap->path);
213
status = do_mount_autofs_indirect(ap);
217
map = lookup_ghost(ap);
218
if (map & LKP_FAIL) {
219
if (map & LKP_DIRECT) {
221
"bad map format,found direct, "
222
"expected indirect exiting");
224
error(ap->logopt, "failed to load map, exiting");
226
/* TODO: Process cleanup ?? */
230
if (map & LKP_NOTSUP)
236
int umount_autofs_indirect(struct autofs_point *ap)
238
char buf[MAX_ERR_BUF];
239
int ret, rv, retries;
242
* Since submounts look after themselves the parent never knows
243
* it needs to close the ioctlfd for offset mounts so we have
244
* to do it here. If the cache entry isn't found then there aren't
248
lookup_source_close_ioctlfd(ap->parent, ap->path);
250
/* If we are trying to shutdown make sure we can umount */
251
rv = ioctl(ap->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &ret);
253
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
254
logerr("ioctl failed: %s", estr);
257
error(ap->logopt, "ask umount returned busy %s", ap->path);
261
ioctl(ap->ioctlfd, AUTOFS_IOC_CATATONIC, 0);
264
close(ap->state_pipe[0]);
265
close(ap->state_pipe[1]);
266
ap->state_pipe[0] = -1;
267
ap->state_pipe[1] = -1;
272
if (ap->kpipefd >= 0)
277
retries = UMOUNT_RETRIES;
278
while ((rv = umount(ap->path)) == -1 && retries--) {
279
struct timespec tm = {0, 100000000};
282
nanosleep(&tm, NULL);
290
"mount point %s does not exist", ap->path);
295
"mount point %s is in use", ap->path);
296
if (ap->state == ST_SHUTDOWN_FORCE)
302
error(ap->logopt, "mount point is not a directory");
312
"forcing umount of indirect mount %s", ap->path);
313
rv = umount2(ap->path, MNT_DETACH);
315
info(ap->logopt, "umounted indirect mount %s", ap->path);
317
rm_unwanted(ap->logopt, ap->path, 1, ap->dev);
323
static int expire_indirect(struct autofs_point *ap, int ioctlfd, const char *path, unsigned int when)
325
char buf[MAX_ERR_BUF];
329
if (fstat(ioctlfd, &st) == -1) {
330
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
331
error(ap->logopt, "fstat failed: %s", estr);
335
retries = (count_mounts(ap->logopt, path, st.st_dev) + 1) * EXPIRE_RETRIES;
338
struct timespec tm = {0, 100000000};
340
/* Ggenerate expire message for the mount. */
341
ret = ioctl(ioctlfd, AUTOFS_IOC_EXPIRE_DIRECT, &when);
343
/* Mount has gone away */
344
if (errno == EBADF || errno == EINVAL)
347
/* Other than need to wait for the kernel ? */
352
nanosleep(&tm, NULL);
355
if (!ioctl(ioctlfd, AUTOFS_IOC_ASKUMOUNT, &ret)) {
363
static void mnts_cleanup(void *arg)
365
struct mnt_list *mnts = (struct mnt_list *) arg;
370
void *expire_proc_indirect(void *arg)
372
struct autofs_point *ap;
373
struct mapent *me = NULL;
374
struct mnt_list *mnts = NULL, *next;
375
struct expire_args *ea;
376
struct expire_args ec;
378
int offsets, submnts, count;
379
int ioctlfd, cur_state;
380
int status, ret, left;
382
ea = (struct expire_args *) arg;
384
status = pthread_mutex_lock(&ea->mutex);
393
status = pthread_cond_signal(&ea->cond);
397
status = pthread_mutex_unlock(&ea->mutex);
401
pthread_cleanup_push(expire_cleanup, &ec);
405
/* Get a list of real mounts and expire them if possible */
406
mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 0);
407
pthread_cleanup_push(mnts_cleanup, mnts);
408
for (next = mnts; next; next = next->next) {
412
if (!strcmp(next->fs_type, "autofs")) {
414
* If we have submounts check if this path lives below
415
* one of them and pass on the state change.
417
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
418
if (strstr(next->opts, "indirect"))
419
master_notify_submount(ap, next->path, ap->state);
420
pthread_setcancelstate(cur_state, NULL);
425
if (ap->state == ST_EXPIRE || ap->state == ST_PRUNE)
426
pthread_testcancel();
429
* If the mount corresponds to an offset trigger then
430
* the key is the path, otherwise it's the last component.
432
ind_key = strrchr(next->path, '/');
437
* If me->key starts with a '/' and it's not an autofs
438
* filesystem it's a nested mount and we need to use
439
* the ioctlfd of the mount to send the expire.
440
* Otherwise it's a top level indirect mount (possibly
441
* with offsets in it) and we use the usual ioctlfd.
443
me = lookup_source_mapent(ap, next->path, LKP_DISTINCT);
445
me = lookup_source_mapent(ap, ind_key, LKP_NORMAL);
449
if (*me->key == '/') {
450
ioctlfd = me->ioctlfd;
452
ioctlfd = ap->ioctlfd;
454
cache_unlock(me->mc);
456
debug(ap->logopt, "expire %s", next->path);
458
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
459
ret = expire_indirect(ap, ioctlfd, next->path, now);
462
pthread_setcancelstate(cur_state, NULL);
464
pthread_cleanup_pop(1);
467
* If there are no more real mounts left we could still
468
* have some offset mounts with no '/' offset so we need to
472
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
473
ret = expire_indirect(ap, ap->ioctlfd, ap->path, now);
476
pthread_setcancelstate(cur_state, NULL);
479
count = offsets = submnts = 0;
480
mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 0);
481
pthread_cleanup_push(mnts_cleanup, mnts);
482
/* Are there any real mounts left */
483
for (next = mnts; next; next = next->next) {
484
if (strcmp(next->fs_type, "autofs"))
487
if (strstr(next->opts, "indirect"))
493
pthread_cleanup_pop(1);
497
"%d submounts remaining in %s", submnts, ap->path);
500
* EXPIRE_MULTI is synchronous, so we can be sure (famous last
501
* words) the umounts are done by the time we reach here
504
info(ap->logopt, "%d remaining in %s", count, ap->path);
508
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
509
pthread_cleanup_pop(1);
510
pthread_setcancelstate(cur_state, NULL);
515
static void pending_cond_destroy(void *arg)
517
struct pending_args *mt;
520
mt = (struct pending_args *) arg;
521
status = pthread_cond_destroy(&mt->cond);
526
static void expire_send_fail(void *arg)
528
struct pending_args *mt = arg;
529
send_fail(mt->ap->logopt, mt->ap->ioctlfd, mt->wait_queue_token);
532
static void free_pending_args(void *arg)
534
struct pending_args *mt = arg;
538
static void expire_mutex_unlock(void *arg)
540
int status = pthread_mutex_unlock(&ea_mutex);
545
static void *do_expire_indirect(void *arg)
547
struct pending_args *mt;
548
struct autofs_point *ap;
551
mt = (struct pending_args *) arg;
553
status = pthread_mutex_lock(&ea_mutex);
560
status = pthread_cond_signal(&mt->cond);
564
expire_mutex_unlock(NULL);
566
pthread_cleanup_push(free_pending_args, mt);
567
pthread_cleanup_push(pending_cond_destroy, mt);
568
pthread_cleanup_push(expire_send_fail, mt);
570
status = do_expire(mt->ap, mt->name, mt->len);
571
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
573
send_fail(ap->logopt, ap->ioctlfd, mt->wait_queue_token);
575
send_ready(ap->logopt, ap->ioctlfd, mt->wait_queue_token);
576
pthread_setcancelstate(state, NULL);
578
pthread_cleanup_pop(0);
579
pthread_cleanup_pop(1);
580
pthread_cleanup_pop(1);
585
int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_indirect_t *pkt)
587
struct pending_args *mt;
588
char buf[MAX_ERR_BUF];
592
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
594
debug(ap->logopt, "token %ld, name %s",
595
(unsigned long) pkt->wait_queue_token, pkt->name);
597
mt = malloc(sizeof(struct pending_args));
599
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
600
logerr("malloc: %s", estr);
601
send_fail(ap->logopt, ap->ioctlfd, pkt->wait_queue_token);
602
pthread_setcancelstate(state, NULL);
606
status = pthread_cond_init(&mt->cond, NULL);
610
status = pthread_mutex_lock(&ea_mutex);
615
strncpy(mt->name, pkt->name, pkt->len);
616
mt->name[pkt->len] = '\0';
618
mt->wait_queue_token = pkt->wait_queue_token;
620
status = pthread_create(&thid, &thread_attr, do_expire_indirect, mt);
622
error(ap->logopt, "expire thread create failed");
623
send_fail(ap->logopt, ap->ioctlfd, pkt->wait_queue_token);
624
expire_mutex_unlock(NULL);
625
pending_cond_destroy(mt);
626
free_pending_args(mt);
627
pthread_setcancelstate(state, NULL);
631
pthread_cleanup_push(expire_mutex_unlock, NULL);
632
pthread_setcancelstate(state, NULL);
635
while (!mt->signaled) {
636
status = pthread_cond_wait(&mt->cond, &ea_mutex);
641
pthread_cleanup_pop(1);
646
static void mount_send_fail(void *arg)
648
struct pending_args *mt = arg;
649
send_fail(mt->ap->logopt, mt->ap->ioctlfd, mt->wait_queue_token);
652
static void mount_mutex_unlock(void *arg)
654
int status = pthread_mutex_unlock(&ma_mutex);
659
static void *do_mount_indirect(void *arg)
661
struct pending_args *mt;
662
struct autofs_point *ap;
663
char buf[PATH_MAX + 1];
666
struct passwd *ppw = &pw;
667
struct passwd **pppw = &ppw;
671
char *pw_tmp, *gr_tmp;
672
struct thread_stdenv_vars *tsv;
673
int len, tmplen, grplen, status, state;
675
mt = (struct pending_args *) arg;
677
status = pthread_mutex_lock(&ma_mutex);
685
status = pthread_cond_signal(&mt->cond);
689
mount_mutex_unlock(NULL);
691
pthread_cleanup_push(free_pending_args, mt);
692
pthread_cleanup_push(pending_cond_destroy, mt);
693
pthread_cleanup_push(mount_send_fail, mt);
695
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
697
len = ncat_path(buf, sizeof(buf), ap->path, mt->name, mt->len);
699
crit(ap->logopt, "path to be mounted is to long");
700
pthread_setcancelstate(state, NULL);
704
status = lstat(buf, &st);
705
if (status != -1 && !(S_ISDIR(st.st_mode) && st.st_dev == mt->dev)) {
707
"indirect trigger not valid or already mounted %s", buf);
708
pthread_setcancelstate(state, NULL);
712
pthread_setcancelstate(state, NULL);
714
info(ap->logopt, "attempting to mount entry %s", buf);
717
* Setup thread specific data values for macro
718
* substution in map entries during the mount.
719
* Best effort only as it must go ahead.
722
tsv = malloc(sizeof(struct thread_stdenv_vars));
729
/* Try to get passwd info */
731
tmplen = sysconf(_SC_GETPW_R_SIZE_MAX);
733
error(ap->logopt, "failed to get buffer size for getpwuid_r");
738
pw_tmp = malloc(tmplen + 1);
740
error(ap->logopt, "failed to malloc buffer for getpwuid_r");
745
status = getpwuid_r(mt->uid, ppw, pw_tmp, tmplen, pppw);
746
if (status || !ppw) {
747
error(ap->logopt, "failed to get passwd info from getpwuid_r");
753
tsv->user = strdup(pw.pw_name);
755
error(ap->logopt, "failed to malloc buffer for user");
761
tsv->home = strdup(pw.pw_dir);
763
error(ap->logopt, "failed to malloc buffer for home");
772
/* Try to get group info */
774
grplen = sysconf(_SC_GETGR_R_SIZE_MAX);
776
error(ap->logopt, "failed to get buffer size for getgrgid_r");
786
char *tmp = realloc(gr_tmp, tmplen + 1);
788
error(ap->logopt, "failed to malloc buffer for getgrgid_r");
799
status = getgrgid_r(mt->gid, pgr, gr_tmp, tmplen, ppgr);
800
if (status != ERANGE)
805
if (status || !pgr) {
806
error(ap->logopt, "failed to get group info from getgrgid_r");
814
tsv->group = strdup(gr.gr_name);
816
error(ap->logopt, "failed to malloc buffer for group");
826
status = pthread_setspecific(key_thread_stdenv_vars, tsv);
828
error(ap->logopt, "failed to set stdenv thread var");
835
status = lookup_nss_mount(ap, NULL, mt->name, mt->len);
836
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
838
send_ready(ap->logopt, ap->ioctlfd, mt->wait_queue_token);
839
info(ap->logopt, "mounted %s", buf);
841
send_fail(ap->logopt, ap->ioctlfd, mt->wait_queue_token);
842
info(ap->logopt, "failed to mount %s", buf);
844
pthread_setcancelstate(state, NULL);
846
pthread_cleanup_pop(0);
847
pthread_cleanup_pop(1);
848
pthread_cleanup_pop(1);
853
int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missing_indirect_t *pkt)
856
char buf[MAX_ERR_BUF];
857
struct pending_args *mt;
860
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
862
debug(ap->logopt, "token %ld, name %s, request pid %u",
863
(unsigned long) pkt->wait_queue_token, pkt->name, pkt->pid);
865
/* Ignore packet if we're trying to shut down */
867
ap->state == ST_SHUTDOWN_FORCE ||
868
ap->state == ST_SHUTDOWN) {
869
send_fail(ap->logopt, ap->ioctlfd, pkt->wait_queue_token);
870
pthread_setcancelstate(state, NULL);
874
mt = malloc(sizeof(struct pending_args));
876
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
877
logerr("malloc: %s", estr);
878
send_fail(ap->logopt, ap->ioctlfd, pkt->wait_queue_token);
879
pthread_setcancelstate(state, NULL);
882
memset(mt, 0, sizeof(struct pending_args));
884
status = pthread_cond_init(&mt->cond, NULL);
888
status = pthread_mutex_lock(&ma_mutex);
893
strncpy(mt->name, pkt->name, pkt->len);
894
mt->name[pkt->len] = '\0';
899
mt->wait_queue_token = pkt->wait_queue_token;
901
status = pthread_create(&thid, &thread_attr, do_mount_indirect, mt);
903
error(ap->logopt, "expire thread create failed");
904
send_fail(ap->logopt, ap->ioctlfd, pkt->wait_queue_token);
905
mount_mutex_unlock(NULL);
906
pending_cond_destroy(mt);
907
free_pending_args(mt);
908
pthread_setcancelstate(state, NULL);
912
pthread_cleanup_push(mount_mutex_unlock, NULL);
913
pthread_setcancelstate(state, NULL);
916
while (!mt->signaled) {
917
status = pthread_cond_wait(&mt->cond, &ma_mutex);
922
pthread_cleanup_pop(1);