autofs/SOURCES/autofs-5.1.6-use-mnt_list-for-amdmounts.patch
2021-12-08 12:28:52 +00:00

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);