diff --git a/CHANGELOG b/CHANGELOG index 8df22ae..2ce58b4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,7 @@ - add multi nsswitch lookup. - change random multiple server selection option name to be consistent with existing downstream version 4 naming. +- fix mount point directory creation for bind mounts. 18/06/2007 autofs-5.0.2 ----------------------- diff --git a/daemon/automount.c b/daemon/automount.c index 294c511..9809b9c 100644 --- a/daemon/automount.c +++ b/daemon/automount.c @@ -104,11 +104,14 @@ static int do_mkdir(const char *parent, const char *path, mode_t mode) status = statfs(parent, &fs); if ((status != -1 && fs.f_type == (__SWORD_TYPE) AUTOFS_SUPER_MAGIC) || contained_in_local_fs(path)) { - if (mkdir(path, mode) == -1) + if (mkdir(path, mode) == -1) { + errno = EACCES; return 0; + } return 1; } + errno = EACCES; return 0; } diff --git a/daemon/direct.c b/daemon/direct.c index 179e74b..9a39a6f 100644 --- a/daemon/direct.c +++ b/daemon/direct.c @@ -604,6 +604,14 @@ int umount_autofs_offset(struct autofs_point *ap, struct mapent *me) } ioctlfd = me->ioctlfd; } else { + /* offset isn't mounted, return success and try to recover */ + if (!is_mounted(_PROC_MOUNTS, me->key, MNTS_AUTOFS)) { + debug(ap->logopt, + "offset %s unexpectedly not mounted", + me->key); + return 0; + } + ioctlfd = open(me->key, O_RDONLY); if (ioctlfd != -1) { if ((cl_flags = fcntl(ioctlfd, F_GETFD, 0)) != -1) { @@ -689,11 +697,19 @@ force_umount: } else msg("umounted offset mount %s", me->key); + if (!rv && me->dir_created) { + if (rmdir(me->key) == -1) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + warn(ap->logopt, "failed to remove dir %s: %s", + me->key, estr); + } + } return rv; } -int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, int is_autofs_fs) +int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) { + char buf[MAX_ERR_BUF]; struct mnt_params *mp; time_t timeout = ap->exp_timeout; struct stat st; @@ -740,36 +756,38 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, int is_autof return 0; } - if (is_autofs_fs) { - /* In case the directory doesn't exist, try to mkdir it */ - if (mkdir_path(me->key, 0555) < 0) { - if (errno != EEXIST) { - crit(ap->logopt, - "failed to create mount directory %s %d", - me->key, errno); - return -1; - } + /* In case the directory doesn't exist, try to mkdir it */ + if (mkdir_path(me->key, 0555) < 0) { + if (errno == EEXIST) { /* * If we recieve an error, and it's EEXIST * we know the directory was not created. */ me->dir_created = 0; + } else if (errno == EACCES) { + /* + * We require the mount point directory to exist when + * installing multi-mount triggers into a host + * filesystem. + * + * If it doesn't exist it is not a valid part of the + * mount heirachy. + */ + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + debug(ap->logopt, + "can't create mount directory: %s, %s", + me->key, estr); + return -1; } else { - /* No errors so the directory was successfully created */ - me->dir_created = 1; + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + crit(ap->logopt, + "failed to create mount directory: %s, %s", + me->key, estr); + return -1; } } else { - me->dir_created = 0; - - /* - * We require the mount point directory to exist when - * installing multi-mount triggers into a host filesystem. - * - * If it doesn't exist it is not a valid part of the - * mount heirachy so we silently succeed here. - */ - if (stat(me->key, &st) == -1 && errno == ENOENT) - return 0; + /* No errors so the directory was successfully created */ + me->dir_created = 1; } debug(ap->logopt, @@ -832,10 +850,8 @@ out_close: out_umount: umount(me->key); out_err: - if (is_autofs_fs) { - if (stat(me->key, &st) == 0 && me->dir_created) - rmdir_path(ap, me->key, st.st_dev); - } + if (stat(me->key, &st) == 0 && me->dir_created) + rmdir_path(ap, me->key, st.st_dev); return -1; } diff --git a/include/automount.h b/include/automount.h index 106ed0a..d9e4ecd 100644 --- a/include/automount.h +++ b/include/automount.h @@ -470,7 +470,7 @@ void *expire_proc_direct(void *); int expire_offsets_direct(struct autofs_point *ap, struct mapent *me, int now); int mount_autofs_indirect(struct autofs_point *ap); int mount_autofs_direct(struct autofs_point *ap); -int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, int is_autofs_fs); +int mount_autofs_offset(struct autofs_point *ap, struct mapent *me); void submount_signal_parent(struct autofs_point *ap, unsigned int success); int umount_autofs(struct autofs_point *ap, int force); int umount_autofs_indirect(struct autofs_point *ap); diff --git a/lib/parse_subs.c b/lib/parse_subs.c index 0c45905..ad19f34 100644 --- a/lib/parse_subs.c +++ b/lib/parse_subs.c @@ -388,10 +388,8 @@ int mount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, struct mapent *oe; struct list_head *pos = NULL; unsigned int fs_path_len; - struct statfs fs; - struct stat st; - unsigned int mounted, is_autofs_fs; - int ret, start; + unsigned int mounted; + int start; fs_path_len = strlen(root) + strlen(base); if (fs_path_len > PATH_MAX) @@ -399,15 +397,6 @@ int mount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, strcpy(path, root); strcat(path, base); - ret = statfs(path, &fs); - if (ret == -1) { - /* There's no mount yet - it must be autofs */ - if (errno == ENOENT) - is_autofs_fs = 1; - else - return -1; - } else - is_autofs_fs = fs.f_type == (__SWORD_TYPE) AUTOFS_SUPER_MAGIC ? 1 : 0; mounted = 0; start = strlen(root); @@ -424,20 +413,9 @@ int mount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, if (!oe) goto cont; - /* - * If the host filesystem is not an autofs fs - * we require the mount point directory exist - * and that permissions are OK. - */ - if (!is_autofs_fs) { - ret = stat(oe->key, &st); - if (ret == -1) - goto cont; - } - debug(ap->logopt, "mount offset %s", oe->key); - if (mount_autofs_offset(ap, oe, is_autofs_fs) < 0) + if (mount_autofs_offset(ap, oe) < 0) warn(ap->logopt, "failed to mount offset"); else mounted++;