autofs-5.0.6 - fix offset mount point directory removal
From: Ian Kent <ikent@redhat.com>
Attempting to remove the last component of a multi-mount offset mount
point is incorrect. The removal and attempted recovery is better
handled in the calling function.
---
CHANGELOG | 1
daemon/direct.c | 7 ----
lib/mounts.c | 82 ++++++++++++++++++++++++++++++++------------------------
3 files changed, 49 insertions(+), 41 deletions(-)
--- autofs-5.0.6.orig/CHANGELOG
+++ autofs-5.0.6/CHANGELOG
@@ -54,6 +54,7 @@
- fix sss map age not updated.
- fix remount deadlock.
- fix umount recovery of busy direct mount.
+- fix offset mount point directory removal.
28/06/2011 autofs-5.0.6
-----------------------
--- autofs-5.0.6.orig/daemon/direct.c
+++ autofs-5.0.6/daemon/direct.c
@@ -633,13 +633,6 @@ force_umount:
} else
info(ap->logopt, "umounted offset mount %s", me->key);
- if (!rv && me->flags & MOUNT_FLAG_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;
}
--- autofs-5.0.6.orig/lib/mounts.c
+++ autofs-5.0.6/lib/mounts.c
@@ -1605,6 +1605,33 @@ int umount_ent(struct autofs_point *ap,
return rv;
}
+static int do_mount_autofs_offset(struct autofs_point *ap,
+ struct mapent *oe, const char *root,
+ char *offset)
+
+{
+ int mounted = 0;
+ int ret;
+
+ debug(ap->logopt, "mount offset %s at %s", oe->key, root);
+
+ ret = mount_autofs_offset(ap, oe, root, offset);
+ if (ret >= MOUNT_OFFSET_OK)
+ mounted++;
+ else {
+ if (ret != MOUNT_OFFSET_IGNORE)
+ warn(ap->logopt, "failed to mount offset");
+ else {
+ debug(ap->logopt, "ignoring \"nohide\" trigger %s",
+ oe->key);
+ free(oe->mapent);
+ oe->mapent = NULL;
+ }
+ }
+
+ return mounted;
+}
+
int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
const char *root, unsigned int start, const char *base)
{
@@ -1613,8 +1640,7 @@ int mount_multi_triggers(struct autofs_p
struct mapent *oe;
struct list_head *pos = NULL;
unsigned int fs_path_len;
- unsigned int mounted;
- int ret;
+ int mounted;
fs_path_len = start + strlen(base);
if (fs_path_len > PATH_MAX)
@@ -1634,22 +1660,7 @@ int mount_multi_triggers(struct autofs_p
if (!oe || !oe->mapent)
goto cont;
- debug(ap->logopt, "mount offset %s at %s", oe->key, root);
-
- ret = mount_autofs_offset(ap, oe, root, offset);
- if (ret >= MOUNT_OFFSET_OK)
- mounted++;
- else {
- if (ret != MOUNT_OFFSET_IGNORE)
- warn(ap->logopt, "failed to mount offset");
- else {
- debug(ap->logopt,
- "ignoring \"nohide\" trigger %s",
- oe->key);
- free(oe->mapent);
- oe->mapent = NULL;
- }
- }
+ mounted += do_mount_autofs_offset(ap, oe, root, offset);
cont:
offset = cache_get_offset(base,
offset, start, &me->multi_list, &pos);
@@ -1681,7 +1692,6 @@ int umount_multi_triggers(struct autofs_
pos = NULL;
offset = path;
- /* Make sure "none" of the offsets have an active mount. */
while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
char *oe_base;
@@ -1700,28 +1710,32 @@ int umount_multi_triggers(struct autofs_
if (oe->ioctlfd != -1 ||
is_mounted(_PROC_MOUNTS, oe->key, MNTS_REAL)) {
left++;
- break;
- }
- }
-
- if (left)
- return left;
-
- pos = NULL;
- offset = path;
-
- /* Make sure "none" of the offsets have an active mount. */
- while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
- oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list);
- /* root offset is a special case */
- if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1)
continue;
+ }
debug(ap->logopt, "umount offset %s", oe->key);
if (umount_autofs_offset(ap, oe)) {
warn(ap->logopt, "failed to umount offset");
left++;
+ } else {
+ struct stat st;
+ int ret;
+
+ if (!(oe->flags & MOUNT_FLAG_DIR_CREATED))
+ continue;
+
+ /*
+ * An error due to partial directory removal is
+ * ok so only try and remount the offset if the
+ * actual mount point still exists.
+ */
+ ret = rmdir_path(ap, oe->key, ap->dev);
+ if (ret == -1 && !stat(oe->key, &st)) {
+ ret = do_mount_autofs_offset(ap, oe, root, offset);
+ if (ret)
+ left++;
+ }
}
}