diff --git a/CHANGELOG b/CHANGELOG index ffc9c17..cf64a61 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -119,6 +119,7 @@ xx/xx/2018 autofs-5.1.5 - update list.h. - add hashtable implementation. - change mountpoint to mp in struct ext_mount. +- make external mounts independent of amd_entry. 19/12/2017 autofs-5.1.4 - fix spec file url. diff --git a/daemon/automount.c b/daemon/automount.c index 8451161..336c988 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 c8fddf0..4e01f69 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 806d658..5e3318a 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 7b77968..b67cc66 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 567f031..6cbcf45 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; @@ -2092,29 +2089,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; } @@ -2122,29 +2139,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 d7c5540..3715c3c 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