548 lines
15 KiB
Diff
548 lines
15 KiB
Diff
autofs-5.1.6 - use mnt_list for amdmounts
|
|
|
|
From: Ian Kent <raven@themaw.net>
|
|
|
|
Use struct mnt_list objects for the list of amd mounts instead of
|
|
struct amd_entry.
|
|
|
|
Signed-off-by: Ian Kent <raven@themaw.net>
|
|
---
|
|
CHANGELOG | 1
|
|
daemon/automount.c | 48 ++++++++++------------
|
|
daemon/lookup.c | 18 +++++---
|
|
include/automount.h | 2
|
|
include/master.h | 2
|
|
include/mounts.h | 12 +++++
|
|
include/parse_amd.h | 1
|
|
lib/master.c | 36 +----------------
|
|
lib/mounts.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++-
|
|
modules/mount_autofs.c | 15 ++++---
|
|
modules/parse_amd.c | 43 +++++++++++++++-----
|
|
11 files changed, 193 insertions(+), 88 deletions(-)
|
|
|
|
--- autofs-5.1.4.orig/CHANGELOG
|
|
+++ autofs-5.1.4/CHANGELOG
|
|
@@ -123,6 +123,7 @@ xx/xx/2018 autofs-5.1.5
|
|
- make external mounts use simpler hashtable.
|
|
- add a hash index to mnt_list.
|
|
- use mnt_list for submounts.
|
|
+- use mnt_list for amdmounts.
|
|
|
|
19/12/2017 autofs-5.1.4
|
|
- fix spec file url.
|
|
--- autofs-5.1.4.orig/daemon/automount.c
|
|
+++ autofs-5.1.4/daemon/automount.c
|
|
@@ -595,7 +595,8 @@ static int umount_subtree_mounts(struct
|
|
* it already to ensure it's ok to remove any offset triggers.
|
|
*/
|
|
if (!is_mm_root && is_mounted(path, MNTS_REAL)) {
|
|
- struct amd_entry *entry;
|
|
+ struct mnt_list *mnt;
|
|
+
|
|
debug(ap->logopt, "unmounting dir = %s", path);
|
|
if (umount_ent(ap, path) &&
|
|
is_mounted(path, MNTS_REAL)) {
|
|
@@ -605,16 +606,12 @@ static int umount_subtree_mounts(struct
|
|
}
|
|
|
|
/* Check for an external mount and umount if possible */
|
|
- mounts_mutex_lock(ap);
|
|
- entry = __master_find_amdmount(ap, path);
|
|
- if (!entry) {
|
|
- mounts_mutex_unlock(ap);
|
|
- goto done;
|
|
+ mnt = mnts_find_amdmount(path);
|
|
+ if (mnt) {
|
|
+ umount_amd_ext_mount(ap, mnt->ext_mp);
|
|
+ mnts_remove_amdmount(path);
|
|
+ mnts_put_mount(mnt);
|
|
}
|
|
- list_del(&entry->entries);
|
|
- mounts_mutex_unlock(ap);
|
|
- umount_amd_ext_mount(ap, entry->fs);
|
|
- free_amd_entry(entry);
|
|
}
|
|
done:
|
|
return left;
|
|
@@ -639,7 +636,8 @@ int umount_multi(struct autofs_point *ap
|
|
|
|
/* if this is a symlink we can handle it now */
|
|
if (S_ISLNK(st.st_mode)) {
|
|
- struct amd_entry *entry;
|
|
+ struct mnt_list *mnt;
|
|
+
|
|
if (st.st_dev != ap->dev) {
|
|
crit(ap->logopt,
|
|
"symlink %s has the wrong device, "
|
|
@@ -671,17 +669,15 @@ int umount_multi(struct autofs_point *ap
|
|
"mkdir_path %s failed: %s", path, estr);
|
|
}
|
|
}
|
|
+
|
|
/* Check for an external mount and attempt umount if needed */
|
|
- mounts_mutex_lock(ap);
|
|
- entry = __master_find_amdmount(ap, path);
|
|
- if (!entry) {
|
|
- mounts_mutex_unlock(ap);
|
|
- return 0;
|
|
- }
|
|
- list_del(&entry->entries);
|
|
- mounts_mutex_unlock(ap);
|
|
- umount_amd_ext_mount(ap, entry->fs);
|
|
- free_amd_entry(entry);
|
|
+ mnt = mnts_find_amdmount(path);
|
|
+ if (mnt) {
|
|
+ umount_amd_ext_mount(ap, mnt->ext_mp);
|
|
+ mnts_remove_amdmount(path);
|
|
+ mnts_put_mount(mnt);
|
|
+ }
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -1720,17 +1716,17 @@ static void handle_mounts_cleanup(void *
|
|
clean = 1;
|
|
|
|
if (submount) {
|
|
- struct amd_entry *am;
|
|
+ struct mnt_list *mnt;
|
|
|
|
/* We are finishing up */
|
|
ap->parent->submnt_count--;
|
|
|
|
/* Submount at ap->path belongs to parent submount list. */
|
|
mnts_remove_submount(ap->path);
|
|
- am = __master_find_amdmount(ap->parent, ap->path);
|
|
- if (am) {
|
|
- list_del_init(&am->entries);
|
|
- free_amd_entry(am);
|
|
+ mnt = mnts_find_amdmount(ap->path);
|
|
+ if (mnt) {
|
|
+ mnts_remove_amdmount(ap->path);
|
|
+ mnts_put_mount(mnt);
|
|
}
|
|
}
|
|
|
|
--- autofs-5.1.4.orig/daemon/lookup.c
|
|
+++ autofs-5.1.4/daemon/lookup.c
|
|
@@ -838,7 +838,7 @@ static int lookup_amd_instance(struct au
|
|
const char *name, int name_len)
|
|
{
|
|
struct map_source *instance;
|
|
- struct amd_entry *entry;
|
|
+ struct mnt_list *mnt;
|
|
const char *argv[2];
|
|
const char **pargv = NULL;
|
|
int argc = 0;
|
|
@@ -861,21 +861,23 @@ static int lookup_amd_instance(struct au
|
|
strcpy(m_key, ap->path);
|
|
strcat(m_key, "/");
|
|
strcat(m_key, me->multi->key);
|
|
- entry = master_find_amdmount(ap, m_key);
|
|
+
|
|
+ mnt = mnts_find_amdmount(m_key);
|
|
free(m_key);
|
|
|
|
- if (!entry) {
|
|
+ if (!mnt) {
|
|
error(ap->logopt, "expected amd mount entry not found");
|
|
return NSS_STATUS_UNKNOWN;
|
|
}
|
|
|
|
- if (strcmp(entry->type, "host")) {
|
|
- error(ap->logopt, "unexpected map type %s", entry->type);
|
|
+ if (strcmp(mnt->amd_type, "host")) {
|
|
+ error(ap->logopt, "unexpected map type %s", mnt->amd_type);
|
|
+ mnts_put_mount(mnt);
|
|
return NSS_STATUS_UNKNOWN;
|
|
}
|
|
|
|
- if (entry->opts && *entry->opts) {
|
|
- argv[0] = entry->opts;
|
|
+ if (mnt->amd_opts && *mnt->amd_opts) {
|
|
+ argv[0] = mnt->amd_opts;
|
|
argv[1] = NULL;
|
|
pargv = argv;
|
|
argc = 1;
|
|
@@ -894,9 +896,11 @@ static int lookup_amd_instance(struct au
|
|
}
|
|
}
|
|
if (!instance) {
|
|
+ mnts_put_mount(mnt);
|
|
error(ap->logopt, "expected hosts map instance not found");
|
|
return NSS_STATUS_UNKNOWN;
|
|
}
|
|
+ mnts_put_mount(mnt);
|
|
|
|
return do_lookup_mount(ap, instance, name, name_len);
|
|
}
|
|
--- autofs-5.1.4.orig/include/automount.h
|
|
+++ autofs-5.1.4/include/automount.h
|
|
@@ -568,10 +568,10 @@ struct autofs_point {
|
|
struct autofs_point *parent; /* Owner of mounts list for submount */
|
|
pthread_mutex_t mounts_mutex; /* Protect mount lists */
|
|
struct list_head mounts; /* List of autofs mounts at current level */
|
|
- struct list_head amdmounts; /* List of non submount amd mounts */
|
|
unsigned int submount; /* Is this a submount */
|
|
unsigned int submnt_count; /* Number of submounts */
|
|
struct list_head submounts; /* List of child submounts */
|
|
+ struct list_head amdmounts; /* List of non submount amd mounts */
|
|
unsigned int shutdown; /* Shutdown notification */
|
|
};
|
|
|
|
--- autofs-5.1.4.orig/include/master.h
|
|
+++ autofs-5.1.4/include/master.h
|
|
@@ -109,8 +109,6 @@ void master_source_current_wait(struct m
|
|
void master_source_current_signal(struct master_mapent *);
|
|
struct master_mapent *master_find_mapent(struct master *, const char *);
|
|
unsigned int master_partial_match_mapent(struct master *, const char *);
|
|
-struct amd_entry *__master_find_amdmount(struct autofs_point *, const char *);
|
|
-struct amd_entry *master_find_amdmount(struct autofs_point *, const char *);
|
|
struct master_mapent *master_new_mapent(struct master *, const char *, time_t);
|
|
void master_add_mapent(struct master *, struct master_mapent *);
|
|
void master_remove_mapent(struct master_mapent *);
|
|
--- autofs-5.1.4.orig/include/mounts.h
|
|
+++ autofs-5.1.4/include/mounts.h
|
|
@@ -38,6 +38,7 @@
|
|
#define MNTS_INDIRECT 0x0008
|
|
#define MNTS_DIRECT 0x0010
|
|
#define MNTS_OFFSET 0x0020
|
|
+#define MNTS_AMD_MOUNT 0x0040
|
|
|
|
#define REMOUNT_SUCCESS 0x0000
|
|
#define REMOUNT_FAIL 0x0001
|
|
@@ -64,6 +65,14 @@ struct mnt_list {
|
|
struct list_head submount;
|
|
struct list_head submount_work;
|
|
|
|
+ /* List of amd-mounts of an autofs_point */
|
|
+ char *ext_mp;
|
|
+ char *amd_pref;
|
|
+ char *amd_type;
|
|
+ char *amd_opts;
|
|
+ unsigned int amd_cache_opts;
|
|
+ struct list_head amdmount;
|
|
+
|
|
/*
|
|
* List operations ie. get_mnt_list.
|
|
*/
|
|
@@ -118,6 +127,9 @@ struct mnt_list *mnts_add_submount(struc
|
|
void mnts_remove_submount(const char *mp);
|
|
void mnts_get_submount_list(struct list_head *mnts, struct autofs_point *ap);
|
|
void mnts_put_submount_list(struct list_head *mnts);
|
|
+struct mnt_list *mnts_find_amdmount(const char *path);
|
|
+struct mnt_list *mnts_add_amdmount(struct autofs_point *ap, struct amd_entry *entry);
|
|
+void mnts_remove_amdmount(const char *mp);
|
|
struct mnt_list *get_mnt_list(const char *path, int include);
|
|
int unlink_mount_tree(struct autofs_point *ap, const char *mp);
|
|
void free_mnt_list(struct mnt_list *list);
|
|
--- autofs-5.1.4.orig/include/parse_amd.h
|
|
+++ autofs-5.1.4/include/parse_amd.h
|
|
@@ -65,7 +65,6 @@ struct amd_entry {
|
|
char *umount;
|
|
struct selector *selector;
|
|
struct list_head list;
|
|
- struct list_head entries;
|
|
};
|
|
|
|
int amd_parse_list(struct autofs_point *,
|
|
--- autofs-5.1.4.orig/lib/master.c
|
|
+++ autofs-5.1.4/lib/master.c
|
|
@@ -152,12 +152,10 @@ void master_free_autofs_point(struct aut
|
|
head = &ap->amdmounts;
|
|
p = head->next;
|
|
while (p != head) {
|
|
- struct amd_entry *entry = list_entry(p, struct amd_entry, entries);
|
|
+ struct mnt_list *mnt = list_entry(p, struct mnt_list, amdmount);
|
|
p = p->next;
|
|
- if (!list_empty(&entry->entries))
|
|
- list_del(&entry->entries);
|
|
- ext_mount_remove(entry->fs);
|
|
- free_amd_entry(entry);
|
|
+ ext_mount_remove(mnt->ext_mp);
|
|
+ mnts_remove_amdmount(mnt->mp);
|
|
}
|
|
mounts_mutex_unlock(ap);
|
|
|
|
@@ -761,34 +759,6 @@ unsigned int master_partial_match_mapent
|
|
return ret;
|
|
}
|
|
|
|
-struct amd_entry *__master_find_amdmount(struct autofs_point *ap, const char *path)
|
|
-{
|
|
- struct list_head *head, *p;
|
|
-
|
|
- head = &ap->amdmounts;
|
|
- list_for_each(p, head) {
|
|
- struct amd_entry *entry;
|
|
-
|
|
- entry = list_entry(p, struct amd_entry, entries);
|
|
-
|
|
- if (!strcmp(entry->path, path))
|
|
- return entry;
|
|
- }
|
|
-
|
|
- return NULL;
|
|
-}
|
|
-
|
|
-struct amd_entry *master_find_amdmount(struct autofs_point *ap, const char *path)
|
|
-{
|
|
- struct amd_entry *entry;
|
|
-
|
|
- mounts_mutex_lock(ap);
|
|
- entry = __master_find_amdmount(ap, path);
|
|
- mounts_mutex_unlock(ap);
|
|
-
|
|
- return entry;
|
|
-}
|
|
-
|
|
struct master_mapent *master_new_mapent(struct master *master, const char *path, time_t age)
|
|
{
|
|
struct master_mapent *entry;
|
|
--- autofs-5.1.4.orig/lib/mounts.c
|
|
+++ autofs-5.1.4/lib/mounts.c
|
|
@@ -546,7 +546,6 @@ struct amd_entry *new_amd_entry(const st
|
|
memset(new, 0, sizeof(*new));
|
|
new->path = path;
|
|
INIT_LIST_HEAD(&new->list);
|
|
- INIT_LIST_HEAD(&new->entries);
|
|
|
|
return new;
|
|
}
|
|
@@ -887,6 +886,7 @@ static struct mnt_list *mnts_alloc_mount
|
|
INIT_HLIST_NODE(&this->hash);
|
|
INIT_LIST_HEAD(&this->submount);
|
|
INIT_LIST_HEAD(&this->submount_work);
|
|
+ INIT_LIST_HEAD(&this->amdmount);
|
|
done:
|
|
return this;
|
|
}
|
|
@@ -1048,6 +1048,107 @@ void mnts_put_submount_list(struct list_
|
|
mnts_hash_mutex_unlock();
|
|
}
|
|
|
|
+struct mnt_list *mnts_find_amdmount(const char *path)
|
|
+{
|
|
+ struct mnt_list *mnt;
|
|
+
|
|
+ mnt = mnts_lookup_mount(path);
|
|
+ if (mnt && mnt->flags & MNTS_AMD_MOUNT)
|
|
+ return mnt;
|
|
+ mnts_put_mount(mnt);
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+struct mnt_list *mnts_add_amdmount(struct autofs_point *ap, struct amd_entry *entry)
|
|
+{
|
|
+ struct mnt_list *this;
|
|
+ char *type, *ext_mp, *pref, *opts;
|
|
+
|
|
+ ext_mp = pref = type = opts = NULL;
|
|
+
|
|
+ if (entry->fs) {
|
|
+ ext_mp = strdup(entry->fs);
|
|
+ if (!ext_mp)
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ if (entry->pref) {
|
|
+ pref = strdup(entry->pref);
|
|
+ if (!pref)
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ if (entry->type) {
|
|
+ type = strdup(entry->type);
|
|
+ if (!type)
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ if (entry->opts) {
|
|
+ opts = strdup(entry->opts);
|
|
+ if (!opts)
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ mnts_hash_mutex_lock();
|
|
+ this = mnts_get_mount(entry->path);
|
|
+ if (this) {
|
|
+ this->ext_mp = ext_mp;
|
|
+ this->amd_pref = pref;
|
|
+ this->amd_type = type;
|
|
+ this->amd_opts = opts;
|
|
+ this->amd_cache_opts = entry->cache_opts;
|
|
+ this->flags |= MNTS_AMD_MOUNT;
|
|
+ if (list_empty(&this->amdmount))
|
|
+ list_add_tail(&this->amdmount, &ap->amdmounts);
|
|
+ }
|
|
+ mnts_hash_mutex_unlock();
|
|
+
|
|
+ return this;
|
|
+fail:
|
|
+ if (ext_mp)
|
|
+ free(ext_mp);
|
|
+ if (pref)
|
|
+ free(pref);
|
|
+ if (type)
|
|
+ free(type);
|
|
+ if (opts)
|
|
+ free(opts);
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+void mnts_remove_amdmount(const char *mp)
|
|
+{
|
|
+ struct mnt_list *this;
|
|
+
|
|
+ mnts_hash_mutex_lock();
|
|
+ this = mnts_lookup(mp);
|
|
+ if (!(this && this->flags & MNTS_AMD_MOUNT))
|
|
+ goto done;
|
|
+ this->flags &= ~MNTS_AMD_MOUNT;
|
|
+ list_del_init(&this->submount);
|
|
+ if (this->ext_mp) {
|
|
+ free(this->ext_mp);
|
|
+ this->ext_mp = NULL;
|
|
+ }
|
|
+ if (this->amd_type) {
|
|
+ free(this->amd_type);
|
|
+ this->amd_type = NULL;
|
|
+ }
|
|
+ if (this->amd_pref) {
|
|
+ free(this->amd_pref);
|
|
+ this->amd_pref = NULL;
|
|
+ }
|
|
+ if (this->amd_opts) {
|
|
+ free(this->amd_opts);
|
|
+ this->amd_opts = NULL;
|
|
+ }
|
|
+ this->amd_cache_opts = 0;
|
|
+ __mnts_put_mount(this);
|
|
+done:
|
|
+ mnts_hash_mutex_unlock();
|
|
+}
|
|
+
|
|
/* From glibc decode_name() */
|
|
/* Since the values in a line are separated by spaces, a name cannot
|
|
* contain a space. Therefore some programs encode spaces in names
|
|
--- autofs-5.1.4.orig/modules/mount_autofs.c
|
|
+++ autofs-5.1.4/modules/mount_autofs.c
|
|
@@ -286,16 +286,19 @@ int mount_mount(struct autofs_point *ap,
|
|
mounts_mutex_lock(ap);
|
|
|
|
if (source->flags & MAP_FLAG_FORMAT_AMD) {
|
|
- struct amd_entry *am_entry = __master_find_amdmount(ap, entry->path);
|
|
+ struct mnt_list *mnt;
|
|
|
|
- if (am_entry) {
|
|
- if (am_entry->pref) {
|
|
- nap->pref = am_entry->pref;
|
|
- am_entry->pref = NULL;
|
|
+ mnt = mnts_find_amdmount(entry->path);
|
|
+ if (mnt) {
|
|
+ if (mnt->amd_pref) {
|
|
+ nap->pref = mnt->amd_pref;
|
|
+ mnt->amd_pref = NULL;
|
|
}
|
|
|
|
- if (am_entry->cache_opts & AMD_CACHE_OPTION_ALL)
|
|
+ if (mnt->amd_cache_opts & AMD_CACHE_OPTION_ALL)
|
|
nap->flags |= MOUNT_FLAG_AMD_CACHE_ALL;
|
|
+
|
|
+ mnts_put_mount(mnt);
|
|
}
|
|
}
|
|
|
|
--- autofs-5.1.4.orig/modules/parse_amd.c
|
|
+++ autofs-5.1.4/modules/parse_amd.c
|
|
@@ -1300,6 +1300,7 @@ static int do_host_mount(struct autofs_p
|
|
{
|
|
struct lookup_mod *lookup;
|
|
struct map_source *instance;
|
|
+ struct mnt_list *mnt = NULL;
|
|
struct mapent *me;
|
|
const char *argv[2];
|
|
const char **pargv = NULL;
|
|
@@ -1316,7 +1317,9 @@ static int do_host_mount(struct autofs_p
|
|
*/
|
|
if (strcmp(name, entry->rhost)) {
|
|
char *target;
|
|
- size_t len = strlen(ap->path) + strlen(entry->rhost) + 2;
|
|
+ size_t len;
|
|
+
|
|
+ len = strlen(ap->path) + strlen(entry->rhost) + 2;
|
|
target = malloc(len);
|
|
if (!target) {
|
|
warn(ap->logopt, MODPREFIX
|
|
@@ -1329,6 +1332,15 @@ static int do_host_mount(struct autofs_p
|
|
if (entry->path)
|
|
free(entry->path);
|
|
entry->path = target;
|
|
+
|
|
+ /* Add an mnt_list entry for the updated path. */
|
|
+ mnt = mnts_add_amdmount(ap, entry);
|
|
+ if (!mnt) {
|
|
+ error(ap->logopt, MODPREFIX
|
|
+ "failed to update mount mnt_list entry");
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
/*
|
|
* Wait for any expire before racing to mount the
|
|
* export tree or bail out if we're shutting down.
|
|
@@ -1388,6 +1400,8 @@ static int do_host_mount(struct autofs_p
|
|
warn(ap->logopt, MODPREFIX
|
|
"failed to create symlink to hosts mount base");
|
|
out:
|
|
+ if (ret && mnt)
|
|
+ mnts_remove_amdmount(mnt->mp);
|
|
return ret;
|
|
}
|
|
|
|
@@ -2204,6 +2218,7 @@ int parse_mount(struct autofs_point *ap,
|
|
struct list_head entries, *p, *head;
|
|
struct amd_entry *defaults_entry;
|
|
struct amd_entry *cur_defaults;
|
|
+ struct mnt_list *mnt;
|
|
int rv = 1;
|
|
int cur_state;
|
|
int ret;
|
|
@@ -2313,21 +2328,27 @@ int parse_mount(struct autofs_point *ap,
|
|
* add parsed entry to parent amd mount list and remove
|
|
* on mount fail.
|
|
*/
|
|
- mounts_mutex_lock(ap);
|
|
- list_add_tail(&this->entries, &ap->amdmounts);
|
|
- mounts_mutex_unlock(ap);
|
|
+ mnt = mnts_add_amdmount(ap, this);
|
|
+ if (!mnt) {
|
|
+ error(ap->logopt, MODPREFIX
|
|
+ "failed to add mount to mnt_list");
|
|
+ break;
|
|
+ }
|
|
|
|
rv = amd_mount(ap, name, this, source, sv, flags, ctxt);
|
|
- mounts_mutex_lock(ap);
|
|
if (!rv) {
|
|
- /* Mounted, remove entry from parsed list */
|
|
- list_del_init(&this->list);
|
|
- mounts_mutex_unlock(ap);
|
|
+ /*
|
|
+ * If entry->path doesn't match the mnt->mp then
|
|
+ * the mount point path has changed and a new
|
|
+ * mnt_list entry added for it, so remove the
|
|
+ * original.
|
|
+ */
|
|
+ if (strcmp(this->path, mnt->mp))
|
|
+ mnts_remove_amdmount(this->path);
|
|
break;
|
|
}
|
|
- /* Not mounted, remove entry from the parent list */
|
|
- list_del_init(&this->entries);
|
|
- mounts_mutex_unlock(ap);
|
|
+ /* Not mounted, remove the mnt_list entry from amdmount list */
|
|
+ mnts_remove_amdmount(this->path);
|
|
}
|
|
free_amd_entry(cur_defaults);
|
|
|