autofs-5.1.6 - make external mounts independent of amd_entry From: Ian Kent The external mounts used by amd map entries should not depend on the amd map entry. The external mounts list is keyed by the external mount path and this should be what's used to locate them. Signed-off-by: Ian Kent --- CHANGELOG | 1 daemon/automount.c | 4 +- include/mounts.h | 6 +-- include/parse_amd.h | 1 lib/master.c | 3 - lib/mounts.c | 114 ++++++++++++++++++++++++++++++--------------------- modules/parse_amd.c | 14 +++--- 7 files changed, 80 insertions(+), 63 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 8e89d5b2..294d064e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -53,6 +53,7 @@ xx/xx/2020 autofs-5.1.7 - update list.h. - add hashtable implementation. - change mountpoint to mp in struct ext_mount. +- make external mounts independent of amd_entry. 07/10/2019 autofs-5.1.6 - support strictexpire mount option. diff --git a/daemon/automount.c b/daemon/automount.c index b9707ef9..2e6e19f9 100644 --- a/daemon/automount.c +++ b/daemon/automount.c @@ -613,7 +613,7 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi } list_del(&entry->entries); mounts_mutex_unlock(ap); - umount_amd_ext_mount(ap, entry); + umount_amd_ext_mount(ap, entry->fs); free_amd_entry(entry); } done: @@ -679,7 +679,7 @@ int umount_multi(struct autofs_point *ap, const char *path, int incl) } list_del(&entry->entries); mounts_mutex_unlock(ap); - umount_amd_ext_mount(ap, entry); + umount_amd_ext_mount(ap, entry->fs); free_amd_entry(entry); return 0; } diff --git a/include/mounts.h b/include/mounts.h index c8fddf00..4e01f697 100644 --- a/include/mounts.h +++ b/include/mounts.h @@ -97,8 +97,8 @@ unsigned int get_kver_minor(void); char *make_options_string(char *path, int pipefd, const char *type, unsigned int flags); char *make_mnt_name_string(char *path); -int ext_mount_add(struct list_head *, const char *, unsigned int); -int ext_mount_remove(struct list_head *, const char *); +int ext_mount_add(const char *, const char *); +int ext_mount_remove(const char *); int ext_mount_inuse(const char *); struct mnt_list *get_mnt_list(const char *path, int include); int unlink_mount_tree(struct autofs_point *ap, const char *mp); @@ -118,7 +118,7 @@ int try_remount(struct autofs_point *, struct mapent *, unsigned int); void set_indirect_mount_tree_catatonic(struct autofs_point *); void set_direct_mount_tree_catatonic(struct autofs_point *, struct mapent *); int umount_ent(struct autofs_point *, const char *); -int umount_amd_ext_mount(struct autofs_point *, struct amd_entry *); +int umount_amd_ext_mount(struct autofs_point *, const char *); int mount_multi_triggers(struct autofs_point *, struct mapent *, const char *, unsigned int, const char *); int umount_multi_triggers(struct autofs_point *, struct mapent *, char *, const char *); int clean_stale_multi_triggers(struct autofs_point *, struct mapent *, char *, const char *); diff --git a/include/parse_amd.h b/include/parse_amd.h index 806d6589..5e3318a0 100644 --- a/include/parse_amd.h +++ b/include/parse_amd.h @@ -66,7 +66,6 @@ struct amd_entry { struct selector *selector; struct list_head list; struct list_head entries; - struct list_head ext_mount; }; int amd_parse_list(struct autofs_point *, diff --git a/lib/master.c b/lib/master.c index 7b77968a..b67cc667 100644 --- a/lib/master.c +++ b/lib/master.c @@ -154,10 +154,9 @@ void master_free_autofs_point(struct autofs_point *ap) while (p != head) { struct amd_entry *entry = list_entry(p, struct amd_entry, entries); p = p->next; - if (!list_empty(&entry->ext_mount)) - ext_mount_remove(&entry->ext_mount, entry->fs); if (!list_empty(&entry->entries)) list_del(&entry->entries); + ext_mount_remove(entry->fs); free_amd_entry(entry); } mounts_mutex_unlock(ap); diff --git a/lib/mounts.c b/lib/mounts.c index 50a59f5f..37fdf09f 100644 --- a/lib/mounts.c +++ b/lib/mounts.c @@ -54,10 +54,10 @@ static size_t maxgrpbuf = 0; #define EXT_MOUNTS_HASH_SIZE 50 struct ext_mount { + unsigned int ref; char *mp; - unsigned int umount; + char *umount; struct list_head mount; - struct list_head mounts; }; static struct list_head ext_mounts_hash[EXT_MOUNTS_HASH_SIZE]; static unsigned int ext_mounts_hash_init_done = 0; @@ -542,7 +542,6 @@ struct amd_entry *new_amd_entry(const struct substvar *sv) new->path = path; INIT_LIST_HEAD(&new->list); INIT_LIST_HEAD(&new->entries); - INIT_LIST_HEAD(&new->ext_mount); return new; } @@ -763,7 +762,7 @@ static struct ext_mount *ext_mount_lookup(const char *mp) return NULL; } -int ext_mount_add(struct list_head *entry, const char *path, unsigned int umount) +int ext_mount_add(const char *path, const char *umount) { struct ext_mount *em; u_int32_t hval; @@ -773,13 +772,7 @@ int ext_mount_add(struct list_head *entry, const char *path, unsigned int umount em = ext_mount_lookup(path); if (em) { - struct list_head *p, *head; - head = &em->mounts; - list_for_each(p, head) { - if (p == entry) - goto done; - } - list_add_tail(entry, &em->mounts); + em->ref++; ret = 1; goto done; } @@ -787,28 +780,34 @@ int ext_mount_add(struct list_head *entry, const char *path, unsigned int umount em = malloc(sizeof(struct ext_mount)); if (!em) goto done; + memset(em, 0, sizeof(*em)); em->mp = strdup(path); if (!em->mp) { free(em); goto done; } - em->umount = umount; + if (umount) { + em->umount = strdup(umount); + if (!em->umount) { + free(em->mp); + free(em); + goto done; + } + } + em->ref = 1; INIT_LIST_HEAD(&em->mount); - INIT_LIST_HEAD(&em->mounts); hval = hash(path, EXT_MOUNTS_HASH_SIZE); list_add_tail(&em->mount, &ext_mounts_hash[hval]); - list_add_tail(entry, &em->mounts); - ret = 1; done: pthread_mutex_unlock(&ext_mount_hash_mutex); return ret; } -int ext_mount_remove(struct list_head *entry, const char *path) +int ext_mount_remove(const char *path) { struct ext_mount *em; int ret = 0; @@ -819,18 +818,18 @@ int ext_mount_remove(struct list_head *entry, const char *path) if (!em) goto done; - list_del_init(entry); - - if (!list_empty(&em->mounts)) + em->ref--; + if (em->ref) goto done; else { list_del_init(&em->mount); - if (em->umount) - ret = 1; if (list_empty(&em->mount)) { free(em->mp); + if (em->umount) + free(em->umount); free(em); } + ret = 1; } done: pthread_mutex_unlock(&ext_mount_hash_mutex); @@ -846,9 +845,7 @@ int ext_mount_inuse(const char *path) em = ext_mount_lookup(path); if (!em) goto done; - - if (!list_empty(&em->mounts)) - ret = 1; + ret = em->ref; done: pthread_mutex_unlock(&ext_mount_hash_mutex); return ret; @@ -2094,29 +2091,49 @@ int umount_ent(struct autofs_point *ap, const char *path) return rv; } -int umount_amd_ext_mount(struct autofs_point *ap, struct amd_entry *entry) +int umount_amd_ext_mount(struct autofs_point *ap, const char *path) { + struct ext_mount *em; + char *umount = NULL; + char *mp; int rv = 1; - if (entry->umount) { - char *prog, *str; - char **argv; - int argc = -1; + pthread_mutex_lock(&ext_mount_hash_mutex); - str = strdup(entry->umount); - if (!str) + em = ext_mount_lookup(path); + if (!em) { + pthread_mutex_unlock(&ext_mount_hash_mutex); + goto out; + } + mp = strdup(em->mp); + if (!mp) { + pthread_mutex_unlock(&ext_mount_hash_mutex); + goto out; + } + if (em->umount) { + umount = strdup(em->umount); + if (!umount) { + pthread_mutex_unlock(&ext_mount_hash_mutex); + free(mp); goto out; + } + } + + pthread_mutex_unlock(&ext_mount_hash_mutex); + + if (umount) { + char *prog; + char **argv; + int argc = -1; prog = NULL; argv = NULL; - argc = construct_argv(str, &prog, &argv); - if (argc == -1) { - free(str); - goto out; - } + argc = construct_argv(umount, &prog, &argv); + if (argc == -1) + goto done; - if (!ext_mount_remove(&entry->ext_mount, entry->fs)) { + if (!ext_mount_remove(mp)) { rv =0; goto out_free; } @@ -2124,29 +2141,30 @@ int umount_amd_ext_mount(struct autofs_point *ap, struct amd_entry *entry) rv = spawnv(ap->logopt, prog, (const char * const *) argv); if (rv == -1 || (WIFEXITED(rv) && WEXITSTATUS(rv))) error(ap->logopt, - "failed to umount program mount at %s", entry->fs); + "failed to umount program mount at %s", mp); else { rv = 0; - debug(ap->logopt, - "umounted program mount at %s", entry->fs); - rmdir_path(ap, entry->fs, ap->dev); + debug(ap->logopt, "umounted program mount at %s", mp); + rmdir_path(ap, mp, ap->dev); } out_free: free_argv(argc, (const char **) argv); - free(str); - goto out; + goto done; } - if (ext_mount_remove(&entry->ext_mount, entry->fs)) { - rv = umount_ent(ap, entry->fs); + if (ext_mount_remove(mp)) { + rv = umount_ent(ap, mp); if (rv) error(ap->logopt, - "failed to umount external mount %s", entry->fs); + "failed to umount external mount %s", mp); else - debug(ap->logopt, - "umounted external mount %s", entry->fs); + debug(ap->logopt, "umounted external mount %s", mp); } +done: + if (umount) + free(umount); + free(mp); out: return rv; } diff --git a/modules/parse_amd.c b/modules/parse_amd.c index 943a48b6..43ee779e 100644 --- a/modules/parse_amd.c +++ b/modules/parse_amd.c @@ -1136,7 +1136,7 @@ symlink: if (entry->sublink) { /* failed to complete sublink mount */ - umount_amd_ext_mount(ap, entry); + umount_amd_ext_mount(ap, entry->fs); } out: return ret; @@ -1183,8 +1183,8 @@ static int do_generic_mount(struct autofs_point *ap, const char *name, goto out; umount = 1; } - /* We have an external mount */ - if (!ext_mount_add(&entry->ext_mount, entry->fs, umount)) { + /* If we have an external mount add it to the list */ + if (umount && !ext_mount_add(entry->fs, entry->umount)) { umount_ent(ap, entry->fs); error(ap->logopt, MODPREFIX "error: could not add external mount %s", @@ -1235,7 +1235,7 @@ static int do_nfs_mount(struct autofs_point *ap, const char *name, umount = 1; } /* We might be using an external mount */ - if (!ext_mount_add(&entry->ext_mount, entry->fs, umount)) { + if (umount && !ext_mount_add(entry->fs, entry->umount)) { umount_ent(ap, entry->fs); error(ap->logopt, MODPREFIX "error: could not add external mount %s", entry->fs); @@ -1429,7 +1429,7 @@ static int do_program_mount(struct autofs_point *ap, /* An external mount with path entry->fs exists * so ext_mount_add() won't fail. */ - ext_mount_add(&entry->ext_mount, entry->fs, 1); + ext_mount_add(entry->fs, entry->umount); } else { rv = mkdir_path(entry->fs, mp_mode); if (rv && errno != EEXIST) { @@ -1445,7 +1445,7 @@ static int do_program_mount(struct autofs_point *ap, rv = spawnv(ap->logopt, prog, (const char * const *) argv); if (WIFEXITED(rv) && !WEXITSTATUS(rv)) { - if (ext_mount_add(&entry->ext_mount, entry->fs, 1)) { + if (ext_mount_add(entry->fs, entry->umount)) { rv = 0; debug(ap->logopt, MODPREFIX "%s: mounted %s", entry->type, entry->fs); @@ -1470,7 +1470,7 @@ do_free: if (!rv) goto out; - if (umount_amd_ext_mount(ap, entry)) { + if (umount_amd_ext_mount(ap, entry->fs)) { if (!ext_mount_inuse(entry->fs)) rmdir_path(ap, entry->fs, ap->dev); debug(ap->logopt, MODPREFIX