- sync up with upstream patches.

This commit is contained in:
Ian Kent 2012-07-03 11:51:28 +08:00
parent db4990362f
commit cc58c12fca
22 changed files with 3240 additions and 0 deletions

View File

@ -0,0 +1,84 @@
autofs-5.0.6 - add function to delete offset cache entry
From: Ian Kent <ikent@redhat.com>
Currently only the entire expanded list of offset cache entries may be
removed from the cache. In order to be able to update already expanded
multi map offset entries we need to be able to delete them.
---
include/automount.h | 1 +
lib/cache.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 48 insertions(+), 0 deletions(-)
diff --git a/include/automount.h b/include/automount.h
index e1246e3..40c1975 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -192,6 +192,7 @@ int cache_add_offset(struct mapent_cache *mc, const char *mkey, const char *key,
int cache_set_parents(struct mapent *mm);
int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age);
int cache_delete(struct mapent_cache *mc, const char *key);
+int cache_delete_offset(struct mapent_cache *mc, const char *key);
void cache_multi_readlock(struct mapent *me);
void cache_multi_writelock(struct mapent *me);
void cache_multi_unlock(struct mapent *me);
diff --git a/lib/cache.c b/lib/cache.c
index 3464e7d..1489273 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -771,6 +771,53 @@ int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key
return ret;
}
+/* cache_multi_lock of the multi mount owner must be held by caller */
+int cache_delete_offset(struct mapent_cache *mc, const char *key)
+{
+ u_int32_t hashval = hash(key, mc->size);
+ struct mapent *me = NULL, *pred;
+ int status;
+
+ me = mc->hash[hashval];
+ if (!me)
+ return CHE_FAIL;
+
+ if (strcmp(key, me->key) == 0) {
+ if (me->multi && me->multi == me)
+ return CHE_FAIL;
+ mc->hash[hashval] = me->next;
+ goto delete;
+ }
+
+ while (me->next != NULL) {
+ pred = me;
+ me = me->next;
+ if (strcmp(key, me->key) == 0) {
+ if (me->multi && me->multi == me)
+ return CHE_FAIL;
+ pred->next = me->next;
+ goto delete;
+ }
+ }
+
+ return CHE_FAIL;
+
+delete:
+ status = pthread_rwlock_destroy(&me->multi_rwlock);
+ if (status)
+ fatal(status);
+ list_del(&me->multi_list);
+ ino_index_lock(mc);
+ list_del(&me->ino_index);
+ ino_index_unlock(mc);
+ free(me->key);
+ if (me->mapent)
+ free(me->mapent);
+ free(me);
+
+ return CHE_OK;
+}
+
/* cache must be write locked by caller */
int cache_delete(struct mapent_cache *mc, const char *key)
{

View File

@ -0,0 +1,498 @@
autofs-5.0.6 - add hup signal handling to hosts map
From: Ian Kent <ikent@redhat.com>
Add HUP signal handling to the internal hosts lookup module.
---
CHANGELOG | 1
daemon/direct.c | 4 -
include/mounts.h | 1
lib/mounts.c | 162 ++++++++++++++++++++++++++++++++++++++++++++++++-
man/auto.master.5.in | 5 +
man/autofs.5 | 8 +-
modules/lookup_hosts.c | 97 ++++++++++++++++++++++++-----
modules/parse_sun.c | 9 ++
8 files changed, 262 insertions(+), 25 deletions(-)
--- autofs-5.0.6.orig/CHANGELOG
+++ autofs-5.0.6/CHANGELOG
@@ -57,6 +57,7 @@
- fix offset mount point directory removal.
- fix remount of multi mount.
- fix devce ioctl alloc path check.
+- add hup signal handling to hosts map.
28/06/2011 autofs-5.0.6
-----------------------
--- autofs-5.0.6.orig/daemon/direct.c
+++ autofs-5.0.6/daemon/direct.c
@@ -654,7 +654,9 @@ int mount_autofs_offset(struct autofs_po
ret = try_remount(ap, me, t_offset);
if (ret == 1)
return MOUNT_OFFSET_OK;
- return MOUNT_OFFSET_FAIL;
+ /* Offset mount not found, fall thru and try to mount it */
+ if (!(ret == -1 && errno == ENOENT))
+ return MOUNT_OFFSET_FAIL;
} else {
/*
if (is_mounted(_PROC_MOUNTS, me->key, MNTS_AUTOFS)) {
--- autofs-5.0.6.orig/include/mounts.h
+++ autofs-5.0.6/include/mounts.h
@@ -112,5 +112,6 @@ int try_remount(struct autofs_point *, s
int umount_ent(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 *);
#endif
--- autofs-5.0.6.orig/lib/mounts.c
+++ autofs-5.0.6/lib/mounts.c
@@ -1436,6 +1436,7 @@ static int remount_active_mount(struct a
/* Re-reading the map, set timeout and return */
if (ap->state == ST_READMAP) {
+ debug(ap->logopt, "already mounted, update timeout");
ops->timeout(ap->logopt, fd, timeout);
ops->close(ap->logopt, fd);
return REMOUNT_READ_MAP;
@@ -1550,7 +1551,9 @@ int try_remount(struct autofs_point *ap,
* record that in the mount point struct. Otherwise we're
* re-reading the map.
*/
- if (ret == REMOUNT_SUCCESS || ret == REMOUNT_READ_MAP) {
+ if (ret == REMOUNT_READ_MAP)
+ return 1;
+ else if (ret == REMOUNT_SUCCESS) {
if (fd != -1) {
if (type == t_indirect)
ap->ioctlfd = fd;
@@ -1781,5 +1784,162 @@ int umount_multi_triggers(struct autofs_
}
return left;
+}
+
+int clean_stale_multi_triggers(struct autofs_point *ap,
+ struct mapent *me, char *top, const char *base)
+{
+ char *root;
+ char mm_top[PATH_MAX + 1];
+ char path[PATH_MAX + 1];
+ char buf[MAX_ERR_BUF];
+ char *offset;
+ struct mapent *oe;
+ struct list_head *mm_root, *pos;
+ const char o_root[] = "/";
+ const char *mm_base;
+ int left, start;
+ time_t age;
+
+ if (top)
+ root = top;
+ else {
+ if (!strchr(me->multi->key, '/'))
+ /* Indirect multi-mount root */
+ /* sprintf okay - if it's mounted, it's
+ * PATH_MAX or less bytes */
+ sprintf(mm_top, "%s/%s", ap->path, me->multi->key);
+ else
+ strcpy(mm_top, me->multi->key);
+ root = mm_top;
+ }
+
+ left = 0;
+ start = strlen(root);
+
+ mm_root = &me->multi->multi_list;
+
+ if (!base)
+ mm_base = o_root;
+ else
+ mm_base = base;
+
+ pos = NULL;
+ offset = path;
+ age = me->multi->age;
+
+ while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
+ char *oe_base;
+ char *key;
+ int ret;
+
+ oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list);
+ /* root offset is a special case */
+ if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1)
+ continue;
+
+ /* Check for and umount stale subtree offsets */
+ oe_base = oe->key + strlen(root);
+ ret = clean_stale_multi_triggers(ap, oe, root, oe_base);
+ left =+ ret;
+ if (ret)
+ continue;
+
+ if (oe->age == age)
+ continue;
+
+ /*
+ * If an offset that has an active mount has been removed
+ * from the multi-mount we don't want to attempt to trigger
+ * mounts for it. Obviously this is because it has been
+ * removed, but less obvious is the potential strange
+ * behaviour that can result if we do try and mount it
+ * again after it's been expired. For example, if an NFS
+ * file system is no longer exported and is later umounted
+ * it can be mounted again without any error message but
+ * shows as an empty directory. That's going to confuse
+ * people for sure.
+ *
+ * If the mount cannot be umounted (the process is now
+ * using a stale mount) the offset needs to be invalidated
+ * so no further mounts will be attempted but the offset
+ * cache entry must remain so expires can continue to
+ * attempt to umount it. If the mount can be umounted and
+ * the offset is removed, at least for NFS we will get
+ * ESTALE errors when attempting list the directory.
+ */
+ if (oe->ioctlfd != -1 ||
+ is_mounted(_PROC_MOUNTS, oe->key, MNTS_REAL)) {
+ if (umount_ent(ap, oe->key)) {
+ debug(ap->logopt,
+ "offset %s has active mount, invalidate",
+ oe->key);
+ if (oe->mapent) {
+ free(oe->mapent);
+ oe->mapent = NULL;
+ }
+ left++;
+ continue;
+ }
+ }
+
+ key = strdup(oe->key);
+ if (!key) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ error(ap->logopt, "malloc: %s", estr);
+ left++;
+ continue;
+ }
+
+ debug(ap->logopt, "umount offset %s", oe->key);
+
+ if (umount_autofs_offset(ap, oe)) {
+ warn(ap->logopt, "failed to umount offset %s", key);
+ left++;
+ } else {
+ struct stat st;
+
+ /* Mount point not ours to delete ? */
+ if (!(oe->flags & MOUNT_FLAG_DIR_CREATED)) {
+ debug(ap->logopt, "delete offset key %s", key);
+ if (cache_delete_offset(oe->mc, key) == CHE_FAIL)
+ error(ap->logopt,
+ "failed to delete offset key %s", key);
+ free(key);
+ continue;
+ }
+
+ /*
+ * An error due to partial directory removal is
+ * ok so only try and remount the offset if the
+ * actual mount point still exists.
+ */
+ ret = rmdir_path(ap, oe->key, ap->dev);
+ if (ret == -1 && !stat(oe->key, &st)) {
+ ret = do_mount_autofs_offset(ap, oe, root, offset);
+ if (ret) {
+ left++;
+ free(key);
+ continue;
+ }
+ /*
+ * Fall through if the trigger can't be mounted
+ * again, since there is no offset there can't
+ * be any mount requests so remove the map
+ * entry from the cache. There's now a dead
+ * offset mount, but what else can we do ....
+ */
+ }
+
+ debug(ap->logopt, "delete offset key %s", key);
+
+ if (cache_delete_offset(oe->mc, key) == CHE_FAIL)
+ error(ap->logopt,
+ "failed to delete offset key %s", key);
+ }
+ free(key);
+ }
+
+ return left;
}
--- autofs-5.0.6.orig/man/auto.master.5.in
+++ autofs-5.0.6/man/auto.master.5.in
@@ -220,7 +220,10 @@ set default log level "none", "verbose"
.SH BUILTIN MAP -hosts
If "-hosts" is given as the map then accessing a key under the mount point
which corresponds to a hostname will allow access to the exports of that
-host.
+host. The hosts map cannot be dynamically updated and requires a HUP signal
+to be sent to the daemon for it to check hosts for an update. Due to possible
+hierarchic dependencies within a mount tree, it might not be completely
+updated during the HUP signal processing.
.P
For example, with an entry in the master map of
.nh
--- autofs-5.0.6.orig/man/autofs.5
+++ autofs-5.0.6/man/autofs.5
@@ -13,10 +13,10 @@ These maps describe how file systems bel
map format; if another map format is specified (e.g. \fBhesiod\fP),
this documentation does not apply.
-Indirect maps can be changed on the fly and the automouter will recognize
-those changes on the next operation it performs on that map. Direct maps
-require a HUP signal be sent to the daemon to refresh their contents as does
-the master map.
+Indirect maps, except for the internal hosts map, can be changed on the fly
+and the automouter will recognize those changes on the next operation it
+performs on that map. Direct maps require a HUP signal be sent to the
+daemon to refresh their contents as does the master map.
.SH "FORMAT"
This is a description of the text file format. Other methods of specifying
these files may exist. All empty lines or lines beginning with # are
--- autofs-5.0.6.orig/modules/lookup_hosts.c
+++ autofs-5.0.6/modules/lookup_hosts.c
@@ -80,10 +80,11 @@ int lookup_read_master(struct master *ma
static char *get_exports(struct autofs_point *ap, const char *host)
{
- char *mapent = NULL;
+ char buf[MAX_ERR_BUF];
+ char *mapent;
exports exp;
- debug(ap->logopt, MODPREFIX "fetchng export list for %s", name);
+ debug(ap->logopt, MODPREFIX "fetchng export list for %s", host);
exp = rpc_get_exports(host, 10, 0, RPC_CLOSE_NOLINGER);
@@ -92,20 +93,20 @@ static char *get_exports(struct autofs_p
if (mapent) {
int len = strlen(mapent) + 1;
- len += strlen(name) + 2*(strlen(exp->ex_dir) + 2) + 3;
+ len += strlen(host) + 2*(strlen(exp->ex_dir) + 2) + 3;
mapent = realloc(mapent, len);
if (!mapent) {
char *estr;
estr = strerror_r(errno, buf, MAX_ERR_BUF);
error(ap->logopt, MODPREFIX "malloc: %s", estr);
rpc_exports_free(exp);
- return NSS_STATUS_UNAVAIL;
+ return NULL;
}
strcat(mapent, " \"");
strcat(mapent, exp->ex_dir);
strcat(mapent, "\"");
} else {
- int len = 2*(strlen(exp->ex_dir) + 2) + strlen(name) + 3;
+ int len = 2*(strlen(exp->ex_dir) + 2) + strlen(host) + 3;
mapent = malloc(len);
if (!mapent) {
@@ -113,14 +114,14 @@ static char *get_exports(struct autofs_p
estr = strerror_r(errno, buf, MAX_ERR_BUF);
error(ap->logopt, MODPREFIX "malloc: %s", estr);
rpc_exports_free(exp);
- return NSS_STATUS_UNAVAIL;
+ return NULL;
}
strcpy(mapent, "\"");
strcat(mapent, exp->ex_dir);
strcat(mapent, "\"");
}
strcat(mapent, " \"");
- strcat(mapent, name);
+ strcat(mapent, host);
strcat(mapent, ":");
strcat(mapent, exp->ex_dir);
strcat(mapent, "\"");
@@ -130,14 +131,14 @@ static char *get_exports(struct autofs_p
rpc_exports_free(exp);
if (!mapent)
- error(ap->logopt, "exports lookup failed for %s", name);
+ error(ap->logopt, MODPREFIX "exports lookup failed for %s", host);
return mapent;
}
-static int do_parse_mount(struct autofs_point *ap,
+static int do_parse_mount(struct autofs_point *ap, struct map_source *source,
const char *name, int name_len, char *mapent,
- void *context)
+ struct lookup_context *ctxt)
{
int ret;
@@ -166,8 +167,68 @@ static int do_parse_mount(struct autofs_
return NSS_STATUS_SUCCESS;
}
+static int update_hosts_mounts(struct autofs_point *ap,
+ struct map_source *source, time_t age,
+ struct lookup_context *ctxt)
+{
+ struct mapent_cache *mc;
+ struct mapent *me;
+ char *mapent;
+ int ret;
+
+ mc = source->mc;
+
+ pthread_cleanup_push(cache_lock_cleanup, mc);
+ cache_writelock(mc);
+ me = cache_lookup_first(mc);
+ while (me) {
+ /* Hosts map entry not yet expanded or already expired */
+ if (!me->multi)
+ goto next;
+
+ debug(ap->logopt, MODPREFIX "get list of exports for %s", me->key);
+
+ mapent = get_exports(ap, me->key);
+ if (mapent) {
+ cache_update(mc, source, me->key, mapent, age);
+ free(mapent);
+ }
+next:
+ me = cache_lookup_next(mc, me);
+ }
+ pthread_cleanup_pop(1);
+
+ pthread_cleanup_push(cache_lock_cleanup, mc);
+ cache_readlock(mc);
+ me = cache_lookup_first(mc);
+ while (me) {
+ /*
+ * Hosts map entry not yet expanded, already expired
+ * or not the base of the tree
+ */
+ if (!me->multi || me->multi != me)
+ goto cont;
+
+ debug(ap->logopt, MODPREFIX
+ "attempt to update exports for exports for %s", me->key);
+
+ master_source_current_wait(ap->entry);
+ ap->entry->current = source;
+ ap->flags |= MOUNT_FLAG_REMOUNT;
+ ret = ctxt->parse->parse_mount(ap, me->key, strlen(me->key),
+ me->mapent, ctxt->parse->context);
+ ap->flags &= ~MOUNT_FLAG_REMOUNT;
+cont:
+ me = cache_lookup_next(mc, me);
+ }
+ pthread_cleanup_pop(1);
+
+ return NSS_STATUS_SUCCESS;
+}
+
int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
{
+ struct lookup_context *ctxt = (struct lookup_context *) context;
struct map_source *source;
struct mapent_cache *mc;
struct hostent *host;
@@ -177,18 +238,23 @@ int lookup_read_map(struct autofs_point
ap->entry->current = NULL;
master_source_current_signal(ap->entry);
+ mc = source->mc;
+
+ debug(ap->logopt, MODPREFIX "read hosts map");
+
/*
* If we don't need to create directories then there's no use
* reading the map. We always need to read the whole map for
* direct mounts in order to mount the triggers.
*/
if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT) {
- debug(ap->logopt, "map read not needed, so not done");
+ debug(ap->logopt, MODPREFIX
+ "map not browsable, update existing host entries only");
+ update_hosts_mounts(ap, source, age, ctxt);
+ source->age = age;
return NSS_STATUS_SUCCESS;
}
- mc = source->mc;
-
status = pthread_mutex_lock(&hostent_mutex);
if (status) {
error(ap->logopt, MODPREFIX "failed to lock hostent mutex");
@@ -209,6 +275,7 @@ int lookup_read_map(struct autofs_point
if (status)
error(ap->logopt, MODPREFIX "failed to unlock hostent mutex");
+ update_hosts_mounts(ap, source, age, ctxt);
source->age = age;
return NSS_STATUS_SUCCESS;
@@ -220,11 +287,9 @@ int lookup_mount(struct autofs_point *ap
struct map_source *source;
struct mapent_cache *mc;
struct mapent *me;
- char buf[MAX_ERR_BUF];
char *mapent = NULL;
int mapent_len;
time_t now = time(NULL);
- exports exp;
int ret;
source = ap->entry->current;
@@ -320,7 +385,7 @@ done:
cache_unlock(mc);
}
- ret = do_parse_mount(ap, name, name_len, mapent, ctxt->parse->context);
+ ret = do_parse_mount(ap, source, name, name_len, mapent, ctxt);
free(mapent);
--- autofs-5.0.6.orig/modules/parse_sun.c
+++ autofs-5.0.6/modules/parse_sun.c
@@ -1355,7 +1355,7 @@ int parse_mount(struct autofs_point *ap,
if (check_is_multi(p)) {
char *m_root = NULL;
int m_root_len;
- time_t age = time(NULL);
+ time_t age;
int l;
/* If name starts with "/" it's a direct mount */
@@ -1399,6 +1399,8 @@ int parse_mount(struct autofs_point *ap,
return 1;
}
+ age = me->age;
+
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
cache_multi_writelock(me);
/* It's a multi-mount; deal with it */
@@ -1472,8 +1474,11 @@ int parse_mount(struct autofs_point *ap,
/*
* We've got the ordered list of multi-mount entries so go
- * through and set the parent entry of each
+ * through and remove any stale entries if this is the top
+ * of the multi-mount and set the parent entry of each.
*/
+ if (me == me->multi)
+ clean_stale_multi_triggers(ap, me, NULL, NULL);
cache_set_parents(me);
rv = mount_subtree(ap, me, name, NULL, options, ctxt);

View File

@ -0,0 +1,104 @@
autofs-5.0.6 - allow update of multi mount offset entries
From: Ian Kent <ikent@redhat.com>
Currently multi mount offsets can only be added or all offsets owned by
an entry deleted at once. In order to be able to update multi mount map
entries we need to be able to update offset entries of an already expanded
multi map cache entry.
---
include/automount.h | 2 +-
lib/cache.c | 4 ++--
modules/parse_sun.c | 20 ++++++++++----------
3 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/include/automount.h b/include/automount.h
index 40c1975..561fcc2 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -188,7 +188,7 @@ struct mapent *cache_lookup_distinct(struct mapent_cache *mc, const char *key);
struct mapent *cache_lookup_offset(const char *prefix, const char *offset, int start, struct list_head *head);
struct mapent *cache_partial_match(struct mapent_cache *mc, const char *prefix);
int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age);
-int cache_add_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age);
+int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age);
int cache_set_parents(struct mapent *mm);
int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age);
int cache_delete(struct mapent_cache *mc, const char *key);
diff --git a/lib/cache.c b/lib/cache.c
index 1489273..9179ad5 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -647,7 +647,7 @@ static void cache_add_ordered_offset(struct mapent *me, struct list_head *head)
}
/* cache must be write locked by caller */
-int cache_add_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age)
+int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age)
{
unsigned logopt = mc->ap ? mc->ap->logopt : master_get_logopt();
struct mapent *me, *owner;
@@ -659,7 +659,7 @@ int cache_add_offset(struct mapent_cache *mc, const char *mkey, const char *key,
me = cache_lookup_distinct(mc, key);
if (me && me->age == age) {
- if (me != owner)
+ if (me->multi != owner)
return CHE_DUPLICATE;
}
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index c4decbc..5be7345 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -781,10 +781,10 @@ static int check_is_multi(const char *mapent)
}
static int
-add_offset_entry(struct autofs_point *ap, const char *name,
- const char *m_root, int m_root_len,
- const char *path, const char *myoptions, const char *loc,
- time_t age)
+update_offset_entry(struct autofs_point *ap, const char *name,
+ const char *m_root, int m_root_len,
+ const char *path, const char *myoptions, const char *loc,
+ time_t age)
{
struct map_source *source;
struct mapent_cache *mc;
@@ -838,17 +838,17 @@ add_offset_entry(struct autofs_point *ap, const char *name,
} else
strcpy(m_mapent, loc);
- ret = cache_add_offset(mc, name, m_key, m_mapent, age);
+ ret = cache_update_offset(mc, name, m_key, m_mapent, age);
if (ret == CHE_DUPLICATE)
warn(ap->logopt, MODPREFIX
"syntax error or duplicate offset %s -> %s", path, loc);
else if (ret == CHE_FAIL)
debug(ap->logopt, MODPREFIX
- "failed to add multi-mount offset %s -> %s", path, m_mapent);
+ "failed to update multi-mount offset %s -> %s", path, m_mapent);
else {
ret = CHE_OK;
debug(ap->logopt, MODPREFIX
- "added multi-mount offset %s -> %s", path, m_mapent);
+ "updated multi-mount offset %s -> %s", path, m_mapent);
}
return ret;
@@ -1448,9 +1448,9 @@ int parse_mount(struct autofs_point *ap, const char *name,
master_source_current_wait(ap->entry);
ap->entry->current = source;
- status = add_offset_entry(ap, name,
- m_root, m_root_len,
- path, myoptions, loc, age);
+ status = update_offset_entry(ap, name,
+ m_root, m_root_len,
+ path, myoptions, loc, age);
if (status != CHE_OK) {
warn(ap->logopt, MODPREFIX "error adding multi-mount");

View File

@ -0,0 +1,70 @@
autofs-5.0.6 - check if /etc/mtab is a link to /proc/self/mounts
From: Leonardo Chiquitto <leonardo.lists@gmail.com>
Check if /etc/mtab is a link to /proc/self/mounts
Some distributions link /etc/mtab to /proc/self/mounts instead
of /proc/mounts.
---
CHANGELOG | 1 +
daemon/spawn.c | 9 ++++++---
include/automount.h | 3 ++-
3 files changed, 9 insertions(+), 4 deletions(-)
--- autofs-5.0.6.orig/CHANGELOG
+++ autofs-5.0.6/CHANGELOG
@@ -48,6 +48,7 @@
- move timeout to map_source (allow per direct map timeout).
- fix kernel verion check of version components.
- dont retry ldap connect if not required.
+- check if /etc/mtab is a link to /proc/self/mounts.
28/06/2011 autofs-5.0.6
-----------------------
--- autofs-5.0.6.orig/daemon/spawn.c
+++ autofs-5.0.6/daemon/spawn.c
@@ -336,7 +336,8 @@ int spawn_mount(unsigned logopt, ...)
ret = readlink(_PATH_MOUNTED, buf, PATH_MAX);
if (ret != -1) {
buf[ret] = '\0';
- if (!strcmp(buf, _PROC_MOUNTS)) {
+ if (!strcmp(buf, _PROC_MOUNTS) ||
+ !strcmp(buf, _PROC_SELF_MOUNTS)) {
debug(logopt,
"mtab link detected, passing -n to mount");
argc++;
@@ -467,7 +468,8 @@ int spawn_bind_mount(unsigned logopt, ..
ret = readlink(_PATH_MOUNTED, buf, PATH_MAX);
if (ret != -1) {
buf[ret] = '\0';
- if (!strcmp(buf, _PROC_MOUNTS)) {
+ if (!strcmp(buf, _PROC_MOUNTS) ||
+ !strcmp(buf, _PROC_SELF_MOUNTS)) {
debug(logopt,
"mtab link detected, passing -n to mount");
argc++;
@@ -569,7 +571,8 @@ int spawn_umount(unsigned logopt, ...)
ret = readlink(_PATH_MOUNTED, buf, PATH_MAX);
if (ret != -1) {
buf[ret] = '\0';
- if (!strcmp(buf, _PROC_MOUNTS)) {
+ if (!strcmp(buf, _PROC_MOUNTS) ||
+ !strcmp(buf, _PROC_SELF_MOUNTS)) {
debug(logopt,
"mtab link detected, passing -n to mount");
argc++;
--- autofs-5.0.6.orig/include/automount.h
+++ autofs-5.0.6/include/automount.h
@@ -84,7 +84,8 @@ int load_autofs4_module(void);
#define MTAB_NOTUPDATED 0x1000 /* mtab succeded but not updated */
#define NOT_MOUNTED 0x0100 /* path notmounted */
#define MNT_FORCE_FAIL -1
-#define _PROC_MOUNTS "/proc/mounts"
+#define _PROC_MOUNTS "/proc/mounts"
+#define _PROC_SELF_MOUNTS "/proc/self/mounts"
/* Constants for lookup modules */

View File

@ -0,0 +1,65 @@
autofs-5.0.6 - dont retry ldap connect if not required
From: Ian Kent <ikent@redhat.com>
When using LDAP and the server is not available autofs retries the
connection when it fails in case the SASL credentail has expired.
But this is done even when not using SASL, so change it check if
SASL authentication is required.
---
CHANGELOG | 1 +
include/lookup_ldap.h | 1 +
modules/lookup_ldap.c | 6 +++---
3 files changed, 5 insertions(+), 3 deletions(-)
--- autofs-5.0.6.orig/CHANGELOG
+++ autofs-5.0.6/CHANGELOG
@@ -47,6 +47,7 @@
- update ->timeout() function to not return timeout.
- move timeout to map_source (allow per direct map timeout).
- fix kernel verion check of version components.
+- dont retry ldap connect if not required.
28/06/2011 autofs-5.0.6
-----------------------
--- autofs-5.0.6.orig/include/lookup_ldap.h
+++ autofs-5.0.6/include/lookup_ldap.h
@@ -104,6 +104,7 @@ struct lookup_context {
#define LDAP_AUTH_NOTREQUIRED 0x0001
#define LDAP_AUTH_REQUIRED 0x0002
#define LDAP_AUTH_AUTODETECT 0x0004
+#define LDAP_NEED_AUTH (LDAP_AUTH_REQUIRED|LDAP_AUTH_AUTODETECT)
#endif
#define LDAP_AUTH_USESIMPLE 0x0008
--- autofs-5.0.6.orig/modules/lookup_ldap.c
+++ autofs-5.0.6/modules/lookup_ldap.c
@@ -511,7 +511,7 @@ static int do_bind(unsigned logopt, LDAP
debug(logopt, MODPREFIX "auth_required: %d, sasl_mech %s",
ctxt->auth_required, ctxt->sasl_mech);
- if (ctxt->auth_required & (LDAP_AUTH_REQUIRED|LDAP_AUTH_AUTODETECT)) {
+ if (ctxt->auth_required & LDAP_NEED_AUTH) {
rv = autofs_sasl_bind(logopt, ldap, ctxt);
debug(logopt, MODPREFIX "autofs_sasl_bind returned %d", rv);
} else {
@@ -731,7 +731,7 @@ static LDAP *do_reconnect(unsigned logop
ldap = do_connect(logopt, ctxt->server, ctxt);
#ifdef WITH_SASL
/* Dispose of the sasl authentication connection and try again. */
- if (!ldap) {
+ if (!ldap && ctxt->auth_required & LDAP_NEED_AUTH) {
autofs_sasl_dispose(ctxt);
ldap = connect_to_server(logopt, ctxt->server, ctxt);
}
@@ -767,7 +767,7 @@ static LDAP *do_reconnect(unsigned logop
* Dispose of the sasl authentication connection and try the
* current server again before trying other servers in the list.
*/
- if (!ldap) {
+ if (!ldap && ctxt->auth_required & LDAP_NEED_AUTH) {
autofs_sasl_dispose(ctxt);
ldap = connect_to_server(logopt, ctxt->uri->uri, ctxt);
}

View File

@ -0,0 +1,158 @@
autofs-5.0.6 - duplicate parent options for included maps
From: Ian Kent <ikent@redhat.com>
Included maps should inherite mount options from their parent mount.
---
CHANGELOG | 1
modules/lookup_file.c | 61 +++++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 54 insertions(+), 8 deletions(-)
--- autofs-5.0.6.orig/CHANGELOG
+++ autofs-5.0.6/CHANGELOG
@@ -43,6 +43,7 @@
- fix initialization in rpc create_client().
- fix libtirpc name clash.
- report map not read when debug logging.
+- duplicate parent options for included maps.
28/06/2011 autofs-5.0.6
-----------------------
--- autofs-5.0.6.orig/modules/lookup_file.c
+++ autofs-5.0.6/modules/lookup_file.c
@@ -41,9 +41,10 @@ typedef enum {
typedef enum { got_nothing, got_star, got_real, got_plus } FOUND_STATE;
typedef enum { esc_none, esc_char, esc_val, esc_all } ESCAPES;
-
struct lookup_context {
const char *mapname;
+ int opts_argc;
+ const char **opts_argv;
struct parse_mod *parse;
};
@@ -88,8 +89,20 @@ int lookup_init(const char *mapfmt, int
if (!mapfmt)
mapfmt = MAPFMT_DEFAULT;
- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
+ argc--;
+ argv++;
+
+ ctxt->opts_argv = copy_argv(argc, (const char **) argv);
+ if (ctxt->opts_argv == NULL) {
+ free(ctxt);
+ warn(LOGOPT_NONE, MODPREFIX "failed to duplicate options");
+ return 1;
+ }
+ ctxt->opts_argc = argc;
+
+ ctxt->parse = open_parse(mapfmt, MODPREFIX, argc, argv);
if (!ctxt->parse) {
+ free_argv(ctxt->opts_argc, ctxt->opts_argv);
free(ctxt);
logmsg(MODPREFIX "failed to open parse context");
return 1;
@@ -512,12 +525,15 @@ static int check_self_include(const char
}
static struct map_source *
-prepare_plus_include(struct autofs_point *ap, time_t age, char *key, unsigned int inc)
+prepare_plus_include(struct autofs_point *ap,
+ time_t age, char *key, unsigned int inc,
+ struct lookup_context *ctxt)
{
struct map_source *current;
struct map_source *source;
struct map_type_info *info;
const char *argv[2];
+ char **tmp_argv, **tmp_opts;
int argc;
char *buf;
@@ -551,9 +567,35 @@ prepare_plus_include(struct autofs_point
argv[0] = info->map;
argv[1] = NULL;
+ tmp_argv = (char **) copy_argv(argc, argv);
+ if (!tmp_argv) {
+ error(ap->logopt, MODPREFIX "failed to allocate args vector");
+ free_map_type_info(info);
+ free(buf);
+ return NULL;
+ }
+
+ tmp_opts = (char **) copy_argv(ctxt->opts_argc, ctxt->opts_argv);
+ if (!tmp_opts) {
+ error(ap->logopt, MODPREFIX "failed to allocate options args vector");
+ free_argv(argc, (const char **) tmp_argv);
+ free_map_type_info(info);
+ free(buf);
+ return NULL;
+ }
+
+ tmp_argv = append_argv(argc, tmp_argv, ctxt->opts_argc, tmp_opts);
+ if (!tmp_argv) {
+ error(ap->logopt, MODPREFIX "failed to append options vector");
+ free_map_type_info(info);
+ free(buf);
+ return NULL;
+ }
+ argc += ctxt->opts_argc;
+
source = master_find_source_instance(current,
info->type, info->format,
- argc, argv);
+ argc, (const char **) tmp_argv);
if (source) {
/*
* Make sure included map age is in sync with its owner
@@ -563,15 +605,17 @@ prepare_plus_include(struct autofs_point
source->stale = 1;
} else {
source = master_add_source_instance(current,
- info->type, info->format,
- age, argc, argv);
+ info->type, info->format, age,
+ argc, (const char **) tmp_argv);
if (!source) {
+ free_argv(argc, (const char **) tmp_argv);
free_map_type_info(info);
free(buf);
error(ap->logopt, "failed to add included map instance");
return NULL;
}
}
+ free_argv(argc, (const char **) tmp_argv);
source->depth = current->depth + 1;
if (inc)
@@ -645,7 +689,7 @@ int lookup_read_map(struct autofs_point
master_source_current_wait(ap->entry);
ap->entry->current = source;
- inc_source = prepare_plus_include(ap, age, key, inc);
+ inc_source = prepare_plus_include(ap, age, key, inc, ctxt);
if (!inc_source) {
debug(ap->logopt,
"failed to select included map %s", key);
@@ -729,7 +773,7 @@ static int lookup_one(struct autofs_poin
master_source_current_wait(ap->entry);
ap->entry->current = source;
- inc_source = prepare_plus_include(ap, age, mkey, inc);
+ inc_source = prepare_plus_include(ap, age, mkey, inc, ctxt);
if (!inc_source) {
debug(ap->logopt,
MODPREFIX
@@ -1096,6 +1140,7 @@ int lookup_done(void *context)
{
struct lookup_context *ctxt = (struct lookup_context *) context;
int rv = close_parse(ctxt->parse);
+ free_argv(ctxt->opts_argc, ctxt->opts_argv);
free(ctxt);
return rv;
}

View File

@ -0,0 +1,37 @@
autofs-5.0.6 - fix devce ioctl alloc path check
From: Ian Kent <ikent@redhat.com>
The errno error should be set in alloc_dev_ioctl_path() if the passed
in path in NULL.
---
CHANGELOG | 1 +
lib/dev-ioctl-lib.c | 4 +++-
2 files changed, 4 insertions(+), 1 deletion(-)
--- autofs-5.0.6.orig/CHANGELOG
+++ autofs-5.0.6/CHANGELOG
@@ -56,6 +56,7 @@
- fix umount recovery of busy direct mount.
- fix offset mount point directory removal.
- fix remount of multi mount.
+- fix devce ioctl alloc path check.
28/06/2011 autofs-5.0.6
-----------------------
--- autofs-5.0.6.orig/lib/dev-ioctl-lib.c
+++ autofs-5.0.6/lib/dev-ioctl-lib.c
@@ -270,8 +270,10 @@ static struct autofs_dev_ioctl *alloc_de
struct autofs_dev_ioctl *ioctl;
size_t size, p_len;
- if (!path)
+ if (!path) {
+ errno = EINVAL;
return NULL;
+ }
p_len = strlen(path);
size = sizeof(struct autofs_dev_ioctl) + p_len + 1;

View File

@ -0,0 +1,33 @@
autofs-5.0.6 - fix fix LDAP result leaks on error paths
From: Ian Kent <raven@themaw.net>
The previous patch with which ensured that the result struture returned
from ldap_search_s(3) was freed could sometimes lead to a segmentation
fault because the local variable used was not initialized before use.
---
modules/lookup_ldap.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- autofs-5.0.6.orig/modules/lookup_ldap.c
+++ autofs-5.0.6/modules/lookup_ldap.c
@@ -1521,7 +1521,7 @@ int lookup_read_master(struct master *ma
char buf[MAX_ERR_BUF];
char parse_buf[PARSE_MAX_BUF];
char *query;
- LDAPMessage *result, *e;
+ LDAPMessage *result = NULL, *e;
char *class, *info, *entry;
char **keyValue = NULL;
char **values = NULL;
@@ -2467,7 +2467,7 @@ static int lookup_one(struct autofs_poin
char buf[MAX_ERR_BUF];
time_t age = time(NULL);
char *query;
- LDAPMessage *result, *e;
+ LDAPMessage *result = NULL, *e;
char *class, *info, *entry;
char *enc_key1, *enc_key2;
int enc_len1 = 0, enc_len2 = 0;

View File

@ -0,0 +1,94 @@
autofs-5.0.6 - fix kernel verion check of version components
From: Ian Kent <ikent@redhat.com>
Oops, not following the ball.
The kernel may have (or will have at times) a two digit version number.
Fix the version check function to allow for this.
---
CHANGELOG | 1 +
include/mounts.h | 15 +--------------
lib/mounts.c | 29 +++++++++++++++++++++++++++++
3 files changed, 31 insertions(+), 14 deletions(-)
--- autofs-5.0.6.orig/CHANGELOG
+++ autofs-5.0.6/CHANGELOG
@@ -46,6 +46,7 @@
- duplicate parent options for included maps.
- update ->timeout() function to not return timeout.
- move timeout to map_source (allow per direct map timeout).
+- fix kernel verion check of version components.
28/06/2011 autofs-5.0.6
-----------------------
--- autofs-5.0.6.orig/include/mounts.h
+++ autofs-5.0.6/include/mounts.h
@@ -75,26 +75,13 @@ struct mnt_list {
struct list_head ordered;
};
-static inline unsigned int linux_version_code(void)
-{
- struct utsname my_utsname;
- unsigned int p, q, r;
- char *save;
-
- if (uname(&my_utsname))
- return 0;
-
- p = (unsigned int) atoi(strtok_r(my_utsname.release, ".", &save));
- q = (unsigned int) atoi(strtok_r(NULL, ".", &save));
- r = (unsigned int) atoi(strtok_r(NULL, ".", &save));
- return KERNEL_VERSION(p, q, r);
-}
struct nfs_mount_vers {
unsigned int major;
unsigned int minor;
unsigned int fix;
};
+unsigned int linux_version_code(void);
int check_nfs_mount_version(struct nfs_mount_vers *, struct nfs_mount_vers *);
extern unsigned int nfs_mount_uses_string_options;
--- autofs-5.0.6.orig/lib/mounts.c
+++ autofs-5.0.6/lib/mounts.c
@@ -46,6 +46,35 @@ static const char mnt_name_template[]
static struct kernel_mod_version kver = {0, 0};
static const char kver_options_template[] = "fd=%d,pgrp=%u,minproto=3,maxproto=5";
+unsigned int linux_version_code(void)
+{
+ struct utsname my_utsname;
+ unsigned int p, q, r;
+ char *tmp, *save;
+
+ if (uname(&my_utsname))
+ return 0;
+
+ p = q = r = 0;
+
+ tmp = strtok_r(my_utsname.release, ".", &save);
+ if (!tmp)
+ return 0;
+ p = (unsigned int ) atoi(tmp);
+
+ tmp = strtok_r(NULL, ".", &save);
+ if (!tmp)
+ return KERNEL_VERSION(p, 0, 0);
+ q = (unsigned int) atoi(tmp);
+
+ tmp = strtok_r(NULL, ".", &save);
+ if (!tmp)
+ return KERNEL_VERSION(p, q, 0);
+ r = (unsigned int) atoi(tmp);
+
+ return KERNEL_VERSION(p, q, r);
+}
+
unsigned int query_kproto_ver(void)
{
struct ioctl_ops *ops = get_ioctl_ops();

View File

@ -0,0 +1,52 @@
autofs-5.0.6 - fix nfs4 contacts portmap
From: Ian Kent <ikent@redhat.com>
When an fstype of nfs4 is specified probing the server for availability
should not need to contact the portmapper, it should use either the port
specified by the port= option or use port 2049.
However, in function modules/replicated.c:get_nfs_info() a check for the
port= option, and subsequent portmap lookup when not it's not present, is
done before the check for whether nfsv3 is to be checked at all.
Oops!
---
CHANGELOG | 1 +
modules/replicated.c | 6 +++---
2 files changed, 4 insertions(+), 3 deletions(-)
--- autofs-5.0.6.orig/CHANGELOG
+++ autofs-5.0.6/CHANGELOG
@@ -49,6 +49,7 @@
- fix kernel verion check of version components.
- dont retry ldap connect if not required.
- check if /etc/mtab is a link to /proc/self/mounts.
+- fix nfs4 contacts portmap.
28/06/2011 autofs-5.0.6
-----------------------
--- autofs-5.0.6.orig/modules/replicated.c
+++ autofs-5.0.6/modules/replicated.c
@@ -589,6 +589,9 @@ static unsigned int get_nfs_info(unsigne
}
v3_ver:
+ if (!(version & NFS3_REQUESTED))
+ goto v2_ver;
+
if (!have_port_opt) {
status = rpc_portmap_getclient(pm_info,
host->name, host->addr, host->addr_len,
@@ -600,9 +603,6 @@ v3_ver:
goto done_ver;
}
- if (!(version & NFS3_REQUESTED))
- goto v2_ver;
-
if (have_port_opt) {
if (!(rpc_info->port = get_port_option(options)))
goto done_ver;

View File

@ -0,0 +1,167 @@
autofs-5.0.6 - fix offset mount point directory removal
From: Ian Kent <ikent@redhat.com>
Attempting to remove the last component of a multi-mount offset mount
point is incorrect. The removal and attempted recovery is better
handled in the calling function.
---
CHANGELOG | 1
daemon/direct.c | 7 ----
lib/mounts.c | 82 ++++++++++++++++++++++++++++++++------------------------
3 files changed, 49 insertions(+), 41 deletions(-)
--- autofs-5.0.6.orig/CHANGELOG
+++ autofs-5.0.6/CHANGELOG
@@ -54,6 +54,7 @@
- fix sss map age not updated.
- fix remount deadlock.
- fix umount recovery of busy direct mount.
+- fix offset mount point directory removal.
28/06/2011 autofs-5.0.6
-----------------------
--- autofs-5.0.6.orig/daemon/direct.c
+++ autofs-5.0.6/daemon/direct.c
@@ -633,13 +633,6 @@ force_umount:
} else
info(ap->logopt, "umounted offset mount %s", me->key);
- if (!rv && me->flags & MOUNT_FLAG_DIR_CREATED) {
- if (rmdir(me->key) == -1) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- warn(ap->logopt, "failed to remove dir %s: %s",
- me->key, estr);
- }
- }
return rv;
}
--- autofs-5.0.6.orig/lib/mounts.c
+++ autofs-5.0.6/lib/mounts.c
@@ -1605,6 +1605,33 @@ int umount_ent(struct autofs_point *ap,
return rv;
}
+static int do_mount_autofs_offset(struct autofs_point *ap,
+ struct mapent *oe, const char *root,
+ char *offset)
+
+{
+ int mounted = 0;
+ int ret;
+
+ debug(ap->logopt, "mount offset %s at %s", oe->key, root);
+
+ ret = mount_autofs_offset(ap, oe, root, offset);
+ if (ret >= MOUNT_OFFSET_OK)
+ mounted++;
+ else {
+ if (ret != MOUNT_OFFSET_IGNORE)
+ warn(ap->logopt, "failed to mount offset");
+ else {
+ debug(ap->logopt, "ignoring \"nohide\" trigger %s",
+ oe->key);
+ free(oe->mapent);
+ oe->mapent = NULL;
+ }
+ }
+
+ return mounted;
+}
+
int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
const char *root, unsigned int start, const char *base)
{
@@ -1613,8 +1640,7 @@ int mount_multi_triggers(struct autofs_p
struct mapent *oe;
struct list_head *pos = NULL;
unsigned int fs_path_len;
- unsigned int mounted;
- int ret;
+ int mounted;
fs_path_len = start + strlen(base);
if (fs_path_len > PATH_MAX)
@@ -1634,22 +1660,7 @@ int mount_multi_triggers(struct autofs_p
if (!oe || !oe->mapent)
goto cont;
- debug(ap->logopt, "mount offset %s at %s", oe->key, root);
-
- ret = mount_autofs_offset(ap, oe, root, offset);
- if (ret >= MOUNT_OFFSET_OK)
- mounted++;
- else {
- if (ret != MOUNT_OFFSET_IGNORE)
- warn(ap->logopt, "failed to mount offset");
- else {
- debug(ap->logopt,
- "ignoring \"nohide\" trigger %s",
- oe->key);
- free(oe->mapent);
- oe->mapent = NULL;
- }
- }
+ mounted += do_mount_autofs_offset(ap, oe, root, offset);
cont:
offset = cache_get_offset(base,
offset, start, &me->multi_list, &pos);
@@ -1681,7 +1692,6 @@ int umount_multi_triggers(struct autofs_
pos = NULL;
offset = path;
- /* Make sure "none" of the offsets have an active mount. */
while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
char *oe_base;
@@ -1700,28 +1710,32 @@ int umount_multi_triggers(struct autofs_
if (oe->ioctlfd != -1 ||
is_mounted(_PROC_MOUNTS, oe->key, MNTS_REAL)) {
left++;
- break;
- }
- }
-
- if (left)
- return left;
-
- pos = NULL;
- offset = path;
-
- /* Make sure "none" of the offsets have an active mount. */
- while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
- oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list);
- /* root offset is a special case */
- if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1)
continue;
+ }
debug(ap->logopt, "umount offset %s", oe->key);
if (umount_autofs_offset(ap, oe)) {
warn(ap->logopt, "failed to umount offset");
left++;
+ } else {
+ struct stat st;
+ int ret;
+
+ if (!(oe->flags & MOUNT_FLAG_DIR_CREATED))
+ continue;
+
+ /*
+ * An error due to partial directory removal is
+ * ok so only try and remount the offset if the
+ * actual mount point still exists.
+ */
+ ret = rmdir_path(ap, oe->key, ap->dev);
+ if (ret == -1 && !stat(oe->key, &st)) {
+ ret = do_mount_autofs_offset(ap, oe, root, offset);
+ if (ret)
+ left++;
+ }
}
}

View File

@ -0,0 +1,136 @@
autofs-5.0.6 - fix remount deadlock
From: Ian Kent <raven@themaw.net>
When reconstructing the mount tree upon restart a writelock to the map
entry cache cannot be taken when parsing a direct map entry because a
readlock is already held higher up in the call tree.
In the place this is done it isn't be necessary to alter the direct map
entries in the cache. Also, it shouldn't be necessary to delete existing
multi-mount cache entries to avoid a duplicate multi-mount entry error
return. The check for a duplicate can be done in the cache handling
functions.
---
CHANGELOG | 1
lib/cache.c | 8 ++++--
modules/parse_sun.c | 60 ++++++++++++++++++++++++++--------------------------
3 files changed, 36 insertions(+), 33 deletions(-)
--- autofs-5.0.6.orig/CHANGELOG
+++ autofs-5.0.6/CHANGELOG
@@ -52,6 +52,7 @@
- fix nfs4 contacts portmap.
- make autofs wait longer for shutdown completion.
- fix sss map age not updated.
+- fix remount deadlock.
28/06/2011 autofs-5.0.6
-----------------------
--- autofs-5.0.6.orig/lib/cache.c
+++ autofs-5.0.6/lib/cache.c
@@ -658,10 +658,12 @@ int cache_add_offset(struct mapent_cache
return CHE_FAIL;
me = cache_lookup_distinct(mc, key);
- if (me && me != owner)
- return CHE_DUPLICATE;
+ if (me && me->age == age) {
+ if (me != owner)
+ return CHE_DUPLICATE;
+ }
- ret = cache_add(mc, owner->source, key, mapent, age);
+ ret = cache_update(mc, owner->source, key, mapent, age);
if (ret == CHE_FAIL) {
warn(logopt, "failed to add key %s to cache", key);
return CHE_FAIL;
--- autofs-5.0.6.orig/modules/parse_sun.c
+++ autofs-5.0.6/modules/parse_sun.c
@@ -843,12 +843,17 @@ add_offset_entry(struct autofs_point *ap
strcpy(m_mapent, loc);
ret = cache_add_offset(mc, name, m_key, m_mapent, age);
- if (ret == CHE_OK)
+ if (ret == CHE_DUPLICATE)
+ warn(ap->logopt, MODPREFIX
+ "syntax error or duplicate offset %s -> %s", path, loc);
+ else if (ret == CHE_FAIL)
+ debug(ap->logopt, MODPREFIX
+ "failed to add multi-mount offset %s -> %s", path, m_mapent);
+ else {
+ ret = CHE_OK;
debug(ap->logopt, MODPREFIX
"added multi-mount offset %s -> %s", path, m_mapent);
- else
- warn(ap->logopt, MODPREFIX
- "syntax error or duplicate offset %s -> %s", path, loc);
+ }
return ret;
}
@@ -1410,7 +1415,7 @@ int parse_mount(struct autofs_point *ap,
char buf[MAX_ERR_BUF];
struct map_source *source;
struct mapent_cache *mc;
- struct mapent *me = NULL;
+ struct mapent *me;
char *pmapent, *options;
const char *p;
int mapent_len, rv = 0;
@@ -1561,33 +1566,28 @@ int parse_mount(struct autofs_point *ap,
strcat(m_root, name);
}
- cache_writelock(mc);
- me = cache_lookup_distinct(mc, name);
- if (!me) {
- int ret;
- /*
- * Not in the cache, perhaps it's a program map
- * or one that doesn't support enumeration
- */
- ret = cache_add(mc, source, name, mapent, time(NULL));
- if (ret == CHE_FAIL) {
- cache_unlock(mc);
- free(options);
- return 1;
+ /*
+ * Can't take the write lock for direct mount entries here
+ * but they should always be present in the map entry cache.
+ */
+ if (ap->type == LKP_INDIRECT) {
+ cache_writelock(mc);
+ me = cache_lookup_distinct(mc, name);
+ if (!me) {
+ int ret;
+ /*
+ * Not in the cache, perhaps it's a program map
+ * or one that doesn't support enumeration.
+ */
+ ret = cache_add(mc, source, name, mapent, age);
+ if (ret == CHE_FAIL) {
+ cache_unlock(mc);
+ free(options);
+ return 1;
+ }
}
- } else {
- /*
- * If the entry exists it must not have any existing
- * multi-mount subordinate entries since we are
- * mounting this afresh. We need to do this to allow
- * us to fail on the check for duplicate offsets in
- * we don't know when submounts go away.
- */
- cache_multi_writelock(me);
- cache_delete_offset_list(mc, name);
- cache_multi_unlock(me);
+ cache_unlock(mc);
}
- cache_unlock(mc);
cache_readlock(mc);
me = cache_lookup_distinct(mc, name);

View File

@ -0,0 +1,49 @@
autofs-5.0.6 - fix remount of multi mount
From: Ian Kent <ikent@redhat.com>
Went accessing a multi-mount only the the offsets that need to be mounted
are mounted. But when re-mounting multi-mounts during a restart we need to
also traverse into existing mounts and re-connect to triggers mounted within
them.
---
CHANGELOG | 1 +
lib/mounts.c | 15 +++++++++++++++
2 files changed, 16 insertions(+)
--- autofs-5.0.6.orig/CHANGELOG
+++ autofs-5.0.6/CHANGELOG
@@ -55,6 +55,7 @@
- fix remount deadlock.
- fix umount recovery of busy direct mount.
- fix offset mount point directory removal.
+- fix remount of multi mount.
28/06/2011 autofs-5.0.6
-----------------------
--- autofs-5.0.6.orig/lib/mounts.c
+++ autofs-5.0.6/lib/mounts.c
@@ -1661,6 +1661,21 @@ int mount_multi_triggers(struct autofs_p
goto cont;
mounted += do_mount_autofs_offset(ap, oe, root, offset);
+
+ /*
+ * If re-constructing a multi-mount it's necessary to walk
+ * into nested mounts, unlike the usual "mount only what's
+ * needed as you go" behavior.
+ */
+ if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) {
+ if (oe->ioctlfd != -1 ||
+ is_mounted(_PROC_MOUNTS, oe->key, MNTS_REAL)) {
+ char oe_root[PATH_MAX + 1];
+ strcpy(oe_root, root);
+ strcat(oe_root, offset);
+ mount_multi_triggers(ap, oe, oe_root, strlen(oe_root), base);
+ }
+ }
cont:
offset = cache_get_offset(base,
offset, start, &me->multi_list, &pos);

View File

@ -0,0 +1,34 @@
autofs-5.0.6 - fix sss map age not updated
From: Ian Kent <ikent@redhat.com>
The map source age field should be updated when the map is read for
map entry cache cleanup.
---
CHANGELOG | 1 +
modules/lookup_sss.c | 2 ++
2 files changed, 3 insertions(+)
--- autofs-5.0.6.orig/CHANGELOG
+++ autofs-5.0.6/CHANGELOG
@@ -51,6 +51,7 @@
- check if /etc/mtab is a link to /proc/self/mounts.
- fix nfs4 contacts portmap.
- make autofs wait longer for shutdown completion.
+- fix sss map age not updated.
28/06/2011 autofs-5.0.6
-----------------------
--- autofs-5.0.6.orig/modules/lookup_sss.c
+++ autofs-5.0.6/modules/lookup_sss.c
@@ -362,6 +362,8 @@ int lookup_read_map(struct autofs_point
endautomntent(ap->logopt, ctxt, &sss_ctxt);
+ source->age = age;
+
return NSS_STATUS_SUCCESS;
}

View File

@ -0,0 +1,66 @@
autofs-5.0.6 - fix umount recovery of busy direct mount
From: Ian Kent <raven@themaw.net>
Reported by Leonardo Chiquitto (along with a problem analysis that lead
to the resolution). Thanks for the effort Leonardo.
When umounting direct mounts at exit, if any are busy and contain offset
trigger mounts automount will try and re-mount them when the umount fails
so they can be used to re-construct the mount tree at restart. But this
fails because the kernel communication pipe, which is used as a parameter
when mounting the offsets, has already been closed. To fix this all we
need do is delay closing the kernel pipe file handle until after the
direct mounts have been umounted since this doesn't affect the in use
status of the mounts.
---
CHANGELOG | 1 +
daemon/direct.c | 18 +++++++++---------
2 files changed, 10 insertions(+), 9 deletions(-)
--- autofs-5.0.6.orig/CHANGELOG
+++ autofs-5.0.6/CHANGELOG
@@ -53,6 +53,7 @@
- make autofs wait longer for shutdown completion.
- fix sss map age not updated.
- fix remount deadlock.
+- fix umount recovery of busy direct mount.
28/06/2011 autofs-5.0.6
-----------------------
--- autofs-5.0.6.orig/daemon/direct.c
+++ autofs-5.0.6/daemon/direct.c
@@ -193,15 +193,6 @@ int umount_autofs_direct(struct autofs_p
struct mnt_list *mnts;
struct mapent *me, *ne;
- close(ap->state_pipe[0]);
- close(ap->state_pipe[1]);
- if (ap->pipefd >= 0)
- close(ap->pipefd);
- if (ap->kpipefd >= 0) {
- close(ap->kpipefd);
- ap->kpipefd = -1;
- }
-
mnts = tree_make_mnt_tree(_PROC_MOUNTS, "/");
pthread_cleanup_push(mnts_cleanup, mnts);
nc = ap->entry->master->nc;
@@ -231,6 +222,15 @@ int umount_autofs_direct(struct autofs_p
pthread_cleanup_pop(1);
pthread_cleanup_pop(1);
+ close(ap->state_pipe[0]);
+ close(ap->state_pipe[1]);
+ if (ap->pipefd >= 0)
+ close(ap->pipefd);
+ if (ap->kpipefd >= 0) {
+ close(ap->kpipefd);
+ ap->kpipefd = -1;
+ }
+
return 0;
}

View File

@ -0,0 +1,78 @@
autofs-5.0.6 - make autofs wait longer for shutdown
From: Ian Kent <ikent@redhat.com>
After signaling the automount daemon to shutdown the autofs init script
doesn't wait long enough for the daemon to exit. This can be a problem
if there are a large number of mounts or if servers are slow to respond.
---
CHANGELOG | 1 +
redhat/autofs.init.in | 5 ++++-
samples/autofs.service.in | 1 +
samples/rc.autofs.in | 5 ++++-
4 files changed, 10 insertions(+), 2 deletions(-)
--- autofs-5.0.6.orig/CHANGELOG
+++ autofs-5.0.6/CHANGELOG
@@ -50,6 +50,7 @@
- dont retry ldap connect if not required.
- check if /etc/mtab is a link to /proc/self/mounts.
- fix nfs4 contacts portmap.
+- make autofs wait longer for shutdown completion.
28/06/2011 autofs-5.0.6
-----------------------
--- autofs-5.0.6.orig/redhat/autofs.init.in
+++ autofs-5.0.6/redhat/autofs.init.in
@@ -108,7 +108,7 @@ function stop() {
while [ -n "`pidof $prog`" -a $count -lt 15 ] ; do
killproc $prog -TERM >& /dev/null
RETVAL=$?
- [ $RETVAL = 0 -a -z "`pidof $prog`" ] || sleep 3
+ [ $RETVAL = 0 -a -z "`pidof $prog`" ] || sleep 20
count=`expr $count + 1`
done
if [ $RETVAL -eq 0 ]; then
@@ -129,6 +129,9 @@ function restart() {
status autofs > /dev/null 2>&1
if [ $? -eq 0 ]; then
stop
+ while [ -n "`pidof $prog`" ] ; do
+ sleep 5
+ done
fi
start
}
--- autofs-5.0.6.orig/samples/autofs.service.in
+++ autofs-5.0.6/samples/autofs.service.in
@@ -8,6 +8,7 @@ PIDFile=@@autofspiddir@@/autofs.pid
EnvironmentFile=-@@autofsconfdir@@/autofs
ExecStart=@@sbindir@@/automount ${OPTIONS} --pid-file @@autofspiddir@@/autofs.pid
ExecReload=/usr/bin/kill -HUP $MAINPID
+TimeoutSec=180
[Install]
WantedBy=multi-user.target
--- autofs-5.0.6.orig/samples/rc.autofs.in
+++ autofs-5.0.6/samples/rc.autofs.in
@@ -91,7 +91,7 @@ function stop() {
while [ -n "`pidof $prog`" -a $count -lt 15 ] ; do
killall -TERM $prog >& /dev/null
RETVAL=$?
- [ $RETVAL = 0 -a -z "`pidof $prog`" ] || sleep 3
+ [ $RETVAL = 0 -a -z "`pidof $prog`" ] || sleep 20
count=`expr $count + 1`
done
if [ -z "`pidof $prog`" ] ; then
@@ -104,6 +104,9 @@ function stop() {
function restart() {
stop
+ while [ -n "`pidof $prog`" ] ; do
+ sleep 5
+ done
start
}

View File

@ -0,0 +1,529 @@
autofs-5.0.6 - move timeout to map_source
From: Ian Kent <ikent@redhat.com>
Move the map entry timeout field from "struct autofs_point" to
"struct map_source".
The result of this change is that an individual timeout may be
set for each direct map master map entry.
---
CHANGELOG | 1 +
daemon/automount.c | 2 +-
daemon/direct.c | 32 +++++++++++++++++++++-----------
daemon/indirect.c | 7 +++----
daemon/lookup.c | 2 ++
daemon/state.c | 18 +++++++++++++++++-
include/automount.h | 5 +++--
include/master.h | 3 ++-
include/mounts.h | 2 +-
lib/master.c | 9 ++++-----
lib/master_parse.y | 32 +++++++++++++-------------------
lib/mounts.c | 37 ++++++++++++++++++-------------------
modules/mount_autofs.c | 5 +++--
13 files changed, 89 insertions(+), 66 deletions(-)
--- autofs-5.0.6.orig/CHANGELOG
+++ autofs-5.0.6/CHANGELOG
@@ -45,6 +45,7 @@
- report map not read when debug logging.
- duplicate parent options for included maps.
- update ->timeout() function to not return timeout.
+- move timeout to map_source (allow per direct map timeout).
28/06/2011 autofs-5.0.6
-----------------------
--- autofs-5.0.6.orig/daemon/automount.c
+++ autofs-5.0.6/daemon/automount.c
@@ -1585,7 +1585,7 @@ void *handle_mounts(void *arg)
/* We often start several automounters at the same time. Add some
randomness so we don't all expire at the same time. */
- if (!ap->submount && ap->exp_timeout)
+ if (!ap->submount && ap->exp_runfreq)
alarm_add(ap, ap->exp_runfreq + rand() % ap->exp_runfreq);
pthread_setcancelstate(cancel_state, NULL);
--- autofs-5.0.6.orig/daemon/direct.c
+++ autofs-5.0.6/daemon/direct.c
@@ -286,7 +286,7 @@ static int unlink_active_mounts(struct a
if (tree_get_mnt_list(mnts, &list, me->key, 1)) {
if (ap->state == ST_READMAP) {
- time_t tout = ap->exp_timeout;
+ time_t tout = me->source->exp_timeout;
int save_ioctlfd, ioctlfd;
save_ioctlfd = ioctlfd = me->ioctlfd;
@@ -321,18 +321,26 @@ static int unlink_active_mounts(struct a
return 1;
}
-int do_mount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me)
+int do_mount_autofs_direct(struct autofs_point *ap,
+ struct mnt_list *mnts, struct mapent *me,
+ time_t timeout)
{
const char *str_direct = mount_type_str(t_direct);
struct ioctl_ops *ops = get_ioctl_ops();
struct mnt_params *mp;
- time_t timeout = ap->exp_timeout;
struct stat st;
int status, ret, ioctlfd;
const char *map_name;
+ time_t runfreq;
- /* Calculate the timeouts */
- ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
+ if (timeout) {
+ /* Calculate the expire run frequency */
+ runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
+ if (ap->exp_runfreq)
+ ap->exp_runfreq = min(ap->exp_runfreq, runfreq);
+ else
+ ap->exp_runfreq = runfreq;
+ }
if (ops->version && !do_force_unlink) {
ap->flags |= MOUNT_FLAG_REMOUNT;
@@ -425,7 +433,7 @@ int do_mount_autofs_direct(struct autofs
}
ops->timeout(ap->logopt, ioctlfd, timeout);
- notify_mount_result(ap, me->key, str_direct);
+ notify_mount_result(ap, me->key, timeout, str_direct);
cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino);
ops->close(ap->logopt, ioctlfd);
@@ -473,6 +481,7 @@ int mount_autofs_direct(struct autofs_po
pthread_cleanup_push(cache_lock_cleanup, nc);
map = ap->entry->maps;
while (map) {
+ time_t timeout;
/*
* Only consider map sources that have been read since
* the map entry was last updated.
@@ -483,6 +492,7 @@ int mount_autofs_direct(struct autofs_po
}
mc = map->mc;
+ timeout = map->exp_timeout;
cache_readlock(mc);
pthread_cleanup_push(cache_lock_cleanup, mc);
me = cache_enumerate(mc, NULL);
@@ -491,7 +501,7 @@ int mount_autofs_direct(struct autofs_po
if (ne) {
if (map->master_line < ne->age) {
/* TODO: check return, locking me */
- do_mount_autofs_direct(ap, mnts, me);
+ do_mount_autofs_direct(ap, mnts, me, timeout);
}
me = cache_enumerate(mc, me);
continue;
@@ -508,7 +518,7 @@ int mount_autofs_direct(struct autofs_po
}
/* TODO: check return, locking me */
- do_mount_autofs_direct(ap, mnts, me);
+ do_mount_autofs_direct(ap, mnts, me, timeout);
me = cache_enumerate(mc, me);
}
@@ -639,7 +649,7 @@ int mount_autofs_offset(struct autofs_po
struct ioctl_ops *ops = get_ioctl_ops();
char buf[MAX_ERR_BUF];
struct mnt_params *mp;
- time_t timeout = ap->exp_timeout;
+ time_t timeout = me->source->exp_timeout;
struct stat st;
int ioctlfd, status, ret;
const char *hosts_map_name = "-hosts";
@@ -774,9 +784,9 @@ int mount_autofs_offset(struct autofs_po
ops->timeout(ap->logopt, ioctlfd, timeout);
cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino);
if (ap->logopt & LOGOPT_DEBUG)
- notify_mount_result(ap, mountpoint, str_offset);
+ notify_mount_result(ap, mountpoint, timeout, str_offset);
else
- notify_mount_result(ap, me->key, str_offset);
+ notify_mount_result(ap, me->key, timeout, str_offset);
ops->close(ap->logopt, ioctlfd);
debug(ap->logopt, "mounted trigger %s at %s", me->key, mountpoint);
--- autofs-5.0.6.orig/daemon/indirect.c
+++ autofs-5.0.6/daemon/indirect.c
@@ -87,7 +87,7 @@ static int do_mount_autofs_indirect(stru
{
const char *str_indirect = mount_type_str(t_indirect);
struct ioctl_ops *ops = get_ioctl_ops();
- time_t timeout = ap->exp_timeout;
+ time_t timeout = ap->entry->maps->exp_timeout;
char *options = NULL;
const char *hosts_map_name = "-hosts";
const char *map_name = hosts_map_name;
@@ -170,13 +170,12 @@ static int do_mount_autofs_indirect(stru
}
ap->dev = st.st_dev; /* Device number for mount point checks */
- ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
ops->timeout(ap->logopt, ap->ioctlfd, timeout);
if (ap->logopt & LOGOPT_DEBUG)
- notify_mount_result(ap, root, str_indirect);
+ notify_mount_result(ap, root, timeout, str_indirect);
else
- notify_mount_result(ap, ap->path, str_indirect);
+ notify_mount_result(ap, ap->path, timeout, str_indirect);
return 0;
--- autofs-5.0.6.orig/daemon/lookup.c
+++ autofs-5.0.6/daemon/lookup.c
@@ -413,6 +413,7 @@ static enum nsswitch_status read_map_sou
tmap.lookup = map->lookup;
tmap.mc = map->mc;
tmap.instance = map->instance;
+ tmap.exp_timeout = map->exp_timeout;
tmap.recurse = map->recurse;
tmap.depth = map->depth;
tmap.stale = map->stale;
@@ -770,6 +771,7 @@ static enum nsswitch_status lookup_map_n
tmap.format = map->format;
tmap.mc = map->mc;
tmap.instance = map->instance;
+ tmap.exp_timeout = map->exp_timeout;
tmap.recurse = map->recurse;
tmap.depth = map->depth;
tmap.argc = 0;
--- autofs-5.0.6.orig/daemon/state.c
+++ autofs-5.0.6/daemon/state.c
@@ -400,6 +400,9 @@ static void do_readmap_mount(struct auto
}
if (valid) {
struct mapent_cache *vmc = valid->mc;
+ struct ioctl_ops *ops = get_ioctl_ops();
+ time_t runfreq;
+
cache_unlock(vmc);
debug(ap->logopt,
"updating cache entry for valid direct trigger %s",
@@ -412,13 +415,22 @@ static void do_readmap_mount(struct auto
/* Set device and inode number of the new mapent */
cache_set_ino_index(vmc, me->key, me->dev, me->ino);
cache_unlock(vmc);
+ /* Set timeout and calculate the expire run frequency */
+ ops->timeout(ap->logopt, valid->ioctlfd, map->exp_timeout);
+ if (map->exp_timeout) {
+ runfreq = (map->exp_timeout + CHECK_RATIO - 1) / CHECK_RATIO;
+ if (ap->exp_runfreq)
+ ap->exp_runfreq = min(ap->exp_runfreq, runfreq);
+ else
+ ap->exp_runfreq = runfreq;
+ }
} else if (!tree_is_mounted(mnts, me->key, MNTS_REAL))
do_umount_autofs_direct(ap, mnts, me);
else
debug(ap->logopt,
"%s is mounted", me->key);
} else
- do_mount_autofs_direct(ap, mnts, me);
+ do_mount_autofs_direct(ap, mnts, me, map->exp_timeout);
return;
}
@@ -466,6 +478,10 @@ static void *do_readmap(void *arg)
pthread_cleanup_pop(1);
if (ap->type == LKP_INDIRECT) {
+ struct ioctl_ops *ops = get_ioctl_ops();
+ time_t timeout = ap->entry->maps->exp_timeout;
+ ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
+ ops->timeout(ap->logopt, ap->ioctlfd, timeout);
lookup_prune_cache(ap, now);
status = lookup_ghost(ap, ap->path);
} else {
--- autofs-5.0.6.orig/include/automount.h
+++ autofs-5.0.6/include/automount.h
@@ -114,6 +114,8 @@ int load_autofs4_module(void);
#define DB(x) do { } while(0)
#endif
+#define min(a, b) (a <= b ? a : b)
+
/* Forward declaraion */
struct autofs_point;
@@ -461,7 +463,6 @@ struct autofs_point {
dev_t dev; /* "Device" number assigned by kernel */
struct master_mapent *entry; /* Master map entry for this mount */
unsigned int type; /* Type of map direct or indirect */
- time_t exp_timeout; /* Timeout for expiring mounts */
time_t exp_runfreq; /* Frequency for polling for timeouts */
time_t negative_timeout; /* timeout in secs for failed mounts */
unsigned int flags; /* autofs mount flags */
@@ -495,7 +496,7 @@ void *expire_proc_indirect(void *);
void *expire_proc_direct(void *);
int expire_offsets_direct(struct autofs_point *ap, struct mapent *me, int now);
int mount_autofs_indirect(struct autofs_point *ap, const char *root);
-int do_mount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me);
+int do_mount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me, time_t timeout);
int mount_autofs_direct(struct autofs_point *ap);
int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char *root, const char *offset);
void submount_signal_parent(struct autofs_point *ap, unsigned int success);
--- autofs-5.0.6.orig/include/master.h
+++ autofs-5.0.6/include/master.h
@@ -23,6 +23,7 @@
struct map_source {
char *type;
char *format;
+ time_t exp_timeout; /* Timeout for expiring mounts */
time_t age;
unsigned int master_line;
struct mapent_cache *mc;
@@ -78,7 +79,7 @@ void master_mutex_unlock(void);
void master_mutex_lock_cleanup(void *);
void master_set_default_timeout(void);
void master_set_default_ghost_mode(void);
-int master_add_autofs_point(struct master_mapent *, time_t, unsigned, unsigned, unsigned, int);
+int master_add_autofs_point(struct master_mapent *, unsigned, unsigned, unsigned, int);
void master_free_autofs_point(struct autofs_point *);
struct map_source *
master_add_map_source(struct master_mapent *, char *, char *, time_t, int, const char **);
--- autofs-5.0.6.orig/include/mounts.h
+++ autofs-5.0.6/include/mounts.h
@@ -120,7 +120,7 @@ int tree_find_mnt_ents(struct mnt_list *
int tree_is_mounted(struct mnt_list *mnts, const char *path, unsigned int type);
void set_tsd_user_vars(unsigned int, uid_t, gid_t);
const char *mount_type_str(unsigned int);
-void notify_mount_result(struct autofs_point *, const char *, const char *);
+void notify_mount_result(struct autofs_point *, const char *, time_t, const char *);
int try_remount(struct autofs_point *, struct mapent *, unsigned int);
int umount_ent(struct autofs_point *, const char *);
int mount_multi_triggers(struct autofs_point *, struct mapent *, const char *, unsigned int, const char *);
--- autofs-5.0.6.orig/lib/master.c
+++ autofs-5.0.6/lib/master.c
@@ -65,9 +65,8 @@ void master_mutex_lock_cleanup(void *arg
return;
}
-int master_add_autofs_point(struct master_mapent *entry, time_t timeout,
- unsigned logopt, unsigned nobind, unsigned ghost,
- int submount)
+int master_add_autofs_point(struct master_mapent *entry, unsigned logopt,
+ unsigned nobind, unsigned ghost, int submount)
{
struct autofs_point *ap;
int status;
@@ -91,7 +90,6 @@ int master_add_autofs_point(struct maste
ap->entry = entry;
ap->exp_thread = 0;
ap->readmap_thread = 0;
- ap->exp_timeout = timeout;
/*
* Program command line option overrides config.
* We can't use 0 negative timeout so use default.
@@ -100,7 +98,7 @@ int master_add_autofs_point(struct maste
ap->negative_timeout = defaults_get_negative_timeout();
else
ap->negative_timeout = global_negative_timeout;
- ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
+ ap->exp_runfreq = 0;
ap->flags = 0;
if (ghost)
ap->flags = MOUNT_FLAG_GHOST;
@@ -437,6 +435,7 @@ master_add_source_instance(struct map_so
new->age = age;
new->master_line = 0;
new->mc = source->mc;
+ new->exp_timeout = source->exp_timeout;
new->stale = 1;
tmpargv = copy_argv(argc, argv);
--- autofs-5.0.6.orig/lib/master_parse.y
+++ autofs-5.0.6/lib/master_parse.y
@@ -765,9 +765,6 @@ int master_parse_entry(const char *buffe
logopt |= (verbose ? LOGOPT_VERBOSE : 0);
}
- if (timeout < 0)
- timeout = default_timeout;
-
new = NULL;
entry = master_find_mapent(master, path);
if (!entry) {
@@ -789,8 +786,19 @@ int master_parse_entry(const char *buffe
}
}
+ if (timeout < 0) {
+ /*
+ * If no timeout is given get the timout from first
+ * map (if it exists).
+ */
+ if (entry->maps)
+ timeout = entry->maps->exp_timeout;
+ else
+ timeout = default_timeout;
+ }
+
if (!entry->ap) {
- ret = master_add_autofs_point(entry, timeout, logopt, nobind, ghost, 0);
+ ret = master_add_autofs_point(entry, logopt, nobind, ghost, 0);
if (!ret) {
error(m_logopt, "failed to add autofs_point");
if (new)
@@ -798,20 +806,6 @@ int master_parse_entry(const char *buffe
local_free_vars();
return 0;
}
- } else {
- struct ioctl_ops *ops = get_ioctl_ops();
- struct autofs_point *ap = entry->ap;
-
- /*
- * Second and subsequent instances of a mount point
- * use the ghost, log and timeout of the first
- */
- if (entry->age < age) {
- ap->exp_timeout = timeout;
- ap->exp_runfreq = (ap->exp_timeout + CHECK_RATIO - 1) / CHECK_RATIO;
- if (ap->ioctlfd != -1 && ap->type == LKP_INDIRECT)
- ops->timeout(ap->logopt, ap->ioctlfd, timeout);
- }
}
if (random_selection)
entry->ap->flags |= MOUNT_FLAG_RANDOM_SELECT;
@@ -838,7 +832,7 @@ int master_parse_entry(const char *buffe
local_free_vars();
return 0;
}
-
+ source->exp_timeout = timeout;
source->master_line = lineno;
entry->age = age;
--- autofs-5.0.6.orig/lib/mounts.c
+++ autofs-5.0.6/lib/mounts.c
@@ -1268,13 +1268,12 @@ const char *mount_type_str(const unsigne
}
void notify_mount_result(struct autofs_point *ap,
- const char *path, const char *type)
+ const char *path, time_t timeout, const char *type)
{
- if (ap->exp_timeout)
+ if (timeout)
info(ap->logopt,
"mounted %s on %s with timeout %u, freq %u seconds",
- type, path,
- (unsigned int) ap->exp_timeout,
+ type, path, (unsigned int) timeout,
(unsigned int) ap->exp_runfreq);
else
info(ap->logopt,
@@ -1382,16 +1381,14 @@ static int do_remount_indirect(struct au
}
static int remount_active_mount(struct autofs_point *ap,
- struct mapent_cache *mc,
- const char *path, dev_t devid,
- const unsigned int type,
- int *ioctlfd)
+ struct mapent *me, const char *path, dev_t devid,
+ const unsigned int type, int *ioctlfd)
{
struct ioctl_ops *ops = get_ioctl_ops();
- time_t timeout = ap->exp_timeout;
const char *str_type = mount_type_str(type);
char buf[MAX_ERR_BUF];
unsigned int mounted;
+ time_t timeout;
struct stat st;
int fd;
@@ -1401,6 +1398,12 @@ static int remount_active_mount(struct a
ops->open(ap->logopt, &fd, devid, path);
if (fd == -1)
return REMOUNT_OPEN_FAIL;
+ else {
+ if (type == t_indirect || type == t_offset)
+ timeout = ap->entry->maps->exp_timeout;
+ else
+ timeout = me->source->exp_timeout;
+ }
/* Re-reading the map, set timeout and return */
if (ap->state == ST_READMAP) {
@@ -1434,11 +1437,11 @@ static int remount_active_mount(struct a
ops->close(ap->logopt, fd);
return REMOUNT_STAT_FAIL;
}
- if (mc)
- cache_set_ino_index(mc, path, st.st_dev, st.st_ino);
+ if (type != t_indirect)
+ cache_set_ino_index(me->mc, path, st.st_dev, st.st_ino);
else
ap->dev = st.st_dev;
- notify_mount_result(ap, path, str_type);
+ notify_mount_result(ap, path, timeout, str_type);
*ioctlfd = fd;
@@ -1481,24 +1484,20 @@ static int remount_active_mount(struct a
int try_remount(struct autofs_point *ap, struct mapent *me, unsigned int type)
{
struct ioctl_ops *ops = get_ioctl_ops();
- struct mapent_cache *mc;
const char *path;
int ret, fd;
dev_t devid;
- if (type == t_indirect) {
- mc = NULL;
+ if (type == t_indirect)
path = ap->path;
- } else {
- mc = me->mc;
+ else
path = me->key;
- }
ret = ops->mount_device(ap->logopt, path, type, &devid);
if (ret == -1 || ret == 0)
return -1;
- ret = remount_active_mount(ap, mc, path, devid, type, &fd);
+ ret = remount_active_mount(ap, me, path, devid, type, &fd);
/*
* The directory must exist since we found a device
--- autofs-5.0.6.orig/modules/mount_autofs.c
+++ autofs-5.0.6/modules/mount_autofs.c
@@ -51,7 +51,7 @@ int mount_mount(struct autofs_point *ap,
int argc, status;
int nobind = ap->flags & MOUNT_FLAG_NOBIND;
int ghost = ap->flags & MOUNT_FLAG_GHOST;
- time_t timeout = ap->exp_timeout;
+ time_t timeout = ap->entry->maps->exp_timeout;
unsigned logopt = ap->logopt;
struct map_type_info *info;
struct master *master;
@@ -149,7 +149,7 @@ int mount_mount(struct autofs_point *ap,
return 1;
}
- ret = master_add_autofs_point(entry, timeout, logopt, nobind, ghost, 1);
+ ret = master_add_autofs_point(entry, logopt, nobind, ghost, 1);
if (!ret) {
error(ap->logopt,
MODPREFIX "failed to add autofs_point to entry");
@@ -203,6 +203,7 @@ int mount_mount(struct autofs_point *ap,
return 1;
}
free_map_type_info(info);
+ source->exp_timeout = timeout;
mounts_mutex_lock(ap);

View File

@ -0,0 +1,248 @@
autofs-5.0.6 - refactor hosts lookup module
From: Ian Kent <ikent@redhat.com>
Simplify lookup hosts lookup_mount() function.
---
modules/lookup_hosts.c | 206 ++++++++++++++++++++++++-------------------------
1 file changed, 101 insertions(+), 105 deletions(-)
--- autofs-5.0.6.orig/modules/lookup_hosts.c
+++ autofs-5.0.6/modules/lookup_hosts.c
@@ -78,6 +78,94 @@ int lookup_read_master(struct master *ma
return NSS_STATUS_UNKNOWN;
}
+static char *get_exports(struct autofs_point *ap, const char *host)
+{
+ char *mapent = NULL;
+ exports exp;
+
+ debug(ap->logopt, MODPREFIX "fetchng export list for %s", name);
+
+ exp = rpc_get_exports(host, 10, 0, RPC_CLOSE_NOLINGER);
+
+ mapent = NULL;
+ while (exp) {
+ if (mapent) {
+ int len = strlen(mapent) + 1;
+
+ len += strlen(name) + 2*(strlen(exp->ex_dir) + 2) + 3;
+ mapent = realloc(mapent, len);
+ if (!mapent) {
+ char *estr;
+ estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ error(ap->logopt, MODPREFIX "malloc: %s", estr);
+ rpc_exports_free(exp);
+ return NSS_STATUS_UNAVAIL;
+ }
+ strcat(mapent, " \"");
+ strcat(mapent, exp->ex_dir);
+ strcat(mapent, "\"");
+ } else {
+ int len = 2*(strlen(exp->ex_dir) + 2) + strlen(name) + 3;
+
+ mapent = malloc(len);
+ if (!mapent) {
+ char *estr;
+ estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ error(ap->logopt, MODPREFIX "malloc: %s", estr);
+ rpc_exports_free(exp);
+ return NSS_STATUS_UNAVAIL;
+ }
+ strcpy(mapent, "\"");
+ strcat(mapent, exp->ex_dir);
+ strcat(mapent, "\"");
+ }
+ strcat(mapent, " \"");
+ strcat(mapent, name);
+ strcat(mapent, ":");
+ strcat(mapent, exp->ex_dir);
+ strcat(mapent, "\"");
+
+ exp = exp->ex_next;
+ }
+ rpc_exports_free(exp);
+
+ if (!mapent)
+ error(ap->logopt, "exports lookup failed for %s", name);
+
+ return mapent;
+}
+
+static int do_parse_mount(struct autofs_point *ap,
+ const char *name, int name_len, char *mapent,
+ void *context)
+{
+ int ret;
+
+ master_source_current_wait(ap->entry);
+ ap->entry->current = source;
+
+ ret = ctxt->parse->parse_mount(ap, name, name_len,
+ mapent, ctxt->parse->context);
+ if (ret) {
+ time_t now = time(NULL);
+ struct mapent_cache *mc = source->mc;
+ struct mapent *me;
+ int rv = CHE_OK;
+
+ cache_writelock(mc);
+ me = cache_lookup_distinct(mc, name);
+ if (!me)
+ rv = cache_update(mc, source, name, NULL, now);
+ if (rv != CHE_FAIL) {
+ me = cache_lookup_distinct(mc, name);
+ me->status = now + ap->negative_timeout;
+ }
+ cache_unlock(mc);
+ return NSS_STATUS_TRYAGAIN;
+ }
+ return NSS_STATUS_SUCCESS;
+}
+
int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
{
struct map_source *source;
@@ -209,126 +297,34 @@ int lookup_mount(struct autofs_point *ap
if (*name == '/') {
pthread_cleanup_push(cache_lock_cleanup, mc);
mapent_len = strlen(me->mapent);
- mapent = alloca(mapent_len + 1);
+ mapent = malloc(mapent_len + 1);
if (mapent)
strcpy(mapent, me->mapent);
pthread_cleanup_pop(0);
}
cache_unlock(mc);
- if (mapent) {
- master_source_current_wait(ap->entry);
- ap->entry->current = source;
-
- debug(ap->logopt, MODPREFIX "%s -> %s", name, me->mapent);
-
- ret = ctxt->parse->parse_mount(ap, name, name_len,
- mapent, ctxt->parse->context);
-
- if (ret) {
- time_t now = time(NULL);
- int rv = CHE_OK;
-
- cache_writelock(mc);
- me = cache_lookup_distinct(mc, name);
- if (!me)
- rv = cache_update(mc, source, name, NULL, now);
- if (rv != CHE_FAIL) {
- me = cache_lookup_distinct(mc, name);
- me->status = now + ap->negative_timeout;
- }
- cache_unlock(mc);
- return NSS_STATUS_TRYAGAIN;
- }
- return NSS_STATUS_SUCCESS;
- }
done:
- /*
- * Otherwise we need to get the exports list and add update
- * the cache.
- */
- debug(ap->logopt, MODPREFIX "fetchng export list for %s", name);
-
- exp = rpc_get_exports(name, 10, 0, RPC_CLOSE_NOLINGER);
-
- mapent = NULL;
- while (exp) {
- if (mapent) {
- int len = strlen(mapent) + 1;
-
- len += strlen(name) + 2*(strlen(exp->ex_dir) + 2) + 3;
- mapent = realloc(mapent, len);
- if (!mapent) {
- char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
- logerr(MODPREFIX "malloc: %s", estr);
- rpc_exports_free(exp);
- return NSS_STATUS_UNAVAIL;
- }
- strcat(mapent, " \"");
- strcat(mapent, exp->ex_dir);
- strcat(mapent, "\"");
- } else {
- int len = 2*(strlen(exp->ex_dir) + 2) + strlen(name) + 3;
-
- mapent = malloc(len);
- if (!mapent) {
- char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
- logerr(MODPREFIX "malloc: %s", estr);
- rpc_exports_free(exp);
- return NSS_STATUS_UNAVAIL;
- }
- strcpy(mapent, "\"");
- strcat(mapent, exp->ex_dir);
- strcat(mapent, "\"");
- }
- strcat(mapent, " \"");
- strcat(mapent, name);
- strcat(mapent, ":");
- strcat(mapent, exp->ex_dir);
- strcat(mapent, "\"");
-
- exp = exp->ex_next;
- }
- rpc_exports_free(exp);
-
- /* Exports lookup failed so we're outa here */
- if (!mapent) {
- error(ap->logopt, "exports lookup failed for %s", name);
- return NSS_STATUS_UNAVAIL;
- }
-
debug(ap->logopt, MODPREFIX "%s -> %s", name, mapent);
- cache_writelock(mc);
- cache_update(mc, source, name, mapent, now);
- cache_unlock(mc);
-
- master_source_current_wait(ap->entry);
- ap->entry->current = source;
-
- ret = ctxt->parse->parse_mount(ap, name, name_len,
- mapent, ctxt->parse->context);
- free(mapent);
+ if (!mapent) {
+ /* We need to get the exports list and update the cache. */
+ mapent = get_exports(ap, name);
- if (ret) {
- time_t now = time(NULL);
- int rv = CHE_OK;
+ /* Exports lookup failed so we're outa here */
+ if (!mapent)
+ return NSS_STATUS_UNAVAIL;
cache_writelock(mc);
- me = cache_lookup_distinct(mc, name);
- if (!me)
- rv = cache_update(mc, source, name, NULL, now);
- if (rv != CHE_FAIL) {
- me = cache_lookup_distinct(mc, name);
- me->status = now + ap->negative_timeout;
- }
+ cache_update(mc, source, name, mapent, now);
cache_unlock(mc);
- return NSS_STATUS_TRYAGAIN;
}
- return NSS_STATUS_SUCCESS;
+ ret = do_parse_mount(ap, name, name_len, mapent, ctxt->parse->context);
+
+ free(mapent);
+
+ return ret;
}
int lookup_done(void *context)

View File

@ -0,0 +1,47 @@
autofs-5.0.6 - remove cache update from parse_mount()
From: Ian Kent <ikent@redhat.com>
I'm not sure why I added this update in the parse sun module.
The lookup modules have the job of updating the map entry cache and
I can't see why an entry would be missing since the parse function
is called following the entry lookup (which does the update).
---
modules/parse_sun.c | 23 -----------------------
1 file changed, 23 deletions(-)
--- autofs-5.0.6.orig/modules/parse_sun.c
+++ autofs-5.0.6/modules/parse_sun.c
@@ -1383,29 +1383,6 @@ int parse_mount(struct autofs_point *ap,
strcat(m_root, name);
}
- /*
- * Can't take the write lock for direct mount entries here
- * but they should always be present in the map entry cache.
- */
- if (ap->type == LKP_INDIRECT) {
- cache_writelock(mc);
- me = cache_lookup_distinct(mc, name);
- if (!me) {
- int ret;
- /*
- * Not in the cache, perhaps it's a program map
- * or one that doesn't support enumeration.
- */
- ret = cache_add(mc, source, name, mapent, age);
- if (ret == CHE_FAIL) {
- cache_unlock(mc);
- free(options);
- return 1;
- }
- }
- cache_unlock(mc);
- }
-
cache_readlock(mc);
me = cache_lookup_distinct(mc, name);
if (me) {

View File

@ -0,0 +1,421 @@
autofs-5.0.6 - remove move mount code and configure option
From: Ian Kent <ikent@redhat.com>
The code to construct a multi-mount tree in a temporary location and then
move it into place is obsolete when using a kernel which includes the
vfs-automount infrastructure.
It is incompatible with systemd and cannot be used if systemd is being used.
So it's being removed.
---
autofs.spec | 2
configure | 18 ----
configure.in | 10 --
daemon/automount.c | 5 -
include/config.h.in | 3
modules/parse_sun.c | 195 +---------------------------------------------------
6 files changed, 7 insertions(+), 226 deletions(-)
--- autofs-5.0.6.orig/autofs.spec
+++ autofs-5.0.6/autofs.spec
@@ -74,7 +74,7 @@ echo %{version}-%{release} > .version
%endif
%build
-CFLAGS="$RPM_OPT_FLAGS -Wall" ./configure --libdir=%{_libdir} --disable-mount-locking --enable-ignore-busy --with-libtirpc --disable-mount-move %{?systemd_configure_arg:}
+CFLAGS="$RPM_OPT_FLAGS -Wall" ./configure --libdir=%{_libdir} --disable-mount-locking --enable-ignore-busy --with-libtirpc %{?systemd_configure_arg:}
CFLAGS="$RPM_OPT_FLAGS -Wall" make initdir=/etc/rc.d/init.d DONTSTRIP=1
%install
--- autofs-5.0.6.orig/configure
+++ autofs-5.0.6/configure
@@ -719,7 +719,6 @@ with_openldap
with_sasl
enable_ext_env
enable_mount_locking
-enable_mount_move
enable_forced_shutdown
enable_ignore_busy
'
@@ -1343,7 +1342,6 @@ Optional Features:
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--disable-ext-env disable search in environment for substitution variable
--disable-mount-locking disable use of locking when spawning mount command
- --disable-mount-move disable use of mount move when when preparing tree of mounts
--enable-force-shutdown enable USR1 signal to force unlink umount of any
busy mounts during shutdown
--enable-ignore-busy enable exit without umounting busy mounts during
@@ -5447,22 +5445,6 @@ $as_echo "#define ENABLE_MOUNT_LOCKING 1
fi
-#
-# Disable use of mount move
-#
-# Check whether --enable-mount-move was given.
-if test "${enable_mount_move+set}" = set; then :
- enableval=$enable_mount_move;
-else
- enableval=yes
-fi
-
-if test x$enable_mount_move = xyes -o x$enableval = xyes; then
-
-$as_echo "#define ENABLE_MOUNT_MOVE 1" >>confdefs.h
-
-fi
-
#
# Enable forced shutdown on USR1 signal (unlink umounts all mounts).
#
--- autofs-5.0.6.orig/configure.in
+++ autofs-5.0.6/configure.in
@@ -338,16 +338,6 @@ if test x$enable_mount_locking = xyes -o
fi
#
-# Disable use of mount move
-#
-AC_ARG_ENABLE(mount-move,
-[ --disable-mount-move disable use of mount move when when preparing tree of mounts],,
- enableval=yes)
-if test x$enable_mount_move = xyes -o x$enableval = xyes; then
- AC_DEFINE(ENABLE_MOUNT_MOVE, 1, [Disable use of mount move when preparing tree of mounts])
-fi
-
-#
# Enable forced shutdown on USR1 signal (unlink umounts all mounts).
#
AC_ARG_ENABLE(forced-shutdown,
--- autofs-5.0.6.orig/daemon/automount.c
+++ autofs-5.0.6/daemon/automount.c
@@ -1748,11 +1748,6 @@ static void show_build_info(void)
count = 22;
#endif
-#ifndef ENABLE_MOUNT_MOVE
- printf("DISABLE_MOUNT_MOVE ");
- count = count + 19;
-#endif
-
#ifdef ENABLE_FORCED_SHUTDOWN
printf("ENABLE_FORCED_SHUTDOWN ");
count = count + 23;
--- autofs-5.0.6.orig/include/config.h.in
+++ autofs-5.0.6/include/config.h.in
@@ -12,9 +12,6 @@
/* Disable use of locking when spawning mount command */
#undef ENABLE_MOUNT_LOCKING
-/* Disable use of mount move when preparing tree of mounts */
-#undef ENABLE_MOUNT_MOVE
-
/* define if you have E2FSCK */
#undef HAVE_E2FSCK
--- autofs-5.0.6.orig/modules/parse_sun.c
+++ autofs-5.0.6/modules/parse_sun.c
@@ -37,10 +37,6 @@
#define MODPREFIX "parse(sun): "
-#define MOUNT_MOVE_NONE 0x00
-#define MOUNT_MOVE_AUTOFS 0x01
-#define MOUNT_MOVE_OTHER 0x02
-
int parse_version = AUTOFS_PARSE_VERSION; /* Required by protocol */
static struct mount_mod *mount_nfs = NULL;
@@ -1047,86 +1043,6 @@ static int parse_mapent(const char *ent,
return (p - ent);
}
-#ifdef ENABLE_MOUNT_MOVE
-static int move_mount(struct autofs_point *ap,
- const char *mm_tmp_root, const char *mm_root,
- unsigned int move)
-{
- char buf[MAX_ERR_BUF];
- int err;
-
- if (move == MOUNT_MOVE_NONE)
- return 1;
-
- err = mkdir_path(mm_root, 0555);
- if (err < 0 && errno != EEXIST) {
- error(ap->logopt,
- "failed to create move target mount point %s", mm_root);
- return 0;
- }
-
- if (move == MOUNT_MOVE_AUTOFS)
- err = mount(mm_tmp_root, mm_root, NULL, MS_MOVE, NULL);
- else
- err = spawn_mount(ap->logopt,
- "--move", mm_tmp_root, mm_root, NULL);
- if (err) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- error(ap->logopt,
- "failed to move mount from %s to %s: %s",
- mm_tmp_root, mm_root, estr);
- return 0;
- }
-
- debug(ap->logopt,
- "moved mount tree from %s to %s", mm_tmp_root, mm_root);
-
- return 1;
-}
-#endif
-
-static void cleanup_multi_root(struct autofs_point *ap, const char *root,
- const char *path, unsigned int move)
-{
- if (move == MOUNT_MOVE_NONE)
- return;
-
- if (move == MOUNT_MOVE_OTHER)
- spawn_umount(ap->logopt, root, NULL);
- else {
- struct ioctl_ops *ops = get_ioctl_ops();
- struct autofs_point *submount;
-
- mounts_mutex_lock(ap);
- submount = __master_find_submount(ap, path);
- if (!submount) {
- mounts_mutex_unlock(ap);
- return;
- }
-
- alarm_delete(submount);
- st_remove_tasks(submount);
- st_wait_state(submount, ST_READY);
-
- submount->parent->submnt_count--;
- list_del_init(&submount->mounts);
-
- ops->catatonic(submount->logopt, submount->ioctlfd);
-
- mounts_mutex_unlock(ap);
-
- if (submount->thid) {
- pthread_cancel(submount->thid);
- close_mount_fds(submount);
- umount(root);
- destroy_logpri_fifo(submount);
- master_free_mapent_sources(submount->entry, 1);
- master_free_mapent(ap->entry);
- }
- }
- return;
-}
-
static void cleanup_multi_triggers(struct autofs_point *ap,
struct mapent *me, const char *root, int start,
const char *base)
@@ -1166,49 +1082,15 @@ static void cleanup_multi_triggers(struc
return;
}
-#ifdef ENABLE_MOUNT_MOVE
-static int check_fstype_autofs_option(const char *options)
-{
- char *tok, *tokbuf;
- int found;
-
- /*
- * Look for fstype= in options and return true if
- * the last occurrence is fstype=autofs.
- */
- found = 0;
- tokbuf = alloca(strlen(options) + 2);
- strcpy(tokbuf, options);
- tok = strtok_r(tokbuf, ",", &tokbuf);
- if (tok) {
- do {
- if (strstr(tok, "fstype=")) {
- if (strstr(tok, "autofs"))
- found = 1;
- else
- found = 0;
- }
- } while ((tok = strtok_r(NULL, ",", &tokbuf)));
- }
-
- return found;
-}
-#endif
-
static int mount_subtree(struct autofs_point *ap, struct mapent *me,
const char *name, char *loc, char *options, void *ctxt)
{
struct mapent *mm;
struct mapent *ro;
char *mm_root, *mm_base, *mm_key;
- const char *mnt_root, *target;
+ const char *mnt_root;
unsigned int mm_root_len, mnt_root_len;
int start, ret = 0, rv;
- unsigned int move = MOUNT_MOVE_NONE;
-#ifdef ENABLE_MOUNT_MOVE
- char t_dir[] = "/tmp/autoXXXXXX";
- char *mnt_tmp_root = NULL;
-#endif
rv = 0;
@@ -1227,26 +1109,12 @@ static int mount_subtree(struct autofs_p
}
mm_root_len = strlen(mm_root);
-#ifndef ENABLE_MOUNT_MOVE
mnt_root = mm_root;
mnt_root_len = mm_root_len;
-#else
- if (ap->flags & MOUNT_FLAG_REMOUNT) {
- mnt_root = mm_root;
- mnt_root_len = mm_root_len;
- } else {
- mnt_root = mkdtemp(t_dir);
- if (!mnt_root)
- return 1;
- mnt_root_len = strlen(mnt_root);
- mnt_tmp_root = (char *) mnt_root;
- }
-#endif
if (me == me->multi) {
/* name = NULL */
/* destination = mm_root */
- target = mm_root;
mm_base = "/";
/* Mount root offset if it exists */
@@ -1263,18 +1131,10 @@ static int mount_subtree(struct autofs_p
warn(ap->logopt,
MODPREFIX "failed to parse root offset");
cache_delete_offset_list(me->mc, name);
- goto error_out;
+ return 1;
}
ro_len = strlen(ro_loc);
-#ifdef ENABLE_MOUNT_MOVE
- if (!(ap->flags & MOUNT_FLAG_REMOUNT)) {
- move = MOUNT_MOVE_OTHER;
- if (check_fstype_autofs_option(myoptions))
- move = MOUNT_MOVE_AUTOFS;
- }
-#endif
-
tmp = alloca(mnt_root_len + 1);
strcpy(tmp, mnt_root);
tmp[mnt_root_len] = '/';
@@ -1293,44 +1153,25 @@ static int mount_subtree(struct autofs_p
error(ap->logopt, MODPREFIX
"failed to mount offset triggers");
cleanup_multi_triggers(ap, me, mnt_root, start, mm_base);
- cleanup_multi_root(ap, mnt_root, mm_root, move);
- goto error_out;
+ return 1;
}
} else if (rv <= 0) {
-#ifdef ENABLE_MOUNT_MOVE
- move = MOUNT_MOVE_NONE;
-#endif
ret = mount_multi_triggers(ap, me, mm_root, start, mm_base);
if (ret == -1) {
error(ap->logopt, MODPREFIX
"failed to mount offset triggers");
cleanup_multi_triggers(ap, me, mm_root, start, mm_base);
- goto error_out;
+ return 1;
}
}
} else {
int loclen = strlen(loc);
int namelen = strlen(name);
-#ifndef ENABLE_MOUNT_MOVE
- /*
- * When using move mount to mount offsets or direct mounts
- * the base of the tree can be the base of the temporary
- * mount point it needs to be the full path when not moving
- * the mount after construction.
- */
mnt_root = name;
-#else
- if (!(ap->flags & MOUNT_FLAG_REMOUNT)) {
- move = MOUNT_MOVE_OTHER;
- if (check_fstype_autofs_option(options))
- move = MOUNT_MOVE_AUTOFS;
- }
-#endif
/* name = mm_root + mm_base */
/* destination = mm_root + mm_base = name */
- target = name;
mm_base = &me->key[start];
rv = sun_mount(ap, mnt_root, name, namelen, loc, loclen, options, ctxt);
@@ -1340,16 +1181,11 @@ static int mount_subtree(struct autofs_p
error(ap->logopt, MODPREFIX
"failed to mount offset triggers");
cleanup_multi_triggers(ap, me, mnt_root, start, mm_base);
- cleanup_multi_root(ap, mnt_root, mm_root, move);
- goto error_out;
+ return 1;
}
} else if (rv < 0) {
char *mm_root_base = alloca(strlen(mm_root) + strlen(mm_base) + 1);
-#ifdef ENABLE_MOUNT_MOVE
- move = MOUNT_MOVE_NONE;
-#endif
-
strcpy(mm_root_base, mm_root);
strcat(mm_root_base, mm_base);
@@ -1358,22 +1194,11 @@ static int mount_subtree(struct autofs_p
error(ap->logopt, MODPREFIX
"failed to mount offset triggers");
cleanup_multi_triggers(ap, me, mm_root, start, mm_base);
- goto error_out;
+ return 1;
}
}
}
-#ifdef ENABLE_MOUNT_MOVE
- if (!move_mount(ap, mnt_root, target, move)) {
- cleanup_multi_triggers(ap, me, mnt_root, start, mm_base);
- cleanup_multi_root(ap, mnt_root, mm_root, move);
- goto error_out;
- }
-
- if (mnt_tmp_root)
- rmdir(mnt_tmp_root);
-#endif
-
/* Mount for base of tree failed */
if (rv > 0)
return rv;
@@ -1386,14 +1211,6 @@ static int mount_subtree(struct autofs_p
rv = 0;
return rv;
-
-error_out:
-#ifdef ENABLE_MOUNT_MOVE
- if (mnt_tmp_root)
- rmdir(mnt_tmp_root);
-#endif
-
- return 1;
}
/*

View File

@ -0,0 +1,99 @@
autofs-5.0.6 - report map not read when debug logging
From: Ian Kent <ikent@redhat.com>
When a map read is called automount will report that is is reading the
map when debug logging is set. If a map read is not actually needed the
lookup module read map function should also report that it didn't need
to read the map.
---
CHANGELOG | 1 +
modules/lookup_hosts.c | 4 +++-
modules/lookup_ldap.c | 4 +++-
modules/lookup_nisplus.c | 4 +++-
modules/lookup_sss.c | 4 +++-
modules/lookup_yp.c | 4 +++-
6 files changed, 16 insertions(+), 5 deletions(-)
--- autofs-5.0.6.orig/CHANGELOG
+++ autofs-5.0.6/CHANGELOG
@@ -42,6 +42,7 @@
- fix configure string length tests for sss library.
- fix initialization in rpc create_client().
- fix libtirpc name clash.
+- report map not read when debug logging.
28/06/2011 autofs-5.0.6
-----------------------
--- autofs-5.0.6.orig/modules/lookup_hosts.c
+++ autofs-5.0.6/modules/lookup_hosts.c
@@ -94,8 +94,10 @@ int lookup_read_map(struct autofs_point
* reading the map. We always need to read the whole map for
* direct mounts in order to mount the triggers.
*/
- if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT)
+ if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT) {
+ debug(ap->logopt, "map read not needed, so not done");
return NSS_STATUS_SUCCESS;
+ }
mc = source->mc;
--- autofs-5.0.6.orig/modules/lookup_ldap.c
+++ autofs-5.0.6/modules/lookup_ldap.c
@@ -2326,8 +2326,10 @@ static int read_one_map(struct autofs_po
* reading the map. We always need to read the whole map for
* direct mounts in order to mount the triggers.
*/
- if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT)
+ if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT) {
+ debug(ap->logopt, "map read not needed, so not done");
return NSS_STATUS_SUCCESS;
+ }
sp.ap = ap;
sp.age = age;
--- autofs-5.0.6.orig/modules/lookup_nisplus.c
+++ autofs-5.0.6/modules/lookup_nisplus.c
@@ -185,8 +185,10 @@ int lookup_read_map(struct autofs_point
* reading the map. We always need to read the whole map for
* direct mounts in order to mount the triggers.
*/
- if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT)
+ if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT) {
+ debug(ap->logopt, "map read not needed, so not done");
return NSS_STATUS_SUCCESS;
+ }
mc = source->mc;
--- autofs-5.0.6.orig/modules/lookup_sss.c
+++ autofs-5.0.6/modules/lookup_sss.c
@@ -275,8 +275,10 @@ int lookup_read_map(struct autofs_point
* reading the map. We always need to read the whole map for
* direct mounts in order to mount the triggers.
*/
- if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT)
+ if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT) {
+ debug(ap->logopt, "map read not needed, so not done");
return NSS_STATUS_SUCCESS;
+ }
if (!setautomntent(ap->logopt, ctxt, ctxt->mapname, &sss_ctxt))
return NSS_STATUS_UNAVAIL;
--- autofs-5.0.6.orig/modules/lookup_yp.c
+++ autofs-5.0.6/modules/lookup_yp.c
@@ -327,8 +327,10 @@ int lookup_read_map(struct autofs_point
* reading the map. We always need to read the whole map for
* direct mounts in order to mount the triggers.
*/
- if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT)
+ if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT) {
+ debug(ap->logopt, "map read not needed, so not done");
return NSS_STATUS_SUCCESS;
+ }
ypcb_data.ap = ap;
ypcb_data.source = source;

View File

@ -0,0 +1,171 @@
autofs-5.0.6 - update ->timeout() function to not return timeout
From: Ian Kent <ikent@redhat.com>
The value returned by the ->timeout() autofs control interface
function is not used so make that usage explict by not using a
pass by address parameter. This saves having to take care to
always use a temporary storage location when using the function.
---
CHANGELOG | 1 +
daemon/direct.c | 6 +++---
daemon/indirect.c | 2 +-
include/dev-ioctl-lib.h | 2 +-
lib/dev-ioctl-lib.c | 15 +++++++--------
lib/master_parse.y | 3 +--
lib/mounts.c | 4 ++--
7 files changed, 16 insertions(+), 17 deletions(-)
--- autofs-5.0.6.orig/CHANGELOG
+++ autofs-5.0.6/CHANGELOG
@@ -44,6 +44,7 @@
- fix libtirpc name clash.
- report map not read when debug logging.
- duplicate parent options for included maps.
+- update ->timeout() function to not return timeout.
28/06/2011 autofs-5.0.6
-----------------------
--- autofs-5.0.6.orig/daemon/direct.c
+++ autofs-5.0.6/daemon/direct.c
@@ -302,7 +302,7 @@ static int unlink_active_mounts(struct a
return 0;
}
- ops->timeout(ap->logopt, ioctlfd, &tout);
+ ops->timeout(ap->logopt, ioctlfd, tout);
if (save_ioctlfd == -1)
ops->close(ap->logopt, ioctlfd);
@@ -424,7 +424,7 @@ int do_mount_autofs_direct(struct autofs
goto out_umount;
}
- ops->timeout(ap->logopt, ioctlfd, &timeout);
+ ops->timeout(ap->logopt, ioctlfd, timeout);
notify_mount_result(ap, me->key, str_direct);
cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino);
ops->close(ap->logopt, ioctlfd);
@@ -771,7 +771,7 @@ int mount_autofs_offset(struct autofs_po
goto out_umount;
}
- ops->timeout(ap->logopt, ioctlfd, &timeout);
+ ops->timeout(ap->logopt, ioctlfd, timeout);
cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino);
if (ap->logopt & LOGOPT_DEBUG)
notify_mount_result(ap, mountpoint, str_offset);
--- autofs-5.0.6.orig/daemon/indirect.c
+++ autofs-5.0.6/daemon/indirect.c
@@ -172,7 +172,7 @@ static int do_mount_autofs_indirect(stru
ap->dev = st.st_dev; /* Device number for mount point checks */
ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
- ops->timeout(ap->logopt, ap->ioctlfd, &timeout);
+ ops->timeout(ap->logopt, ap->ioctlfd, timeout);
if (ap->logopt & LOGOPT_DEBUG)
notify_mount_result(ap, root, str_indirect);
else
--- autofs-5.0.6.orig/include/dev-ioctl-lib.h
+++ autofs-5.0.6/include/dev-ioctl-lib.h
@@ -45,7 +45,7 @@ struct ioctl_ops {
int (*send_fail)(unsigned int, int, unsigned int, int);
int (*setpipefd)(unsigned int, int, int);
int (*catatonic)(unsigned int, int);
- int (*timeout)(unsigned int, int, time_t *);
+ int (*timeout)(unsigned int, int, time_t);
int (*requestor)(unsigned int, int, const char *, uid_t *, gid_t *);
int (*expire)(unsigned int, int, const char *, unsigned int);
int (*askumount)(unsigned int, int, unsigned int *);
--- autofs-5.0.6.orig/lib/dev-ioctl-lib.c
+++ autofs-5.0.6/lib/dev-ioctl-lib.c
@@ -55,7 +55,7 @@ static int dev_ioctl_send_ready(unsigned
static int dev_ioctl_send_fail(unsigned int, int, unsigned int, int);
static int dev_ioctl_setpipefd(unsigned int, int, int);
static int dev_ioctl_catatonic(unsigned int, int);
-static int dev_ioctl_timeout(unsigned int, int, time_t *);
+static int dev_ioctl_timeout(unsigned int, int, time_t);
static int dev_ioctl_requestor(unsigned int, int, const char *, uid_t *, gid_t *);
static int dev_ioctl_expire(unsigned int, int, const char *, unsigned int);
static int dev_ioctl_askumount(unsigned int, int, unsigned int *);
@@ -69,7 +69,7 @@ static int ioctl_close(unsigned int, int
static int ioctl_send_ready(unsigned int, int, unsigned int);
static int ioctl_send_fail(unsigned int, int, unsigned int, int);
static int ioctl_catatonic(unsigned int, int);
-static int ioctl_timeout(unsigned int, int, time_t *);
+static int ioctl_timeout(unsigned int, int, time_t);
static int ioctl_expire(unsigned int, int, const char *, unsigned int);
static int ioctl_askumount(unsigned int, int, unsigned int *);
@@ -577,25 +577,24 @@ static int ioctl_catatonic(unsigned int
}
/* Set the autofs mount timeout */
-static int dev_ioctl_timeout(unsigned int logopt, int ioctlfd, time_t *timeout)
+static int dev_ioctl_timeout(unsigned int logopt, int ioctlfd, time_t timeout)
{
struct autofs_dev_ioctl param;
init_autofs_dev_ioctl(&param);
param.ioctlfd = ioctlfd;
- param.timeout.timeout = *timeout;
+ param.timeout.timeout = timeout;
if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_TIMEOUT, &param) == -1)
return -1;
- *timeout = param.timeout.timeout;
-
return 0;
}
-static int ioctl_timeout(unsigned int logopt, int ioctlfd, time_t *timeout)
+static int ioctl_timeout(unsigned int logopt, int ioctlfd, time_t timeout)
{
- return ioctl(ioctlfd, AUTOFS_IOC_SETTIMEOUT, timeout);
+ time_t tout = timeout;
+ return ioctl(ioctlfd, AUTOFS_IOC_SETTIMEOUT, &tout);
}
/*
--- autofs-5.0.6.orig/lib/master_parse.y
+++ autofs-5.0.6/lib/master_parse.y
@@ -801,7 +801,6 @@ int master_parse_entry(const char *buffe
} else {
struct ioctl_ops *ops = get_ioctl_ops();
struct autofs_point *ap = entry->ap;
- time_t tout = timeout;
/*
* Second and subsequent instances of a mount point
@@ -811,7 +810,7 @@ int master_parse_entry(const char *buffe
ap->exp_timeout = timeout;
ap->exp_runfreq = (ap->exp_timeout + CHECK_RATIO - 1) / CHECK_RATIO;
if (ap->ioctlfd != -1 && ap->type == LKP_INDIRECT)
- ops->timeout(ap->logopt, ap->ioctlfd, &tout);
+ ops->timeout(ap->logopt, ap->ioctlfd, timeout);
}
}
if (random_selection)
--- autofs-5.0.6.orig/lib/mounts.c
+++ autofs-5.0.6/lib/mounts.c
@@ -1404,7 +1404,7 @@ static int remount_active_mount(struct a
/* Re-reading the map, set timeout and return */
if (ap->state == ST_READMAP) {
- ops->timeout(ap->logopt, fd, &timeout);
+ ops->timeout(ap->logopt, fd, timeout);
ops->close(ap->logopt, fd);
return REMOUNT_READ_MAP;
}
@@ -1426,7 +1426,7 @@ static int remount_active_mount(struct a
ops->close(ap->logopt, fd);
return REMOUNT_OPEN_FAIL;
}
- ops->timeout(ap->logopt, fd, &timeout);
+ ops->timeout(ap->logopt, fd, timeout);
if (fstat(fd, &st) == -1) {
error(ap->logopt,
"failed to stat %s mount %s", str_type, path);