16
15
#include <stdlib.h>
17
16
#include <string.h>
21
17
#include <limits.h>
22
18
#include <sys/types.h>
23
19
#include <sys/stat.h>
20
#include <sys/ioctl.h>
21
#include <sys/mount.h>
26
30
#include "automount.h"
32
#define MAX_OPTIONS_LEN 80
33
#define MAX_MNT_NAME_LEN 30
37
const unsigned int t_indirect = AUTOFS_TYPE_INDIRECT;
38
const unsigned int t_direct = AUTOFS_TYPE_DIRECT;
39
const unsigned int t_offset = AUTOFS_TYPE_OFFSET;
40
const unsigned int type_count = 3;
42
static const char options_template[] = "fd=%d,pgrp=%u,minproto=5,maxproto=%d";
43
static const char options_template_extra[] = "fd=%d,pgrp=%u,minproto=5,maxproto=%d,%s";
44
static const char mnt_name_template[] = "automount(pid%u)";
46
static struct kernel_mod_version kver = {0, 0};
47
static const char kver_options_template[] = "fd=%d,pgrp=%u,minproto=3,maxproto=5";
49
unsigned int query_kproto_ver(void)
51
struct ioctl_ops *ops = get_ioctl_ops();
52
char dir[] = "/tmp/autoXXXXXX", *t_dir;
53
char options[MAX_OPTIONS_LEN + 1];
54
pid_t pgrp = getpgrp();
55
int pipefd[2], ioctlfd, len;
62
if (pipe(pipefd) == -1) {
67
len = snprintf(options, MAX_OPTIONS_LEN,
68
kver_options_template, pipefd[1], (unsigned) pgrp);
76
if (mount("automount", t_dir, "autofs", MS_MGC_VAL, options)) {
85
if (stat(t_dir, &st) == -1) {
92
ops->open(LOGOPT_NONE, &ioctlfd, st.st_dev, t_dir);
100
ops->catatonic(LOGOPT_NONE, ioctlfd);
102
/* If this ioctl() doesn't work, it is kernel version 2 */
103
if (ops->protover(LOGOPT_NONE, ioctlfd, &kver.major)) {
104
ops->close(LOGOPT_NONE, ioctlfd);
111
/* If this ioctl() doesn't work, version is 4 or less */
112
if (ops->protosubver(LOGOPT_NONE, ioctlfd, &kver.minor)) {
113
ops->close(LOGOPT_NONE, ioctlfd);
120
ops->close(LOGOPT_NONE, ioctlfd);
128
unsigned int get_kver_major(void)
133
unsigned int get_kver_minor(void)
138
#ifdef HAVE_MOUNT_NFS
139
static int extract_version(char *start, struct nfs_mount_vers *vers)
141
char *s_ver = strchr(start, ' ');
142
while (*s_ver && !isdigit(*s_ver)) {
148
vers->major = atoi(strtok(s_ver, "."));
149
vers->minor = (unsigned int) atoi(strtok(NULL, "."));
150
vers->fix = (unsigned int) atoi(strtok(NULL, "."));
154
int check_nfs_mount_version(struct nfs_mount_vers *vers,
155
struct nfs_mount_vers *check)
158
int ret, status, pipefd[2];
159
char errbuf[EBUFSIZ + 1], *p, *sp;
161
sigset_t allsigs, tmpsig, oldsig;
168
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state);
170
sigfillset(&allsigs);
171
pthread_sigmask(SIG_BLOCK, &allsigs, &oldsig);
177
dup2(pipefd[1], STDOUT_FILENO);
178
dup2(pipefd[1], STDERR_FILENO);
181
execl(PATH_MOUNT_NFS, PATH_MOUNT_NFS, "-V", (char *) NULL);
182
_exit(255); /* execv() failed */
189
sigaddset(&tmpsig, SIGCHLD);
190
pthread_sigmask(SIG_SETMASK, &tmpsig, NULL);
196
pthread_sigmask(SIG_SETMASK, &oldsig, NULL);
197
pthread_setcancelstate(cancel_state, NULL);
204
errn = read(pipefd[0], errbuf + errp, EBUFSIZ - errp);
205
if (errn == -1 && errno == EINTR)
214
while (errp && (p = memchr(sp, '\n', errp))) {
220
if (errp && sp != errbuf)
221
memmove(errbuf, sp, errp);
223
if (errp >= EBUFSIZ) {
224
/* Line too long, split */
226
if ((s_ver = strstr(errbuf, "nfs-utils"))) {
227
if (extract_version(s_ver, vers))
233
if ((s_ver = strstr(errbuf, "nfs-utils"))) {
234
if (extract_version(s_ver, vers))
243
/* End of file without \n */
245
if ((s_ver = strstr(errbuf, "nfs-utils"))) {
246
if (extract_version(s_ver, vers))
252
if ((vers->major < check->major) ||
253
((vers->major == check->major) && (vers->minor < check->minor)) ||
254
((vers->major == check->major) && (vers->minor == check->minor) &&
255
(vers->fix < check->fix)))
259
if (waitpid(f, &status, 0) != f) ;
261
pthread_sigmask(SIG_SETMASK, &oldsig, NULL);
262
pthread_setcancelstate(cancel_state, NULL);
267
int check_nfs_mount_version(struct nfs_mount_vers *vers,
268
struct nfs_mount_vers *check)
275
* Make common autofs mount options string
277
char *make_options_string(char *path, int pipefd, const char *extra)
282
options = malloc(MAX_OPTIONS_LEN + 1);
284
logerr("can't malloc options string");
289
len = snprintf(options, MAX_OPTIONS_LEN,
290
options_template_extra,
291
pipefd, (unsigned) getpgrp(),
292
AUTOFS_MAX_PROTO_VERSION, extra);
294
len = snprintf(options, MAX_OPTIONS_LEN, options_template,
295
pipefd, (unsigned) getpgrp(),
296
AUTOFS_MAX_PROTO_VERSION);
298
if (len >= MAX_OPTIONS_LEN) {
299
logerr("buffer to small for options - truncated");
300
len = MAX_OPTIONS_LEN - 1;
304
logerr("failed to malloc autofs mount options for %s", path);
313
char *make_mnt_name_string(char *path)
318
mnt_name = malloc(MAX_MNT_NAME_LEN + 1);
320
logerr("can't malloc mnt_name string");
324
len = snprintf(mnt_name, MAX_MNT_NAME_LEN,
325
mnt_name_template, (unsigned) getpid());
327
if (len >= MAX_MNT_NAME_LEN) {
328
logerr("buffer to small for mnt_name - truncated");
329
len = MAX_MNT_NAME_LEN - 1;
333
logerr("failed setting up mnt_name for autofs path %s", path);
337
mnt_name[len] = '\0';
29
343
* Get list of mounts under path in longest->shortest order
31
345
struct mnt_list *get_mnt_list(const char *table, const char *path, int include)
34
int pathlen = strlen(path);
348
size_t pathlen = strlen(path);
349
struct mntent mnt_wrk;
350
char buf[PATH_MAX * 3];
35
351
struct mntent *mnt;
36
352
struct mnt_list *ent, *mptr, *last;
37
353
struct mnt_list *list = NULL;
41
357
if (!path || !pathlen || pathlen > PATH_MAX)
44
tab = setmntent(table, "r");
360
tab = open_setmntent_r(table);
46
error("get_mntlist: setmntent: %m");
362
char *estr = strerror_r(errno, buf, PATH_MAX - 1);
363
logerr("setmntent: %s", estr);
50
while ((mnt = getmntent(tab)) != NULL) {
367
while ((mnt = getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) {
51
368
len = strlen(mnt->mnt_dir);
53
370
if ((!include && len <= pathlen) ||
243
485
free(this->path);
245
490
if (this->fs_type)
246
491
free(this->fs_type);
252
static int find_mntent(const char *table, const char *path, struct mntent *ent)
500
int contained_in_local_fs(const char *path)
502
struct mnt_list *mnts, *this;
503
size_t pathlen = strlen(path);
506
if (!path || !pathlen || pathlen > PATH_MAX)
509
mnts = get_mnt_list(_PATH_MOUNTED, "/", 1);
515
for (this = mnts; this != NULL; this = this->next) {
516
size_t len = strlen(this->path);
518
if (!strncmp(path, this->path, len)) {
519
if (len > 1 && pathlen > len && path[len] != '/')
521
else if (len == 1 && this->path[0] == '/') {
523
* always return true on rootfs, we don't
524
* want to break diskless clients.
527
} else if (this->fs_name[0] == '/') {
528
if (strlen(this->fs_name) > 1) {
529
if (this->fs_name[1] != '/')
533
} else if (!strncmp("LABEL=", this->fs_name, 6) ||
534
!strncmp("UUID=", this->fs_name, 5))
545
static int table_is_mounted(const char *table, const char *path, unsigned int type)
254
547
struct mntent *mnt;
548
struct mntent mnt_wrk;
549
char buf[PATH_MAX * 3];
550
size_t pathlen = strlen(path);
256
int pathlen = strlen(path);
259
if (!path || !pathlen || pathlen > PATH_MAX)
554
if (!path || !pathlen || pathlen >= PATH_MAX)
262
tab = setmntent(table, "r");
557
tab = open_setmntent_r(table);
264
error("find_mntent: setmntent: %m");
559
char *estr = strerror_r(errno, buf, PATH_MAX - 1);
560
logerr("setmntent: %s", estr);
268
while ((mnt = getmntent(tab)) != NULL) {
269
int len = strlen(mnt->mnt_dir);
564
while ((mnt = getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) {
565
size_t len = strlen(mnt->mnt_dir);
568
unsigned int autofs_fs;
570
autofs_fs = !strcmp(mnt->mnt_type, "autofs");
572
if (type & MNTS_REAL)
576
if (type & MNTS_AUTOFS)
271
581
if (pathlen == len && !strncmp(path, mnt->mnt_dir, pathlen)) {
272
int szent = sizeof(struct mntent);
275
memcpy(ent, mnt, szent);
286
int is_mounted(const char *table, const char *path)
290
if (find_mntent(table, path, NULL))
296
int has_fstab_option(const char *path, const char *opt)
301
if (find_mntent(_PATH_MNTTAB, path, &ent)) {
302
if ((res = hasmntopt(&ent, opt)))
310
* Check id owner option is present in fstab of requested
311
* mount. If it is return iowner uid of requested dev.
313
int allow_owner_mount(const char *path)
318
if (getuid() || is_mounted(_PATH_MOUNTED, path))
321
if (find_mntent(_PATH_MNTTAB, path, &ent)) {
324
if (!hasmntopt(&ent, "owner"))
327
if (stat(ent.mnt_fsname, &st) == -1)
591
static int ioctl_is_mounted(const char *path, unsigned int type)
593
struct ioctl_ops *ops = get_ioctl_ops();
594
unsigned int mounted;
596
ops->ismountpoint(LOGOPT_NONE, -1, path, &mounted);
602
return (mounted & DEV_IOCTL_IS_AUTOFS);
604
return (mounted & DEV_IOCTL_IS_OTHER);
610
int is_mounted(const char *table, const char *path, unsigned int type)
612
struct ioctl_ops *ops = get_ioctl_ops();
614
if (ops->ismountpoint)
615
return ioctl_is_mounted(path, type);
617
return table_is_mounted(table, path, type);
620
int has_fstab_option(const char *opt)
623
struct mntent mnt_wrk;
624
char buf[PATH_MAX * 3];
631
tab = open_setmntent_r(_PATH_MNTTAB);
633
char *estr = strerror_r(errno, buf, PATH_MAX - 1);
634
logerr("setmntent: %s", estr);
638
while ((mnt = getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) {
639
if (hasmntopt(mnt, opt)) {
649
char *get_offset(const char *prefix, char *offset,
650
struct list_head *head, struct list_head **pos)
652
struct list_head *next;
653
struct mnt_list *this;
654
size_t plen = strlen(prefix);
658
next = *pos ? (*pos)->next : head->next;
659
while (next != head) {
662
this = list_entry(next, struct mnt_list, ordered);
666
if (strlen(this->path) <= plen)
669
if (!strncmp(prefix, this->path, plen)) {
670
pstart = &this->path[plen];
672
/* not part of this sub-tree */
676
/* get next offset */
679
len = pend - pstart - 1;
680
strncpy(offset, pstart, len);
686
while (next != head) {
689
this = list_entry(next, struct mnt_list, ordered);
691
if (strlen(this->path) <= plen + len)
694
pstart = &this->path[plen];
696
/* not part of this sub-tree */
701
if (!*(pstart + len + 1))
704
/* compare next offset */
705
if (pstart[len] != '/' || strncmp(offset, pstart, len))
712
return *offset ? offset : NULL;
715
void add_ordered_list(struct mnt_list *ent, struct list_head *head)
718
struct mnt_list *this;
720
list_for_each(p, head) {
724
this = list_entry(p, struct mnt_list, ordered);
725
tlen = strlen(this->path);
727
eq = strncmp(this->path, ent->path, tlen);
728
if (!eq && tlen == strlen(ent->path))
732
INIT_LIST_HEAD(&ent->ordered);
733
list_add_tail(&ent->ordered, p);
737
INIT_LIST_HEAD(&ent->ordered);
738
list_add_tail(&ent->ordered, p);
744
* Since we have to look at the entire mount tree for direct
745
* mounts (all mounts under "/") and we may have a large number
746
* of entries to traverse again and again we need to
747
* use a more efficient method than the routines above.
749
* Thre tree_... routines allow us to read the mount tree
750
* once and pass it to subsequent functions for use. Since
751
* it's a tree structure searching should be a low overhead
754
void tree_free_mnt_tree(struct mnt_list *tree)
756
struct list_head *head, *p;
761
tree_free_mnt_tree(tree->left);
762
tree_free_mnt_tree(tree->right);
767
struct mnt_list *this;
769
this = list_entry(p, struct mnt_list, self);
773
list_del(&this->self);
796
* Make tree of system mounts in /proc/mounts.
798
struct mnt_list *tree_make_mnt_tree(const char *table, const char *path)
801
struct mntent mnt_wrk;
802
char buf[PATH_MAX * 3];
804
struct mnt_list *ent, *mptr;
805
struct mnt_list *tree = NULL;
810
tab = open_setmntent_r(table);
812
char *estr = strerror_r(errno, buf, PATH_MAX - 1);
813
logerr("setmntent: %s", estr);
819
while ((mnt = getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) {
820
size_t len = strlen(mnt->mnt_dir);
822
/* Not matching path */
823
if (strncmp(mnt->mnt_dir, path, plen))
826
/* Not a subdirectory of requested path */
827
if (plen > 1 && len > plen && mnt->mnt_dir[plen] != '/')
830
ent = malloc(sizeof(*ent));
833
tree_free_mnt_tree(tree);
836
memset(ent, 0, sizeof(*ent));
838
INIT_LIST_HEAD(&ent->self);
839
INIT_LIST_HEAD(&ent->list);
840
INIT_LIST_HEAD(&ent->entries);
841
INIT_LIST_HEAD(&ent->sublist);
842
INIT_LIST_HEAD(&ent->ordered);
844
ent->path = malloc(len + 1);
848
tree_free_mnt_tree(tree);
851
strcpy(ent->path, mnt->mnt_dir);
853
ent->fs_name = malloc(strlen(mnt->mnt_fsname) + 1);
858
tree_free_mnt_tree(tree);
861
strcpy(ent->fs_name, mnt->mnt_fsname);
863
ent->fs_type = malloc(strlen(mnt->mnt_type) + 1);
869
tree_free_mnt_tree(tree);
872
strcpy(ent->fs_type, mnt->mnt_type);
874
ent->opts = malloc(strlen(mnt->mnt_opts) + 1);
881
tree_free_mnt_tree(tree);
884
strcpy(ent->opts, mnt->mnt_opts);
887
pgrp = strstr(mnt->mnt_opts, "pgrp=");
889
char *end = strchr(pgrp, ',');
892
sscanf(pgrp, "pgrp=%d", &ent->owner);
897
int elen = strlen(ent->path);
898
int mlen = strlen(mptr->path);
908
} else if (elen > mlen) {
918
eq = strcmp(ent->path, mptr->path);
934
list_add_tail(&ent->self, &mptr->self);
948
* Get list of mounts under "path" in longest->shortest order
950
int tree_get_mnt_list(struct mnt_list *mnts, struct list_head *list, const char *path, int include)
958
mlen = strlen(mnts->path);
960
return tree_get_mnt_list(mnts->right, list, path, include);
962
struct list_head *self, *p;
964
tree_get_mnt_list(mnts->left, list, path, include);
966
if ((!include && mlen <= plen) ||
967
strncmp(mnts->path, path, plen))
970
if (plen > 1 && mlen > plen && mnts->path[plen] != '/')
973
INIT_LIST_HEAD(&mnts->list);
974
list_add(&mnts->list, list);
977
list_for_each(p, self) {
978
struct mnt_list *this;
980
this = list_entry(p, struct mnt_list, self);
981
INIT_LIST_HEAD(&this->list);
982
list_add(&this->list, list);
985
tree_get_mnt_list(mnts->right, list, path, include);
988
if (list_empty(list))
995
* Get list of mounts under "path" in longest->shortest order
997
int tree_get_mnt_sublist(struct mnt_list *mnts, struct list_head *list, const char *path, int include)
1004
plen = strlen(path);
1005
mlen = strlen(mnts->path);
1007
return tree_get_mnt_sublist(mnts->right, list, path, include);
1009
struct list_head *self, *p;
1011
tree_get_mnt_sublist(mnts->left, list, path, include);
1013
if ((!include && mlen <= plen) ||
1014
strncmp(mnts->path, path, plen))
1017
if (plen > 1 && mlen > plen && mnts->path[plen] != '/')
1020
INIT_LIST_HEAD(&mnts->sublist);
1021
list_add(&mnts->sublist, list);
1024
list_for_each(p, self) {
1025
struct mnt_list *this;
1027
this = list_entry(p, struct mnt_list, self);
1028
INIT_LIST_HEAD(&this->sublist);
1029
list_add(&this->sublist, list);
1032
tree_get_mnt_sublist(mnts->right, list, path, include);
1035
if (list_empty(list))
1041
int tree_find_mnt_ents(struct mnt_list *mnts, struct list_head *list, const char *path)
1048
plen = strlen(path);
1049
mlen = strlen(mnts->path);
1051
return tree_find_mnt_ents(mnts->right, list, path);
1052
else if (mlen > plen)
1053
return tree_find_mnt_ents(mnts->left, list, path);
1055
struct list_head *self, *p;
1057
tree_find_mnt_ents(mnts->left, list, path);
1059
if (!strcmp(mnts->path, path)) {
1060
INIT_LIST_HEAD(&mnts->entries);
1061
list_add(&mnts->entries, list);
1065
list_for_each(p, self) {
1066
struct mnt_list *this;
1068
this = list_entry(p, struct mnt_list, self);
1070
if (!strcmp(this->path, path)) {
1071
INIT_LIST_HEAD(&this->entries);
1072
list_add(&this->entries, list);
1076
tree_find_mnt_ents(mnts->right, list, path);
1078
if (!list_empty(list))
1085
int tree_is_mounted(struct mnt_list *mnts, const char *path, unsigned int type)
1087
struct ioctl_ops *ops = get_ioctl_ops();
1088
struct list_head *p;
1089
struct list_head list;
1092
if (ops->ismountpoint)
1093
return ioctl_is_mounted(path, type);
1095
INIT_LIST_HEAD(&list);
1097
if (!tree_find_mnt_ents(mnts, &list, path))
1100
list_for_each(p, &list) {
1101
struct mnt_list *mptr;
1103
mptr = list_entry(p, struct mnt_list, entries);
1106
unsigned int autofs_fs;
1108
autofs_fs = !strcmp(mptr->fs_type, "autofs");
1110
if (type & MNTS_REAL) {
1115
} else if (type & MNTS_AUTOFS) {
1129
void set_tsd_user_vars(unsigned int logopt, uid_t uid, gid_t gid)
1131
struct thread_stdenv_vars *tsv;
1133
struct passwd *ppw = &pw;
1134
struct passwd **pppw = &ppw;
1137
struct group **ppgr;
1138
char *pw_tmp, *gr_tmp;
1139
int status, tmplen, grplen;
1142
* Setup thread specific data values for macro
1143
* substution in map entries during the mount.
1144
* Best effort only as it must go ahead.
1147
tsv = malloc(sizeof(struct thread_stdenv_vars));
1149
error(logopt, "failed alloc tsv storage");
1156
/* Try to get passwd info */
1158
tmplen = sysconf(_SC_GETPW_R_SIZE_MAX);
1160
error(logopt, "failed to get buffer size for getpwuid_r");
1164
pw_tmp = malloc(tmplen + 1);
1166
error(logopt, "failed to malloc buffer for getpwuid_r");
1170
status = getpwuid_r(uid, ppw, pw_tmp, tmplen, pppw);
1171
if (status || !ppw) {
1172
error(logopt, "failed to get passwd info from getpwuid_r");
1177
tsv->user = strdup(pw.pw_name);
1179
error(logopt, "failed to malloc buffer for user");
1184
tsv->home = strdup(pw.pw_dir);
1186
error(logopt, "failed to malloc buffer for home");
1193
/* Try to get group info */
1195
grplen = sysconf(_SC_GETGR_R_SIZE_MAX);
1197
error(logopt, "failed to get buffer size for getgrgid_r");
1204
char *tmp = realloc(gr_tmp, tmplen + 1);
1206
error(logopt, "failed to malloc buffer for getgrgid_r");
1214
status = getgrgid_r(gid, pgr, gr_tmp, tmplen, ppgr);
1215
if (status != ERANGE)
1220
if (status || !pgr) {
1221
error(logopt, "failed to get group info from getgrgid_r");
1226
tsv->group = strdup(gr.gr_name);
1228
error(logopt, "failed to malloc buffer for group");
1235
status = pthread_setspecific(key_thread_stdenv_vars, tsv);
1237
error(logopt, "failed to set stdenv thread var");
1238
goto free_tsv_group;
1254
const char *mount_type_str(const unsigned int type)
1256
static const char *str_type[] = {
1261
unsigned int pos, i;
1263
for (pos = 0, i = type; pos < type_count; i >>= 1, pos++)
1267
return (pos == type_count ? NULL : str_type[pos]);
1270
void notify_mount_result(struct autofs_point *ap,
1271
const char *path, const char *type)
1273
if (ap->exp_timeout)
1275
"mounted %s on %s with timeout %u, freq %u seconds",
1277
(unsigned int) ap->exp_timeout,
1278
(unsigned int) ap->exp_runfreq);
1281
"mounted %s on %s with timeouts disabled",
1287
static int do_remount_direct(struct autofs_point *ap, int fd, const char *path)
1289
struct ioctl_ops *ops = get_ioctl_ops();
1290
int status = REMOUNT_SUCCESS;
1295
ops->requestor(ap->logopt, fd, path, &uid, &gid);
1296
if (uid != -1 && gid != -1)
1297
set_tsd_user_vars(ap->logopt, uid, gid);
1299
ret = lookup_nss_mount(ap, NULL, path, strlen(path));
1301
info(ap->logopt, "re-connected to %s", path);
1303
status = REMOUNT_FAIL;
1304
info(ap->logopt, "failed to re-connect %s", path);
1310
static int do_remount_indirect(struct autofs_point *ap, int fd, const char *path)
1312
struct ioctl_ops *ops = get_ioctl_ops();
1313
int status = REMOUNT_SUCCESS;
1315
char buf[PATH_MAX + 1];
1318
unsigned int mounted;
1321
n = scandir(path, &de, 0, alphasort);
1330
if (strcmp(de[n]->d_name, ".") == 0 ||
1331
strcmp(de[n]->d_name, "..") == 0) {
1336
ret = cat_path(buf, size, path, de[n]->d_name);
1345
ops->ismountpoint(ap->logopt, -1, buf, &mounted);
1347
struct dirent **de2;
1350
i = j = scandir(buf, &de2, 0, alphasort);
1364
ops->requestor(ap->logopt, fd, buf, &uid, &gid);
1365
if (uid != -1 && gid != -1)
1366
set_tsd_user_vars(ap->logopt, uid, gid);
1368
len = strlen(de[n]->d_name);
1370
ret = lookup_nss_mount(ap, NULL, de[n]->d_name, len);
1372
info(ap->logopt, "re-connected to %s", buf);
1374
status = REMOUNT_FAIL;
1375
info(ap->logopt, "failed to re-connect %s", buf);
1384
static int remount_active_mount(struct autofs_point *ap,
1385
struct mapent_cache *mc,
1386
const char *path, dev_t devid,
1387
const unsigned int type,
1390
struct ioctl_ops *ops = get_ioctl_ops();
1391
time_t timeout = ap->exp_timeout;
1392
const char *str_type = mount_type_str(type);
1393
char buf[MAX_ERR_BUF];
1394
unsigned int mounted;
1400
/* Open failed, no mount present */
1401
ops->open(ap->logopt, &fd, devid, path);
1403
return REMOUNT_OPEN_FAIL;
1405
/* Re-reading the map, set timeout and return */
1406
if (ap->state == ST_READMAP) {
1407
ops->timeout(ap->logopt, fd, &timeout);
1408
ops->close(ap->logopt, fd);
1409
return REMOUNT_READ_MAP;
1412
debug(ap->logopt, "trying to re-connect to mount %s", path);
1414
/* Mounted so set pipefd and timeout etc. */
1415
if (ops->catatonic(ap->logopt, fd) == -1) {
1416
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
1417
error(ap->logopt, "set catatonic failed: %s", estr);
1418
debug(ap->logopt, "couldn't re-connect to mount %s", path);
1419
ops->close(ap->logopt, fd);
1420
return REMOUNT_OPEN_FAIL;
1422
if (ops->setpipefd(ap->logopt, fd, ap->kpipefd) == -1) {
1423
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
1424
error(ap->logopt, "set pipefd failed: %s", estr);
1425
debug(ap->logopt, "couldn't re-connect to mount %s", path);
1426
ops->close(ap->logopt, fd);
1427
return REMOUNT_OPEN_FAIL;
1429
ops->timeout(ap->logopt, fd, &timeout);
1430
if (fstat(fd, &st) == -1) {
1432
"failed to stat %s mount %s", str_type, path);
1433
debug(ap->logopt, "couldn't re-connect to mount %s", path);
1434
ops->close(ap->logopt, fd);
1435
return REMOUNT_STAT_FAIL;
1438
cache_set_ino_index(mc, path, st.st_dev, st.st_ino);
1440
ap->dev = st.st_dev;
1441
notify_mount_result(ap, path, str_type);
1445
/* Any mounts on or below? */
1446
if (ops->ismountpoint(ap->logopt, fd, path, &mounted) == -1) {
1447
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
1448
error(ap->logopt, "ismountpoint %s failed: %s", path, estr);
1449
debug(ap->logopt, "couldn't re-connect to mount %s", path);
1450
ops->close(ap->logopt, fd);
1451
return REMOUNT_FAIL;
1455
* If we're an indirect mount we pass back the fd.
1456
* But if were a direct or offset mount with no active
1457
* mount we don't retain an open file descriptor.
1459
if (type != t_indirect) {
1460
ops->close(ap->logopt, fd);
1466
* What can I do if we can't remount the existing
1467
* mount(s) (possibly a partial failure), everything
1468
* following will be broken?
1470
if (type == t_indirect)
1471
ret = do_remount_indirect(ap, fd, path);
1473
ret = do_remount_direct(ap, fd, path);
1476
debug(ap->logopt, "re-connected to mount %s", path);
1478
return REMOUNT_SUCCESS;
1481
int try_remount(struct autofs_point *ap, struct mapent *me, unsigned int type)
1483
struct ioctl_ops *ops = get_ioctl_ops();
1484
struct mapent_cache *mc;
1489
if (type == t_indirect) {
1497
ret = ops->mount_device(ap->logopt, path, type, &devid);
1498
if (ret == -1 || ret == 0)
1501
ret = remount_active_mount(ap, mc, path, devid, type, &fd);
1504
* The directory must exist since we found a device
1505
* number for the mount but we can't know if we created
1506
* it or not. However, if this is an indirect mount with
1507
* the nobrowse option we need to remove the mount point
1508
* directory at umount anyway.
1510
if (type == t_indirect) {
1511
if (ap->flags & MOUNT_FLAG_GHOST)
1512
ap->flags &= ~MOUNT_FLAG_DIR_CREATED;
1514
ap->flags |= MOUNT_FLAG_DIR_CREATED;
1516
me->flags &= ~MOUNT_FLAG_DIR_CREATED;
1519
* Either we opened the mount or we're re-reading the map.
1520
* If we opened the mount and ioctlfd is not -1 we have
1521
* a descriptor for the indirect mount so we need to
1522
* record that in the mount point struct. Otherwise we're
1523
* re-reading the map.
1525
if (ret == REMOUNT_SUCCESS || ret == REMOUNT_READ_MAP) {
1527
if (type == t_indirect)
1534
/* Indirect mount requires a valid fd */
1535
if (type != t_indirect)
1540
* Since we got the device number above a mount exists so
1541
* any other failure warrants a failure return here.
1546
int umount_ent(struct autofs_point *ap, const char *path)
1550
rv = spawn_umount(ap->logopt, path, NULL);
1551
/* We are doing a forced shutcwdown down so unlink busy mounts */
1552
if (rv && (ap->state == ST_SHUTDOWN_FORCE || ap->state == ST_SHUTDOWN)) {
1553
if (ap->state == ST_SHUTDOWN_FORCE) {
1554
info(ap->logopt, "forcing umount of %s", path);
1555
rv = spawn_umount(ap->logopt, "-l", path, NULL);
1559
* Verify that we actually unmounted the thing. This is a
1560
* belt and suspenders approach to not eating user data.
1561
* We have seen cases where umount succeeds, but there is
1562
* still a file system mounted on the mount point. How
1563
* this happens has not yet been determined, but we want to
1564
* make sure to return failure here, if that is the case,
1565
* so that we do not try to call rmdir_path on the
1568
if (!rv && is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) {
1570
"the umount binary reported that %s was "
1571
"unmounted, but there is still something "
1572
"mounted on this path.", path);
1580
int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
1581
const char *root, unsigned int start, const char *base)
1583
char path[PATH_MAX + 1];
1584
char *offset = path;
1586
struct list_head *pos = NULL;
1587
unsigned int fs_path_len;
1588
unsigned int mounted;
1591
fs_path_len = start + strlen(base);
1592
if (fs_path_len > PATH_MAX)
1596
offset = cache_get_offset(base, offset, start, &me->multi_list, &pos);
1598
int plen = fs_path_len + strlen(offset);
1600
if (plen > PATH_MAX) {
1601
warn(ap->logopt, "path loo long");
1605
oe = cache_lookup_offset(base, offset, start, &me->multi_list);
1606
if (!oe || !oe->mapent)
1609
debug(ap->logopt, "mount offset %s at %s", oe->key, root);
1611
ret = mount_autofs_offset(ap, oe, root, offset);
1612
if (ret >= MOUNT_OFFSET_OK)
1615
if (ret != MOUNT_OFFSET_IGNORE)
1616
warn(ap->logopt, "failed to mount offset");
1619
"ignoring \"nohide\" trigger %s",
1626
offset = cache_get_offset(base,
1627
offset, start, &me->multi_list, &pos);
1633
int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base)
1635
char path[PATH_MAX + 1];
1638
struct list_head *mm_root, *pos;
1639
const char o_root[] = "/";
1640
const char *mm_base;
1644
start = strlen(root);
1646
mm_root = &me->multi->multi_list;
1656
/* Make sure "none" of the offsets have an active mount. */
1657
while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
1660
oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list);
1661
/* root offset is a special case */
1662
if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1)
1666
* Check for and umount subtree offsets resulting from
1667
* nonstrict mount fail.
1669
oe_base = oe->key + strlen(root);
1670
left += umount_multi_triggers(ap, oe, root, oe_base);
1672
if (oe->ioctlfd != -1 ||
1673
is_mounted(_PROC_MOUNTS, oe->key, MNTS_REAL)) {
1685
/* Make sure "none" of the offsets have an active mount. */
1686
while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
1687
oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list);
1688
/* root offset is a special case */
1689
if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1)
1692
debug(ap->logopt, "umount offset %s", oe->key);
1694
if (umount_autofs_offset(ap, oe)) {
1695
warn(ap->logopt, "failed to umount offset");
1700
if (!left && me->multi == me) {
1701
struct mapent_cache *mc = me->mc;
1706
* If we can't umount the root container then we can't
1707
* delete the offsets from the cache and we need to put
1708
* the offset triggers back.
1710
if (is_mounted(_PATH_MOUNTED, root, MNTS_REAL)) {
1711
info(ap->logopt, "unmounting dir = %s", root);
1712
if (umount_ent(ap, root)) {
1713
if (mount_multi_triggers(ap, me, root, strlen(root), "/") < 0)
1715
"failed to remount offset triggers");
1720
/* We're done - clean out the offsets */
1721
status = cache_delete_offset_list(mc, me->key);
1722
if (status != CHE_OK)
1723
warn(ap->logopt, "couldn't delete offset list");