Ian Kent bdb1ad
autofs-5.0.6 - fix offset dir removal
Ian Kent bdb1ad
Ian Kent bdb1ad
From: Ian Kent <ikent@redhat.com>
Ian Kent bdb1ad
Ian Kent bdb1ad
When removing autofs multi-mount directories (which usually means the
Ian Kent bdb1ad
top level tree where no mount is present at the base) at expire we
Ian Kent bdb1ad
need to take care not to remove the top directory of the tree if the
Ian Kent bdb1ad
origin map is an indirect mount that has the browse option set.
Ian Kent bdb1ad
---
Ian Kent bdb1ad
Ian Kent bdb1ad
 lib/mounts.c |   43 +++++++++++++++++++++++++++++++++++++++++--
Ian Kent bdb1ad
 1 file changed, 41 insertions(+), 2 deletions(-)
Ian Kent bdb1ad
Ian Kent bdb1ad
Ian Kent bdb1ad
--- autofs-5.0.6.orig/lib/mounts.c
Ian Kent bdb1ad
+++ autofs-5.0.6/lib/mounts.c
Ian Kent bdb1ad
@@ -1687,6 +1687,41 @@ cont:
Ian Kent bdb1ad
 	return mounted;
Ian Kent bdb1ad
 }
Ian Kent bdb1ad
 
Ian Kent bdb1ad
+static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe)
Ian Kent bdb1ad
+{
Ian Kent bdb1ad
+	char *dir, *path;
Ian Kent bdb1ad
+	unsigned int split;
Ian Kent bdb1ad
+	int ret;
Ian Kent bdb1ad
+
Ian Kent bdb1ad
+	if (ap->type == LKP_DIRECT)
Ian Kent bdb1ad
+		return rmdir_path(ap, oe->key, oe->multi->dev);
Ian Kent bdb1ad
+
Ian Kent bdb1ad
+	dir = strdup(oe->key);
Ian Kent bdb1ad
+
Ian Kent bdb1ad
+	if (ap->flags & MOUNT_FLAG_GHOST)
Ian Kent bdb1ad
+		split = strlen(ap->path) + strlen(oe->multi->key) + 1;
Ian Kent bdb1ad
+	else
Ian Kent bdb1ad
+		split = strlen(ap->path);
Ian Kent bdb1ad
+
Ian Kent bdb1ad
+	dir[split] = '\0';
Ian Kent bdb1ad
+	path = &dir[split + 1];
Ian Kent bdb1ad
+
Ian Kent bdb1ad
+	if (chdir(dir) == -1) {
Ian Kent bdb1ad
+		error(ap->logopt, "failed to chdir to %s", dir);
Ian Kent bdb1ad
+		free(dir);
Ian Kent bdb1ad
+		return -1;
Ian Kent bdb1ad
+	}
Ian Kent bdb1ad
+
Ian Kent bdb1ad
+	ret = rmdir_path(ap, path, ap->dev);
Ian Kent bdb1ad
+
Ian Kent bdb1ad
+	free(dir);
Ian Kent bdb1ad
+
Ian Kent bdb1ad
+	if (chdir("/") == -1)
Ian Kent bdb1ad
+		error(ap->logopt, "failed to chdir to /");
Ian Kent bdb1ad
+
Ian Kent bdb1ad
+	return ret;
Ian Kent bdb1ad
+}
Ian Kent bdb1ad
+
Ian Kent bdb1ad
 int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base)
Ian Kent bdb1ad
 {
Ian Kent bdb1ad
 	char path[PATH_MAX + 1];
Ian Kent bdb1ad
@@ -1748,11 +1783,13 @@ int umount_multi_triggers(struct autofs_
Ian Kent bdb1ad
 			 * ok so only try and remount the offset if the
Ian Kent bdb1ad
 			 * actual mount point still exists.
Ian Kent bdb1ad
 			 */
Ian Kent bdb1ad
-			ret = rmdir_path(ap, oe->key, ap->dev);
Ian Kent bdb1ad
+			ret = rmdir_path_offset(ap, oe);
Ian Kent bdb1ad
 			if (ret == -1 && !stat(oe->key, &st)) {
Ian Kent bdb1ad
 				ret = do_mount_autofs_offset(ap, oe, root, offset);
Ian Kent bdb1ad
 				if (ret)
Ian Kent bdb1ad
 					left++;
Ian Kent bdb1ad
+				/* But we did origianlly create this */
Ian Kent bdb1ad
+				oe->flags |= MOUNT_FLAG_DIR_CREATED;
Ian Kent bdb1ad
 			}
Ian Kent bdb1ad
 		}
Ian Kent bdb1ad
 	}
Ian Kent bdb1ad
@@ -1914,11 +1951,13 @@ int clean_stale_multi_triggers(struct au
Ian Kent bdb1ad
 			 * ok so only try and remount the offset if the
Ian Kent bdb1ad
 			 * actual mount point still exists.
Ian Kent bdb1ad
 			 */
Ian Kent bdb1ad
-			ret = rmdir_path(ap, oe->key, ap->dev);
Ian Kent bdb1ad
+			ret = rmdir_path_offset(ap, oe);
Ian Kent bdb1ad
 			if (ret == -1 && !stat(oe->key, &st)) {
Ian Kent bdb1ad
 				ret = do_mount_autofs_offset(ap, oe, root, offset);
Ian Kent bdb1ad
 				if (ret) {
Ian Kent bdb1ad
 					left++;
Ian Kent bdb1ad
+					/* But we did origianlly create this */
Ian Kent bdb1ad
+					oe->flags |= MOUNT_FLAG_DIR_CREATED;
Ian Kent bdb1ad
 					free(key);
Ian Kent bdb1ad
 					continue;
Ian Kent bdb1ad
 				}