|
|
49b67f |
autofs-5.1.7 - refactor umount_multi_triggers()
|
|
|
49b67f |
|
|
|
49b67f |
From: Ian Kent <raven@themaw.net>
|
|
|
49b67f |
|
|
|
49b67f |
Refactor umount_multi_triggers() to try the umount of an offset subtree
|
|
|
49b67f |
in a seperate function.
|
|
|
49b67f |
|
|
|
49b67f |
Signed-off-by: Ian Kent <raven@themaw.net>
|
|
|
49b67f |
---
|
|
|
49b67f |
CHANGELOG | 1
|
|
|
49b67f |
lib/mounts.c | 187 ++++++++++++++++++++++++++++++++---------------------------
|
|
|
49b67f |
2 files changed, 104 insertions(+), 84 deletions(-)
|
|
|
49b67f |
|
|
|
49b67f |
--- autofs-5.1.4.orig/CHANGELOG
|
|
|
49b67f |
+++ autofs-5.1.4/CHANGELOG
|
|
|
49b67f |
@@ -10,6 +10,7 @@
|
|
|
49b67f |
- set offset parent in update_offset_entry().
|
|
|
49b67f |
- remove redundant variables from mount_autofs_offset().
|
|
|
49b67f |
- remove unused parameter form do_mount_autofs_offset().
|
|
|
49b67f |
+- refactor umount_multi_triggers().
|
|
|
49b67f |
|
|
|
49b67f |
xx/xx/2018 autofs-5.1.5
|
|
|
49b67f |
- fix flag file permission.
|
|
|
49b67f |
--- autofs-5.1.4.orig/lib/mounts.c
|
|
|
49b67f |
+++ autofs-5.1.4/lib/mounts.c
|
|
|
49b67f |
@@ -2490,57 +2490,6 @@ static int do_mount_autofs_offset(struct
|
|
|
49b67f |
return mounted;
|
|
|
49b67f |
}
|
|
|
49b67f |
|
|
|
49b67f |
-int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
|
|
|
49b67f |
- const char *root, unsigned int start, const char *base)
|
|
|
49b67f |
-{
|
|
|
49b67f |
- char path[PATH_MAX + 1];
|
|
|
49b67f |
- char *offset = path;
|
|
|
49b67f |
- struct mapent *oe;
|
|
|
49b67f |
- struct list_head *pos = NULL;
|
|
|
49b67f |
- unsigned int root_len = strlen(root);
|
|
|
49b67f |
- int mounted;
|
|
|
49b67f |
-
|
|
|
49b67f |
- mounted = 0;
|
|
|
49b67f |
- offset = cache_get_offset(base, offset, start, &me->multi_list, &pos;;
|
|
|
49b67f |
- while (offset) {
|
|
|
49b67f |
- char key[PATH_MAX + 1];
|
|
|
49b67f |
- int key_len = root_len + strlen(offset);
|
|
|
49b67f |
-
|
|
|
49b67f |
- if (key_len > PATH_MAX) {
|
|
|
49b67f |
- warn(ap->logopt, "path loo long");
|
|
|
49b67f |
- goto cont;
|
|
|
49b67f |
- }
|
|
|
49b67f |
-
|
|
|
49b67f |
- /* The root offset is always mounted seperately so the
|
|
|
49b67f |
- * offset path will always be root + offset.
|
|
|
49b67f |
- */
|
|
|
49b67f |
- strcpy(key, root);
|
|
|
49b67f |
- strcat(key, offset);
|
|
|
49b67f |
-
|
|
|
49b67f |
- oe = cache_lookup_distinct(me->mc, key);
|
|
|
49b67f |
- if (!oe || !oe->mapent)
|
|
|
49b67f |
- goto cont;
|
|
|
49b67f |
-
|
|
|
49b67f |
- mounted += do_mount_autofs_offset(ap, oe, root);
|
|
|
49b67f |
-
|
|
|
49b67f |
- /*
|
|
|
49b67f |
- * If re-constructing a multi-mount it's necessary to walk
|
|
|
49b67f |
- * into nested mounts, unlike the usual "mount only what's
|
|
|
49b67f |
- * needed as you go" behavior.
|
|
|
49b67f |
- */
|
|
|
49b67f |
- if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) {
|
|
|
49b67f |
- if (oe->ioctlfd != -1 ||
|
|
|
49b67f |
- is_mounted(oe->key, MNTS_REAL))
|
|
|
49b67f |
- mount_multi_triggers(ap, oe, key, strlen(key), base);
|
|
|
49b67f |
- }
|
|
|
49b67f |
-cont:
|
|
|
49b67f |
- offset = cache_get_offset(base,
|
|
|
49b67f |
- offset, start, &me->multi_list, &pos;;
|
|
|
49b67f |
- }
|
|
|
49b67f |
-
|
|
|
49b67f |
- return mounted;
|
|
|
49b67f |
-}
|
|
|
49b67f |
-
|
|
|
49b67f |
static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe)
|
|
|
49b67f |
{
|
|
|
49b67f |
char *dir, *path;
|
|
|
49b67f |
@@ -2576,7 +2525,10 @@ static int rmdir_path_offset(struct auto
|
|
|
49b67f |
return ret;
|
|
|
49b67f |
}
|
|
|
49b67f |
|
|
|
49b67f |
-int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base)
|
|
|
49b67f |
+static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const char *root);
|
|
|
49b67f |
+
|
|
|
49b67f |
+static int do_umount_multi_triggers(struct autofs_point *ap,
|
|
|
49b67f |
+ struct mapent *me, const char *root, const char *base)
|
|
|
49b67f |
{
|
|
|
49b67f |
char path[PATH_MAX + 1];
|
|
|
49b67f |
char *offset;
|
|
|
49b67f |
@@ -2606,7 +2558,6 @@ int umount_multi_triggers(struct autofs_
|
|
|
49b67f |
while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
|
|
|
49b67f |
char key[PATH_MAX + 1];
|
|
|
49b67f |
int key_len = root_len + strlen(offset);
|
|
|
49b67f |
- char *oe_base;
|
|
|
49b67f |
|
|
|
49b67f |
if (mm_base_len > 1)
|
|
|
49b67f |
key_len += mm_base_len;
|
|
|
49b67f |
@@ -2626,47 +2577,116 @@ int umount_multi_triggers(struct autofs_
|
|
|
49b67f |
if (!oe || (strlen(oe->key) - start) == 1)
|
|
|
49b67f |
continue;
|
|
|
49b67f |
|
|
|
49b67f |
+ left += do_umount_offset(ap, oe, root);
|
|
|
49b67f |
+ }
|
|
|
49b67f |
+
|
|
|
49b67f |
+ return left;
|
|
|
49b67f |
+}
|
|
|
49b67f |
+
|
|
|
49b67f |
+static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const char *root)
|
|
|
49b67f |
+{
|
|
|
49b67f |
+ char *oe_base;
|
|
|
49b67f |
+ int left = 0;
|
|
|
49b67f |
+
|
|
|
49b67f |
+ /*
|
|
|
49b67f |
+ * Check for and umount subtree offsets resulting from
|
|
|
49b67f |
+ * nonstrict mount fail.
|
|
|
49b67f |
+ */
|
|
|
49b67f |
+ oe_base = oe->key + strlen(root);
|
|
|
49b67f |
+ left += do_umount_multi_triggers(ap, oe, root, oe_base);
|
|
|
49b67f |
+
|
|
|
49b67f |
+ if (oe->ioctlfd != -1 ||
|
|
|
49b67f |
+ is_mounted(oe->key, MNTS_REAL)) {
|
|
|
49b67f |
+ left++;
|
|
|
49b67f |
+ return left;
|
|
|
49b67f |
+ }
|
|
|
49b67f |
+
|
|
|
49b67f |
+ debug(ap->logopt, "umount offset %s", oe->key);
|
|
|
49b67f |
+
|
|
|
49b67f |
+ if (umount_autofs_offset(ap, oe)) {
|
|
|
49b67f |
+ warn(ap->logopt, "failed to umount offset");
|
|
|
49b67f |
+ left++;
|
|
|
49b67f |
+ } else {
|
|
|
49b67f |
+ struct stat st;
|
|
|
49b67f |
+ int ret;
|
|
|
49b67f |
+
|
|
|
49b67f |
+ if (!(oe->flags & MOUNT_FLAG_DIR_CREATED))
|
|
|
49b67f |
+ return left;
|
|
|
49b67f |
+
|
|
|
49b67f |
/*
|
|
|
49b67f |
- * Check for and umount subtree offsets resulting from
|
|
|
49b67f |
- * nonstrict mount fail.
|
|
|
49b67f |
+ * An error due to partial directory removal is
|
|
|
49b67f |
+ * ok so only try and remount the offset if the
|
|
|
49b67f |
+ * actual mount point still exists.
|
|
|
49b67f |
*/
|
|
|
49b67f |
- oe_base = oe->key + strlen(root);
|
|
|
49b67f |
- left += umount_multi_triggers(ap, oe, root, oe_base);
|
|
|
49b67f |
+ ret = rmdir_path_offset(ap, oe);
|
|
|
49b67f |
+ if (ret == -1 && !stat(oe->key, &st)) {
|
|
|
49b67f |
+ ret = do_mount_autofs_offset(ap, oe, root);
|
|
|
49b67f |
+ if (ret)
|
|
|
49b67f |
+ left++;
|
|
|
49b67f |
+ /* But we did origianlly create this */
|
|
|
49b67f |
+ oe->flags |= MOUNT_FLAG_DIR_CREATED;
|
|
|
49b67f |
+ }
|
|
|
49b67f |
+ }
|
|
|
49b67f |
+ return left;
|
|
|
49b67f |
+}
|
|
|
49b67f |
|
|
|
49b67f |
- if (oe->ioctlfd != -1 ||
|
|
|
49b67f |
- is_mounted(oe->key, MNTS_REAL)) {
|
|
|
49b67f |
- left++;
|
|
|
49b67f |
- continue;
|
|
|
49b67f |
+int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
|
|
|
49b67f |
+ const char *root, unsigned int start, const char *base)
|
|
|
49b67f |
+{
|
|
|
49b67f |
+ char path[PATH_MAX + 1];
|
|
|
49b67f |
+ char *offset = path;
|
|
|
49b67f |
+ struct mapent *oe;
|
|
|
49b67f |
+ struct list_head *pos = NULL;
|
|
|
49b67f |
+ unsigned int root_len = strlen(root);
|
|
|
49b67f |
+ int mounted;
|
|
|
49b67f |
+
|
|
|
49b67f |
+ mounted = 0;
|
|
|
49b67f |
+ offset = cache_get_offset(base, offset, start, &me->multi_list, &pos;;
|
|
|
49b67f |
+ while (offset) {
|
|
|
49b67f |
+ char key[PATH_MAX + 1];
|
|
|
49b67f |
+ int key_len = root_len + strlen(offset);
|
|
|
49b67f |
+
|
|
|
49b67f |
+ if (key_len > PATH_MAX) {
|
|
|
49b67f |
+ warn(ap->logopt, "path loo long");
|
|
|
49b67f |
+ goto cont;
|
|
|
49b67f |
}
|
|
|
49b67f |
|
|
|
49b67f |
- debug(ap->logopt, "umount offset %s", oe->key);
|
|
|
49b67f |
+ /* The root offset is always mounted seperately so the
|
|
|
49b67f |
+ * offset path will always be root + offset.
|
|
|
49b67f |
+ */
|
|
|
49b67f |
+ strcpy(key, root);
|
|
|
49b67f |
+ strcat(key, offset);
|
|
|
49b67f |
|
|
|
49b67f |
- if (umount_autofs_offset(ap, oe)) {
|
|
|
49b67f |
- warn(ap->logopt, "failed to umount offset");
|
|
|
49b67f |
- left++;
|
|
|
49b67f |
- } else {
|
|
|
49b67f |
- struct stat st;
|
|
|
49b67f |
- int ret;
|
|
|
49b67f |
+ oe = cache_lookup_distinct(me->mc, key);
|
|
|
49b67f |
+ if (!oe || !oe->mapent)
|
|
|
49b67f |
+ goto cont;
|
|
|
49b67f |
|
|
|
49b67f |
- if (!(oe->flags & MOUNT_FLAG_DIR_CREATED))
|
|
|
49b67f |
- continue;
|
|
|
49b67f |
+ mounted += do_mount_autofs_offset(ap, oe, root);
|
|
|
49b67f |
|
|
|
49b67f |
- /*
|
|
|
49b67f |
- * An error due to partial directory removal is
|
|
|
49b67f |
- * ok so only try and remount the offset if the
|
|
|
49b67f |
- * actual mount point still exists.
|
|
|
49b67f |
- */
|
|
|
49b67f |
- ret = rmdir_path_offset(ap, oe);
|
|
|
49b67f |
- if (ret == -1 && !stat(oe->key, &st)) {
|
|
|
49b67f |
- ret = do_mount_autofs_offset(ap, oe, root);
|
|
|
49b67f |
- if (ret)
|
|
|
49b67f |
- left++;
|
|
|
49b67f |
- /* But we did origianlly create this */
|
|
|
49b67f |
- oe->flags |= MOUNT_FLAG_DIR_CREATED;
|
|
|
49b67f |
- }
|
|
|
49b67f |
+ /*
|
|
|
49b67f |
+ * If re-constructing a multi-mount it's necessary to walk
|
|
|
49b67f |
+ * into nested mounts, unlike the usual "mount only what's
|
|
|
49b67f |
+ * needed as you go" behavior.
|
|
|
49b67f |
+ */
|
|
|
49b67f |
+ if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) {
|
|
|
49b67f |
+ if (oe->ioctlfd != -1 ||
|
|
|
49b67f |
+ is_mounted(oe->key, MNTS_REAL))
|
|
|
49b67f |
+ mount_multi_triggers(ap, oe, key, strlen(key), base);
|
|
|
49b67f |
}
|
|
|
49b67f |
+cont:
|
|
|
49b67f |
+ offset = cache_get_offset(base,
|
|
|
49b67f |
+ offset, start, &me->multi_list, &pos;;
|
|
|
49b67f |
}
|
|
|
49b67f |
|
|
|
49b67f |
+ return mounted;
|
|
|
49b67f |
+}
|
|
|
49b67f |
+
|
|
|
49b67f |
+int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base)
|
|
|
49b67f |
+{
|
|
|
49b67f |
+ int left;
|
|
|
49b67f |
+
|
|
|
49b67f |
+ left = do_umount_multi_triggers(ap, me, root, base);
|
|
|
49b67f |
+
|
|
|
49b67f |
if (!left && me->multi == me) {
|
|
|
49b67f |
struct mapent_cache *mc = me->mc;
|
|
|
49b67f |
int status;
|
|
|
49b67f |
@@ -2865,4 +2885,3 @@ int clean_stale_multi_triggers(struct au
|
|
|
49b67f |
|
|
|
49b67f |
return left;
|
|
|
49b67f |
}
|
|
|
49b67f |
-
|