- update source to latest upstream version.

- this is essentially a consolidation of the patches already in this rpm.
- add dist tag to match latest RHEL-5 package tag format.
- also, remove now unused patches.
This commit is contained in:
Ian Kent 2009-09-04 05:02:47 +00:00
parent 76de435cdf
commit 4c774a60be
65 changed files with 0 additions and 20281 deletions

View File

@ -1,69 +0,0 @@
autofs-5.0.4 - add lsb init script parameter block
From: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
redhat/autofs.init.in | 11 ++++++++++-
samples/rc.autofs.in | 11 ++++++++++-
3 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 4df6a60..aab3209 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -30,6 +30,7 @@
- fix return start status on fail.
- fix double free in expire_proc().
- another easy alloca replacements fix.
+- add LSB init script parameter block.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/redhat/autofs.init.in b/redhat/autofs.init.in
index 471667e..0fd1777 100644
--- a/redhat/autofs.init.in
+++ b/redhat/autofs.init.in
@@ -6,7 +6,16 @@
# processname: /usr/sbin/automount
# config: /etc/auto.master
# description: Automounts filesystems on demand
-
+#
+### BEGIN INIT INFO
+# Provides: $autofs
+# Should-Start: $network $ypbind
+# Should-Stop: $network $ypbind
+# Default-Start: 3 4 5
+# Default-Stop: 0 1 2 6
+# Short-Description: Automounts filesystems on demand
+# Description: Automounts filesystems on demand
+### END INIT INFO
#
# Location of the automount daemon and the init directory
#
diff --git a/samples/rc.autofs.in b/samples/rc.autofs.in
index 2877fe2..63a0c5d 100644
--- a/samples/rc.autofs.in
+++ b/samples/rc.autofs.in
@@ -5,7 +5,16 @@
# On most distributions, this file should be called:
# /etc/rc.d/init.d/autofs or /etc/init.d/autofs or /etc/rc.d/rc.autofs
#
-
+#
+### BEGIN INIT INFO
+# Provides: $autofs
+# Should-Start: $network $ypbind
+# Should-Stop: $network $ypbind
+# Default-Start: 3 4 5
+# Default-Stop: 0 1 2 6
+# Short-Description: Automounts filesystems on demand
+# Description: Automounts filesystems on demand
+### END INIT INFO
#
# Location of the automount daemon and the init directory
#

View File

@ -1,181 +0,0 @@
autofs-5.0.4 - add nfs mount protocol default configuration option
From: Ian Kent <raven@themaw.net>
Add configuration option MOUNT_NFS_DEFAULT_PROTOCOL with default of 3.
Since the default mount protocol used by mount.nfs(8) will change to
NFS version 4 at some point, and because we can't identify the default
automatically, we need to be able to set it in our configuration.
This will only make a difference for replicated map entries as
availability probing isn't used for single host map entries.
---
CHANGELOG | 1 +
include/defaults.h | 2 ++
lib/defaults.c | 15 ++++++++++++++-
man/auto.master.5.in | 6 ++++++
modules/mount_nfs.c | 8 +++++---
redhat/autofs.sysconfig.in | 10 ++++++++++
samples/autofs.conf.default.in | 10 ++++++++++
7 files changed, 48 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index ad74b7d..0ce2a56 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -25,6 +25,7 @@
- add check for alternate libtirpc library for libtirpc tsd workaround.
- cleanup configure defines for libtirpc.
- add WITH_LIBTIRPC to -V status report.
+- add nfs mount protocol default configuration option.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/include/defaults.h b/include/defaults.h
index 9a2430f..9bf16e5 100644
--- a/include/defaults.h
+++ b/include/defaults.h
@@ -37,6 +37,7 @@
#define DEFAULT_ENTRY_ATTR "cn"
#define DEFAULT_VALUE_ATTR "nisMapEntry"
+#define DEFAULT_NFS_MOUNT_PROTOCOL 3
#define DEFAULT_APPEND_OPTIONS 1
#define DEFAULT_AUTH_CONF_FILE AUTOFS_MAP_DIR "/autofs_ldap_auth.conf"
@@ -61,6 +62,7 @@ struct ldap_schema *defaults_get_default_schema(void);
struct ldap_schema *defaults_get_schema(void);
struct ldap_searchdn *defaults_get_searchdns(void);
void defaults_free_searchdns(struct ldap_searchdn *);
+unsigned int defaults_get_mount_nfs_default_proto(void);
unsigned int defaults_get_append_options(void);
unsigned int defaults_get_umount_wait(void);
const char *defaults_get_auth_conf_file(void);
diff --git a/lib/defaults.c b/lib/defaults.c
index e507a59..17164bd 100644
--- a/lib/defaults.c
+++ b/lib/defaults.c
@@ -45,6 +45,7 @@
#define ENV_NAME_ENTRY_ATTR "ENTRY_ATTRIBUTE"
#define ENV_NAME_VALUE_ATTR "VALUE_ATTRIBUTE"
+#define ENV_MOUNT_NFS_DEFAULT_PROTOCOL "MOUNT_NFS_DEFAULT_PROTOCOL"
#define ENV_APPEND_OPTIONS "APPEND_OPTIONS"
#define ENV_UMOUNT_WAIT "UMOUNT_WAIT"
#define ENV_AUTH_CONF_FILE "AUTH_CONF_FILE"
@@ -326,7 +327,8 @@ unsigned int defaults_read_config(unsigned int to_syslog)
check_set_config_value(key, ENV_APPEND_OPTIONS, value, to_syslog) ||
check_set_config_value(key, ENV_UMOUNT_WAIT, value, to_syslog) ||
check_set_config_value(key, ENV_AUTH_CONF_FILE, value, to_syslog) ||
- check_set_config_value(key, ENV_MAP_HASH_TABLE_SIZE, value, to_syslog))
+ check_set_config_value(key, ENV_MAP_HASH_TABLE_SIZE, value, to_syslog) ||
+ check_set_config_value(key, ENV_MOUNT_NFS_DEFAULT_PROTOCOL, value, to_syslog))
;
}
@@ -643,6 +645,17 @@ struct ldap_schema *defaults_get_schema(void)
return schema;
}
+unsigned int defaults_get_mount_nfs_default_proto(void)
+{
+ long proto;
+
+ proto = get_env_number(ENV_MOUNT_NFS_DEFAULT_PROTOCOL);
+ if (proto < 2 || proto > 4)
+ proto = DEFAULT_NFS_MOUNT_PROTOCOL;
+
+ return (unsigned int) proto;
+}
+
unsigned int defaults_get_append_options(void)
{
int res;
diff --git a/man/auto.master.5.in b/man/auto.master.5.in
index 9cc5f02..aaa6324 100644
--- a/man/auto.master.5.in
+++ b/man/auto.master.5.in
@@ -183,6 +183,12 @@ but it is the best we can do.
.B BROWSE_MODE
Maps are browsable by default (program default "yes").
.TP
+.B MOUNT_NFS_DEFAULT_PROTOCOL
+Specify the default protocol used by mount.nfs(8) (program default 3). Since
+we can't identify this default automatically we need to set it in the autofs
+configuration. This option will only make a difference for replicated map
+entries as availability probing isn't used for single host map entries.
+.TP
.B APPEND_OPTIONS
Determine whether global options, given on the command line or per mount
in the master map, are appended to map entry options or if the map entry
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
index 4f3f514..14d3850 100644
--- a/modules/mount_nfs.c
+++ b/modules/mount_nfs.c
@@ -61,7 +61,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
char fullpath[PATH_MAX];
char buf[MAX_ERR_BUF];
struct host *this, *hosts = NULL;
- unsigned int vers;
+ unsigned int mount_default_proto, vers;
char *nfsoptions = NULL;
unsigned int random_selection = ap->flags & MOUNT_FLAG_RANDOM_SELECT;
int len, status, err, existed = 1;
@@ -130,10 +130,12 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
nfsoptions, nosymlink, ro);
}
+ mount_default_proto = defaults_get_mount_nfs_default_proto();
+ vers = NFS_VERS_MASK | NFS_PROTO_MASK;
if (strcmp(fstype, "nfs4") == 0)
vers = NFS4_VERS_MASK | TCP_SUPPORTED;
- else
- vers = NFS_VERS_MASK | NFS_PROTO_MASK;
+ else if (mount_default_proto == 4)
+ vers = vers | NFS4_VERS_MASK;
if (!parse_location(ap->logopt, &hosts, what)) {
info(ap->logopt, MODPREFIX "no hosts available");
diff --git a/redhat/autofs.sysconfig.in b/redhat/autofs.sysconfig.in
index fe36f45..04e521c 100644
--- a/redhat/autofs.sysconfig.in
+++ b/redhat/autofs.sysconfig.in
@@ -22,6 +22,16 @@ TIMEOUT=300
#
BROWSE_MODE="no"
#
+# MOUNT_NFS_DEFAULT_PROTOCOL - specify the default protocol used by
+# mount.nfs(8). Since we can't identify
+# the default automatically we need to
+# set it in our configuration. This will
+# only make a difference for replicated
+# map entries as availability probing isn't
+# used for single host map entries.
+#
+#MOUNT_NFS_DEFAULT_PROTOCOL=3
+#
# APPEND_OPTIONS - append to global options instead of replace.
#
#APPEND_OPTIONS="yes"
diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in
index 4496738..52d18ec 100644
--- a/samples/autofs.conf.default.in
+++ b/samples/autofs.conf.default.in
@@ -22,6 +22,16 @@ TIMEOUT=300
#
BROWSE_MODE="no"
#
+# MOUNT_NFS_DEFAULT_PROTOCOL - specify the default protocol used by
+# mount.nfs(8). Since we can't identify
+# the default automatically we need to
+# set it in our configuration. This will
+# only make a difference for replicated
+# map entries as availability probing isn't
+# used for single host map entries.
+#
+#MOUNT_NFS_DEFAULT_PROTOCOL=3
+#
# APPEND_OPTIONS - append to global options instead of replace.
#
#APPEND_OPTIONS="yes"

View File

@ -1,83 +0,0 @@
autofs-5.0.4 - allow the automount daemon to dump core
From: Jeff Moyer <jmoyer@redhat.com>
Right now, the automount daemon blocks all signals. We should at least
unblock those that will cause us to dump core. Otherwise, I think the
behaviour could be, umm, interesting.
I tested this by sending SIGBUS and SIGSEGV to the automount daemon.
edit - raven
- I changed this a little so that the change to the signals is
done in one place and added SIGABRT and SIGTRAP to the list
of signals that aren't blocked.
Signed-off-by: Jeff Moyer <jmoyer@redhat.com>
---
CHANGELOG | 1 +
daemon/automount.c | 16 ++++++++++++----
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 7f27f5e..4b85649 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -57,6 +57,7 @@
- mannual umount recovery fixes.
- fix map type info parse error.
- fix an RPC fd leak.
+- don't block signals we expect to dump core.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/daemon/automount.c b/daemon/automount.c
index 44dcdd6..e7f801b 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -64,6 +64,8 @@ static int st_stat = 1;
static int *pst_stat = &st_stat;
static pthread_t state_mach_thid;
+static sigset_t block_sigs;
+
/* Pre-calculated kernel packet length */
static size_t kpkt_len;
@@ -1321,7 +1323,7 @@ static void *statemachine(void *arg)
sigset_t signalset;
int sig;
- sigfillset(&signalset);
+ memcpy(&signalset, &block_sigs, sizeof(signalset));
sigdelset(&signalset, SIGCHLD);
sigdelset(&signalset, SIGCONT);
@@ -1817,7 +1819,6 @@ int main(int argc, char *argv[])
unsigned foreground, have_global_options;
time_t timeout;
time_t age = time(NULL);
- sigset_t allsigs;
struct rlimit rlim;
static const struct option long_options[] = {
{"help", 0, 0, 'h'},
@@ -1837,8 +1838,15 @@ int main(int argc, char *argv[])
{0, 0, 0, 0}
};
- sigfillset(&allsigs);
- sigprocmask(SIG_BLOCK, &allsigs, NULL);
+ sigfillset(&block_sigs);
+ /* allow for the dropping of core files */
+ sigdelset(&block_sigs, SIGABRT);
+ sigdelset(&block_sigs, SIGBUS);
+ sigdelset(&block_sigs, SIGSEGV);
+ sigdelset(&block_sigs, SIGILL);
+ sigdelset(&block_sigs, SIGFPE);
+ sigdelset(&block_sigs, SIGTRAP);
+ sigprocmask(SIG_BLOCK, &block_sigs, NULL);
program = argv[0];

View File

@ -1,61 +0,0 @@
autofs-5.0.4 - always read file maps fix
From: Ian Kent <raven@themaw.net>
If map instances are present for a map source then either we have
plus included entries or we are looking through a list of nsswitch
sources. In either case we cannot avoid reading through the map
because we must preserve the key lookup order over multiple sources.
But also, we can't know if a source instance has been changed since
the last time we checked it until we preform a lookup against it.
So, in this case a lookup within the internal cache cannot be relied
upon to find the key we're looking for. At least, when we get to the
file source instance itself, the lookup for the key will be done from
the cache.
---
CHANGELOG | 1 +
modules/lookup_file.c | 17 ++++++++++++++---
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index aab3209..da7ecbf 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -31,6 +31,7 @@
- fix double free in expire_proc().
- another easy alloca replacements fix.
- add LSB init script parameter block.
+- fix file map lookup when reading included or nsswitch sources.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index ec78090..bd30bc5 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -998,9 +998,20 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
cache_readlock(mc);
me = cache_lookup_first(mc);
- if (me && st.st_mtime <= me->age)
- goto do_cache_lookup;
- else
+ if (me && st.st_mtime <= me->age) {
+ /*
+ * If any map instances are present for this source
+ * then either we have plus included entries or we
+ * are looking through the list of nsswitch sources.
+ * In either case we cannot avoid reading through the
+ * map because we must preserve the key order over
+ * multiple sources. But also, we can't know, at this
+ * point, if a source instance has been changed since
+ * the last time we checked it.
+ */
+ if (!source->instance)
+ goto do_cache_lookup;
+ } else
source->stale = 1;
me = cache_lookup_distinct(mc, key);

View File

@ -1,65 +0,0 @@
autofs-5.0.4 - always read file maps key lookup fixes
From: Ian Kent <raven@themaw.net>
Since we always read file maps at start we need to ensure that
we return a not found if the key isn't found in the cache. Also,
if we're looking through a "multi" map we can't use the cache
lookup optimisation because, in this case, there is a single map
source shared by the "multi" maps so we may not get correct results
from the lookup if a map later in the search has been modified.
---
CHANGELOG | 1 +
modules/lookup_file.c | 17 +++++++++++------
2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 972ef63..5000f0c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -48,6 +48,7 @@
- improve manual umount recovery.
- dont fail on ipv6 address when adding host.
- always read file maps multi map fix.
+- always read file maps key lookup fixes.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index bd30bc5..a4ca39d 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -1003,13 +1003,15 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
* If any map instances are present for this source
* then either we have plus included entries or we
* are looking through the list of nsswitch sources.
- * In either case we cannot avoid reading through the
- * map because we must preserve the key order over
- * multiple sources. But also, we can't know, at this
- * point, if a source instance has been changed since
- * the last time we checked it.
+ * In either case, or if it's a "multi" source, we
+ * cannot avoid reading through the map because we
+ * must preserve the key order over multiple sources
+ * or maps. But also, we can't know, at this point,
+ * if a source instance has been changed since the
+ * last time we checked it.
*/
- if (!source->instance)
+ if (!source->instance &&
+ source->type && strcmp(source->type, "multi"))
goto do_cache_lookup;
} else
source->stale = 1;
@@ -1055,6 +1057,9 @@ do_cache_lookup:
}
cache_unlock(mc);
+ if (!me)
+ return NSS_STATUS_NOTFOUND;
+
if (!mapent)
return NSS_STATUS_TRYAGAIN;

View File

@ -1,132 +0,0 @@
autofs-5.0.4 - always read file maps multi map fix
From: Ian Kent <raven@themaw.net>
Since "multi" map entries may contain file maps themselves and we
always want to read file maps we need to move the chack of whether
to read the map from lookup_nss_read_map() into the individual
map type lookup modules.
---
CHANGELOG | 1 +
daemon/lookup.c | 14 --------------
modules/lookup_hosts.c | 8 ++++++++
modules/lookup_ldap.c | 8 ++++++++
modules/lookup_nisplus.c | 8 ++++++++
modules/lookup_yp.c | 8 ++++++++
6 files changed, 33 insertions(+), 14 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 7e1012f..972ef63 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -47,6 +47,7 @@
- fix incorrect shutdown introduced by library relaod fixes.
- improve manual umount recovery.
- dont fail on ipv6 address when adding host.
+- always read file maps multi map fix.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/daemon/lookup.c b/daemon/lookup.c
index bc94655..9d5a5c8 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -278,20 +278,6 @@ static int do_read_map(struct autofs_point *ap, struct map_source *map, time_t a
map->lookup = lookup;
master_source_unlock(ap->entry);
- /* If we don't need to create directories then there's no use
- * reading the map. We just need to test that the map is valid
- * for the fail cases to function correctly and to cache the
- * lookup handle.
- *
- * We always need to read the whole map for direct mounts in
- * order to mount the triggers. We also want to read the whole
- * map if it's a file map to avoid potentially lengthy linear
- * file scanning.
- */
- if (strcmp(map->type, "file") &&
- !(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT)
- return NSS_STATUS_SUCCESS;
-
if (!map->stale)
return NSS_STATUS_SUCCESS;
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
index d3ae0e2..a213780 100644
--- a/modules/lookup_hosts.c
+++ b/modules/lookup_hosts.c
@@ -89,6 +89,14 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
ap->entry->current = NULL;
master_source_current_signal(ap->entry);
+ /*
+ * 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)
+ return NSS_STATUS_SUCCESS;
+
mc = source->mc;
status = pthread_mutex_lock(&hostent_mutex);
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 8c6a8f2..a847622 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -2236,6 +2236,14 @@ static int read_one_map(struct autofs_point *ap,
ap->entry->current = NULL;
master_source_current_signal(ap->entry);
+ /*
+ * 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)
+ return NSS_STATUS_SUCCESS;
+
sp.ap = ap;
sp.age = age;
diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
index 0c75905..ae53481 100644
--- a/modules/lookup_nisplus.c
+++ b/modules/lookup_nisplus.c
@@ -180,6 +180,14 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
ap->entry->current = NULL;
master_source_current_signal(ap->entry);
+ /*
+ * 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)
+ return NSS_STATUS_SUCCESS;
+
mc = source->mc;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
index ce438e8..208f95e 100644
--- a/modules/lookup_yp.c
+++ b/modules/lookup_yp.c
@@ -322,6 +322,14 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
ap->entry->current = NULL;
master_source_current_signal(ap->entry);
+ /*
+ * 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)
+ return NSS_STATUS_SUCCESS;
+
ypcb_data.ap = ap;
ypcb_data.source = source;
ypcb_data.logopt = logopt;

View File

@ -1,226 +0,0 @@
autofs-5.0.4 - always read file maps
From: Ian Kent <raven@themaw.net>
autofs tries to not load an entire map into the internal cache unless it
has to. For maps that do get loaded into the cache it relies on checks to
work out if a map is up to date in order to trigger a map read. This is
fine for maps that can do direct key lookups but file maps need to do a
linear search through the file when locating an entry for a key. For large
maps this can be a huge overhead. This patch make autofs always load file
based maps at start and makes use of the map file mtime to discover if the
cache needs to be refreshed.
---
CHANGELOG | 1 +
daemon/lookup.c | 9 +++++--
modules/lookup_file.c | 65 ++++++++++++++++---------------------------------
3 files changed, 28 insertions(+), 47 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index d4dd70b..afd1335 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -14,6 +14,7 @@
- check for stale SASL credentials upon connect fail.
- add "forcestart" and "forcerestart" init script options to allow
use of 5.0.3 strartup behavior if required.
+- always read entire file map into cache to speed lookups.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/daemon/lookup.c b/daemon/lookup.c
index 741d846..e034348 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -283,10 +283,13 @@ static int do_read_map(struct autofs_point *ap, struct map_source *map, time_t a
* for the fail cases to function correctly and to cache the
* lookup handle.
*
- * We always need to whole map for direct mounts in order to
- * mount the triggers.
+ * We always need to read the whole map for direct mounts in
+ * order to mount the triggers. We also want to read the whole
+ * map if it's a file map to avoid potentially lengthy linear
+ * file scanning.
*/
- if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT)
+ if (strcmp(map->type, "file") &&
+ !(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT)
return NSS_STATUS_SUCCESS;
if (!map->stale)
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index 95b9f6f..aafeb8b 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -44,7 +44,6 @@ typedef enum { esc_none, esc_char, esc_val, esc_all } ESCAPES;
struct lookup_context {
const char *mapname;
- time_t mtime;
struct parse_mod *parse;
};
@@ -54,7 +53,6 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
{
struct lookup_context *ctxt;
char buf[MAX_ERR_BUF];
- struct stat st;
*context = NULL;
@@ -87,15 +85,6 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
return 1;
}
- if (stat(ctxt->mapname, &st)) {
- free(ctxt);
- logmsg(MODPREFIX "file map %s, could not stat",
- argv[0]);
- return 1;
- }
-
- ctxt->mtime = st.st_mtime;
-
if (!mapfmt)
mapfmt = MAPFMT_DEFAULT;
@@ -391,9 +380,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
int blen;
char *path;
char *ent;
- struct stat st;
FILE *f;
- int fd;
unsigned int path_len, ent_len;
int entry, cur_state;
@@ -428,8 +415,6 @@ int lookup_read_master(struct master *master, time_t age, void *context)
return NSS_STATUS_UNAVAIL;
}
- fd = fileno(f);
-
while(1) {
entry = read_one(logopt, f, path, &path_len, ent, &ent_len);
if (!entry) {
@@ -504,13 +489,6 @@ int lookup_read_master(struct master *master, time_t age, void *context)
break;
}
- if (fstat(fd, &st)) {
- crit(logopt, MODPREFIX "file map %s, could not stat",
- ctxt->mapname);
- return NSS_STATUS_UNAVAIL;
- }
- ctxt->mtime = st.st_mtime;
-
fclose(f);
return NSS_STATUS_SUCCESS;
@@ -642,9 +620,7 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
struct mapent_cache *mc;
char *key;
char *mapent;
- struct stat st;
FILE *f;
- int fd;
unsigned int k_len, m_len;
int entry;
@@ -684,8 +660,6 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
return NSS_STATUS_UNAVAIL;
}
- fd = fileno(f);
-
while(1) {
entry = read_one(ap->logopt, f, key, &k_len, mapent, &m_len);
if (!entry) {
@@ -748,13 +722,6 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
break;
}
- if (fstat(fd, &st)) {
- crit(ap->logopt,
- MODPREFIX "file map %s, could not stat",
- ctxt->mapname);
- return NSS_STATUS_UNAVAIL;
- }
- ctxt->mtime = st.st_mtime;
source->age = age;
fclose(f);
@@ -951,9 +918,6 @@ static int check_map_indirect(struct autofs_point *ap,
if (ret == CHE_FAIL)
return NSS_STATUS_NOTFOUND;
- if (ret & CHE_UPDATED)
- source->stale = 1;
-
pthread_cleanup_push(cache_lock_cleanup, mc);
cache_writelock(mc);
exists = cache_lookup_distinct(mc, key);
@@ -963,7 +927,6 @@ static int check_map_indirect(struct autofs_point *ap,
free(exists->mapent);
exists->mapent = NULL;
exists->status = 0;
- source->stale = 1;
}
}
pthread_cleanup_pop(1);
@@ -985,14 +948,8 @@ static int check_map_indirect(struct autofs_point *ap,
we = cache_lookup_distinct(mc, "*");
if (we) {
/* Wildcard entry existed and is now gone */
- if (we->source == source && (wild & CHE_MISSING)) {
+ if (we->source == source && (wild & CHE_MISSING))
cache_delete(mc, "*");
- source->stale = 1;
- }
- } else {
- /* Wildcard not in map but now is */
- if (wild & (CHE_OK | CHE_UPDATED))
- source->stale = 1;
}
pthread_cleanup_pop(1);
@@ -1062,9 +1019,28 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
* we never know about it.
*/
if (ap->type == LKP_INDIRECT && *key != '/') {
+ struct stat st;
char *lkp_key;
+ /*
+ * We can skip the map lookup and cache update altogether
+ * if we know the map hasn't been modified since it was
+ * last read. If it has then we can mark the map stale
+ * so a re-read is triggered following the lookup.
+ */
+ if (stat(ctxt->mapname, &st)) {
+ error(ap->logopt, MODPREFIX
+ "file map %s, could not stat", ctxt->mapname);
+ return NSS_STATUS_UNAVAIL;
+ }
+
cache_readlock(mc);
+ me = cache_lookup_first(mc);
+ if (me && st.st_mtime <= me->age)
+ goto do_cache_lookup;
+ else
+ source->stale = 1;
+
me = cache_lookup_distinct(mc, key);
if (me && me->multi)
lkp_key = strdup(me->multi->key);
@@ -1088,6 +1064,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
}
cache_readlock(mc);
+do_cache_lookup:
me = cache_lookup(mc, key);
/* Stale mapent => check for entry in alternate source or wildcard */
if (me && !me->mapent) {

View File

@ -1,36 +0,0 @@
autofs-5.0.4 - another easy alloca replacements fix
From: Ian Kent <raven@themaw.net>
Fix array out of bounds access in modules/lookup_ldap.c:get_query_dn().
---
CHANGELOG | 1 +
modules/lookup_ldap.c | 1 -
2 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 8860b2c..4df6a60 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -29,6 +29,7 @@
- fix bad token declaration in master map parser.
- fix return start status on fail.
- fix double free in expire_proc().
+- another easy alloca replacements fix.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 547ca01..5a54b5f 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -323,7 +323,6 @@ static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt
}
scope = LDAP_SCOPE_SUBTREE;
}
- query[l] = '\0';
if (!ctxt->base) {
sdns = defaults_get_searchdns();

View File

@ -1,47 +0,0 @@
autofs-5.0.4 - clear rpc client on lookup fail
From: Ian Kent <raven@themaw.net>
If a name lookup failure occurs in create_tcp_client() or create_udp_client()
the client is destoryed and the file descriptor is closed at exit but the rpc
client isn't set to NULL. This leads to a subsequent SEGV when attempting to
use the invalid client.
---
CHANGELOG | 1 +
lib/rpc_subs.c | 2 ++
2 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 00b455e..91edd14 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -34,6 +34,7 @@
- fix file map lookup when reading included or nsswitch sources.
- use misc device ioctl interface by default, if available.
- fix call restorecon when misc device file doesn't exist.
+- clear rpc client on lookup fail.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c
index a822f1f..d034b29 100644
--- a/lib/rpc_subs.c
+++ b/lib/rpc_subs.c
@@ -346,6 +346,7 @@ static CLIENT *create_udp_client(struct conn_info *info)
if (ret) {
error(LOGOPT_ANY,
"hostname lookup failed: %s", gai_strerror(ret));
+ info->client = NULL;
goto out_close;
}
@@ -470,6 +471,7 @@ static CLIENT *create_tcp_client(struct conn_info *info)
if (ret) {
error(LOGOPT_ANY,
"hostname lookup failed: %s", gai_strerror(ret));
+ info->client = NULL;
goto out_close;
}

View File

@ -1,552 +0,0 @@
autofs-5.0.4 - code analysis corrections
From: Ian Kent <raven@themaw.net>
Several mistakes have been reported by Paul Wankadia <junyer@google.com>:
- a malloc(3) allocation return was not being checked in make_fullpath().
- a double free and a use after free was identified in lookup_prune_cache().
- off-by-one buffer overflow in lib/macros.c:macro_parse_globalvar().
- several potential buffer overflows in modules/parse_hesiod.c.
- double free in daemon/indirect.c:do_mount_autofs_indirect().
- bogus struct name used for sizeof in lib/cache.c:cache_init() and
lib/cache.c:cache_init_null_cache().
- in daemon/direct.c:handle_packet_expire_direct master_unlock_mutex() not
needed and mutexes not unlocked for file descriptor fail case.
- in modules/lookup_multi.c:lookup_init() struct module_info array not
checked before free for allocation failure case.
- in modules/lookup_program.c:lookup_mount() mapent not freed on cache update failure.
- in modules/mount_nfs.c allocation of mount location not checked.
- in modules/parse_sun.c:parse_mapent() mount location not freed on syntax error.
- in modules/parse_sun.c:parse_mount() mount location not freed on syntax error.
- in modules/parse_sun.c:parse_init() a malloc is not checked and the
handling of the fail case is poor.
- in lib/mounts.c:tree_make_mnt_tree() variable ent is not freed on ent->path
alloc fail.
- in modules/replicated.c:add_host() NULL pointer dereference.
- add missing pthread_attr_destroy() in lib/alarm.c:alarm_start_handler().
- add missing pthread_attr_destroy() in daemon/state.c:st_start_handler().
- add missing fclose() in lib/defaults.c:*defaults_get_searchdns().
- add missing close()es in modules/mount_changer.c:swapCD().
---
daemon/direct.c | 6 ++-
daemon/indirect.c | 3 +-
daemon/lookup.c | 20 +++++-------
daemon/state.c | 6 ++-
lib/alarm.c | 6 ++-
lib/cache.c | 4 +-
lib/defaults.c | 1 +
lib/macros.c | 2 +
lib/mounts.c | 5 ++-
modules/lookup_multi.c | 15 +++++----
modules/lookup_program.c | 4 ++
modules/mount_changer.c | 2 +
modules/mount_nfs.c | 5 +++
modules/parse_hesiod.c | 79 ++++++++++++++++++++++++++++++++++++++++------
modules/parse_sun.c | 18 ++++++----
modules/replicated.c | 2 +
16 files changed, 123 insertions(+), 55 deletions(-)
diff --git a/daemon/direct.c b/daemon/direct.c
index 2d979f1..fc3c969 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -1088,7 +1088,6 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
crit(ap->logopt, "can't find map entry for (%lu,%lu)",
(unsigned long) pkt->dev, (unsigned long) pkt->ino);
master_source_unlock(ap->entry);
- master_mutex_unlock();
pthread_setcancelstate(state, NULL);
return 1;
}
@@ -1098,8 +1097,9 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
int ioctlfd;
ops->open(ap->logopt, &ioctlfd, me->dev, me->key);
if (ioctlfd == -1) {
- crit(ap->logopt, "can't open ioctlfd for %s",
- me->key);
+ crit(ap->logopt, "can't open ioctlfd for %s", me->key);
+ cache_unlock(mc);
+ master_source_unlock(ap->entry);
pthread_setcancelstate(state, NULL);
return 1;
}
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 2ccbc53..f40c393 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -159,6 +159,7 @@ static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root)
}
free(options);
+ options = NULL;
ret = stat(root, &st);
if (ret == -1) {
@@ -167,8 +168,6 @@ static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root)
goto out_umount;
}
- options = NULL;
-
if (ops->open(ap->logopt, &ap->ioctlfd, st.st_dev, root)) {
crit(ap->logopt,
"failed to create ioctl fd for autofs path %s", ap->path);
diff --git a/daemon/lookup.c b/daemon/lookup.c
index e034348..fd2ce55 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -1001,12 +1001,16 @@ static char *make_fullpath(const char *root, const char *key)
if (l > KEY_MAX_LEN)
return NULL;
path = malloc(l);
+ if (!path)
+ return NULL;
strcpy(path, key);
} else {
l = strlen(key) + 1 + strlen(root) + 1;
if (l > KEY_MAX_LEN)
return NULL;
path = malloc(l);
+ if (!path)
+ return NULL;
sprintf(path, "%s/%s", root, key);
}
return path;
@@ -1076,10 +1080,6 @@ int lookup_prune_cache(struct autofs_point *ap, time_t age)
this = cache_lookup_distinct(mc, key);
if (!this) {
cache_unlock(mc);
- free(key);
- if (next_key)
- free(next_key);
- free(path);
goto next;
}
@@ -1097,18 +1097,14 @@ int lookup_prune_cache(struct autofs_point *ap, time_t age)
}
cache_unlock(mc);
- if (!next_key) {
- free(key);
- free(path);
- cache_readlock(mc);
- continue;
- }
next:
cache_readlock(mc);
- me = cache_lookup_distinct(mc, next_key);
+ if (next_key) {
+ me = cache_lookup_distinct(mc, next_key);
+ free(next_key);
+ }
free(key);
free(path);
- free(next_key);
}
pthread_cleanup_pop(1);
map->stale = 0;
diff --git a/daemon/state.c b/daemon/state.c
index cd63be1..606743b 100644
--- a/daemon/state.c
+++ b/daemon/state.c
@@ -1140,9 +1140,9 @@ int st_start_handler(void)
}
status = pthread_create(&thid, pattrs, st_queue_handler, NULL);
- if (status)
- return 0;
- return 1;
+ pthread_attr_destroy(pattrs);
+
+ return !status;
}
diff --git a/lib/alarm.c b/lib/alarm.c
index 1e32291..46df38a 100755
--- a/lib/alarm.c
+++ b/lib/alarm.c
@@ -238,9 +238,9 @@ int alarm_start_handler(void)
}
status = pthread_create(&thid, pattrs, alarm_handler, NULL);
- if (status)
- return 0;
- return 1;
+ pthread_attr_destroy(pattrs);
+
+ return !status;
}
diff --git a/lib/cache.c b/lib/cache.c
index edb3192..4cb4582 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -192,7 +192,7 @@ struct mapent_cache *cache_init(struct autofs_point *ap, struct map_source *map)
mc->size = defaults_get_map_hash_table_size();
- mc->hash = malloc(mc->size * sizeof(struct entry *));
+ mc->hash = malloc(mc->size * sizeof(struct mapent *));
if (!mc->hash) {
free(mc);
return NULL;
@@ -243,7 +243,7 @@ struct mapent_cache *cache_init_null_cache(struct master *master)
mc->size = NULL_MAP_HASHSIZE;
- mc->hash = malloc(mc->size * sizeof(struct entry *));
+ mc->hash = malloc(mc->size * sizeof(struct mapent *));
if (!mc->hash) {
free(mc);
return NULL;
diff --git a/lib/defaults.c b/lib/defaults.c
index 0d39716..e507a59 100644
--- a/lib/defaults.c
+++ b/lib/defaults.c
@@ -565,6 +565,7 @@ struct ldap_searchdn *defaults_get_searchdns(void)
if (!new) {
defaults_free_searchdns(sdn);
+ fclose(f);
return NULL;
}
diff --git a/lib/macros.c b/lib/macros.c
index 85f9cd3..32b70bf 100644
--- a/lib/macros.c
+++ b/lib/macros.c
@@ -165,7 +165,7 @@ int macro_parse_globalvar(const char *define)
char buf[MAX_MACRO_STRING];
char *pbuf, *value;
- if (strlen(define) > MAX_MACRO_STRING)
+ if (strlen(define) >= MAX_MACRO_STRING)
return 0;
strcpy(buf, define);
diff --git a/lib/mounts.c b/lib/mounts.c
index b98e1a4..08ca4e3 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -257,10 +257,10 @@ struct mnt_list *get_mnt_list(const char *table, const char *path, int include)
if (mptr == list)
list = ent;
+ else
+ last->next = ent;
ent->next = mptr;
- if (last)
- last->next = ent;
ent->path = malloc(len + 1);
if (!ent->path) {
@@ -705,6 +705,7 @@ struct mnt_list *tree_make_mnt_tree(const char *table, const char *path)
ent->path = malloc(len + 1);
if (!ent->path) {
endmntent(tab);
+ free(ent);
tree_free_mnt_tree(tree);
return NULL;
}
diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c
index 1bf2e0a..6ec8434 100644
--- a/modules/lookup_multi.c
+++ b/modules/lookup_multi.c
@@ -212,14 +212,15 @@ nomem:
logerr(MODPREFIX "error: %s", estr);
error_out:
if (ctxt) {
- for (i = 0; i < ctxt->n; i++) {
- if (ctxt->m[i].mod)
- close_lookup(ctxt->m[i].mod);
- if (ctxt->m[i].argv)
- free_argv(ctxt->m[i].argc, ctxt->m[i].argv);
- }
- if (ctxt->m)
+ if (ctxt->m) {
+ for (i = 0; i < ctxt->n; i++) {
+ if (ctxt->m[i].mod)
+ close_lookup(ctxt->m[i].mod);
+ if (ctxt->m[i].argv)
+ free_argv(ctxt->m[i].argc, ctxt->m[i].argv);
+ }
free(ctxt->m);
+ }
if (ctxt->argl)
free(ctxt->argl);
free(ctxt);
diff --git a/modules/lookup_program.c b/modules/lookup_program.c
index 9878936..5b295a5 100644
--- a/modules/lookup_program.c
+++ b/modules/lookup_program.c
@@ -396,8 +396,10 @@ next:
cache_writelock(mc);
ret = cache_update(mc, source, name, mapent, time(NULL));
cache_unlock(mc);
- if (ret == CHE_FAIL)
+ if (ret == CHE_FAIL) {
+ free(mapent);
return NSS_STATUS_UNAVAIL;
+ }
debug(ap->logopt, MODPREFIX "%s -> %s", name, mapent);
diff --git a/modules/mount_changer.c b/modules/mount_changer.c
index 92bb72b..c30190d 100644
--- a/modules/mount_changer.c
+++ b/modules/mount_changer.c
@@ -162,6 +162,7 @@ int swapCD(const char *device, const char *slotName)
logerr(MODPREFIX
"Device %s is not an ATAPI compliant CD changer.",
device);
+ close(fd);
return 1;
}
@@ -169,6 +170,7 @@ int swapCD(const char *device, const char *slotName)
slot = ioctl(fd, CDROM_SELECT_DISC, slot);
if (slot < 0) {
logerr(MODPREFIX "CDROM_SELECT_DISC failed");
+ close(fd);
return 1;
}
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
index 20732f8..6f54f47 100644
--- a/modules/mount_nfs.c
+++ b/modules/mount_nfs.c
@@ -221,6 +221,11 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
/* Not a local host - do an NFS mount */
loc = malloc(strlen(this->name) + 1 + strlen(this->path) + 1);
+ if (!loc) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ error(ap->logopt, "malloc: %s", estr);
+ return 1;
+ }
strcpy(loc, this->name);
strcat(loc, ":");
strcat(loc, this->path);
diff --git a/modules/parse_hesiod.c b/modules/parse_hesiod.c
index d5bb0f4..7a6a57d 100644
--- a/modules/parse_hesiod.c
+++ b/modules/parse_hesiod.c
@@ -46,6 +46,12 @@ static int parse_afs(struct autofs_point *ap,
/* Isolate the source for this AFS fs. */
for (i = 0; (!isspace(p[i]) && i < source_len); i++) {
+ if (!p[i]) {
+ error(ap->logopt, MODPREFIX
+ "unexpeced end of input looking for AFS "
+ "source: %s", p);
+ return 1;
+ }
source[i] = p[i];
}
@@ -56,8 +62,14 @@ static int parse_afs(struct autofs_point *ap,
while ((*p) && (isspace(*p)))
p++;
- /* Isolate the source for this AFS fs. */
+ /* Isolate the options for this AFS fs. */
for (i = 0; (!isspace(p[i]) && i < options_len); i++) {
+ if (!p[i]) {
+ error(ap->logopt, MODPREFIX
+ "unexpeced end of input looking for AFS "
+ "options: %s", p);
+ return 1;
+ }
options[i] = p[i];
}
options[i] = 0;
@@ -106,6 +118,12 @@ static int parse_nfs(struct autofs_point *ap,
/* Isolate the remote mountpoint for this NFS fs. */
for (i = 0; (!isspace(p[i]) && i < (int) sizeof(mount)); i++) {
+ if (!p[i]) {
+ error(ap->logopt, MODPREFIX
+ "unexpeced end of input looking for NFS "
+ "mountpoint: %s", p);
+ return 1;
+ }
mount[i] = p[i];
}
@@ -118,15 +136,26 @@ static int parse_nfs(struct autofs_point *ap,
/* Isolate the remote host. */
for (i = 0; (!isspace(p[i]) && i < source_len); i++) {
+ if (!p[i]) {
+ error(ap->logopt, MODPREFIX
+ "unexpeced end of input looking for NFS "
+ "host: %s", p);
+ return 1;
+ }
source[i] = p[i];
}
source[i] = 0;
p += i;
+ if (strlen(source) + strlen(mount) + 2 > source_len) {
+ error(ap->logopt, MODPREFIX "entry too log for mount source");
+ return 1;
+ }
+
/* Append ":mountpoint" to the source to get "host:mountpoint". */
- strncat(source, ":", source_len);
- strncat(source, mount, source_len);
+ strcat(source, ":");
+ strcat(source, mount);
/* Skip whitespace. */
while ((*p) && (isspace(*p)))
@@ -134,6 +163,12 @@ static int parse_nfs(struct autofs_point *ap,
/* Isolate the mount options. */
for (i = 0; (!isspace(p[i]) && i < options_len); i++) {
+ if (!p[i]) {
+ error(ap->logopt, MODPREFIX
+ "unexpeced end of input looking for NFS "
+ "mount options: %s", p);
+ return 1;
+ }
options[i] = p[i];
}
options[i] = 0;
@@ -178,6 +213,12 @@ static int parse_generic(struct autofs_point *ap,
/* Isolate the source for this fs. */
for (i = 0; (!isspace(p[i]) && i < source_len); i++) {
+ if (!p[i]) {
+ error(ap->logopt, MODPREFIX
+ "unexpeced end of input looking for generic "
+ "mount source: %s", p);
+ return 1;
+ }
source[i] = p[i];
}
@@ -190,6 +231,12 @@ static int parse_generic(struct autofs_point *ap,
/* Isolate the mount options. */
for (i = 0; (!isspace(p[i]) && i < options_len); i++) {
+ if (!p[i]) {
+ error(ap->logopt, MODPREFIX
+ "unexpeced end of input looking for generic "
+ "mount options: %s", p);
+ return 1;
+ }
options[i] = p[i];
}
options[i] = 0;
@@ -227,6 +274,7 @@ int parse_mount(struct autofs_point *ap, const char *name,
char options[HESIOD_LEN + 1];
char *q;
const char *p;
+ int ret;
ap->entry->current = NULL;
master_source_current_signal(ap->entry);
@@ -250,19 +298,28 @@ int parse_mount(struct autofs_point *ap, const char *name,
return 1;
/* If it's an AFS fs... */
} else if (!strcasecmp(fstype, "afs"))
- parse_afs(ap, mapent, name, name_len,
- source, sizeof(source), options, sizeof(options));
+ ret = parse_afs(ap, mapent, name, name_len,
+ source, sizeof(source), options,
+ sizeof(options));
/* If it's NFS... */
else if (!strcasecmp(fstype, "nfs"))
- parse_nfs(ap, mapent, name, name_len,
- source, sizeof(source), options, sizeof(options));
+ ret = parse_nfs(ap, mapent, name, name_len,
+ source, sizeof(source), options,
+ sizeof(options));
/* Punt. */
else
- parse_generic(ap, mapent, name, name_len, source, sizeof(source),
- options, sizeof(options));
+ ret = parse_generic(ap, mapent, name, name_len,
+ source, sizeof(source), options,
+ sizeof(options));
- debug(ap->logopt,
- MODPREFIX "mount %s is type %s from %s", name, fstype, source);
+ if (ret) {
+ error(ap->logopt, MODPREFIX "failed to parse entry");
+ return 1;
+ } else {
+ debug(ap->logopt,
+ MODPREFIX "mount %s is type %s from %s",
+ name, fstype, source);
+ }
return do_mount(ap, ap->path, name, name_len, source, fstype, options);
}
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 72e51e2..ed73e46 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -379,15 +379,17 @@ int parse_init(int argc, const char *const *argv, void **context)
if (ctxt->optstr) {
noptstr =
(char *) realloc(ctxt->optstr, optlen + len + 2);
- if (!noptstr)
- break;
- noptstr[optlen] = ',';
- strcpy(noptstr + optlen + 1, argv[i] + offset);
- optlen += len + 1;
+ if (noptstr) {
+ noptstr[optlen] = ',';
+ strcpy(noptstr + optlen + 1, argv[i] + offset);
+ optlen += len + 1;
+ }
} else {
noptstr = (char *) malloc(len + 1);
- strcpy(noptstr, argv[i] + offset);
- optlen = len;
+ if (noptstr) {
+ strcpy(noptstr, argv[i] + offset);
+ optlen = len;
+ }
}
if (!noptstr) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
@@ -895,6 +897,7 @@ static int parse_mapent(const char *ent, char *g_options, char **options, char *
if (*p == '/') {
warn(logopt, MODPREFIX "error location begins with \"/\"");
free(myoptions);
+ free(loc);
return 0;
}
@@ -1636,6 +1639,7 @@ int parse_mount(struct autofs_point *ap, const char *name,
/* Location can't begin with a '/' */
if (*p == '/') {
free(options);
+ free(loc);
warn(ap->logopt,
MODPREFIX "error location begins with \"/\"");
return 1;
diff --git a/modules/replicated.c b/modules/replicated.c
index 63829a2..835af97 100644
--- a/modules/replicated.c
+++ b/modules/replicated.c
@@ -304,7 +304,7 @@ static int add_host(struct host **list, struct host *host)
{
struct host *this, *last;
- if (!list) {
+ if (!*list) {
*list = host;
return 1;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,68 +0,0 @@
autofs-5.0.4 - dont fail on ipv6 address adding host
From: Ian Kent <raven@themaw.net>
We don't have IPv6 support enabled in libtirpc yet. When we
perform name (or address) lookup and we get a mixture of IPv4
and IPv6 addresses the lack of IPv6 support can cause the
parse_location() function to fail to add any valid hosts when
in fact it should.
---
CHANGELOG | 1 +
include/replicated.h | 1 +
modules/replicated.c | 9 ++++++++-
3 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 89aaa99..7e1012f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -46,6 +46,7 @@
- dont umount existing direct mount on master re-read.
- fix incorrect shutdown introduced by library relaod fixes.
- improve manual umount recovery.
+- dont fail on ipv6 address when adding host.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/include/replicated.h b/include/replicated.h
index e0133ff..fd87c08 100644
--- a/include/replicated.h
+++ b/include/replicated.h
@@ -21,6 +21,7 @@
#define PROXIMITY_SUBNET 0x0002
#define PROXIMITY_NET 0x0004
#define PROXIMITY_OTHER 0x0008
+#define PROXIMITY_UNSUPPORTED 0x0010
#define NFS2_SUPPORTED 0x0010
#define NFS3_SUPPORTED 0x0020
diff --git a/modules/replicated.c b/modules/replicated.c
index 79845d0..a66de9f 100644
--- a/modules/replicated.c
+++ b/modules/replicated.c
@@ -181,7 +181,7 @@ static unsigned int get_proximity(struct sockaddr *host_addr)
case AF_INET6:
#ifndef INET6
- return PROXIMITY_ERROR;
+ return PROXIMITY_UNSUPPORTED;
#else
addr6 = (struct sockaddr_in6 *) host_addr;
hst6_addr = (struct in6_addr *) &addr6->sin6_addr;
@@ -1048,6 +1048,13 @@ static int add_new_host(struct host **list,
int addr_len;
prx = get_proximity(host_addr->ai_addr);
+ /*
+ * If we tried to add an IPv6 address and we don't have IPv6
+ * support return success in the hope of getting an IPv4
+ * address later.
+ */
+ if (prx == PROXIMITY_UNSUPPORTED)
+ return 1;
if (prx == PROXIMITY_ERROR)
return 0;

View File

@ -1,368 +0,0 @@
autofs-5.0.4 - dont umount existing direct mount on master re-read
From: Ian Kent <raven@themaw.net>
Since direct mounts can have multiple entries in the master map they each
have an instance associated with them. If one entry changes, such as the
mount options, the instance comparison test fails and a new instance is
added. This causes autofs to get confused because there are now two
entries that contain the same mount information in different internal
caches. There are several consequences of this, most of which are just
noise in the log, but it also causes confuion for the expiration of mounts
since, for an active mount, the old cache entry can't be pruned until it's
umounted. Also, the map caches were not being properly pruned.
---
CHANGELOG | 1
daemon/lookup.c | 160 ++++++++++++++++++++++++++++-----------------------
daemon/state.c | 90 +++++++++++++++++++++--------
include/automount.h | 1
4 files changed, 156 insertions(+), 96 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 387af5e..7ca45fd 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -43,6 +43,7 @@
- use percent hack for master map keys.
- use intr option as hosts mount default.
- fix kernel includes.
+- dont umount existing direct mount on master re-read.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/daemon/lookup.c b/daemon/lookup.c
index fd2ce55..bc94655 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -1016,96 +1016,114 @@ static char *make_fullpath(const char *root, const char *key)
return path;
}
-int lookup_prune_cache(struct autofs_point *ap, time_t age)
+void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, time_t age)
{
- struct master_mapent *entry = ap->entry;
- struct map_source *map;
- struct mapent_cache *mc;
struct mapent *me, *this;
char *path;
int status = CHE_FAIL;
- pthread_cleanup_push(master_source_lock_cleanup, entry);
- master_source_readlock(entry);
+ me = cache_enumerate(mc, NULL);
+ while (me) {
+ struct mapent *valid;
+ char *key = NULL, *next_key = NULL;
- map = entry->maps;
- while (map) {
- /* Is the map stale */
- if (!map->stale) {
- map = map->next;
+ if (me->age >= age) {
+ me = cache_enumerate(mc, me);
continue;
}
- mc = map->mc;
- pthread_cleanup_push(cache_lock_cleanup, mc);
- cache_readlock(mc);
- me = cache_enumerate(mc, NULL);
- while (me) {
- char *key = NULL, *next_key = NULL;
- if (me->age >= age) {
- me = cache_enumerate(mc, me);
- continue;
- }
+ key = strdup(me->key);
+ me = cache_enumerate(mc, me);
+ if (!key || *key == '*') {
+ if (key)
+ free(key);
+ continue;
+ }
- key = strdup(me->key);
- me = cache_enumerate(mc, me);
- if (!key || *key == '*') {
- if (key)
- free(key);
- continue;
- }
+ path = make_fullpath(ap->path, key);
+ if (!path) {
+ warn(ap->logopt, "can't malloc storage for path");
+ free(key);
+ continue;
+ }
- path = make_fullpath(ap->path, key);
- if (!path) {
- warn(ap->logopt,
- "can't malloc storage for path");
- free(key);
- continue;
- }
+ /*
+ * If this key has another valid entry we want to prune it,
+ * even if it's a mount, as the valid entry will take the
+ * mount if it is a direct mount or it's just a stale indirect
+ * cache entry.
+ */
+ valid = lookup_source_valid_mapent(ap, key, LKP_DISTINCT);
+ if (!valid &&
+ is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) {
+ debug(ap->logopt,
+ "prune check posponed, %s mounted", path);
+ free(key);
+ free(path);
+ continue;
+ }
+ if (valid)
+ cache_unlock(valid->mc);
- if (is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) {
- debug(ap->logopt,
- "prune check posponed, %s mounted", path);
- free(key);
- free(path);
- continue;
- }
+ if (me)
+ next_key = strdup(me->key);
- if (me)
- next_key = strdup(me->key);
+ cache_unlock(mc);
+ cache_writelock(mc);
+ this = cache_lookup_distinct(mc, key);
+ if (!this) {
cache_unlock(mc);
+ goto next;
+ }
- cache_writelock(mc);
- this = cache_lookup_distinct(mc, key);
- if (!this) {
- cache_unlock(mc);
- goto next;
- }
-
- if (!is_mounted(_PROC_MOUNTS, path, MNTS_AUTOFS)) {
- status = CHE_FAIL;
- if (this->ioctlfd == -1)
- status = cache_delete(mc, key);
- if (status != CHE_FAIL) {
- if (ap->type == LKP_INDIRECT) {
- if (ap->flags & MOUNT_FLAG_GHOST)
- rmdir_path(ap, path, ap->dev);
- } else
- rmdir_path(ap, path, this->dev);
- }
+ if (valid)
+ cache_delete(mc, key);
+ else if (!is_mounted(_PROC_MOUNTS, path, MNTS_AUTOFS)) {
+ status = CHE_FAIL;
+ if (this->ioctlfd == -1)
+ status = cache_delete(mc, key);
+ if (status != CHE_FAIL) {
+ if (ap->type == LKP_INDIRECT) {
+ if (ap->flags & MOUNT_FLAG_GHOST)
+ rmdir_path(ap, path, ap->dev);
+ } else
+ rmdir_path(ap, path, this->dev);
}
- cache_unlock(mc);
+ }
+ cache_unlock(mc);
next:
- cache_readlock(mc);
- if (next_key) {
- me = cache_lookup_distinct(mc, next_key);
- free(next_key);
- }
- free(key);
- free(path);
+ cache_readlock(mc);
+ if (next_key) {
+ me = cache_lookup_distinct(mc, next_key);
+ free(next_key);
}
+ free(key);
+ free(path);
+ }
+
+ return;
+}
+
+int lookup_prune_cache(struct autofs_point *ap, time_t age)
+{
+ struct master_mapent *entry = ap->entry;
+ struct map_source *map;
+
+ pthread_cleanup_push(master_source_lock_cleanup, entry);
+ master_source_readlock(entry);
+
+ map = entry->maps;
+ while (map) {
+ /* Is the map stale */
+ if (!map->stale) {
+ map = map->next;
+ continue;
+ }
+ pthread_cleanup_push(cache_lock_cleanup, map->mc);
+ cache_readlock(map->mc);
+ lookup_prune_one_cache(ap, map->mc, age);
pthread_cleanup_pop(1);
map->stale = 0;
map = map->next;
@@ -1124,7 +1142,6 @@ struct mapent *lookup_source_valid_mapent(struct autofs_point *ap, const char *k
struct mapent_cache *mc;
struct mapent *me = NULL;
- master_source_readlock(entry);
map = entry->maps;
while (map) {
/*
@@ -1147,7 +1164,6 @@ struct mapent *lookup_source_valid_mapent(struct autofs_point *ap, const char *k
cache_unlock(mc);
map = map->next;
}
- master_source_unlock(entry);
return me;
}
diff --git a/daemon/state.c b/daemon/state.c
index 533e241..84ccba3 100644
--- a/daemon/state.c
+++ b/daemon/state.c
@@ -352,6 +352,68 @@ static void tree_mnts_cleanup(void *arg)
return;
}
+static void do_readmap_mount(struct autofs_point *ap, struct mnt_list *mnts,
+ struct map_source *map, struct mapent *me, time_t now)
+{
+ struct mapent_cache *nc;
+ struct mapent *ne, *nested, *valid;
+
+ nc = ap->entry->master->nc;
+
+ ne = cache_lookup_distinct(nc, me->key);
+ if (!ne) {
+ nested = cache_partial_match(nc, me->key);
+ if (nested) {
+ error(ap->logopt,
+ "removing invalid nested null entry %s",
+ nested->key);
+ nested = cache_partial_match(nc, me->key);
+ if (nested)
+ cache_delete(nc, nested->key);
+ }
+ }
+
+ if (me->age < now || (ne && map->master_line > ne->age)) {
+ /*
+ * The map instance may have changed, such as the map name or
+ * the mount options, but the direct map entry may still exist
+ * in one of the other maps. If so then update the new cache
+ * entry device and inode so we can find it at lookup. Later,
+ * the mount for the new cache entry will just update the
+ * timeout.
+ *
+ * TODO: how do we recognise these orphaned map instances. We
+ * can't just delete these instances when the cache becomes
+ * empty because that is a valid state for a master map entry.
+ * This is becuase of the requirement to continue running with
+ * an empty cache awaiting a map re-load.
+ */
+ valid = lookup_source_valid_mapent(ap, me->key, LKP_DISTINCT);
+ if (valid) {
+ struct mapent_cache *vmc = valid->mc;
+ cache_unlock(vmc);
+ debug(ap->logopt,
+ "updating cache entry for valid direct trigger %s",
+ me->key);
+ cache_writelock(vmc);
+ valid = cache_lookup_distinct(vmc, me->key);
+ /* Take over the mount if there is one */
+ valid->ioctlfd = me->ioctlfd;
+ me->ioctlfd = -1;
+ /* Set device and inode number of the new mapent */
+ cache_set_ino_index(vmc, me->key, me->dev, me->ino);
+ cache_unlock(vmc);
+ } 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);
+
+ return;
+}
+
static void *do_readmap(void *arg)
{
struct autofs_point *ap;
@@ -398,7 +460,8 @@ static void *do_readmap(void *arg)
lookup_prune_cache(ap, now);
status = lookup_ghost(ap, ap->path);
} else {
- struct mapent *me, *ne, *nested;
+ struct mapent *me;
+
mnts = tree_make_mnt_tree(_PROC_MOUNTS, "/");
pthread_cleanup_push(tree_mnts_cleanup, mnts);
pthread_cleanup_push(master_source_lock_cleanup, ap->entry);
@@ -418,31 +481,10 @@ static void *do_readmap(void *arg)
cache_readlock(mc);
me = cache_enumerate(mc, NULL);
while (me) {
- ne = cache_lookup_distinct(nc, me->key);
- if (!ne) {
- nested = cache_partial_match(nc, me->key);
- if (nested) {
- error(ap->logopt,
- "removing invalid nested null entry %s",
- nested->key);
- nested = cache_partial_match(nc, me->key);
- if (nested)
- cache_delete(nc, nested->key);
- }
- }
-
- /* TODO: check return of do_... */
- if (me->age < now || (ne && map->master_line > ne->age)) {
- 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_readmap_mount(ap, mnts, map, me, now);
me = cache_enumerate(mc, me);
}
+ lookup_prune_one_cache(ap, map->mc, now);
pthread_cleanup_pop(1);
map->stale = 0;
map = map->next;
diff --git a/include/automount.h b/include/automount.h
index d4675bd..ae517a7 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -238,6 +238,7 @@ int lookup_enumerate(struct autofs_point *ap,
int lookup_ghost(struct autofs_point *ap, const char *root);
int lookup_nss_mount(struct autofs_point *ap, struct map_source *source, const char *name, int name_len);
void lookup_close_lookup(struct autofs_point *ap);
+void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, time_t age);
int lookup_prune_cache(struct autofs_point *ap, time_t age);
struct mapent *lookup_source_valid_mapent(struct autofs_point *ap, const char *key, unsigned int type);
struct mapent *lookup_source_mapent(struct autofs_point *ap, const char *key, unsigned int type);

View File

@ -1,190 +0,0 @@
autofs-5.0.4 - easy alloca replacements fix
From: Ian Kent <raven@themaw.net>
Fix array out of bounds accesses and remove alloca(3) calls from
modules/mount_autofs.c and modules/mount_nfs.c as well.
---
CHANGELOG | 1 +
modules/lookup_ldap.c | 3 ---
modules/mount_autofs.c | 9 ++-------
modules/mount_bind.c | 6 +++++-
modules/mount_changer.c | 6 +++++-
modules/mount_ext2.c | 6 +++++-
modules/mount_generic.c | 6 +++++-
modules/mount_nfs.c | 12 +++++++-----
8 files changed, 30 insertions(+), 19 deletions(-)
--- autofs-5.0.4.orig/CHANGELOG
+++ autofs-5.0.4/CHANGELOG
@@ -20,6 +20,7 @@
- update to configure libtirpc if present.
- update to provide ipv6 name and address support.
- update to provide ipv6 address parsing.
+- easy alloca replacements fix.
4/11/2008 autofs-5.0.4
-----------------------
--- autofs-5.0.4.orig/modules/lookup_ldap.c
+++ autofs-5.0.4/modules/lookup_ldap.c
@@ -1474,7 +1474,6 @@ int lookup_read_master(struct master *ma
free(query);
return NSS_STATUS_UNAVAIL;
}
- query[l] = '\0';
/* Initialize the LDAP context. */
ldap = do_reconnect(logopt, ctxt);
@@ -2213,7 +2212,6 @@ static int read_one_map(struct autofs_po
free(sp.query);
return NSS_STATUS_UNAVAIL;
}
- sp.query[l] = '\0';
/* Initialize the LDAP context. */
sp.ldap = do_reconnect(ap->logopt, ctxt);
@@ -2404,7 +2402,6 @@ static int lookup_one(struct autofs_poin
free(query);
return CHE_FAIL;
}
- query[ql] = '\0';
/* Initialize the LDAP context. */
ldap = do_reconnect(ap->logopt, ctxt);
--- autofs-5.0.4.orig/modules/mount_autofs.c
+++ autofs-5.0.4/modules/mount_autofs.c
@@ -45,7 +45,8 @@ int mount_mount(struct autofs_point *ap,
{
struct startup_cond suc;
pthread_t thid;
- char *realpath, *mountpoint;
+ char realpath[PATH_MAX];
+ char mountpoint[PATH_MAX];
const char **argv;
int argc, status, ghost = ap->flags & MOUNT_FLAG_GHOST;
time_t timeout = ap->exp_timeout;
@@ -62,8 +63,6 @@ int mount_mount(struct autofs_point *ap,
/* Root offset of multi-mount */
len = strlen(root);
if (root[len - 1] == '/') {
- realpath = alloca(strlen(ap->path) + name_len + 2);
- mountpoint = alloca(len + 1);
strcpy(realpath, ap->path);
strcat(realpath, "/");
strcat(realpath, name);
@@ -71,8 +70,6 @@ int mount_mount(struct autofs_point *ap,
strncpy(mountpoint, root, len);
mountpoint[len] = '\0';
} else if (*name == '/') {
- realpath = alloca(name_len + 1);
- mountpoint = alloca(len + 1);
if (ap->flags & MOUNT_FLAG_REMOUNT) {
strcpy(mountpoint, name);
strcpy(realpath, name);
@@ -81,8 +78,6 @@ int mount_mount(struct autofs_point *ap,
strcpy(realpath, name);
}
} else {
- realpath = alloca(len + name_len + 2);
- mountpoint = alloca(len + name_len + 2);
strcpy(mountpoint, root);
strcat(mountpoint, "/");
strcpy(realpath, mountpoint);
--- autofs-5.0.4.orig/modules/mount_bind.c
+++ autofs-5.0.4/modules/mount_bind.c
@@ -81,8 +81,12 @@ int mount_mount(struct autofs_point *ap,
len = strlen(root);
if (root[len - 1] == '/') {
len = snprintf(fullpath, len, "%s", root);
- /* Direct mount name is absolute path so don't use root */
} else if (*name == '/') {
+ /*
+ * Direct or offset mount, name is absolute path so
+ * don't use root (but with move mount changes root
+ * is now the same as name).
+ */
len = sprintf(fullpath, "%s", root);
} else {
len = sprintf(fullpath, "%s/%s", root, name);
--- autofs-5.0.4.orig/modules/mount_changer.c
+++ autofs-5.0.4/modules/mount_changer.c
@@ -58,8 +58,12 @@ int mount_mount(struct autofs_point *ap,
len = strlen(root);
if (root[len - 1] == '/') {
len = snprintf(fullpath, len, "%s", root);
- /* Direct mount name is absolute path so don't use root */
} else if (*name == '/') {
+ /*
+ * Direct or offset mount, name is absolute path so
+ * don't use root (but with move mount changes root
+ * is now the same as name).
+ */
len = sprintf(fullpath, "%s", root);
} else {
len = sprintf(fullpath, "%s/%s", root, name);
--- autofs-5.0.4.orig/modules/mount_ext2.c
+++ autofs-5.0.4/modules/mount_ext2.c
@@ -50,8 +50,12 @@ int mount_mount(struct autofs_point *ap,
len = strlen(root);
if (root[len - 1] == '/') {
len = snprintf(fullpath, len, "%s", root);
- /* Direct mount name is absolute path so don't use root */
} else if (*name == '/') {
+ /*
+ * Direct or offset mount, name is absolute path so
+ * don't use root (but with move mount changes root
+ * is now the same as name).
+ */
len = sprintf(fullpath, "%s", root);
} else {
len = sprintf(fullpath, "%s/%s", root, name);
--- autofs-5.0.4.orig/modules/mount_generic.c
+++ autofs-5.0.4/modules/mount_generic.c
@@ -49,8 +49,12 @@ int mount_mount(struct autofs_point *ap,
len = strlen(root);
if (root[len - 1] == '/') {
len = snprintf(fullpath, len, "%s", root);
- /* Direct mount name is absolute path so don't use root */
} else if (*name == '/') {
+ /*
+ * Direct or offset mount, name is absolute path so
+ * don't use root (but with move mount changes root
+ * is now the same as name).
+ */
len = sprintf(fullpath, "%s", root);
} else {
len = sprintf(fullpath, "%s/%s", root, name);
--- autofs-5.0.4.orig/modules/mount_nfs.c
+++ autofs-5.0.4/modules/mount_nfs.c
@@ -58,7 +58,8 @@ int mount_mount(struct autofs_point *ap,
const char *what, const char *fstype, const char *options,
void *context)
{
- char *fullpath, buf[MAX_ERR_BUF];
+ char fullpath[PATH_MAX];
+ char buf[MAX_ERR_BUF];
struct host *this, *hosts = NULL;
unsigned int vers;
char *nfsoptions = NULL;
@@ -150,14 +151,15 @@ int mount_mount(struct autofs_point *ap,
/* Root offset of multi-mount */
len = strlen(root);
if (root[len - 1] == '/') {
- fullpath = alloca(len);
len = snprintf(fullpath, len, "%s", root);
- /* Direct mount name is absolute path so don't use root */
} else if (*name == '/') {
- fullpath = alloca(len + 1);
+ /*
+ * Direct or offset mount, name is absolute path so
+ * don't use root (but with move mount changes root
+ * is now the same as name).
+ */
len = sprintf(fullpath, "%s", root);
} else {
- fullpath = alloca(len + name_len + 2);
len = sprintf(fullpath, "%s/%s", root, name);
}
fullpath[len] = '\0';

File diff suppressed because it is too large Load Diff

View File

@ -1,94 +0,0 @@
autofs-5.0.4 - expire specific submount only
From: Ian Kent <raven@themaw.net>
The submount shutdown at expire assumes that certain locks are not
held but when notifying submounts containing nested submounts not
all locks were being released. This leads to occassional deadlock
when child submounts attempt to shutdown.
---
CHANGELOG | 1 +
lib/master.c | 33 ++++++++-------------------------
2 files changed, 9 insertions(+), 25 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 4e8209e..88ca579 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
??/??/2009 autofs-5.0.5
-----------------------
- fix dumb libxml2 check
+- fix nested submount expire deadlock.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/lib/master.c b/lib/master.c
index a243e6a..e1cc062 100644
--- a/lib/master.c
+++ b/lib/master.c
@@ -834,7 +834,6 @@ int master_notify_submount(struct autofs_point *ap, const char *path, enum state
{
struct list_head *head, *p;
struct autofs_point *this = NULL;
- size_t plen = strlen(path);
int ret = 1;
mounts_mutex_lock(ap);
@@ -842,37 +841,19 @@ int master_notify_submount(struct autofs_point *ap, const char *path, enum state
head = &ap->submounts;
p = head->prev;
while (p != head) {
- size_t len;
-
this = list_entry(p, struct autofs_point, mounts);
p = p->prev;
if (!master_submount_list_empty(this)) {
- if (!master_notify_submount(this, path, state)) {
- ret = 0;
- break;
- }
+ mounts_mutex_unlock(ap);
+ return master_notify_submount(this, path, state);
}
- len = strlen(this->path);
-
- /* Initial path not the same */
- if (strncmp(this->path, path, len))
+ /* path not the same */
+ if (strcmp(this->path, path))
continue;
- /*
- * Part of submount tree?
- * We must wait till we get to submount itself.
- * If it is tell caller by returning true.
- */
- if (plen > len) {
- /* Not part of this directory tree */
- if (path[len] != '/')
- continue;
- break;
- }
-
- /* Now we have a submount to expire */
+ /* Now we have found the submount we want to expire */
st_mutex_lock();
@@ -901,8 +882,10 @@ int master_notify_submount(struct autofs_point *ap, const char *path, enum state
struct timespec t = { 0, 300000000 };
struct timespec r;
- if (this->state != ST_SHUTDOWN)
+ if (this->state != ST_SHUTDOWN) {
+ ret = 0;
break;
+ }
st_mutex_unlock();
mounts_mutex_unlock(ap);

View File

@ -1,39 +0,0 @@
autofs-5.0.4 - fix bad token declaration
From: Ian Kent <raven@themaw.net>
Fix an incorrect %token declaration in the master map parser.
In some rare cases this can cause the timeout sent from the tokenizer
to the parser to always be zero.
---
CHANGELOG | 1 +
lib/master_parse.y | 2 +-
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 0ce2a56..fdde400 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -26,6 +26,7 @@
- cleanup configure defines for libtirpc.
- add WITH_LIBTIRPC to -V status report.
- add nfs mount protocol default configuration option.
+- fix bad token declaration in master map parser.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/lib/master_parse.y b/lib/master_parse.y
index 3e598d9..454a2ed 100644
--- a/lib/master_parse.y
+++ b/lib/master_parse.y
@@ -122,7 +122,7 @@ static int master_fprintf(FILE *, char *, ...);
%token <strtype> MAPNULL
%token <strtype> MAPXFN
%token <strtype> MAPNAME
-%token <inttype> NUMBER
+%token <longtype> NUMBER
%token <strtype> OPTION
%start file

View File

@ -1,61 +0,0 @@
autofs-5.0.4 - fix direct map cache locking
From: Ian Kent <raven@themaw.net>
Some time during the recent round of updates some locking of the
null map and the direct map entry caches was removed. This patch
adds it back again.
---
CHANGELOG | 1 +
daemon/direct.c | 6 ++++++
2 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index af7792d..82ebc83 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -60,6 +60,7 @@
- don't block signals we expect to dump core.
- fix pthread push order in expire_proc_direct().
- fix libxml2 non-thread-safe calls.
+- fix direct map cache locking.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/daemon/direct.c b/daemon/direct.c
index 0f33d03..0c78627 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -470,6 +470,8 @@ int mount_autofs_direct(struct autofs_point *ap)
pthread_cleanup_push(master_source_lock_cleanup, ap->entry);
master_source_readlock(ap->entry);
nc = ap->entry->master->nc;
+ cache_readlock(nc);
+ pthread_cleanup_push(cache_lock_cleanup, nc);
map = ap->entry->maps;
while (map) {
/*
@@ -482,6 +484,8 @@ int mount_autofs_direct(struct autofs_point *ap)
}
mc = map->mc;
+ cache_readlock(mc);
+ pthread_cleanup_push(cache_lock_cleanup, mc);
me = cache_enumerate(mc, NULL);
while (me) {
ne = cache_lookup_distinct(nc, me->key);
@@ -509,10 +513,12 @@ int mount_autofs_direct(struct autofs_point *ap)
me = cache_enumerate(mc, me);
}
+ pthread_cleanup_pop(1);
map = map->next;
}
pthread_cleanup_pop(1);
pthread_cleanup_pop(1);
+ pthread_cleanup_pop(1);
return 0;
}

View File

@ -1,53 +0,0 @@
autofs-5.0.4 - fix dont umount existing direct mount on reread
From: Ian Kent <raven@themaw.net>
A recent problem where we incorrectly umounted direct mounts on map
re-read, when the map name in the master map has changed, checks for
the stale entry in an old map source and updates the new entry from
information in the the stale entry. But this check can also match
an entry that has been removed from a direct map whose name hasn't
changed which leads to a deadlock when we try and take the cache
write lock on the (alleged) stale cache to update the new entry.
This is because, in this case, the cache we want to lock is in
fact the one we are reading and we already hold a read lock on it.
---
CHANGELOG | 1 +
daemon/state.c | 10 ++++++++++
2 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 82ebc83..929a21f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -61,6 +61,7 @@
- fix pthread push order in expire_proc_direct().
- fix libxml2 non-thread-safe calls.
- fix direct map cache locking.
+- fix dont umount existing direct mount on reread.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/daemon/state.c b/daemon/state.c
index 84ccba3..71af46a 100644
--- a/daemon/state.c
+++ b/daemon/state.c
@@ -389,6 +389,16 @@ static void do_readmap_mount(struct autofs_point *ap, struct mnt_list *mnts,
* an empty cache awaiting a map re-load.
*/
valid = lookup_source_valid_mapent(ap, me->key, LKP_DISTINCT);
+ if (valid && valid->mc == me->mc) {
+ /*
+ * We've found a map entry that has been removed from
+ * the current cache so there is no need to update it.
+ * The stale entry will be dealt with when we prune the
+ * cache later.
+ */
+ cache_unlock(valid->mc);
+ valid = NULL;
+ }
if (valid) {
struct mapent_cache *vmc = valid->mc;
cache_unlock(vmc);

View File

@ -1,42 +0,0 @@
autofs-5.0.4 - fix double free in do_sasl_bind()
From: Ian Kent <raven@themaw.net>
In do_sasl_bind() the connection negotiation loop can exit with the
local variable server_cred non-null after it has been freed, leading
to a double free.
---
CHANGELOG | 1 +
modules/cyrus-sasl.c | 4 +++-
2 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index e138ca3..f0d0e58 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -53,6 +53,7 @@
- fix not releasing resources when using submounts.
- fix notify mount message path.
- remount we created mount point fix.
+- fix double free in sasl_bind().
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/modules/cyrus-sasl.c b/modules/cyrus-sasl.c
index ec2ab0c..04001d0 100644
--- a/modules/cyrus-sasl.c
+++ b/modules/cyrus-sasl.c
@@ -348,8 +348,10 @@ do_sasl_bind(unsigned logopt, LDAP *ld, sasl_conn_t *conn, const char **clientou
}
}
- if (server_cred && server_cred->bv_len > 0)
+ if (server_cred && server_cred->bv_len > 0) {
ber_bvfree(server_cred);
+ server_cred = NULL;
+ }
} while ((bind_result == LDAP_SASL_BIND_IN_PROGRESS) ||
(sasl_result == SASL_CONTINUE));

View File

@ -1,38 +0,0 @@
autofs-5.0.4 - fix double free in expire_proc()
From: Ian Kent <raven@themaw.net>
In state.c:expire_proc() the function expire_proc_cleanup() is called
which frees the parameter structure but automount frees this again in
the following line.
---
CHANGELOG | 1 +
daemon/state.c | 1 -
2 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 2cb35dc..8860b2c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -28,6 +28,7 @@
- add nfs mount protocol default configuration option.
- fix bad token declaration in master map parser.
- fix return start status on fail.
+- fix double free in expire_proc().
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/daemon/state.c b/daemon/state.c
index 606743b..417fde1 100644
--- a/daemon/state.c
+++ b/daemon/state.c
@@ -298,7 +298,6 @@ static enum expire expire_proc(struct autofs_point *ap, int now)
error(ap->logopt,
"expire thread create for %s failed", ap->path);
expire_proc_cleanup((void *) ea);
- free(ea);
return EXP_ERROR;
}
ap->exp_thread = thid;

View File

@ -1,87 +0,0 @@
autofs-5.0.4 - fix dumb libxml2 check
From: Ian Kent <raven@themaw.net>
The workaround for libxml2 not deleting its thread specific data
key at library unload has become broken. It was foolish of me to
think that the libxml2 folks would fix this in any reasonable time.
This patch changes the version check to 99 for the major and minor
revisions, the same as the check for the revision to ensure that
the workaround is always used and adds the setting to the build
information produced by the -V option.
---
CHANGELOG | 4 ++++
aclocal.m4 | 4 ++--
configure | 4 ++--
daemon/automount.c | 10 ++++++++++
4 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index a618d7e..4e8209e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,7 @@
+??/??/2009 autofs-5.0.5
+-----------------------
+- fix dumb libxml2 check
+
4/11/2008 autofs-5.0.4
-----------------------
- correct configure test for ldapr page control functions.
diff --git a/aclocal.m4 b/aclocal.m4
index 52a1e47..bb0ab21 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -201,10 +201,10 @@ else
XML_FLAGS=`$XML_CONFIG --cflags`
XML_VER=`$XML_CONFIG --version`
XML_MAJOR=`echo $XML_VER|cut -d\. -f1`
- if test $XML_MAJOR -le 2
+ if test $XML_MAJOR -le 99
then
XML_MINOR=`echo $XML_VER|cut -d\. -f2`
- if test $XML_MINOR -le 6
+ if test $XML_MINOR -le 99
then
XML_REV=`echo $XML_VER|cut -d\. -f3`
if test $XML_REV -le 99; then
diff --git a/configure b/configure
index b8cc62f..ed17660 100755
--- a/configure
+++ b/configure
@@ -2564,10 +2564,10 @@ echo "${ECHO_T}yes" >&6; }
XML_FLAGS=`$XML_CONFIG --cflags`
XML_VER=`$XML_CONFIG --version`
XML_MAJOR=`echo $XML_VER|cut -d\. -f1`
- if test $XML_MAJOR -le 2
+ if test $XML_MAJOR -le 99
then
XML_MINOR=`echo $XML_VER|cut -d\. -f2`
- if test $XML_MINOR -le 6
+ if test $XML_MINOR -le 99
then
XML_REV=`echo $XML_VER|cut -d\. -f3`
if test $XML_REV -le 99; then
diff --git a/daemon/automount.c b/daemon/automount.c
index 863aac5..6f078c1 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -1743,6 +1743,16 @@ static void show_build_info(void)
#ifdef WITH_DMALLOC
printf("WITH_DMALLOC ");
count = count + 13;
+
+ if (count > 60) {
+ printf("\n ");
+ count = 0;
+ }
+#endif
+
+#ifdef LIBXML2_WORKAROUND
+ printf("LIBXML2_WORKAROUND ");
+ count = count + 19;
#endif
printf("\n\n");

View File

@ -1,52 +0,0 @@
autofs-5.0.4 - fix hosts map use after free
From: Ian Kent <raven@themaw.net>
This patch fixed use a map entry after it has been freed in the
hosts map lookup module.
---
CHANGELOG | 1 +
modules/lookup_hosts.c | 8 +++++---
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index eb4a189..3199e4d 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -9,6 +9,7 @@
Valerie Aurora Henson).
- clear the quoted flag after each character from program map input.
- use CLOEXEC flag for setmntent also.
+- fix hosts map use after free.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
index 93b975a..d3ae0e2 100644
--- a/modules/lookup_hosts.c
+++ b/modules/lookup_hosts.c
@@ -138,17 +138,19 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
/* Check if we recorded a mount fail for this key anywhere */
me = lookup_source_mapent(ap, name, LKP_DISTINCT);
if (me) {
+ struct mapent_cache *fmc = me->mc;
+
if (me->status >= time(NULL)) {
- cache_unlock(me->mc);
+ cache_unlock(fmc);
return NSS_STATUS_NOTFOUND;
}
if (!me->mapent) {
- cache_delete(me->mc, name);
+ cache_delete(fmc, name);
me = NULL;
}
- cache_unlock(me->mc);
+ cache_unlock(fmc);
}
cache_readlock(mc);

View File

@ -1,39 +0,0 @@
autofs-5.0.4 - fix incorrect dclist free
From: Ian Kent <raven@themaw.net>
We incorrectly try to free dclist in modules/lookup_ldap.c:find_server().
---
modules/lookup_ldap.c | 10 ++++++++--
1 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index f6b3f42..8f352d6 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -688,6 +688,10 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
}
}
if (!uri) {
+ if (dclist) {
+ free_dclist(dclist);
+ dclist = NULL;
+ }
p = p->next;
continue;
}
@@ -700,8 +704,10 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
}
free(uri);
uri = NULL;
- free_dclist(dclist);
- dclist = NULL;
+ if (dclist) {
+ free_dclist(dclist);
+ dclist = NULL;
+ }
p = p->next;
}

View File

@ -1,103 +0,0 @@
autofs-5.0.4 - fix kernel includes
From: Valerie Aurora Henson <vaurora@redhat.com>
autofs_dev-ioctl.h is included by both the kernel module and autofs,
and it includes two kernel header files. The compile worked if the
kernel headers were installed but failed otherwise.
imk: there are a couple of other instances were we include kernel
headers. I've tried to fix that up too.
---
CHANGELOG | 1 +
include/automount.h | 3 +--
include/dev-ioctl-lib.h | 3 +--
include/linux/auto_dev-ioctl.h | 7 ++++++-
include/linux/auto_fs.h | 6 ++++--
5 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index a42dd14..387af5e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -42,6 +42,7 @@
- zero s_magic is valid.
- use percent hack for master map keys.
- use intr option as hosts mount default.
+- fix kernel includes.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/include/automount.h b/include/automount.h
index 615e07d..d4675bd 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -8,12 +8,11 @@
#ifndef AUTOMOUNT_H
#define AUTOMOUNT_H
-#include <sys/types.h>
#include <paths.h>
#include <limits.h>
#include <time.h>
#include <syslog.h>
-#include <linux/types.h>
+#include <sys/types.h>
#include <pthread.h>
#include <sched.h>
#include <errno.h>
diff --git a/include/dev-ioctl-lib.h b/include/dev-ioctl-lib.h
index b7b8211..6d35da2 100644
--- a/include/dev-ioctl-lib.h
+++ b/include/dev-ioctl-lib.h
@@ -21,8 +21,7 @@
#ifndef AUTOFS_DEV_IOCTL_LIB_H
#define AUTOFS_DEV_IOCTL_LIB_H
-#include <sys/types.h>
-#include "linux/auto_dev-ioctl.h"
+#include <linux/auto_dev-ioctl.h>
#define CONTROL_DEVICE "/dev/autofs"
diff --git a/include/linux/auto_dev-ioctl.h b/include/linux/auto_dev-ioctl.h
index 91a7739..850f39b 100644
--- a/include/linux/auto_dev-ioctl.h
+++ b/include/linux/auto_dev-ioctl.h
@@ -10,8 +10,13 @@
#ifndef _LINUX_AUTO_DEV_IOCTL_H
#define _LINUX_AUTO_DEV_IOCTL_H
+#include <linux/auto_fs.h>
+
+#ifdef __KERNEL__
#include <linux/string.h>
-#include <linux/types.h>
+#else
+#include <string.h>
+#endif /* __KERNEL__ */
#define AUTOFS_DEVICE_NAME "autofs"
diff --git a/include/linux/auto_fs.h b/include/linux/auto_fs.h
index bd39f09..91d414f 100644
--- a/include/linux/auto_fs.h
+++ b/include/linux/auto_fs.h
@@ -17,11 +17,13 @@
#ifdef __KERNEL__
#include <linux/fs.h>
#include <linux/limits.h>
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#else
#include <asm/types.h>
+#include <sys/ioctl.h>
#endif /* __KERNEL__ */
-#include <linux/ioctl.h>
-
/* This file describes autofs v3 */
#define AUTOFS_PROTO_VERSION 3

View File

@ -1,115 +0,0 @@
autofs-5.0.4 - fix ldap detection
From: Guillaume Rousse <Guillaume.Rousse@inria.fr>
The test for LDAP library wrongly use LDFLAGS to add -lldap to the gcc
call. However, when strict linker ordering is in effect, it doesn't work
correctly. As described in autoconf documentation, additional libs
should be added through LIBS variable instead.
---
aclocal.m4 | 20 ++++++++++----------
configure | 20 ++++++++++----------
2 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/aclocal.m4 b/aclocal.m4
index bb0ab21..ab11112 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -246,9 +246,9 @@ dnl --------------------------------------------------------------------------
AC_DEFUN([AF_CHECK_FUNC_LDAP_CREATE_PAGE_CONTROL],
[AC_MSG_CHECKING(for ldap_create_page_control in -lldap)
-# save current ldflags
-af_check_ldap_create_page_control_save_ldflags="$LDFLAGS"
-LDFLAGS="$LDFLAGS -lldap"
+# save current libs
+af_check_ldap_create_page_control_save_libs="$LIBS"
+LIBS="$LIBS -lldap"
AC_TRY_LINK(
[ #include <ldap.h> ],
@@ -267,8 +267,8 @@ if test "$af_have_ldap_create_page_control" = "yes"; then
[Define to 1 if you have the `ldap_create_page_control' function.])
fi
-# restore ldflags
-LDFLAGS="$af_check_ldap_create_page_control_save_ldflags"
+# restore libs
+LIBS="$af_check_ldap_create_page_control_save_libs"
])
dnl --------------------------------------------------------------------------
@@ -279,9 +279,9 @@ dnl --------------------------------------------------------------------------
AC_DEFUN([AF_CHECK_FUNC_LDAP_PARSE_PAGE_CONTROL],
[AC_MSG_CHECKING(for ldap_parse_page_control in -lldap)
-# save current ldflags
-af_check_ldap_parse_page_control_save_ldflags="$LDFLAGS"
-LDFLAGS="$LDFLAGS -lldap"
+# save current libs
+af_check_ldap_parse_page_control_save_libs="$LIBS"
+LIBS="$LIBS -lldap"
AC_TRY_LINK(
[ #include <ldap.h> ],
@@ -300,7 +300,7 @@ if test "$af_have_ldap_create_page_control" = "yes"; then
[Define to 1 if you have the `ldap_parse_page_control' function.])
fi
-# restore ldflags
-LDFLAGS="$af_check_ldap_parse_page_control_save_ldflags"
+# restore libs
+LIBS="$af_check_ldap_parse_page_control_save_libs"
])
diff --git a/configure b/configure
index ed17660..afa692c 100755
--- a/configure
+++ b/configure
@@ -4608,9 +4608,9 @@ _ACEOF
{ echo "$as_me:$LINENO: checking for ldap_create_page_control in -lldap" >&5
echo $ECHO_N "checking for ldap_create_page_control in -lldap... $ECHO_C" >&6; }
-# save current ldflags
-af_check_ldap_create_page_control_save_ldflags="$LDFLAGS"
-LDFLAGS="$LDFLAGS -lldap"
+# save current libs
+af_check_ldap_create_page_control_save_libs="$LIBS"
+LIBS="$LIBS -lldap"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
@@ -4672,15 +4672,15 @@ _ACEOF
fi
-# restore ldflags
-LDFLAGS="$af_check_ldap_create_page_control_save_ldflags"
+# restore libs
+LIBS="$af_check_ldap_create_page_control_save_libs"
{ echo "$as_me:$LINENO: checking for ldap_parse_page_control in -lldap" >&5
echo $ECHO_N "checking for ldap_parse_page_control in -lldap... $ECHO_C" >&6; }
-# save current ldflags
-af_check_ldap_parse_page_control_save_ldflags="$LDFLAGS"
-LDFLAGS="$LDFLAGS -lldap"
+# save current libs
+af_check_ldap_parse_page_control_save_libs="$LIBS"
+LIBS="$LIBS -lldap"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
@@ -4742,8 +4742,8 @@ _ACEOF
fi
-# restore ldflags
-LDFLAGS="$af_check_ldap_parse_page_control_save_ldflags"
+# restore libs
+LIBS="$af_check_ldap_parse_page_control_save_libs"
fi

View File

@ -1,100 +0,0 @@
autofs-5.0.4 - fix libxml2 non-thread-safe calls
From: Ian Kent <raven@themaw.net>
The libxml2 call xmlCleanupParser() is definitely not thread safe.
This patch moves it and the xmlInitParser() call to the location
of the code to workaround the libxml2 incorrect TSD handling so
they are called only at start and at exit.
---
CHANGELOG | 1 +
daemon/Makefile | 7 +++++++
daemon/automount.c | 7 ++++++-
modules/lookup_ldap.c | 2 --
4 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 4491449..af7792d 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -59,6 +59,7 @@
- fix an RPC fd leak.
- don't block signals we expect to dump core.
- fix pthread push order in expire_proc_direct().
+- fix libxml2 non-thread-safe calls.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/daemon/Makefile b/daemon/Makefile
index 9c2d858..371ec72 100644
--- a/daemon/Makefile
+++ b/daemon/Makefile
@@ -22,6 +22,13 @@ CFLAGS += -DVERSION_STRING=\"$(version)\"
LDFLAGS += -rdynamic
LIBS = -ldl
+ifeq ($(LDAP), 1)
+ ifeq ($(SASL), 1)
+ CFLAGS += $(XML_FLAGS)
+ LIBS += $(XML_LIBS)
+ endif
+endif
+
all: automount
automount: $(OBJS) $(AUTOFS_LIB)
diff --git a/daemon/automount.c b/daemon/automount.c
index 6759883..979ecd6 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -40,6 +40,7 @@
#include "automount.h"
#ifdef LIBXML2_WORKAROUND
#include <dlfcn.h>
+#include <libxml/parser.h>
#endif
const char *program; /* Initialized with argv[0] */
@@ -2113,6 +2114,8 @@ int main(int argc, char *argv[])
void *dh_xml2 = dlopen("libxml2.so", RTLD_NOW);
if (!dh_xml2)
dh_xml2 = dlopen("libxml2.so.2", RTLD_NOW);
+ if (dh_xml2)
+ xmlInitParser();
#endif
#ifdef TIRPC_WORKAROUND
void *dh_tirpc = dlopen("libitirpc.so", RTLD_NOW);
@@ -2156,8 +2159,10 @@ int main(int argc, char *argv[])
dlclose(dh_tirpc);
#endif
#ifdef LIBXML2_WORKAROUND
- if (dh_xml2)
+ if (dh_xml2) {
+ xmlCleanupParser();
dlclose(dh_xml2);
+ }
#endif
close_ioctl_ctl();
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 8f352d6..2ecf5fe 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -897,7 +897,6 @@ int parse_ldap_config(unsigned logopt, struct lookup_context *ctxt)
return -1;
}
- xmlInitParser();
doc = xmlParseFile(auth_conf);
if (!doc) {
error(logopt, MODPREFIX
@@ -1069,7 +1068,6 @@ int parse_ldap_config(unsigned logopt, struct lookup_context *ctxt)
out:
xmlFreeDoc(doc);
- xmlCleanupParser();
if (fallback)
return 0;

View File

@ -1,57 +0,0 @@
autofs-5.0.4 - fix lsb init script header
From: Ian Kent <raven@themaw.net>
It truns out that "Should-Start:" is not sufficient to enforce
the required ordering of services and a "Required-Start:" is
needed instead.
---
CHANGELOG | 1 +
redhat/autofs.init.in | 4 ++--
samples/rc.autofs.in | 4 ++--
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 91edd14..2be7683 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -35,6 +35,7 @@
- use misc device ioctl interface by default, if available.
- fix call restorecon when misc device file doesn't exist.
- clear rpc client on lookup fail.
+- fix lsb init script header.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/redhat/autofs.init.in b/redhat/autofs.init.in
index a9a33c8..fded1d8 100644
--- a/redhat/autofs.init.in
+++ b/redhat/autofs.init.in
@@ -9,8 +9,8 @@
#
### BEGIN INIT INFO
# Provides: $autofs
-# Should-Start: $network $ypbind
-# Should-Stop: $network $ypbind
+# Required-Start: $network $ypbind
+# Required-Stop: $network $ypbind
# Default-Start: 3 4 5
# Default-Stop: 0 1 2 6
# Short-Description: Automounts filesystems on demand
diff --git a/samples/rc.autofs.in b/samples/rc.autofs.in
index 78cbec2..b193a4e 100644
--- a/samples/rc.autofs.in
+++ b/samples/rc.autofs.in
@@ -8,8 +8,8 @@
#
### BEGIN INIT INFO
# Provides: $autofs
-# Should-Start: $network $ypbind
-# Should-Stop: $network $ypbind
+# Required-Start: $network $ypbind
+# Required-Stop: $network $ypbind
# Default-Start: 3 4 5
# Default-Stop: 0 1 2 6
# Short-Description: Automounts filesystems on demand

View File

@ -1,165 +0,0 @@
autofs-5.0.4 - fix map type info parse error update
From: Ian Kent <raven@themaw.net>
Make parsing map type info more robust.
---
lib/parse_subs.c | 123 +++++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 102 insertions(+), 21 deletions(-)
diff --git a/lib/parse_subs.c b/lib/parse_subs.c
index 0608cb7..2326838 100644
--- a/lib/parse_subs.c
+++ b/lib/parse_subs.c
@@ -20,6 +20,30 @@
#include <ctype.h>
#include "automount.h"
+struct types {
+ char *type;
+ unsigned int len;
+};
+
+static struct types map_type[] = {
+ { "file", 4 },
+ { "program", 7 },
+ { "yp", 2 },
+ { "nis", 3 },
+ { "nisplus", 7 },
+ { "ldap", 4 },
+ { "ldaps", 5 },
+ { "hesiod", 6 },
+ { "userdir", 7 },
+};
+static unsigned int map_type_count = sizeof(map_type)/sizeof(struct types);
+
+static struct types format_type[] = {
+ { "sun", 3 },
+ { "hesiod", 6 },
+};
+static unsigned int format_type_count = sizeof(format_type)/sizeof(struct types);
+
/*
* Skip whitespace in a string; if we hit a #, consider the rest of the
* entry a comment.
@@ -315,7 +339,7 @@ struct map_type_info *parse_map_type_info(const char *str)
{
struct map_type_info *info;
char *buf, *type, *fmt, *map, *tmp;
- int seen_colon = 0;
+ char *pos;
buf = strdup(str);
if (!buf)
@@ -328,32 +352,89 @@ struct map_type_info *parse_map_type_info(const char *str)
}
memset(info, 0, sizeof(struct map_type_info));
- type = fmt = NULL;
+ type = fmt = map = NULL;
+
+ tmp = strchr(buf, ':');
+ if (!tmp) {
+ pos = buf;
+ while (*pos == ' ')
+ *pos++ = '\0';
+ map = pos;
+ } else {
+ int i, j;
+
+ for (i = 0; i < map_type_count; i++) {
+ char *m_type = map_type[i].type;
+ unsigned int m_len = map_type[i].len;
+
+ pos = buf;
+
+ if (strncmp(m_type, pos, m_len))
+ continue;
+
+ type = pos;
+ pos += m_len;
+
+ if (*pos == ' ' || *pos == ':') {
+ while (*pos == ' ')
+ *pos++ = '\0';
+ if (*pos != ':') {
+ free(buf);
+ free(info);
+ return NULL;
+ } else {
+ *pos++ = '\0';
+ while (*pos == ' ')
+ *pos++ = '\0';
+ map = pos;
+ break;
+ }
+ }
+
+ if (*pos == ',') {
+ *pos++ = '\0';
+ for (j = 0; j < format_type_count; j++) {
+ char *f_type = format_type[j].type;
+ unsigned int f_len = format_type[j].len;
+
+ if (strncmp(f_type, pos, f_len))
+ continue;
+
+ fmt = pos;
+ pos += f_len;
+
+ if (*pos == ' ' || *pos == ':') {
+ while (*pos == ' ')
+ *pos++ = '\0';
+ if (*pos != ':') {
+ free(buf);
+ free(info);
+ return NULL;
+ } else {
+ *pos++ = '\0';
+ while (*pos == ' ')
+ *pos++ = '\0';
+ map = pos;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (!type) {
+ pos = buf;
+ while (*pos == ' ')
+ *pos++ = '\0';
+ map = pos;
+ }
+ }
/* Look for space terminator - ignore local options */
- map = buf;
for (tmp = buf; *tmp; tmp++) {
if (*tmp == ' ') {
*tmp = '\0';
break;
- } else if (!seen_colon && *tmp == ',') {
- type = buf;
- *tmp++ = '\0';
- fmt = tmp;
- } else if (*tmp == ':') {
- seen_colon = 1;
- if (!fmt)
- type = buf;
- *tmp++ = '\0';
- map = tmp;
- } else if (*tmp == '[') {
- /*
- * Unescaped '[' is a syntax error here as only
- * an ldap map with a type specified should contain
- * them.
- */
- free(buf);
- return 0;
}
if (*tmp == '\\')
tmp++;

View File

@ -1,51 +0,0 @@
autofs-5.0.4 - fix map type info parse error
From: Ian Kent <raven@themaw.net>
Fix a mistake in map type info parsing introduced by the IPv6 parse
changes.
---
CHANGELOG | 1 +
lib/parse_subs.c | 4 +++-
2 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 05e0206..3fd97d3 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -55,6 +55,7 @@
- remount we created mount point fix.
- fix double free in sasl_bind().
- mannual umount recovery fixes.
+- fix map type info parse error.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/lib/parse_subs.c b/lib/parse_subs.c
index 0cba95a..0608cb7 100644
--- a/lib/parse_subs.c
+++ b/lib/parse_subs.c
@@ -315,6 +315,7 @@ struct map_type_info *parse_map_type_info(const char *str)
{
struct map_type_info *info;
char *buf, *type, *fmt, *map, *tmp;
+ int seen_colon = 0;
buf = strdup(str);
if (!buf)
@@ -335,11 +336,12 @@ struct map_type_info *parse_map_type_info(const char *str)
if (*tmp == ' ') {
*tmp = '\0';
break;
- } else if (*tmp == ',') {
+ } else if (!seen_colon && *tmp == ',') {
type = buf;
*tmp++ = '\0';
fmt = tmp;
} else if (*tmp == ':') {
+ seen_colon = 1;
if (!fmt)
type = buf;
*tmp++ = '\0';

View File

@ -1,38 +0,0 @@
autofs-5.0.4 - fix memory leak reading ldap master map
From: Ian Kent <raven@themaw.net>
When reading the master map the storage allocated by getting the location
value is not freed after use.
---
CHANGELOG | 1 +
modules/lookup_ldap.c | 2 ++
2 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 2be7683..a143294 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -36,6 +36,7 @@
- fix call restorecon when misc device file doesn't exist.
- clear rpc client on lookup fail.
- fix lsb init script header.
+- fix memory leak reading master map.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 5a54b5f..9b1180c 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -1563,6 +1563,8 @@ int lookup_read_master(struct master *master, time_t age, void *context)
ldap_value_free(values);
goto next;
}
+ ldap_value_free(values);
+
master_parse_entry(parse_buf, timeout, logging, age);
next:
ldap_value_free(keyValue);

View File

@ -1,331 +0,0 @@
autofs-5.0.4 - fix negative cache non-existent key
From: Ian Kent <raven@themaw.net>
autofs was not recording map entries that don't exist for negative
caching. This was causing unwanted network map lookups.
---
CHANGELOG | 1 +
daemon/lookup.c | 48 ++++++++++++++++++++++++++++++++++++++++++++--
modules/lookup_file.c | 20 ++++++++++++-------
modules/lookup_hosts.c | 21 ++++++++++++++++----
modules/lookup_ldap.c | 20 ++++++++++++-------
modules/lookup_nisplus.c | 19 ++++++++++++------
modules/lookup_program.c | 35 ++++++++++++++++++++++++++--------
modules/lookup_yp.c | 19 ++++++++++++------
8 files changed, 143 insertions(+), 40 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 88ca579..bd35b00 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,7 @@
-----------------------
- fix dumb libxml2 check
- fix nested submount expire deadlock.
+- fix negative caching for non-existent map keys.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/daemon/lookup.c b/daemon/lookup.c
index 803df4f..0cf6e3f 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -804,6 +804,45 @@ static enum nsswitch_status lookup_map_name(struct nss_source *this,
return result;
}
+static void update_negative_cache(struct autofs_point *ap, struct map_source *source, const char *name)
+{
+ struct master_mapent *entry = ap->entry;
+ struct map_source *map;
+ struct mapent *me;
+
+ /* Have we recorded the lookup fail for negative caching? */
+ me = lookup_source_mapent(ap, name, LKP_DISTINCT);
+ if (me)
+ /*
+ * Already exists in the cache, the mount fail updates
+ * will update negative timeout status.
+ */
+ cache_unlock(me->mc);
+ else {
+ /* Notify only once after fail */
+ error(ap->logopt, "key \"%s\" not found in map.", name);
+
+ /* Doesn't exist in any source, just add it somewhere */
+ if (source)
+ map = source;
+ else
+ map = entry->maps;
+ if (map) {
+ time_t now = time(NULL);
+ int rv = CHE_FAIL;
+
+ cache_writelock(map->mc);
+ rv = cache_update(map->mc, map, name, NULL, now);
+ if (rv != CHE_FAIL) {
+ me = cache_lookup_distinct(map->mc, name);
+ me->status = now + ap->negative_timeout;
+ }
+ cache_unlock(map->mc);
+ }
+ }
+ return;
+}
+
int lookup_nss_mount(struct autofs_point *ap, struct map_source *source, const char *name, int name_len)
{
struct master_mapent *entry = ap->entry;
@@ -907,8 +946,13 @@ int lookup_nss_mount(struct autofs_point *ap, struct map_source *source, const c
send_map_update_request(ap);
pthread_cleanup_pop(1);
- if (result == NSS_STATUS_NOTFOUND)
- error(ap->logopt, "key \"%s\" not found in map.", name);
+ /*
+ * The last source lookup will return NSS_STATUS_NOTFOUND if the
+ * map exits and the key has not been found but the map may also
+ * not exist in which case the key is also not found.
+ */
+ if (result == NSS_STATUS_NOTFOUND || result == NSS_STATUS_UNAVAIL)
+ update_negative_cache(ap, source, name);
return !result;
}
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index 807ceab..9e34b72 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -1069,14 +1069,20 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
if (key_len > KEY_MAX_LEN)
return NSS_STATUS_NOTFOUND;
- /* Check if we recorded a mount fail for this key */
- cache_readlock(mc);
- me = cache_lookup_distinct(mc, key);
- if (me && me->status >= time(NULL)) {
- cache_unlock(mc);
- return NSS_STATUS_UNAVAIL;
+ /* Check if we recorded a mount fail for this key anywhere */
+ me = lookup_source_mapent(ap, key, LKP_DISTINCT);
+ if (me) {
+ if (me->status >= time(NULL)) {
+ cache_unlock(me->mc);
+ return NSS_STATUS_NOTFOUND;
+ }
+
+ /* Negative timeout expired for non-existent entry. */
+ if (!me->mapent)
+ cache_delete(me->mc, key);
+
+ cache_unlock(me->mc);
}
- cache_unlock(mc);
/*
* We can't check the direct mount map as if it's not in
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
index bf24d7f..f8d4269 100644
--- a/modules/lookup_hosts.c
+++ b/modules/lookup_hosts.c
@@ -136,12 +136,25 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
mc = source->mc;
+ /* Check if we recorded a mount fail for this key anywhere */
+ me = lookup_source_mapent(ap, name, LKP_DISTINCT);
+ if (me) {
+ if (me->status >= time(NULL)) {
+ cache_unlock(me->mc);
+ return NSS_STATUS_NOTFOUND;
+ }
+
+ if (!me->mapent) {
+ cache_delete(me->mc, name);
+ me = NULL;
+ }
+
+ cache_unlock(me->mc);
+ }
+
cache_readlock(mc);
me = cache_lookup_distinct(mc, name);
- if (me && me->status >= time(NULL)) {
- cache_unlock(mc);
- return NSS_STATUS_NOTFOUND;
- } else if (!me) {
+ if (!me) {
cache_unlock(mc);
/*
* We haven't read the list of hosts into the
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 31c2c13..42c3235 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -2709,14 +2709,20 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
if (key_len > KEY_MAX_LEN)
return NSS_STATUS_NOTFOUND;
- /* Check if we recorded a mount fail for this key */
- cache_readlock(mc);
- me = cache_lookup_distinct(mc, key);
- if (me && me->status >= time(NULL)) {
- cache_unlock(mc);
- return NSS_STATUS_NOTFOUND;
+ /* Check if we recorded a mount fail for this key anywhere */
+ me = lookup_source_mapent(ap, key, LKP_DISTINCT);
+ if (me) {
+ if (me->status >= time(NULL)) {
+ cache_unlock(me->mc);
+ return NSS_STATUS_NOTFOUND;
+ }
+
+ /* Negative timeout expired for non-existent entry. */
+ if (!me->mapent)
+ cache_delete(me->mc, key);
+
+ cache_unlock(me->mc);
}
- cache_unlock(mc);
/*
* We can't check the direct mount map as if it's not in
diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
index 755556d..f15465f 100644
--- a/modules/lookup_nisplus.c
+++ b/modules/lookup_nisplus.c
@@ -493,13 +493,20 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
if (key_len > KEY_MAX_LEN)
return NSS_STATUS_NOTFOUND;
- cache_readlock(mc);
- me = cache_lookup_distinct(mc, key);
- if (me && me->status >= time(NULL)) {
- cache_unlock(mc);
- return NSS_STATUS_NOTFOUND;
+ /* Check if we recorded a mount fail for this key anywhere */
+ me = lookup_source_mapent(ap, key, LKP_DISTINCT);
+ if (me) {
+ if (me->status >= time(NULL)) {
+ cache_unlock(me->mc);
+ return NSS_STATUS_NOTFOUND;
+ }
+
+ /* Negative timeout expired for non-existent entry. */
+ if (!me->mapent)
+ cache_delete(me->mc, key);
+
+ cache_unlock(me->mc);
}
- cache_unlock(mc);
/*
* We can't check the direct mount map as if it's not in
diff --git a/modules/lookup_program.c b/modules/lookup_program.c
index daf874d..bf32d3b 100644
--- a/modules/lookup_program.c
+++ b/modules/lookup_program.c
@@ -131,13 +131,25 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
mc = source->mc;
+ /* Check if we recorded a mount fail for this key anywhere */
+ me = lookup_source_mapent(ap, name, LKP_DISTINCT);
+ if (me) {
+ if (me->status >= time(NULL)) {
+ cache_unlock(me->mc);
+ return NSS_STATUS_NOTFOUND;
+ }
+
+ /* Negative timeout expired for non-existent entry. */
+ if (!me->mapent)
+ cache_delete(me->mc, name);
+
+ cache_unlock(me->mc);
+ }
+
/* Catch installed direct offset triggers */
- cache_readlock(mc);
+ cache_writelock(mc);
me = cache_lookup_distinct(mc, name);
- if (me && me->status >= time(NULL)) {
- cache_unlock(mc);
- return NSS_STATUS_NOTFOUND;
- } else if (!me) {
+ if (!me) {
cache_unlock(mc);
/*
* If there's a '/' in the name and the offset is not in
@@ -149,8 +161,6 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
return NSS_STATUS_NOTFOUND;
}
} else {
- cache_unlock(mc);
-
/* Otherwise we found a valid offset so try mount it */
debug(ap->logopt, MODPREFIX "%s -> %s", name, me->mapent);
@@ -163,19 +173,28 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
*/
if (strchr(name, '/') ||
me->age + ap->negative_timeout > time(NULL)) {
+ char *ent = NULL;
+
+ if (me->mapent) {
+ ent = alloca(strlen(me->mapent) + 1);
+ strcpy(ent, me->mapent);
+ }
+ cache_unlock(mc);
master_source_current_wait(ap->entry);
ap->entry->current = source;
ret = ctxt->parse->parse_mount(ap, name,
- name_len, me->mapent, ctxt->parse->context);
+ name_len, ent, ctxt->parse->context);
goto out_free;
} else {
if (me->multi) {
+ cache_unlock(mc);
warn(ap->logopt, MODPREFIX
"unexpected lookup for active multi-mount"
" key %s, returning fail", name);
return NSS_STATUS_UNAVAIL;
}
cache_delete(mc, name);
+ cache_unlock(mc);
}
}
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
index 8b6408b..1b62f57 100644
--- a/modules/lookup_yp.c
+++ b/modules/lookup_yp.c
@@ -603,13 +603,20 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
if (key_len > KEY_MAX_LEN)
return NSS_STATUS_NOTFOUND;
- cache_readlock(mc);
- me = cache_lookup_distinct(mc, key);
- if (me && me->status >= time(NULL)) {
- cache_unlock(mc);
- return NSS_STATUS_NOTFOUND;
+ /* Check if we recorded a mount fail for this key anywhere */
+ me = lookup_source_mapent(ap, key, LKP_DISTINCT);
+ if (me) {
+ if (me->status >= time(NULL)) {
+ cache_unlock(me->mc);
+ return NSS_STATUS_NOTFOUND;
+ }
+
+ /* Negative timeout expired for non-existent entry. */
+ if (!me->mapent)
+ cache_delete(me->mc, key);
+
+ cache_unlock(me->mc);
}
- cache_unlock(mc);
/*
* We can't check the direct mount map as if it's not in

View File

@ -1,61 +0,0 @@
autofs-5.0.4 - fix notify mount message path
From: Ian Kent <raven@themaw.net>
If logging is set to verbose we want to log the actual path rather
than the false root. Hoevever, when logging is set to debug we do
need to show the false root to give us the true picture in relation
to accompanying log messages.
---
CHANGELOG | 1 +
daemon/direct.c | 5 ++++-
daemon/indirect.c | 5 ++++-
3 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index d1cc113..0a0519f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -51,6 +51,7 @@
- always read file maps key lookup fixes.
- use srv query for domain dn.
- fix not releasing resources when using submounts.
+- fix notify mount message path.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/daemon/direct.c b/daemon/direct.c
index 1ed2b15..74a9acc 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -767,8 +767,11 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char *
}
ops->timeout(ap->logopt, ioctlfd, &timeout);
- notify_mount_result(ap, mountpoint, str_offset);
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);
+ else
+ notify_mount_result(ap, me->key, str_offset);
ops->close(ap->logopt, ioctlfd);
debug(ap->logopt, "mounted trigger %s at %s", me->key, mountpoint);
diff --git a/daemon/indirect.c b/daemon/indirect.c
index bc39e63..463b39c 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -174,7 +174,10 @@ static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root)
ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
ops->timeout(ap->logopt, ap->ioctlfd, &timeout);
- notify_mount_result(ap, root, str_indirect);
+ if (ap->logopt & LOGOPT_DEBUG)
+ notify_mount_result(ap, root, str_indirect);
+ else
+ notify_mount_result(ap, ap->path, str_indirect);
return 0;

View File

@ -1,36 +0,0 @@
autofs-5.0.4 - fix pthread push order in expire_proc_direct()
From: Ian Kent <raven@themaw.net>
Apparently the pthread_cleanup_push() has the quite stupid semantic
of not working properly if the value of the pointer passed to it
changes after it has been called.
---
CHANGELOG | 1 +
daemon/direct.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
--- autofs-5.0.4.orig/CHANGELOG
+++ autofs-5.0.4/CHANGELOG
@@ -58,6 +58,7 @@
- fix map type info parse error.
- fix an RPC fd leak.
- don't block signals we expect to dump core.
+- fix pthread push order in expire_proc_direct().
4/11/2008 autofs-5.0.4
-----------------------
--- autofs-5.0.4.orig/daemon/direct.c
+++ autofs-5.0.4/daemon/direct.c
@@ -823,8 +823,8 @@ void *expire_proc_direct(void *arg)
left = 0;
- pthread_cleanup_push(mnts_cleanup, mnts);
mnts = tree_make_mnt_tree(_PROC_MOUNTS, "/");
+ pthread_cleanup_push(mnts_cleanup, mnts);
/* Get a list of mounts select real ones and expire them if possible */
INIT_LIST_HEAD(&list);

View File

@ -1,34 +0,0 @@
autofs-5.0.4 - clear the quoted flag after each character
From: Jeff Moyer <jmoyer@redhat.com>
This regression was introduced by autofs-5.0.4-fix-select-fd-limit.patch.
The fix is to clear the quoted flag after processing each character from
program map input.
---
CHANGELOG | 1 +
modules/lookup_program.c | 1 +
2 files changed, 2 insertions(+)
--- autofs-5.0.4.orig/CHANGELOG
+++ autofs-5.0.4/CHANGELOG
@@ -7,6 +7,7 @@
- fix select(2) fd limit.
- make hash table scale to thousands of entries (Paul Wankadia,
Valerie Aurora Henson).
+- clear the quoted flag after each character from program map input.
4/11/2008 autofs-5.0.4
-----------------------
--- autofs-5.0.4.orig/modules/lookup_program.c
+++ autofs-5.0.4/modules/lookup_program.c
@@ -341,6 +341,7 @@ cont:
/* Eat characters till there's no more output */
break;
}
+ quoted = 0;
goto cont;
}
quoted = 0;

View File

@ -1,51 +0,0 @@
autofs-5.0.4 - fix restorecon
From: Ian Kent <raven@themaw.net>
If the misc device node doesn't exist don't try to run restorecon on it.
---
CHANGELOG | 1 +
redhat/autofs.init.in | 2 +-
samples/rc.autofs.in | 2 +-
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 96a4617..00b455e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -33,6 +33,7 @@
- add LSB init script parameter block.
- fix file map lookup when reading included or nsswitch sources.
- use misc device ioctl interface by default, if available.
+- fix call restorecon when misc device file doesn't exist.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/redhat/autofs.init.in b/redhat/autofs.init.in
index 0fd1777..a9a33c8 100644
--- a/redhat/autofs.init.in
+++ b/redhat/autofs.init.in
@@ -76,7 +76,7 @@ function start() {
mknod -m 0600 /dev/$DEVICE c 10 $MINOR
fi
fi
- if [ -x /sbin/restorecon ]; then
+ if [ -x /sbin/restorecon -a -c /dev/$DEVICE ]; then
/sbin/restorecon /dev/$DEVICE
fi
else
diff --git a/samples/rc.autofs.in b/samples/rc.autofs.in
index 63a0c5d..78cbec2 100644
--- a/samples/rc.autofs.in
+++ b/samples/rc.autofs.in
@@ -66,7 +66,7 @@ function start() {
mknod -m 0600 /dev/$DEVICE c 10 $MINOR
fi
fi
- if [ -x /sbin/restorecon ]; then
+ if [ -x /sbin/restorecon -a -c /dev/$DEVICE ]; then
/sbin/restorecon /dev/$DEVICE
fi
else

View File

@ -1,157 +0,0 @@
autofs-5.0.4 - fix return start status on fail
From: Ian Kent <raven@themaw.net>
We're not returning the status to the parent when automount(8) is waiting
for the daemon to finish its startup.
---
CHANGELOG | 1 +
daemon/automount.c | 27 +++++++++++++++++++++------
2 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index fdde400..2cb35dc 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -27,6 +27,7 @@
- add WITH_LIBTIRPC to -V status report.
- add nfs mount protocol default configuration option.
- fix bad token declaration in master map parser.
+- fix return start status on fail.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/daemon/automount.c b/daemon/automount.c
index 776c92c..80691fa 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -60,7 +60,7 @@ long global_negative_timeout = -1;
int do_force_unlink = 0; /* Forceably unlink mount tree at startup */
static int start_pipefd[2];
-static int st_stat = 0;
+static int st_stat = 1;
static int *pst_stat = &st_stat;
static pthread_t state_mach_thid;
@@ -1046,6 +1046,7 @@ static void become_daemon(unsigned foreground, unsigned daemon_check)
{
FILE *pidfp;
char buf[MAX_ERR_BUF];
+ int res;
pid_t pid;
/* Don't BUSY any directories unnecessarily */
@@ -1072,10 +1073,9 @@ static void become_daemon(unsigned foreground, unsigned daemon_check)
} else {
pid = fork();
if (pid > 0) {
- int r;
close(start_pipefd[1]);
- r = read(start_pipefd[0], pst_stat, sizeof(*pst_stat));
- if (r < 0)
+ res = read(start_pipefd[0], pst_stat, sizeof(*pst_stat));
+ if (res < 0)
exit(1);
exit(*pst_stat);
} else if (pid < 0) {
@@ -1088,8 +1088,13 @@ static void become_daemon(unsigned foreground, unsigned daemon_check)
if (daemon_check && !aquire_flag_file()) {
fprintf(stderr, "%s: program is already running.\n",
program);
+ /* Return success if already running */
+ st_stat = 0;
+ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
+ if (res < 0)
+ exit(1);
close(start_pipefd[1]);
- exit(1);
+ exit(*pst_stat);
}
/*
@@ -1099,8 +1104,9 @@ static void become_daemon(unsigned foreground, unsigned daemon_check)
if (setsid() == -1) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
fprintf(stderr, "setsid: %s", estr);
+ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
close(start_pipefd[1]);
- exit(1);
+ exit(*pst_stat);
}
log_to_syslog();
}
@@ -1991,6 +1997,7 @@ int main(int argc, char *argv[])
if (!master_list) {
logerr("%s: can't create master map %s",
program, argv[0]);
+ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
close(start_pipefd[1]);
release_flag_file();
exit(1);
@@ -1999,6 +2006,7 @@ int main(int argc, char *argv[])
if (pthread_attr_init(&th_attr)) {
logerr("%s: failed to init thread attribute struct!",
program);
+ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
close(start_pipefd[1]);
release_flag_file();
exit(1);
@@ -2007,6 +2015,7 @@ int main(int argc, char *argv[])
if (pthread_attr_init(&th_attr_detached)) {
logerr("%s: failed to init thread attribute struct!",
program);
+ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
close(start_pipefd[1]);
release_flag_file();
exit(1);
@@ -2016,6 +2025,7 @@ int main(int argc, char *argv[])
&th_attr_detached, PTHREAD_CREATE_DETACHED)) {
logerr("%s: failed to set detached thread attribute!",
program);
+ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
close(start_pipefd[1]);
release_flag_file();
exit(1);
@@ -2026,6 +2036,7 @@ int main(int argc, char *argv[])
&th_attr_detached, PTHREAD_STACK_MIN*64)) {
logerr("%s: failed to set stack size thread attribute!",
program);
+ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
close(start_pipefd[1]);
release_flag_file();
exit(1);
@@ -2043,6 +2054,7 @@ int main(int argc, char *argv[])
logerr("%s: failed to create thread data key for std env vars!",
program);
master_kill(master_list);
+ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
close(start_pipefd[1]);
release_flag_file();
exit(1);
@@ -2053,6 +2065,7 @@ int main(int argc, char *argv[])
if (!alarm_start_handler()) {
logerr("%s: failed to create alarm handler thread!", program);
master_kill(master_list);
+ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
close(start_pipefd[1]);
release_flag_file();
exit(1);
@@ -2061,6 +2074,7 @@ int main(int argc, char *argv[])
if (!st_start_handler()) {
logerr("%s: failed to create FSM handler thread!", program);
master_kill(master_list);
+ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
close(start_pipefd[1]);
release_flag_file();
exit(1);
@@ -2092,6 +2106,7 @@ int main(int argc, char *argv[])
*/
do_force_unlink = 0;
+ st_stat = 0;
res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
close(start_pipefd[1]);

View File

@ -1,47 +0,0 @@
autofs-5.0.4 - fix rpc fd leak
From: Ian Kent <raven@themaw.net>
Recent changes which introduced the ability to handle to cope with
IPv6 addresses causes a file descriptor leak in the RPC library.
---
CHANGELOG | 1 +
lib/rpc_subs.c | 11 -----------
2 files changed, 1 insertions(+), 11 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 3fd97d3..9edb113 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -56,6 +56,7 @@
- fix double free in sasl_bind().
- mannual umount recovery fixes.
- fix map type info parse error.
+- fix an RPC fd leak.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c
index d034b29..cafc775 100644
--- a/lib/rpc_subs.c
+++ b/lib/rpc_subs.c
@@ -253,17 +253,6 @@ static CLIENT *rpc_do_create_client(struct sockaddr *addr, struct conn_info *inf
return NULL;
}
- if (!info->client) {
- *fd = open_sock(addr->sa_family, type, proto);
- if (*fd < 0)
- return NULL;
-
- if (bind(*fd, laddr, slen) < 0) {
- close(*fd);
- return NULL;
- }
- }
-
switch (info->proto->p_proto) {
case IPPROTO_UDP:
if (!info->client) {

View File

@ -1,275 +0,0 @@
autofs-5.0.4 - fix select fd limit
From: Ian Kent <raven@themaw.net>
Using a large number of direct mounts causes autofs to hang. This is
because select(2) is limited to 1024 file handles (usually). To resolve
this we need to convert calls to select(2) to use poll(2).
---
CHANGELOG | 1 +
daemon/spawn.c | 19 ++++++------
lib/rpc_subs.c | 32 ++++++++++++++------
modules/lookup_program.c | 74 +++++++++++++++++++++++++++-------------------
4 files changed, 78 insertions(+), 48 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 43f3205..0fb7db5 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -4,6 +4,7 @@
- fix nested submount expire deadlock.
- fix negative caching for non-existent map keys.
- use CLOEXEC flag.
+- fix select(2) fd limit.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/daemon/spawn.c b/daemon/spawn.c
index 4ddf46f..e02d926 100644
--- a/daemon/spawn.c
+++ b/daemon/spawn.c
@@ -21,6 +21,7 @@
#include <sys/types.h>
#include <dirent.h>
#include <time.h>
+#include <poll.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/mount.h>
@@ -89,21 +90,21 @@ void reset_signals(void)
static int timed_read(int pipe, char *buf, size_t len, int time)
{
- struct timeval timeout = { 0, 0 };
- struct timeval *tout = NULL;
- fd_set wset, rset;
+ struct pollfd pfd[1];
+ int timeout = time;
int ret;
- FD_ZERO(&rset);
- FD_SET(pipe, &rset);
- wset = rset;
+ pfd[0].fd = pipe;
+ pfd[0].events = POLLIN;
if (time != -1) {
- timeout.tv_sec = time;
- tout = &timeout;
+ if (time >= (INT_MAX - 1)/1000)
+ timeout = INT_MAX - 1;
+ else
+ timeout = time * 1000;
}
- ret = select(pipe + 1, &rset, &wset, NULL, tout);
+ ret = poll(pfd, 1, timeout);
if (ret <= 0) {
if (ret == 0)
ret = -ETIMEDOUT;
diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c
index 9ac3657..7b347a7 100644
--- a/lib/rpc_subs.c
+++ b/lib/rpc_subs.c
@@ -31,6 +31,7 @@
#include <sys/ioctl.h>
#include <ctype.h>
#include <pthread.h>
+#include <poll.h>
#include "mount.h"
#include "rpc_subs.h"
@@ -197,14 +198,15 @@ void rpc_destroy_udp_client(struct conn_info *info)
/*
* Perform a non-blocking connect on the socket fd.
*
- * tout contains the timeout. It will be modified to contain the time
- * remaining (i.e. time provided - time elasped).
+ * The input struct timeval always has tv_nsec set to zero,
+ * we only ever use tv_sec for timeouts.
*/
static int connect_nb(int fd, struct sockaddr_in *addr, struct timeval *tout)
{
+ struct pollfd pfd[1];
+ int timeout = tout->tv_sec;
int flags, ret;
socklen_t len;
- fd_set wset, rset;
flags = fcntl(fd, F_GETFL, 0);
if (flags < 0)
@@ -229,12 +231,10 @@ static int connect_nb(int fd, struct sockaddr_in *addr, struct timeval *tout)
if (ret == 0)
goto done;
- /* now wait */
- FD_ZERO(&rset);
- FD_SET(fd, &rset);
- wset = rset;
+ pfd[0].fd = fd;
+ pfd[0].events = POLLOUT;
- ret = select(fd + 1, &rset, &wset, NULL, tout);
+ ret = poll(pfd, 1, timeout);
if (ret <= 0) {
if (ret == 0)
ret = -ETIMEDOUT;
@@ -243,13 +243,27 @@ static int connect_nb(int fd, struct sockaddr_in *addr, struct timeval *tout)
goto done;
}
- if (FD_ISSET(fd, &rset) || FD_ISSET(fd, &wset)) {
+ if (pfd[0].revents) {
int status;
len = sizeof(ret);
status = getsockopt(fd, SOL_SOCKET, SO_ERROR, &ret, &len);
if (status < 0) {
+ char buf[MAX_ERR_BUF + 1];
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+
+ /*
+ * We assume getsockopt amounts to a read on the
+ * descriptor and gives us the errno we need for
+ * the POLLERR revent case.
+ */
ret = -errno;
+
+ /* Unexpected case, log it so we know we got caught */
+ if (pfd[0].revents & POLLNVAL)
+ logerr("unexpected poll(2) error on connect:"
+ " %s", estr);
+
goto done;
}
diff --git a/modules/lookup_program.c b/modules/lookup_program.c
index 6f4e2a3..f62d3ef 100644
--- a/modules/lookup_program.c
+++ b/modules/lookup_program.c
@@ -24,6 +24,7 @@
#include <sys/times.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <poll.h>
#define MODULE_LOOKUP
#include "automount.h"
@@ -113,14 +114,12 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
char errbuf[1024], *errp;
char ch;
int pipefd[2], epipefd[2];
+ struct pollfd pfd[2];
pid_t f;
- int files_left;
int status;
- fd_set readfds, ourfds;
enum state { st_space, st_map, st_done } state;
int quoted = 0;
int ret = 1;
- int max_fd;
int distance;
int alloci = 1;
@@ -253,30 +252,39 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
errp = errbuf;
state = st_space;
- FD_ZERO(&ourfds);
- FD_SET(pipefd[0], &ourfds);
- FD_SET(epipefd[0], &ourfds);
+ pfd[0].fd = pipefd[0];
+ pfd[0].events = POLLIN;
+ pfd[1].fd = epipefd[0];
+ pfd[1].events = POLLIN;
- max_fd = pipefd[0] > epipefd[0] ? pipefd[0] : epipefd[0];
+ while (1) {
+ int bytes;
- files_left = 2;
+ if (poll(pfd, 2, -1) < 0 && errno != EINTR)
+ break;
+
+ if (pfd[0].fd == -1 && pfd[1].fd == -1)
+ break;
- while (files_left != 0) {
- readfds = ourfds;
- if (select(max_fd + 1, &readfds, NULL, NULL, NULL) < 0 && errno != EINTR)
+ if ((pfd[0].revents & (POLLIN|POLLHUP)) == POLLHUP &&
+ (pfd[1].revents & (POLLIN|POLLHUP)) == POLLHUP)
break;
/* Parse maps from stdout */
- if (FD_ISSET(pipefd[0], &readfds)) {
- if (read(pipefd[0], &ch, 1) < 1) {
- FD_CLR(pipefd[0], &ourfds);
- files_left--;
+ if (pfd[0].revents) {
+cont:
+ bytes = read(pipefd[0], &ch, 1);
+ if (bytes == 0)
+ goto next;
+ else if (bytes < 0) {
+ pfd[0].fd = -1;
state = st_done;
+ goto next;
}
if (!quoted && ch == '\\') {
quoted = 1;
- continue;
+ goto cont;
}
switch (state) {
@@ -333,26 +341,32 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
/* Eat characters till there's no more output */
break;
}
+ goto cont;
}
quoted = 0;
-
+next:
/* Deal with stderr */
- if (FD_ISSET(epipefd[0], &readfds)) {
- if (read(epipefd[0], &ch, 1) < 1) {
- FD_CLR(epipefd[0], &ourfds);
- files_left--;
- } else if (ch == '\n') {
- *errp = '\0';
- if (errbuf[0])
- logmsg(">> %s", errbuf);
- errp = errbuf;
- } else {
- if (errp >= &errbuf[1023]) {
+ if (pfd[1].revents) {
+ while (1) {
+ bytes = read(epipefd[0], &ch, 1);
+ if (bytes == 0)
+ break;
+ else if (bytes < 0) {
+ pfd[1].fd = -1;
+ break;
+ } else if (ch == '\n') {
*errp = '\0';
- logmsg(">> %s", errbuf);
+ if (errbuf[0])
+ logmsg(">> %s", errbuf);
errp = errbuf;
+ } else {
+ if (errp >= &errbuf[1023]) {
+ *errp = '\0';
+ logmsg(">> %s", errbuf);
+ errp = errbuf;
+ }
+ *(errp++) = ch;
}
- *(errp++) = ch;
}
}
}

View File

@ -1,60 +0,0 @@
autofs-5.0.4 - fix st_remove_tasks() locking
From: Ian Kent <raven@themaw.net>
The autofs serialization of state changing during task (mount, umount etc.)
execution was being done twice, with the state queue manager and by using
a pipe to communicate state changes to the handle_mounts() thread. This
required the use of two mutexes which was unnecessary and problematic. So
the pipe was removed and the state queue alone now handles this. When this
was done most of the state queue locking was moved into the state queue
manager functions, however, the locking was inadvertantly left out of the
st_remove_tasks() function.
---
CHANGELOG | 1 +
daemon/state.c | 8 +++++++-
2 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index a143294..c8b88e4 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -37,6 +37,7 @@
- clear rpc client on lookup fail.
- fix lsb init script header.
- fix memory leak reading master map.
+- fix st_remove_tasks() locking.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/daemon/state.c b/daemon/state.c
index 417fde1..533e241 100644
--- a/daemon/state.c
+++ b/daemon/state.c
@@ -783,10 +783,14 @@ void st_remove_tasks(struct autofs_point *ap)
struct state_queue *task, *waiting;
int status;
+ st_mutex_lock();
+
head = &state_queue;
- if (list_empty(head))
+ if (list_empty(head)) {
+ st_mutex_unlock();
return;
+ }
p = head->next;
while (p != head) {
@@ -823,6 +827,8 @@ void st_remove_tasks(struct autofs_point *ap)
if (status)
fatal(status);
+ st_mutex_unlock();
+
return;
}

View File

@ -1,235 +0,0 @@
autofs-5.0.4 - force unlink umount at startup
From: Ian Kent <raven@themaw.net>
Version 5.0.3 autofs would unlink existing mounts at startup. This
functioned OK most of the time but caused processes whose working
directory was within unlinked automounted directories to not get a
correct pwd reported by the system.
There can be situations where the unlink umounting is desirable, such
as when the daemon is forceably killed and we want to get rid of any
existing mounts at startup. This change provides a way to force this
old behavior by passing the "--force" option to the daemon. This can
also be done by using the "forcestart" and "forcerestart" actions to
the init script.
Note that the old behavior will always be used if the kernel does not
include the iotcl re-implementation which provides the ability to
re-connect to existing mounts.
---
CHANGELOG | 2 ++
daemon/automount.c | 14 +++++++++++++-
daemon/direct.c | 2 +-
daemon/indirect.c | 2 +-
include/automount.h | 3 +++
man/automount.8 | 13 +++++++++++++
redhat/autofs.init.in | 10 +++++++++-
samples/rc.autofs.in | 10 +++++++++-
8 files changed, 51 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 7dee674..d4dd70b 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -12,6 +12,8 @@
- fix hosts map use after free.
- fix uri list locking (again).
- check for stale SASL credentials upon connect fail.
+- add "forcestart" and "forcerestart" init script options to allow
+ use of 5.0.3 strartup behavior if required.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/daemon/automount.c b/daemon/automount.c
index f04273f..e20e7c9 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -57,6 +57,7 @@ static char *pid_file = NULL; /* File in which to keep pid */
unsigned int global_random_selection; /* use random policy when selecting
* which multi-mount host to mount */
long global_negative_timeout = -1;
+int do_force_unlink = 0; /* Forceably unlink mount tree at startup */
static int start_pipefd[2];
static int st_stat = 0;
@@ -1798,6 +1799,7 @@ int main(int argc, char *argv[])
{"version", 0, 0, 'V'},
{"set-log-priority", 1, 0, 'l'},
{"dont-check-daemon", 0, 0, 'C'},
+ {"force", 0, 0, 'F'},
{0, 0, 0, 0}
};
@@ -1819,7 +1821,7 @@ int main(int argc, char *argv[])
daemon_check = 1;
opterr = 0;
- while ((opt = getopt_long(argc, argv, "+hp:t:vdD:fVrO:l:n:C", long_options, NULL)) != EOF) {
+ while ((opt = getopt_long(argc, argv, "+hp:t:vdD:fVrO:l:n:CF", long_options, NULL)) != EOF) {
switch (opt) {
case 'h':
usage();
@@ -1892,6 +1894,10 @@ int main(int argc, char *argv[])
daemon_check = 0;
break;
+ case 'F':
+ do_force_unlink = 1;
+ break;
+
case '?':
case ':':
printf("%s: Ambiguous or unknown options\n", program);
@@ -2066,6 +2072,12 @@ int main(int argc, char *argv[])
exit(3);
}
+ /*
+ * Mmm ... reset force unlink umount so we don't also do this
+ * in future when we receive a HUP signal.
+ */
+ do_force_unlink = 0;
+
res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
close(start_pipefd[1]);
diff --git a/daemon/direct.c b/daemon/direct.c
index d9dda3d..2d979f1 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -335,7 +335,7 @@ int do_mount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struc
/* Calculate the timeouts */
ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
- if (ops->version) {
+ if (ops->version && !do_force_unlink) {
ap->flags |= MOUNT_FLAG_REMOUNT;
ret = try_remount(ap, me, t_direct);
ap->flags &= ~MOUNT_FLAG_REMOUNT;
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 0721707..2ccbc53 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -97,7 +97,7 @@ static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root)
ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
- if (ops->version) {
+ if (ops->version && !do_force_unlink) {
ap->flags |= MOUNT_FLAG_REMOUNT;
ret = try_remount(ap, NULL, t_indirect);
ap->flags &= ~MOUNT_FLAG_REMOUNT;
diff --git a/include/automount.h b/include/automount.h
index 46cb6c6..1f14d5b 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -428,6 +428,9 @@ struct autofs_point {
struct list_head submounts; /* List of child submounts */
};
+/* Foreably unlink existing mounts at startup. */
+extern int do_force_unlink;
+
/* Standard functions used by daemon or modules */
#define MOUNT_OFFSET_OK 0
diff --git a/man/automount.8 b/man/automount.8
index d9285bf..9fcaaf4 100644
--- a/man/automount.8
+++ b/man/automount.8
@@ -84,6 +84,11 @@ path name as specified in the master map.
.TP
.I "\-C, \-\-dont-check-daemon"
Don't check if the daemon is currently running (see NOTES).
+.TP
+.I "\-F, \-\-force"
+Force an unlink umount of existing mounts under autofs managed mount points
+during startup. This can cause problems for processes with working directories
+within these mounts (see NOTES).
.SH ARGUMENTS
\fBautomount\fP takes one optional argument, the name of the master map to
use.
@@ -132,6 +137,14 @@ for certain types of automount maps. The mounts of the seperate daemons
might interfere with one another. The implications of running multiple
daemon instances needs to be checked and tested before we can say this
is supported.
+.P
+If the option to force an unlink of mounts at startup is used then processes
+whose working directory is within unlinked automounted directories will not
+get the correct pwd from the system. This is because, after the mount is
+unlinked from the mount tree, anything that needs to walk back up the mount
+tree to construct a path, such as getcwd(2) and the proc filesystem
+/proc/<pid>/cwd, cannot work because the point from which the path is
+constructed has been detached from the mount tree.
.SH "SEE ALSO"
.BR autofs (5),
.BR autofs (8),
diff --git a/redhat/autofs.init.in b/redhat/autofs.init.in
index 65c786e..471667e 100644
--- a/redhat/autofs.init.in
+++ b/redhat/autofs.init.in
@@ -137,6 +137,10 @@ case "$1" in
start)
start
;;
+ forcestart)
+ OPTIONS="$OPTIONS --force"
+ start
+ ;;
stop)
stop
;;
@@ -146,6 +150,10 @@ case "$1" in
restart)
restart
;;
+ forcerestart)
+ OPTIONS="$OPTIONS --force"
+ restart
+ ;;
reload)
reload
;;
@@ -155,7 +163,7 @@ case "$1" in
fi
;;
*)
- echo $"Usage: $0 {start|stop|status|restart|reload|condrestart}"
+ echo $"Usage: $0 {start|forcestart|stop|status|restart|orcerestart|reload|condrestart}"
exit 1;
;;
esac
diff --git a/samples/rc.autofs.in b/samples/rc.autofs.in
index 51f5b02..2877fe2 100644
--- a/samples/rc.autofs.in
+++ b/samples/rc.autofs.in
@@ -117,17 +117,25 @@ case "$1" in
start)
start
;;
+ forcestart)
+ OPTIONS="$OPTIONS --force"
+ start
+ ;;
stop)
stop
;;
restart)
restart
;;
+ forcerestart)
+ OPTIONS="$OPTIONS --force"
+ restart
+ ;;
reload)
reload
;;
*)
- echo $"Usage: $0 {start|stop|restart|reload}"
+ echo $"Usage: $0 {start|forcestart|stop|restart|forcerestart|reload}"
exit 1;
;;
esac

View File

@ -1,161 +0,0 @@
autofs-5.0.4 - improve manual umount recovery
From: Ian Kent <raven@themaw.net>
The check for manually umounted mounts in the expire of direct mounts is
racy and the check itself is inadequate in that it can incorrectly clear
the descriptor of an active mount. Also, we do a similar test following
the expire which is a waste since we can catch this on the next expire.
So these two tests have been combined and the check done only prior to
the expire. In the indirect expire we don't have a check at all so we
add one.
---
CHANGELOG | 1 +
daemon/direct.c | 28 ++++++++++------------------
daemon/indirect.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 57 insertions(+), 19 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 5e01812..89aaa99 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -45,6 +45,7 @@
- fix kernel includes.
- dont umount existing direct mount on master re-read.
- fix incorrect shutdown introduced by library relaod fixes.
+- improve manual umount recovery.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/daemon/direct.c b/daemon/direct.c
index 4f4ff20..1ed2b15 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -881,13 +881,14 @@ void *expire_proc_direct(void *arg)
* avoid maintaining a file handle for control
* functions as once it's mounted all opens are
* directed to the mount not the trigger.
- * But first expire possible rootless offsets first.
*/
- /* Offsets always have a real mount at their base */
+ /* Check for manual umount */
cache_writelock(me->mc);
- if (strstr(next->opts, "offset")) {
- ops->close(ap->logopt, me->ioctlfd);
+ if (me->ioctlfd != -1 &&
+ fstat(ioctlfd, &st) != -1 &&
+ !count_mounts(ap->logopt, next->path, st.st_dev)) {
+ ops->close(ap->logopt, ioctlfd);
me->ioctlfd = -1;
cache_unlock(me->mc);
pthread_setcancelstate(cur_state, NULL);
@@ -904,15 +905,6 @@ void *expire_proc_direct(void *arg)
continue;
}
- cache_writelock(me->mc);
- if (me->ioctlfd != -1 &&
- fstat(ioctlfd, &st) != -1 &&
- !count_mounts(ap->logopt, next->path, st.st_dev)) {
- ops->close(ap->logopt, ioctlfd);
- me->ioctlfd = -1;
- }
- cache_unlock(me->mc);
-
pthread_setcancelstate(cur_state, NULL);
continue;
}
@@ -1068,7 +1060,7 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
map = ap->entry->maps;
while (map) {
mc = map->mc;
- cache_readlock(mc);
+ cache_writelock(mc);
me = cache_lookup_ino(mc, pkt->dev, pkt->ino);
if (me)
break;
@@ -1345,7 +1337,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
}
mc = map->mc;
- cache_readlock(mc);
+ cache_writelock(mc);
me = cache_lookup_ino(mc, pkt->dev, pkt->ino);
if (me)
break;
@@ -1367,10 +1359,10 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
if (me->ioctlfd != -1) {
/* Maybe someone did a manual umount, clean up ! */
- ioctlfd = me->ioctlfd;
+ close(me->ioctlfd);
me->ioctlfd = -1;
- } else
- ops->open(ap->logopt, &ioctlfd, me->dev, me->key);
+ }
+ ops->open(ap->logopt, &ioctlfd, me->dev, me->key);
if (ioctlfd == -1) {
cache_unlock(mc);
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 2539282..bc39e63 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -428,8 +428,53 @@ void *expire_proc_indirect(void *arg)
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
if (strstr(next->opts, "indirect"))
master_notify_submount(ap, next->path, ap->state);
- pthread_setcancelstate(cur_state, NULL);
+ else if (strstr(next->opts, "offset")) {
+ struct map_source *map;
+ struct mapent_cache *mc = NULL;
+ struct mapent *me = NULL;
+ struct stat st;
+
+ master_source_readlock(ap->entry);
+
+ map = ap->entry->maps;
+ while (map) {
+ mc = map->mc;
+ cache_writelock(mc);
+ me = cache_lookup_distinct(mc, next->path);
+ if (me)
+ break;
+ cache_unlock(mc);
+ map = map->next;
+ }
+ if (!mc || !me) {
+ master_source_unlock(ap->entry);
+ pthread_setcancelstate(cur_state, NULL);
+ continue;
+ }
+
+ /* Check for manual umount */
+ if (me->ioctlfd != -1 &&
+ (fstat(me->ioctlfd, &st) == -1 ||
+ !count_mounts(ap->logopt, me->key, st.st_dev))) {
+ if (is_mounted(_PROC_MOUNTS, me->key, MNTS_REAL)) {
+ error(ap->logopt,
+ "error: possible mtab mismatch %s",
+ me->key);
+ cache_unlock(mc);
+ master_source_unlock(ap->entry);
+ pthread_setcancelstate(cur_state, NULL);
+ continue;
+ }
+ close(me->ioctlfd);
+ me->ioctlfd = -1;
+ }
+
+ cache_unlock(mc);
+ master_source_unlock(ap->entry);
+ }
+
+ pthread_setcancelstate(cur_state, NULL);
continue;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,462 +0,0 @@
autofs-5.0.4 - ipv6 parse
From: Ian Kent <raven@themaw.net>
Since ipv6 addresses use a colon separator and we use the colon quite a
bit as a delimiting character we need to distinguish between when the
colon is the delimeter we are looking for and when it is part of an ipv6
address. Since there is widespread use of "[" and "]" to provide the
ability to separate a port specification from an ipv6 address this
convention has also been used in autofs.
---
CHANGELOG | 1
include/parse_subs.h | 8 +++
lib/master_tok.l | 10 ++--
lib/parse_subs.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++---
modules/lookup_file.c | 40 +++++++------------
modules/lookup_ldap.c | 21 ++++++++--
modules/mount_autofs.c | 29 +++++---------
modules/parse_sun.c | 16 ++++---
modules/replicated.c | 26 +++++++++++-
9 files changed, 187 insertions(+), 63 deletions(-)
--- autofs-5.0.4.orig/include/parse_subs.h
+++ autofs-5.0.4/include/parse_subs.h
@@ -20,6 +20,12 @@
struct mapent;
+struct map_type_info {
+ char *type;
+ char *format;
+ char *map;
+};
+
const char *skipspace(const char *);
int check_colon(const char *);
int chunklen(const char *, int);
@@ -27,5 +33,7 @@ int strmcmp(const char *, const char *,
char *dequote(const char *, int, unsigned int);
int span_space(const char *, unsigned int);
char *sanitize_path(const char *, int, unsigned int, unsigned int);
+void free_map_type_info(struct map_type_info *);
+struct map_type_info *parse_map_type_info(const char *);
#endif
--- autofs-5.0.4.orig/lib/master_tok.l
+++ autofs-5.0.4/lib/master_tok.l
@@ -96,10 +96,12 @@ SLASHIFYSTR (--(no-)?slashify-colons)
NUMBER [0-9]+
DNSERVSTR1 ([[:alpha:]][[:alnum:]\-.]*(:[0-9]+)?:)
-DNSERVSTR2 (\/\/[[:alpha:]][[:alnum:]\-.]*(:[0-9]+)?\/)
-DNSERVSTR3 (([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?:)
-DNSERVSTR4 (\/\/([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?\/)
-DNSERVERSTR ({DNSERVSTR1}|{DNSERVSTR2}|{DNSERVSTR3}|{DNSERVSTR4})
+DNSERVSTR2 (\[([[:xdigit:]]:.)+\](:[0-9]+)?:)
+DNSERVSTR3 (\/\/[[:alpha:]][[:alnum:]\-.]*(:[0-9]+)?\/)
+DNSERVSTR4 (\/\/\[([[:xdigit:]]:.)+\](:[0-9]+)?\/)
+DNSERVSTR5 (([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?:)
+DNSERVSTR6 (\/\/([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?\/)
+DNSERVERSTR ({DNSERVSTR1}|{DNSERVSTR2}|{DNSERVSTR3}|{DNSERVSTR4}|{DNSERVSTR5}|{DNSERVSTR6})
AT_CN ([cC][[nN])
AT_NMN ([nN][iI][sS][Mm][aA][pP][Nn][aA][mM][eE])
--- autofs-5.0.4.orig/lib/parse_subs.c
+++ autofs-5.0.4/lib/parse_subs.c
@@ -56,14 +56,13 @@ int check_colon(const char *str)
char *ptr = (char *) str;
/* Colon escape */
- if (*ptr == ':')
+ if (!strncmp(ptr, ":/", 2))
return 1;
- while (*ptr && *ptr != ':' && *ptr != '/') {
+ while (*ptr && strncmp(ptr, ":/", 2))
ptr++;
- }
- if (!*ptr || *ptr == '/')
+ if (!*ptr)
return 0;
return 1;
@@ -93,12 +92,12 @@ int chunklen(const char *whence, int exp
n++;
if (*str == '"')
break;
- if (*str == ':')
+ if (!strncmp(str, ":/", 2))
expect_colon = 0;
}
break;
case ':':
- if (expect_colon)
+ if (expect_colon && !strncmp(str, ":/", 2))
expect_colon = 0;
continue;
case ' ':
@@ -300,3 +299,91 @@ char *sanitize_path(const char *path, in
return s_path;
}
+void free_map_type_info(struct map_type_info *info)
+{
+ if (info->type)
+ free(info->type);
+ if (info->format)
+ free(info->format);
+ if (info->map)
+ free(info->map);
+ free(info);
+ return;
+}
+
+struct map_type_info *parse_map_type_info(const char *str)
+{
+ struct map_type_info *info;
+ char *buf, *type, *fmt, *map, *tmp;
+
+ buf = strdup(str);
+ if (!buf)
+ return NULL;
+
+ info = malloc(sizeof(struct map_type_info));
+ if (!info) {
+ free(buf);
+ return NULL;
+ }
+ memset(info, 0, sizeof(struct map_type_info));
+
+ type = fmt = NULL;
+
+ /* Look for space terminator - ignore local options */
+ map = buf;
+ for (tmp = buf; *tmp; tmp++) {
+ if (*tmp == ' ') {
+ *tmp = '\0';
+ break;
+ } else if (*tmp == ',') {
+ type = buf;
+ *tmp++ = '\0';
+ fmt = tmp;
+ } else if (*tmp == ':') {
+ if (!fmt)
+ type = buf;
+ *tmp++ = '\0';
+ map = tmp;
+ } else if (*tmp == '[') {
+ /*
+ * Unescaped '[' is a syntax error here as only
+ * an ldap map with a type specified should contain
+ * them.
+ */
+ free(buf);
+ return 0;
+ }
+ if (*tmp == '\\')
+ tmp++;
+ }
+
+ if (type) {
+ info->type = strdup(type);
+ if (!info->type) {
+ free(buf);
+ free_map_type_info(info);
+ return NULL;
+ }
+ }
+
+ if (fmt) {
+ info->format = strdup(fmt);
+ if (!info->format) {
+ free(buf);
+ free_map_type_info(info);
+ return NULL;
+ }
+ }
+
+ info->map = strdup(map);
+ if (!info->map) {
+ free(buf);
+ free_map_type_info(info);
+ return NULL;
+ }
+
+ free(buf);
+
+ return info;
+}
+
--- autofs-5.0.4.orig/modules/lookup_file.c
+++ autofs-5.0.4/modules/lookup_file.c
@@ -523,10 +523,10 @@ prepare_plus_include(struct autofs_point
{
struct map_source *current;
struct map_source *source;
- char *type, *map, *fmt;
+ struct map_type_info *info;
const char *argv[2];
int argc;
- char *buf, *tmp;
+ char *buf;
current = ap->entry->current;
ap->entry->current = NULL;
@@ -548,33 +548,19 @@ prepare_plus_include(struct autofs_point
return NULL;
}
- type = fmt = NULL;
-
- /* Look for space terminator - ignore local options */
- map = buf;
- for (tmp = buf; *tmp; tmp++) {
- if (*tmp == ' ') {
- *tmp = '\0';
- break;
- } else if (*tmp == ',') {
- type = buf;
- *tmp++ = '\0';
- fmt = tmp;
- } else if (*tmp == ':') {
- if (!fmt)
- type = buf;
- *tmp++ = '\0';
- map = tmp;
- }
- if (*tmp == '\\')
- tmp++;
+ if (!(info = parse_map_type_info(buf))) {
+ error(ap->logopt, MODPREFIX "failed to parse map info");
+ free(buf);
+ return NULL;
}
argc = 1;
- argv[0] = map;
+ argv[0] = info->map;
argv[1] = NULL;
- source = master_find_source_instance(current, type, fmt, argc, argv);
+ source = master_find_source_instance(current,
+ info->type, info->format,
+ argc, argv);
if (source)
/*
* Make sure included map age is in sync with its owner
@@ -582,8 +568,11 @@ prepare_plus_include(struct autofs_point
*/
source->age = age;
else {
- source = master_add_source_instance(current, type, fmt, age, argc, argv);
+ source = master_add_source_instance(current,
+ info->type, info->format,
+ age, argc, argv);
if (!source) {
+ free_map_type_info(info);
free(buf);
error(ap->logopt, "failed to add included map instance");
return NULL;
@@ -594,6 +583,7 @@ prepare_plus_include(struct autofs_point
if (inc)
source->recurse = 1;
+ free_map_type_info(info);
free(buf);
return source;
--- autofs-5.0.4.orig/modules/lookup_ldap.c
+++ autofs-5.0.4/modules/lookup_ldap.c
@@ -1119,11 +1119,26 @@ static int parse_server_string(unsigned
memcpy(ctxt->server, s, l);
*/
}
- } else if (strchr(ptr, ':') != NULL) {
- char *q = NULL;
+ } else if (strchr(ptr, ':') != NULL || *ptr == '[') {
+ const char *q = NULL;
/* Isolate the server. Include the port spec */
- q = strchr(ptr, ':');
+ if (*ptr != '[')
+ q = strchr(ptr, ':');
+ else {
+ q = ++ptr;
+ while (*q == ':' || isxdigit(*q))
+ q++;
+ if (*q != ']') {
+ crit(logopt, MODPREFIX
+ "invalid LDAP map syntax %s", ptr);
+ return 0;
+ }
+ q++;
+ if (*q == ':')
+ q++;
+ }
+
if (isdigit(*q))
while (isdigit(*q))
q++;
--- autofs-5.0.4.orig/modules/mount_autofs.c
+++ autofs-5.0.4/modules/mount_autofs.c
@@ -50,7 +50,7 @@ int mount_mount(struct autofs_point *ap,
int argc, status, ghost = ap->flags & MOUNT_FLAG_GHOST;
time_t timeout = ap->exp_timeout;
unsigned logopt = ap->logopt;
- char *type, *format, *tmp, *tmp2;
+ struct map_type_info *info;
struct master *master;
struct master_mapent *entry;
struct map_source *source;
@@ -174,21 +174,12 @@ int mount_mount(struct autofs_point *ap,
argc = 1;
- type = NULL;
- format = NULL;
-
- tmp = strchr(what, ':');
- if (tmp) {
- *tmp++ = '\0';
- tmp2 = strchr(what, ',');
- if (tmp2) {
- *tmp2++ = '\0';
- format = tmp2;
- }
- type = (char *) what;
- argv[0] = tmp;
- } else
- argv[0] = (char *) what;
+ if (!(info = parse_map_type_info(what))) {
+ error(ap->logopt, MODPREFIX "failed to parse map info");
+ master_free_mapent(entry);
+ return 1;
+ }
+ argv[0] = info->map;
if (options) {
p = options;
@@ -202,13 +193,17 @@ int mount_mount(struct autofs_point *ap,
}
argv[argc] = NULL;
- source = master_add_map_source(entry, type, format, time(NULL), argc, argv);
+ source = master_add_map_source(entry,
+ info->type, info->format,
+ time(NULL), argc, argv);
if (!source) {
error(ap->logopt,
MODPREFIX "failed to add map source to entry");
master_free_mapent(entry);
+ free_map_type_info(info);
return 1;
}
+ free_map_type_info(info);
source->mc = cache_init(entry->ap, source);
if (!source->mc) {
--- autofs-5.0.4.orig/modules/parse_sun.c
+++ autofs-5.0.4/modules/parse_sun.c
@@ -245,7 +245,9 @@ int expandsunent(const char *src, char *
*(dst++) =
(seen_colons && slashify_colons) ? '/' : ':';
len++;
- seen_colons = 1;
+ /* Were looking for the colon preceeding a path */
+ if (*src == '/')
+ seen_colons = 1;
break;
default:
@@ -814,21 +816,23 @@ static int validate_location(char *loc)
return 1;
/*
- * If a ':' is present now it must be a host name, except
+ * If a ':/' is present now it must be a host name, except
* for those special file systems like sshfs which use "#"
- * and "@" in the host name part.
+ * and "@" in the host name part and ipv6 addresses that
+ * have ":", "[" and "]".
*/
if (check_colon(ptr)) {
- while (*ptr && *ptr != ':') {
+ while (*ptr && strncmp(ptr, ":/", 2)) {
if (!(isalnum(*ptr) ||
*ptr == '-' || *ptr == '.' || *ptr == '_' ||
*ptr == ',' || *ptr == '(' || *ptr == ')' ||
- *ptr == '#' || *ptr == '@'))
+ *ptr == '#' || *ptr == '@' || *ptr == ':' ||
+ *ptr == '[' || *ptr == ']'))
return 0;
ptr++;
}
- if (*ptr && *ptr == ':')
+ if (*ptr && !strncmp(ptr, ":/", 2))
ptr++;
}
--- autofs-5.0.4.orig/modules/replicated.c
+++ autofs-5.0.4/modules/replicated.c
@@ -1168,6 +1168,28 @@ static int add_local_path(struct host **
return 1;
}
+static char *seek_delim(const char *s)
+{
+ const char *p = s;
+ char *delim;
+
+ delim = strpbrk(p, "(, \t:");
+ if (delim && *delim != ':')
+ return delim;
+
+ while (*p) {
+ if (*p != ':') {
+ p++;
+ continue;
+ }
+ if (!strncmp(p, ":/", 2))
+ return (char *) p;
+ p++;
+ }
+
+ return NULL;
+}
+
int parse_location(unsigned logopt, struct host **hosts, const char *list)
{
char *str, *p, *delim;
@@ -1187,7 +1209,7 @@ int parse_location(unsigned logopt, stru
int weight = 0;
p += strspn(p, " \t,");
- delim = strpbrk(p, "(, \t:");
+ delim = seek_delim(p);
if (delim) {
if (*delim == '(') {
@@ -1211,7 +1233,7 @@ int parse_location(unsigned logopt, stru
/* Oh boy - might have spaces in the path */
next = path;
- while (*next && *next != ':')
+ while (*next && strncmp(next, ":/", 2))
next++;
/* No spaces in host names at least */
--- autofs-5.0.4.orig/CHANGELOG
+++ autofs-5.0.4/CHANGELOG
@@ -19,6 +19,7 @@
- make some easy alloca replacements (Valerie Aurora Henson).
- update to configure libtirpc if present.
- update to provide ipv6 name and address support.
+- update to provide ipv6 address parsing.
4/11/2008 autofs-5.0.4
-----------------------

View File

@ -1,53 +0,0 @@
autofs-5.0.4 - library reload fix update fix 2
From: Ian Kent <raven@themaw.net>
The library reload fixes introduced a bug which causes autofs to
not release mount thread resources when using submounts.
---
CHANGELOG | 1 +
daemon/automount.c | 11 +++++++++--
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index f49784a..d1cc113 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -50,6 +50,7 @@
- always read file maps multi map fix.
- always read file maps key lookup fixes.
- use srv query for domain dn.
+- fix not releasing resources when using submounts.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/daemon/automount.c b/daemon/automount.c
index 3a0fe0b..44dcdd6 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -1460,14 +1460,21 @@ static void handle_mounts_cleanup(void *arg)
master_remove_mapent(ap->entry);
master_source_unlock(ap->entry);
+ destroy_logpri_fifo(ap);
+
+ /*
+ * Submounts are detached threads and don't belong to the
+ * master map entry list so we need to free their resources
+ * here.
+ */
if (submount) {
mounts_mutex_unlock(ap->parent);
master_source_unlock(ap->parent->entry);
+ master_free_mapent_sources(ap->entry, 1);
+ master_free_mapent(ap->entry);
}
master_mutex_unlock();
- destroy_logpri_fifo(ap);
-
if (clean) {
if (rmdir(path) == -1) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);

View File

@ -1,82 +0,0 @@
autofs-5.0.4 - library reload fix update fix
From: Ian Kent <raven@themaw.net>
The library reload fixes introduced a bug which causes autofs to
incorrectly shutdown. Previously the signal handling thread only
recieved signals either when they were explicity sent or it was
time to shutdown so continuing on to call the signal handling
routine was the correct thing to do. Now we need to join with
the mount handling thread at exit but, in this case, we don't
want to continue on to the signal handling routine as that will
incorrectly cause the signal to be passed on to other mount
handling threads.
---
CHANGELOG | 1 +
daemon/automount.c | 18 ++++++++++++++++--
lib/master.c | 2 --
3 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 7ca45fd..5e01812 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -44,6 +44,7 @@
- use intr option as hosts mount default.
- fix kernel includes.
- dont umount existing direct mount on master re-read.
+- fix incorrect shutdown introduced by library relaod fixes.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/daemon/automount.c b/daemon/automount.c
index 80691fa..3a0fe0b 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -1332,8 +1332,22 @@ static void *statemachine(void *arg)
case SIGTERM:
case SIGINT:
case SIGUSR2:
- if (master_done(master_list))
- return NULL;
+ master_mutex_lock();
+ if (list_empty(&master_list->completed)) {
+ if (list_empty(&master_list->mounts)) {
+ master_mutex_unlock();
+ return NULL;
+ }
+ } else {
+ if (master_done(master_list)) {
+ master_mutex_unlock();
+ return NULL;
+ }
+ master_mutex_unlock();
+ break;
+ }
+ master_mutex_unlock();
+
case SIGUSR1:
do_signals(master_list, sig);
break;
diff --git a/lib/master.c b/lib/master.c
index 762094f..e43f835 100644
--- a/lib/master.c
+++ b/lib/master.c
@@ -1182,7 +1182,6 @@ int master_done(struct master *master)
struct master_mapent *entry;
int res = 0;
- master_mutex_lock();
head = &master->completed;
p = head->next;
while (p != head) {
@@ -1195,7 +1194,6 @@ int master_done(struct master *master)
}
if (list_empty(&master->mounts))
res = 1;
- master_mutex_unlock();
return res;
}

View File

@ -1,352 +0,0 @@
autofs-5.0.4 - library reload fix update
From: Ian Kent <raven@themaw.net>
We still have a problem with libxml2 being unloaded before its thread
specific data destructor is called. This is due to the main thread
exiting (closing the handle we hold open to prevent this) before all
the mount handling threads have actually completed. This patch makes
the mount handling threads joinable (and joins with them as they exit)
to ensure that the mount handling threads have completed before allowing
the main thread to complete.
---
daemon/automount.c | 35 +++++++++++++++++++++++------------
daemon/direct.c | 7 ++++---
daemon/indirect.c | 7 ++++---
daemon/state.c | 7 ++++---
include/master.h | 3 +++
lib/master.c | 38 ++++++++++++++++++++++++++++++++++----
modules/mount_autofs.c | 4 ++--
7 files changed, 74 insertions(+), 27 deletions(-)
diff --git a/daemon/automount.c b/daemon/automount.c
index e120f50..f04273f 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -69,8 +69,9 @@ static size_t kpkt_len;
/* Does kernel know about SOCK_CLOEXEC and friends */
static int cloexec_works = 0;
-/* Attribute to create detached thread */
-pthread_attr_t thread_attr;
+/* Attributes for creating detached and joinable threads */
+pthread_attr_t th_attr;
+pthread_attr_t th_attr_detached;
struct master_readmap_cond mrc = {
PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, NULL, 0, 0, 0, 0};
@@ -1192,7 +1193,7 @@ static pthread_t do_signals(struct master *master, int sig)
if (status)
fatal(status);
- status = pthread_create(&thid, &thread_attr, do_notify_state, &r_sig);
+ status = pthread_create(&thid, &th_attr_detached, do_notify_state, &r_sig);
if (status) {
error(master->logopt,
"mount state notify thread create failed");
@@ -1281,7 +1282,7 @@ static int do_hup_signal(struct master *master, time_t age)
master->reading = 1;
- status = pthread_create(&thid, &thread_attr, do_read_master, NULL);
+ status = pthread_create(&thid, &th_attr_detached, do_read_master, NULL);
if (status) {
error(logopt,
"master read map thread create failed");
@@ -1327,7 +1328,7 @@ static void *statemachine(void *arg)
case SIGTERM:
case SIGINT:
case SIGUSR2:
- if (master_list_empty(master_list))
+ if (master_done(master_list))
return NULL;
case SIGUSR1:
do_signals(master_list, sig);
@@ -1448,8 +1449,6 @@ static void handle_mounts_cleanup(void *arg)
master_mutex_unlock();
destroy_logpri_fifo(ap);
- master_free_mapent_sources(ap->entry, 1);
- master_free_mapent(ap->entry);
if (clean) {
if (rmdir(path) == -1) {
@@ -1461,8 +1460,12 @@ static void handle_mounts_cleanup(void *arg)
info(logopt, "shut down path %s", path);
- /* If we are the last tell the state machine to shutdown */
- if (!submount && master_list_empty(master_list))
+ /*
+ * If we are not a submount send a signal to the signal handler
+ * so it can join with any completed handle_mounts() threads and
+ * perform final cleanup.
+ */
+ if (!submount)
pthread_kill(state_mach_thid, SIGTERM);
return;
@@ -1980,7 +1983,15 @@ int main(int argc, char *argv[])
exit(1);
}
- if (pthread_attr_init(&thread_attr)) {
+ if (pthread_attr_init(&th_attr)) {
+ logerr("%s: failed to init thread attribute struct!",
+ program);
+ close(start_pipefd[1]);
+ release_flag_file();
+ exit(1);
+ }
+
+ if (pthread_attr_init(&th_attr_detached)) {
logerr("%s: failed to init thread attribute struct!",
program);
close(start_pipefd[1]);
@@ -1989,7 +2000,7 @@ int main(int argc, char *argv[])
}
if (pthread_attr_setdetachstate(
- &thread_attr, PTHREAD_CREATE_DETACHED)) {
+ &th_attr_detached, PTHREAD_CREATE_DETACHED)) {
logerr("%s: failed to set detached thread attribute!",
program);
close(start_pipefd[1]);
@@ -1999,7 +2010,7 @@ int main(int argc, char *argv[])
#ifdef _POSIX_THREAD_ATTR_STACKSIZE
if (pthread_attr_setstacksize(
- &thread_attr, PTHREAD_STACK_MIN*64)) {
+ &th_attr_detached, PTHREAD_STACK_MIN*64)) {
logerr("%s: failed to set stack size thread attribute!",
program);
close(start_pipefd[1]);
diff --git a/daemon/direct.c b/daemon/direct.c
index c0243c4..d9dda3d 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -37,7 +37,8 @@
#include "automount.h"
-extern pthread_attr_t thread_attr;
+/* Attribute to create detached thread */
+extern pthread_attr_t th_attr_detached;
struct mnt_params {
char *options;
@@ -1142,7 +1143,7 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
debug(ap->logopt, "token %ld, name %s",
(unsigned long) pkt->wait_queue_token, mt->name);
- status = pthread_create(&thid, &thread_attr, do_expire_direct, mt);
+ status = pthread_create(&thid, &th_attr_detached, do_expire_direct, mt);
if (status) {
error(ap->logopt, "expire thread create failed");
ops->send_fail(ap->logopt,
@@ -1451,7 +1452,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
mt->gid = pkt->gid;
mt->wait_queue_token = pkt->wait_queue_token;
- status = pthread_create(&thid, &thread_attr, do_mount_direct, mt);
+ status = pthread_create(&thid, &th_attr_detached, do_mount_direct, mt);
if (status) {
error(ap->logopt, "missing mount thread create failed");
ops->send_fail(ap->logopt,
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 9d3745c..0721707 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -36,7 +36,8 @@
#include "automount.h"
-extern pthread_attr_t thread_attr;
+/* Attribute to create detached thread */
+extern pthread_attr_t th_attr_detached;
static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -647,7 +648,7 @@ int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_
mt->len = pkt->len;
mt->wait_queue_token = pkt->wait_queue_token;
- status = pthread_create(&thid, &thread_attr, do_expire_indirect, mt);
+ status = pthread_create(&thid, &th_attr_detached, do_expire_indirect, mt);
if (status) {
error(ap->logopt, "expire thread create failed");
ops->send_fail(ap->logopt,
@@ -835,7 +836,7 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin
mt->gid = pkt->gid;
mt->wait_queue_token = pkt->wait_queue_token;
- status = pthread_create(&thid, &thread_attr, do_mount_indirect, mt);
+ status = pthread_create(&thid, &th_attr_detached, do_mount_indirect, mt);
if (status) {
error(ap->logopt, "expire thread create failed");
ops->send_fail(ap->logopt,
diff --git a/daemon/state.c b/daemon/state.c
index 87c16a6..cd63be1 100644
--- a/daemon/state.c
+++ b/daemon/state.c
@@ -16,7 +16,8 @@
#include "automount.h"
-extern pthread_attr_t thread_attr;
+/* Attribute to create detached thread */
+extern pthread_attr_t th_attr_detached;
struct state_queue {
pthread_t thid;
@@ -292,7 +293,7 @@ static enum expire expire_proc(struct autofs_point *ap, int now)
else
expire = expire_proc_direct;
- status = pthread_create(&thid, &thread_attr, expire, ea);
+ status = pthread_create(&thid, &th_attr_detached, expire, ea);
if (status) {
error(ap->logopt,
"expire thread create for %s failed", ap->path);
@@ -519,7 +520,7 @@ static unsigned int st_readmap(struct autofs_point *ap)
ra->ap = ap;
ra->now = now;
- status = pthread_create(&thid, &thread_attr, do_readmap, ra);
+ status = pthread_create(&thid, &th_attr_detached, do_readmap, ra);
if (status) {
error(ap->logopt, "read map thread create failed");
st_readmap_cleanup(ra);
diff --git a/include/master.h b/include/master.h
index 6d801a9..c519e97 100644
--- a/include/master.h
+++ b/include/master.h
@@ -48,6 +48,7 @@ struct master_mapent {
struct map_source *maps;
struct autofs_point *ap;
struct list_head list;
+ struct list_head join;
};
struct master {
@@ -61,6 +62,7 @@ struct master {
unsigned int logopt;
struct mapent_cache *nc;
struct list_head mounts;
+ struct list_head completed;
};
/* From the yacc master map parser */
@@ -109,6 +111,7 @@ void master_notify_state_change(struct master *, int);
int master_mount_mounts(struct master *, time_t, int);
extern inline unsigned int master_get_logopt(void);
int master_list_empty(struct master *);
+int master_done(struct master *);
int master_kill(struct master *);
#endif
diff --git a/lib/master.c b/lib/master.c
index e1cc062..762094f 100644
--- a/lib/master.c
+++ b/lib/master.c
@@ -32,8 +32,8 @@ struct master *master_list = NULL;
extern long global_negative_timeout;
-/* Attribute to create detached thread */
-extern pthread_attr_t thread_attr;
+/* Attribute to create a joinable thread */
+extern pthread_attr_t th_attr;
extern struct startup_cond suc;
@@ -704,11 +704,16 @@ void master_add_mapent(struct master *master, struct master_mapent *entry)
void master_remove_mapent(struct master_mapent *entry)
{
+ struct master *master = entry->master;
+
if (entry->ap->submount)
return;
- if (!list_empty(&entry->list))
+ if (!list_empty(&entry->list)) {
list_del_init(&entry->list);
+ list_add(&entry->join, &master->completed);
+ }
+
return;
}
@@ -786,6 +791,7 @@ struct master *master_new(const char *name, unsigned int timeout, unsigned int g
master->logopt = master->default_logging;
INIT_LIST_HEAD(&master->mounts);
+ INIT_LIST_HEAD(&master->completed);
return master;
}
@@ -993,7 +999,7 @@ static int master_do_mount(struct master_mapent *entry)
debug(ap->logopt, "mounting %s", entry->path);
- status = pthread_create(&thid, &thread_attr, handle_mounts, &suc);
+ status = pthread_create(&thid, &th_attr, handle_mounts, &suc);
if (status) {
crit(ap->logopt,
"failed to create mount handler thread for %s",
@@ -1170,6 +1176,30 @@ int master_list_empty(struct master *master)
return res;
}
+int master_done(struct master *master)
+{
+ struct list_head *head, *p;
+ struct master_mapent *entry;
+ int res = 0;
+
+ master_mutex_lock();
+ head = &master->completed;
+ p = head->next;
+ while (p != head) {
+ entry = list_entry(p, struct master_mapent, join);
+ p = p->next;
+ list_del(&entry->join);
+ pthread_join(entry->thid, NULL);
+ master_free_mapent_sources(entry, 1);
+ master_free_mapent(entry);
+ }
+ if (list_empty(&master->mounts))
+ res = 1;
+ master_mutex_unlock();
+
+ return res;
+}
+
inline unsigned int master_get_logopt(void)
{
return master_list ? master_list->logopt : LOGOPT_NONE;
diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c
index 82a5ef3..44fc043 100644
--- a/modules/mount_autofs.c
+++ b/modules/mount_autofs.c
@@ -30,7 +30,7 @@
#define MODPREFIX "mount(autofs): "
/* Attribute to create detached thread */
-extern pthread_attr_t thread_attr;
+extern pthread_attr_t th_attr_detached;
extern struct startup_cond suc;
int mount_version = AUTOFS_MOUNT_VERSION; /* Required by protocol */
@@ -235,7 +235,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
suc.done = 0;
suc.status = 0;
- if (pthread_create(&thid, &thread_attr, handle_mounts, &suc)) {
+ if (pthread_create(&thid, &th_attr_detached, handle_mounts, &suc)) {
crit(ap->logopt,
MODPREFIX
"failed to create mount handler thread for %s",

View File

@ -1,38 +0,0 @@
autofs-5.0.4 - libxml2 workaround fix
From: Ian Kent <raven@themaw.net>
Add a check for libxml2.so.2 for the libxml2 workaround in case libxml2.so
is not present.
---
CHANGELOG | 1 +
daemon/automount.c | 2 ++
2 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 1cb56fe..b8ad22e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -21,6 +21,7 @@
- update to provide ipv6 name and address support.
- update to provide ipv6 address parsing.
- easy alloca replacements fix.
+- add check for alternate libxml2 library for libxml2 tsd workaround.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/daemon/automount.c b/daemon/automount.c
index 1ec686b..a664277 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -2058,6 +2058,8 @@ int main(int argc, char *argv[])
#ifdef LIBXML2_WORKAROUND
void *dh_xml2 = dlopen("libxml2.so", RTLD_NOW);
+ if (!dh_xml2)
+ dh_xml2 = dlopen("libxml2.so.2", RTLD_NOW);
#endif
#ifdef TIRPC_WORKAROUND
void *dh_tirpc = dlopen("libitirpc.so", RTLD_NOW);

View File

@ -1,222 +0,0 @@
autofs-5.0.4 - make MAX_ERR_BUF and PARSE_MAX_BUF use easier to audit
From: Valerie Aurora Henson <vaurora@redhat.com>
Non-critical changes to make auditing buffer lengths easier.
* Some buffers were the wrong (too big) size, some were used twice for
different purposes.
* Use sizeof(buf) instead of repeating the *MAX* define in functions
that need to know the size of a statically allocated buffer.
* Fix a compiler warning about discarding the const on a string.
---
CHANGELOG | 1 +
modules/lookup_ldap.c | 51 ++++++++++++++++++++++---------------------------
2 files changed, 24 insertions(+), 28 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index afd1335..417a001 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -15,6 +15,7 @@
- add "forcestart" and "forcerestart" init script options to allow
use of 5.0.3 strartup behavior if required.
- always read entire file map into cache to speed lookups.
+- make MAX_ERR_BUF and PARSE_MAX_BUF use easier to audit.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index bee97ae..d8a60d3 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -272,7 +272,7 @@ LDAP *init_ldap_connection(unsigned logopt, const char *uri, struct lookup_conte
static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt, const char *class, const char *key)
{
- char buf[PARSE_MAX_BUF];
+ char buf[MAX_ERR_BUF];
char *query, *dn, *qdn;
LDAPMessage *result, *e;
struct ldap_searchdn *sdns = NULL;
@@ -296,7 +296,7 @@ static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt
query = alloca(l);
if (query == NULL) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ char *estr = strerror_r(errno, buf, sizeof(buf));
crit(logopt, MODPREFIX "alloca: %s", estr);
return NSS_STATUS_UNAVAIL;
}
@@ -1082,7 +1082,7 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c
}
if (!tmp) {
char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ estr = strerror_r(errno, buf, sizeof(buf));
logerr(MODPREFIX "malloc: %s", estr);
return 0;
}
@@ -1104,7 +1104,7 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c
tmp = malloc(l + 1);
if (!tmp) {
char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ estr = strerror_r(errno, buf, sizeof(buf));
crit(logopt, MODPREFIX "malloc: %s", estr);
return 0;
}
@@ -1139,7 +1139,7 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c
/* Isolate the server's name. */
if (!tmp) {
char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ estr = strerror_r(errno, buf, sizeof(buf));
logerr(MODPREFIX "malloc: %s", estr);
return 0;
}
@@ -1180,7 +1180,7 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c
ctxt->mapname = map;
else {
char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ estr = strerror_r(errno, buf, sizeof(buf));
logerr(MODPREFIX "malloc: %s", estr);
if (ctxt->server)
free(ctxt->server);
@@ -1191,7 +1191,7 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c
base = malloc(l + 1);
if (!base) {
char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ estr = strerror_r(errno, buf, sizeof(buf));
logerr(MODPREFIX "malloc: %s", estr);
if (ctxt->server)
free(ctxt->server);
@@ -1205,7 +1205,7 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c
char *map = malloc(l + 1);
if (!map) {
char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ estr = strerror_r(errno, buf, sizeof(buf));
logerr(MODPREFIX "malloc: %s", estr);
if (ctxt->server)
free(ctxt->server);
@@ -1318,7 +1318,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
/* If we can't build a context, bail. */
ctxt = malloc(sizeof(struct lookup_context));
if (!ctxt) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ char *estr = strerror_r(errno, buf, sizeof(buf));
logerr(MODPREFIX "malloc: %s", estr);
return 1;
}
@@ -1419,8 +1419,9 @@ int lookup_read_master(struct master *master, time_t age, void *context)
unsigned int timeout = master->default_timeout;
unsigned int logging = master->default_logging;
unsigned int logopt = master->logopt;
- int rv, l, count, blen;
- char buf[PARSE_MAX_BUF];
+ int rv, l, count;
+ char buf[MAX_ERR_BUF];
+ char parse_buf[PARSE_MAX_BUF];
char *query;
LDAPMessage *result, *e;
char *class, *info, *entry;
@@ -1442,7 +1443,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
query = alloca(l);
if (query == NULL) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ char *estr = strerror_r(errno, buf, sizeof(buf));
logerr(MODPREFIX "alloca: %s", estr);
return NSS_STATUS_UNAVAIL;
}
@@ -1532,19 +1533,13 @@ int lookup_read_master(struct master *master, time_t age, void *context)
goto next;
}
- blen = strlen(*keyValue) + 1 + strlen(*values) + 2;
- if (blen > PARSE_MAX_BUF) {
+ if (snprintf(parse_buf, sizeof(parse_buf), "%s %s",
+ *keyValue, *values) >= sizeof(parse_buf)) {
error(logopt, MODPREFIX "map entry too long");
ldap_value_free(values);
goto next;
}
- memset(buf, 0, PARSE_MAX_BUF);
-
- strcpy(buf, *keyValue);
- strcat(buf, " ");
- strcat(buf, *values);
-
- master_parse_entry(buf, timeout, logging, age);
+ master_parse_entry(parse_buf, timeout, logging, age);
next:
ldap_value_free(keyValue);
e = ldap_next_entry(ldap, e);
@@ -1561,7 +1556,7 @@ static int get_percent_decoded_len(const char *name)
{
int escapes = 0;
int escaped = 0;
- char *tmp = name;
+ const char *tmp = name;
int look_for_close = 0;
while (*tmp) {
@@ -2060,7 +2055,7 @@ static int do_get_entries(struct ldap_search_params *sp, struct map_source *sour
mapent = malloc(v_len + 1);
if (!mapent) {
char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ estr = strerror_r(errno, buf, sizeof(buf));
logerr(MODPREFIX "malloc: %s", estr);
ldap_value_free_len(bvValues);
goto next;
@@ -2080,7 +2075,7 @@ static int do_get_entries(struct ldap_search_params *sp, struct map_source *sour
mapent_len = new_size;
} else {
char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ estr = strerror_r(errno, buf, sizeof(buf));
logerr(MODPREFIX "realloc: %s", estr);
}
}
@@ -2181,7 +2176,7 @@ static int read_one_map(struct autofs_point *ap,
sp.query = alloca(l);
if (sp.query == NULL) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ char *estr = strerror_r(errno, buf, sizeof(buf));
logerr(MODPREFIX "malloc: %s", estr);
return NSS_STATUS_UNAVAIL;
}
@@ -2335,7 +2330,7 @@ static int lookup_one(struct autofs_point *ap,
query = alloca(l);
if (query == NULL) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ char *estr = strerror_r(errno, buf, sizeof(buf));
crit(ap->logopt, MODPREFIX "malloc: %s", estr);
if (enc_len1) {
free(enc_key1);
@@ -2507,7 +2502,7 @@ static int lookup_one(struct autofs_point *ap,
mapent = malloc(v_len + 1);
if (!mapent) {
char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ estr = strerror_r(errno, buf, sizeof(buf));
logerr(MODPREFIX "malloc: %s", estr);
ldap_value_free_len(bvValues);
goto next;
@@ -2527,7 +2522,7 @@ static int lookup_one(struct autofs_point *ap,
mapent_len = new_size;
} else {
char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ estr = strerror_r(errno, buf, sizeof(buf));
logerr(MODPREFIX "realloc: %s", estr);
}
}

View File

@ -1,294 +0,0 @@
autofs-5.0.4 - make hash table scale to thousands of entries
From: Valerie Aurora Henson <vaurora@redhat.com>
Originally written by Paul Wankadia <junyer@google.com>.
The autofs cache lookup performs poorly for large maps.
The additive hashing algorithm used by autofs results in a clustering
of hash values around the average hash chain size. It is biased toward
a small range of hash indexes which becomes worse as the hash table size
increases.
Simple testing shows that the "One-at-a-time" hash function (implemented
by this patch) gives a much better distribution of hash indexes as table
size increases.
The only change made to the original patch is to make the hash table size
configurable with a default somewhat larger than it is currently.
---
CHANGELOG | 2 ++
include/automount.h | 2 +-
include/defaults.h | 3 +++
lib/cache.c | 47 +++++++++++++++++++++++-----------------
lib/defaults.c | 16 +++++++++++++-
redhat/autofs.sysconfig.in | 6 +++++
samples/autofs.conf.default.in | 6 +++++
7 files changed, 60 insertions(+), 22 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 0fb7db5..912c088 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -5,6 +5,8 @@
- fix negative caching for non-existent map keys.
- use CLOEXEC flag.
- fix select(2) fd limit.
+- make hash table scale to thousands of entries (Paul Wankadia,
+ Valerie Aurora Henson).
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/include/automount.h b/include/automount.h
index a55ddbc..fa24885 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -128,7 +128,7 @@ struct autofs_point;
#define CHE_DUPLICATE 0x0020
#define CHE_UNAVAIL 0x0040
-#define HASHSIZE 77
+#define NULL_MAP_HASHSIZE 64
#define NEGATIVE_TIMEOUT 10
#define UMOUNT_RETRIES 8
#define EXPIRE_RETRIES 3
diff --git a/include/defaults.h b/include/defaults.h
index 12534ec..9a2430f 100644
--- a/include/defaults.h
+++ b/include/defaults.h
@@ -40,6 +40,8 @@
#define DEFAULT_APPEND_OPTIONS 1
#define DEFAULT_AUTH_CONF_FILE AUTOFS_MAP_DIR "/autofs_ldap_auth.conf"
+#define DEFAULT_MAP_HASH_TABLE_SIZE 1024
+
struct ldap_schema;
struct ldap_searchdn;
@@ -62,6 +64,7 @@ void defaults_free_searchdns(struct ldap_searchdn *);
unsigned int defaults_get_append_options(void);
unsigned int defaults_get_umount_wait(void);
const char *defaults_get_auth_conf_file(void);
+unsigned int defaults_get_map_hash_table_size(void);
#endif
diff --git a/lib/cache.c b/lib/cache.c
index 4a00367..edb3192 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -190,7 +190,7 @@ struct mapent_cache *cache_init(struct autofs_point *ap, struct map_source *map)
if (!mc)
return NULL;
- mc->size = HASHSIZE;
+ mc->size = defaults_get_map_hash_table_size();
mc->hash = malloc(mc->size * sizeof(struct entry *));
if (!mc->hash) {
@@ -241,7 +241,7 @@ struct mapent_cache *cache_init_null_cache(struct master *master)
if (!mc)
return NULL;
- mc->size = HASHSIZE;
+ mc->size = NULL_MAP_HASHSIZE;
mc->hash = malloc(mc->size * sizeof(struct entry *));
if (!mc->hash) {
@@ -279,29 +279,36 @@ struct mapent_cache *cache_init_null_cache(struct master *master)
return mc;
}
-static unsigned int hash(const char *key)
+static u_int32_t hash(const char *key, unsigned int size)
{
- unsigned long hashval;
+ u_int32_t hashval;
char *s = (char *) key;
- for (hashval = 0; *s != '\0';)
- hashval += *s++;
+ for (hashval = 0; *s != '\0';) {
+ hashval += (unsigned char) *s++;
+ hashval += (hashval << 10);
+ hashval ^= (hashval >> 6);
+ }
+
+ hashval += (hashval << 3);
+ hashval ^= (hashval >> 11);
+ hashval += (hashval << 15);
- return hashval % HASHSIZE;
+ return hashval % size;
}
-static unsigned int ino_hash(dev_t dev, ino_t ino)
+static u_int32_t ino_hash(dev_t dev, ino_t ino, unsigned int size)
{
- unsigned long hashval;
+ u_int32_t hashval;
hashval = dev + ino;
- return hashval % HASHSIZE;
+ return hashval % size;
}
int cache_set_ino_index(struct mapent_cache *mc, const char *key, dev_t dev, ino_t ino)
{
- unsigned int ino_index = ino_hash(dev, ino);
+ u_int32_t ino_index = ino_hash(dev, ino, mc->size);
struct mapent *me;
me = cache_lookup_distinct(mc, key);
@@ -323,10 +330,10 @@ struct mapent *cache_lookup_ino(struct mapent_cache *mc, dev_t dev, ino_t ino)
{
struct mapent *me = NULL;
struct list_head *head, *p;
- unsigned int ino_index;
+ u_int32_t ino_index;
ino_index_lock(mc);
- ino_index = ino_hash(dev, ino);
+ ino_index = ino_hash(dev, ino, mc->size);
head = &mc->ino_index[ino_index];
list_for_each(p, head) {
@@ -369,7 +376,7 @@ struct mapent *cache_lookup_first(struct mapent_cache *mc)
struct mapent *cache_lookup_next(struct mapent_cache *mc, struct mapent *me)
{
struct mapent *this;
- unsigned long hashval;
+ u_int32_t hashval;
unsigned int i;
if (!me)
@@ -385,7 +392,7 @@ struct mapent *cache_lookup_next(struct mapent_cache *mc, struct mapent *me)
return this;
}
- hashval = hash(me->key) + 1;
+ hashval = hash(me->key, mc->size) + 1;
if (hashval < mc->size) {
for (i = (unsigned int) hashval; i < mc->size; i++) {
this = mc->hash[i];
@@ -433,7 +440,7 @@ struct mapent *cache_lookup(struct mapent_cache *mc, const char *key)
if (!key)
return NULL;
- for (me = mc->hash[hash(key)]; me != NULL; me = me->next) {
+ for (me = mc->hash[hash(key, mc->size)]; me != NULL; me = me->next) {
if (strcmp(key, me->key) == 0)
goto done;
}
@@ -446,7 +453,7 @@ struct mapent *cache_lookup(struct mapent_cache *mc, const char *key)
goto done;
}
- for (me = mc->hash[hash("*")]; me != NULL; me = me->next)
+ for (me = mc->hash[hash("*", mc->size)]; me != NULL; me = me->next)
if (strcmp("*", me->key) == 0)
goto done;
}
@@ -462,7 +469,7 @@ struct mapent *cache_lookup_distinct(struct mapent_cache *mc, const char *key)
if (!key)
return NULL;
- for (me = mc->hash[hash(key)]; me != NULL; me = me->next) {
+ for (me = mc->hash[hash(key, mc->size)]; me != NULL; me = me->next) {
if (strcmp(key, me->key) == 0)
return me;
}
@@ -530,7 +537,7 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c
{
struct mapent *me, *existing = NULL;
char *pkey, *pent;
- unsigned int hashval = hash(key);
+ u_int32_t hashval = hash(key, mc->size);
int status;
me = (struct mapent *) malloc(sizeof(struct mapent));
@@ -750,7 +757,7 @@ int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key
int cache_delete(struct mapent_cache *mc, const char *key)
{
struct mapent *me = NULL, *pred;
- unsigned int hashval = hash(key);
+ u_int32_t hashval = hash(key, mc->size);
int status, ret = CHE_OK;
char *this;
diff --git a/lib/defaults.c b/lib/defaults.c
index ff653e3..0d39716 100644
--- a/lib/defaults.c
+++ b/lib/defaults.c
@@ -49,6 +49,8 @@
#define ENV_UMOUNT_WAIT "UMOUNT_WAIT"
#define ENV_AUTH_CONF_FILE "AUTH_CONF_FILE"
+#define ENV_MAP_HASH_TABLE_SIZE "MAP_HASH_TABLE_SIZE"
+
static const char *default_master_map_name = DEFAULT_MASTER_MAP_NAME;
static const char *default_auth_conf_file = DEFAULT_AUTH_CONF_FILE;
@@ -323,7 +325,8 @@ unsigned int defaults_read_config(unsigned int to_syslog)
check_set_config_value(key, ENV_NAME_VALUE_ATTR, value, to_syslog) ||
check_set_config_value(key, ENV_APPEND_OPTIONS, value, to_syslog) ||
check_set_config_value(key, ENV_UMOUNT_WAIT, value, to_syslog) ||
- check_set_config_value(key, ENV_AUTH_CONF_FILE, value, to_syslog))
+ check_set_config_value(key, ENV_AUTH_CONF_FILE, value, to_syslog) ||
+ check_set_config_value(key, ENV_MAP_HASH_TABLE_SIZE, value, to_syslog))
;
}
@@ -672,3 +675,14 @@ const char *defaults_get_auth_conf_file(void)
return (const char *) cf;
}
+unsigned int defaults_get_map_hash_table_size(void)
+{
+ long size;
+
+ size = get_env_number(ENV_MAP_HASH_TABLE_SIZE);
+ if (size < 0)
+ size = DEFAULT_MAP_HASH_TABLE_SIZE;
+
+ return (unsigned int) size;
+}
+
diff --git a/redhat/autofs.sysconfig.in b/redhat/autofs.sysconfig.in
index 8256888..fe36f45 100644
--- a/redhat/autofs.sysconfig.in
+++ b/redhat/autofs.sysconfig.in
@@ -89,6 +89,12 @@ BROWSE_MODE="no"
#
#AUTH_CONF_FILE="@@autofsmapdir@@/autofs_ldap_auth.conf"
#
+# MAP_HASH_TABLE_SIZE - set the map cache hash table size.
+# Should be a power of 2 with a ratio roughly
+# between 1:10 and 1:20 for each map.
+#
+#MAP_HASH_TABLE_SIZE=1024
+#
# General global options
#
# If the kernel supports using the autofs miscellanous device
diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in
index 844a6f3..4496738 100644
--- a/samples/autofs.conf.default.in
+++ b/samples/autofs.conf.default.in
@@ -89,6 +89,12 @@ BROWSE_MODE="no"
#
#AUTH_CONF_FILE="@@autofsmapdir@@/autofs_ldap_auth.conf"
#
+# MAP_HASH_TABLE_SIZE - set the map cache hash table size.
+# Should be a power of 2 with a ratio roughly
+# between 1:10 and 1:20 for each map.
+#
+#MAP_HASH_TABLE_SIZE=1024
+#
# General global options
#
# If the kernel supports using the autofs miscellanous device

View File

@ -1,100 +0,0 @@
autofs-5.0.4 - mannual umount recovery fixes
From: Ian Kent <raven@themaw.net>
Check for the absence of a mount before doing the manual umount
checks and check ioctlfd is valid seperately. Take a write lock
on the map entry mutex to ensure any mount request is complete
before checking.
---
CHANGELOG | 1 +
daemon/direct.c | 4 ++--
daemon/indirect.c | 37 +++++++++++++++++++++++--------------
3 files changed, 26 insertions(+), 16 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index f0d0e58..05e0206 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -54,6 +54,7 @@
- fix notify mount message path.
- remount we created mount point fix.
- fix double free in sasl_bind().
+- mannual umount recovery fixes.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/daemon/direct.c b/daemon/direct.c
index 74a9acc..7b02c7a 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -889,9 +889,9 @@ void *expire_proc_direct(void *arg)
/* Check for manual umount */
cache_writelock(me->mc);
if (me->ioctlfd != -1 &&
- fstat(ioctlfd, &st) != -1 &&
+ fstat(me->ioctlfd, &st) != -1 &&
!count_mounts(ap->logopt, next->path, st.st_dev)) {
- ops->close(ap->logopt, ioctlfd);
+ ops->close(ap->logopt, me->ioctlfd);
me->ioctlfd = -1;
cache_unlock(me->mc);
pthread_setcancelstate(cur_state, NULL);
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 463b39c..8025ee4 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -437,7 +437,19 @@ void *expire_proc_indirect(void *arg)
struct mapent *me = NULL;
struct stat st;
- master_source_readlock(ap->entry);
+ /* It's got a mount, deal with in the outer loop */
+ if (is_mounted(_PATH_MOUNTED, next->path, MNTS_REAL)) {
+ pthread_setcancelstate(cur_state, NULL);
+ continue;
+ }
+
+ /* Don't touch submounts */
+ if (master_find_submount(ap, next->path)) {
+ pthread_setcancelstate(cur_state, NULL);
+ continue;
+ }
+
+ master_source_writelock(ap->entry);
map = ap->entry->maps;
while (map) {
@@ -456,20 +468,17 @@ void *expire_proc_indirect(void *arg)
continue;
}
+ if (me->ioctlfd == -1) {
+ cache_unlock(mc);
+ master_source_unlock(ap->entry);
+ pthread_setcancelstate(cur_state, NULL);
+ continue;
+ }
+
/* Check for manual umount */
- if (me->ioctlfd != -1 &&
- (fstat(me->ioctlfd, &st) == -1 ||
- !count_mounts(ap->logopt, me->key, st.st_dev))) {
- if (is_mounted(_PROC_MOUNTS, me->key, MNTS_REAL)) {
- error(ap->logopt,
- "error: possible mtab mismatch %s",
- me->key);
- cache_unlock(mc);
- master_source_unlock(ap->entry);
- pthread_setcancelstate(cur_state, NULL);
- continue;
- }
- close(me->ioctlfd);
+ if (fstat(me->ioctlfd, &st) == -1 ||
+ !count_mounts(ap->logopt, me->key, st.st_dev)) {
+ ops->close(ap->logopt, me->ioctlfd);
me->ioctlfd = -1;
}

View File

@ -1,55 +0,0 @@
autofs-5.0.4 - remount we created mount point fix
From: Ian Kent <raven@themaw.net>
During remount determine if autofs created the mount point directory,
as best we can.
---
CHANGELOG | 1 +
lib/mounts.c | 15 +++++++--------
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 0a0519f..e138ca3 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -52,6 +52,7 @@
- use srv query for domain dn.
- fix not releasing resources when using submounts.
- fix notify mount message path.
+- remount we created mount point fix.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/lib/mounts.c b/lib/mounts.c
index 4787bb6..4c44982 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1359,18 +1359,17 @@ int try_remount(struct autofs_point *ap, struct mapent *me, unsigned int type)
/*
* The directory must exist since we found a device
* number for the mount but we can't know if we created
- * it or not. However, if we're mounted on an autofs fs
- * then we need to cleanup the path anyway.
+ * it or not. However, if this is an indirect mount with
+ * the nobrowse option we need to remove the mount point
+ * directory at umount anyway.
*/
if (type == t_indirect) {
- ap->flags &= ~MOUNT_FLAG_DIR_CREATED;
- if (ret == DEV_IOCTL_IS_AUTOFS)
+ if (ap->flags & MOUNT_FLAG_GHOST)
+ ap->flags &= ~MOUNT_FLAG_DIR_CREATED;
+ else
ap->flags |= MOUNT_FLAG_DIR_CREATED;
- } else {
+ } else
me->flags &= ~MOUNT_FLAG_DIR_CREATED;
- if (ret == DEV_IOCTL_IS_AUTOFS)
- me->flags |= MOUNT_FLAG_DIR_CREATED;
- }
/*
* Either we opened the mount or we're re-reading the map.

View File

@ -1,61 +0,0 @@
autofs-5.0.4 - renew sasl creds upon reconnect fail
From: Ian Kent <raven@themaw.net>
If a server re-connect fails it could be due to the authentication
credentail having timed out. So we need to dispose of this and retry
the connection including refreshing re-authenticating.
---
CHANGELOG | 1 +
modules/lookup_ldap.c | 17 +++++++++++++++++
2 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index b093451..7dee674 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -11,6 +11,7 @@
- use CLOEXEC flag for setmntent also.
- fix hosts map use after free.
- fix uri list locking (again).
+- check for stale SASL credentials upon connect fail.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index b6784e1..bee97ae 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -675,6 +675,13 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt)
if (ctxt->server || !ctxt->uris) {
ldap = do_connect(logopt, ctxt->server, ctxt);
+#ifdef WITH_SASL
+ /* Dispose of the sasl authentication connection and try again. */
+ if (!ldap) {
+ autofs_sasl_dispose(ctxt);
+ ldap = connect_to_server(logopt, ctxt->server, ctxt);
+ }
+#endif
return ldap;
}
@@ -682,6 +689,16 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt)
this = ctxt->uri;
uris_mutex_unlock(ctxt);
ldap = do_connect(logopt, this->uri, ctxt);
+#ifdef WITH_SASL
+ /*
+ * Dispose of the sasl authentication connection and try the
+ * current server again before trying other servers in the list.
+ */
+ if (!ldap) {
+ autofs_sasl_dispose(ctxt);
+ ldap = connect_to_server(logopt, this->uri, ctxt);
+ }
+#endif
if (ldap)
return ldap;

View File

@ -1,59 +0,0 @@
autofs-5.0.4 - reset flex scanner when setting buffer
From: Ian Kent <raven@themaw.net>
We still have problems resetting the flex scan buffer after an error
is detected. This appears to fix the problem.
---
CHANGELOG | 1 +
lib/master_tok.l | 9 ++++++++-
2 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index c8b88e4..5f1cf7f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -38,6 +38,7 @@
- fix lsb init script header.
- fix memory leak reading master map.
- fix st_remove_tasks() locking.
+- reset flex scanner when setting buffer.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/lib/master_tok.l b/lib/master_tok.l
index b6cc8be..373248b 100644
--- a/lib/master_tok.l
+++ b/lib/master_tok.l
@@ -130,7 +130,6 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeo
\x00 {
if (optr != buff) {
*optr = '\0';
- optr = buff;
strcpy(master_lval.strtype, buff);
return NILL;
}
@@ -139,6 +138,11 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeo
#.* { return COMMENT; }
"/" {
+ if (optr != buff) {
+ *optr = '\0';
+ strcpy(master_lval.strtype, buff);
+ return NILL;
+ }
BEGIN(PATHSTR);
bptr = buff;
yyless(0);
@@ -410,6 +414,9 @@ static void master_echo(void)
void master_set_scan_buffer(const char *buffer)
{
+ master_lex_destroy();
+ optr = buff;
+
line = buffer;
line_pos = &line[0];
/*

View File

@ -1,37 +0,0 @@
autofs-5.0.4 - srv lookup handle endianness
From: Ian Kent <raven@themaw.net>
---
modules/dclist.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/modules/dclist.c b/modules/dclist.c
index 5b0e577..967581c 100644
--- a/modules/dclist.c
+++ b/modules/dclist.c
@@ -34,6 +34,7 @@
#include <ldap.h>
#include <sys/param.h>
#include <errno.h>
+#include <endian.h>
#include "automount.h"
#include "dclist.h"
@@ -72,8 +73,13 @@
#define SVAL(buf, pos) (*(const uint16_t *)((const char *)(buf) + (pos)))
#define IVAL(buf, pos) (*(const uint32_t *)((const char *)(buf) + (pos)))
+#if __BYTE_ORDER == __LITTLE_ENDIAN
#define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF))
#define IREV(x) ((SREV(x)<<16) | (SREV((x)>>16)))
+#else
+#define SREV(x) (x)
+#define IREV(x) (x)
+#endif
#define RSVAL(buf, pos) SREV(SVAL(buf, pos))
#define RIVAL(buf, pos) IREV(IVAL(buf, pos))

View File

@ -1,224 +0,0 @@
autofs-5.0.4 - uris list locking fix
From: Ian Kent <raven@themaw.net>
The ldap uris list doesn't need to change we just need to keep
track of current server uri in the list and try to connect in
a round robin order. Also it's possible multiple concurrent
connection attempts may not be able to use the full list of
servers (if one is present).
---
CHANGELOG | 1 +
include/lookup_ldap.h | 3 +-
modules/lookup_ldap.c | 68 ++++++++++++++++++++++---------------------------
3 files changed, 33 insertions(+), 39 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 3199e4d..b093451 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -10,6 +10,7 @@
- clear the quoted flag after each character from program map input.
- use CLOEXEC flag for setmntent also.
- fix hosts map use after free.
+- fix uri list locking (again).
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h
index f9ed778..b47bf5d 100644
--- a/include/lookup_ldap.h
+++ b/include/lookup_ldap.h
@@ -55,7 +55,8 @@ struct lookup_context {
* given in configuration.
*/
pthread_mutex_t uris_mutex;
- struct list_head *uri;
+ struct list_head *uris;
+ struct ldap_uri *uri;
char *cur_host;
struct ldap_searchdn *sdns;
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 6ba80eb..b6784e1 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -137,7 +137,7 @@ static void uris_mutex_unlock(struct lookup_context *ctxt)
return;
}
-int bind_ldap_anonymous(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
+int bind_ldap_anonymous(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_context *ctxt)
{
int rv;
@@ -147,16 +147,14 @@ int bind_ldap_anonymous(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt
rv = ldap_simple_bind_s(ldap, NULL, NULL);
if (rv != LDAP_SUCCESS) {
- if (!ctxt->uri) {
+ if (!ctxt->uris) {
crit(logopt, MODPREFIX
"Unable to bind to the LDAP server: "
"%s, error %s", ctxt->server ? "" : "(default)",
ldap_err2string(rv));
} else {
- struct ldap_uri *uri;
- uri = list_entry(ctxt->uri->next, struct ldap_uri, list);
info(logopt, MODPREFIX "Unable to bind to the LDAP server: "
- "%s, error %s", uri->uri, ldap_err2string(rv));
+ "%s, error %s", uri, ldap_err2string(rv));
}
return -1;
}
@@ -498,7 +496,7 @@ static int find_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctx
return 0;
}
-static int do_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
+static int do_bind(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_context *ctxt)
{
char *host = NULL, *nhost;
int rv, need_base = 1;
@@ -511,11 +509,11 @@ static int do_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
rv = autofs_sasl_bind(logopt, ldap, ctxt);
debug(logopt, MODPREFIX "autofs_sasl_bind returned %d", rv);
} else {
- rv = bind_ldap_anonymous(logopt, ldap, ctxt);
+ rv = bind_ldap_anonymous(logopt, ldap, uri, ctxt);
debug(logopt, MODPREFIX "ldap anonymous bind returned %d", rv);
}
#else
- rv = bind_ldap_anonymous(logopt, ldap, ctxt);
+ rv = bind_ldap_anonymous(logopt, ldap, uri, ctxt);
debug(logopt, MODPREFIX "ldap anonymous bind returned %d", rv);
#endif
@@ -584,7 +582,7 @@ static LDAP *do_connect(unsigned logopt, const char *uri, struct lookup_context
if (!ldap)
return NULL;
- if (!do_bind(logopt, ldap, ctxt)) {
+ if (!do_bind(logopt, ldap, uri, ctxt)) {
unbind_ldap_connection(logopt, ldap, ctxt);
return NULL;
}
@@ -612,7 +610,7 @@ static LDAP *connect_to_server(unsigned logopt, const char *uri, struct lookup_c
return NULL;
}
- if (!do_bind(logopt, ldap, ctxt)) {
+ if (!do_bind(logopt, ldap, uri, ctxt)) {
unbind_ldap_connection(logopt, ldap, ctxt);
autofs_sasl_dispose(ctxt);
error(logopt, MODPREFIX "cannot bind to server");
@@ -638,36 +636,34 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
{
LDAP *ldap = NULL;
struct ldap_uri *this;
- struct list_head *p;
- LIST_HEAD(tmp);
+ struct list_head *p, *first;
/* Try each uri in list, add connect fails to tmp list */
uris_mutex_lock(ctxt);
- p = ctxt->uri->next;
- while(p != ctxt->uri) {
+ if (!ctxt->uri)
+ first = ctxt->uris;
+ else
+ first = &ctxt->uri->list;
+ uris_mutex_unlock(ctxt);
+ p = first->next;
+ while(p != first) {
+ /* Skip list head */
+ if (p == ctxt->uris) {
+ p = p->next;
+ continue;
+ }
this = list_entry(p, struct ldap_uri, list);
- uris_mutex_unlock(ctxt);
debug(logopt, "trying server %s", this->uri);
ldap = connect_to_server(logopt, this->uri, ctxt);
if (ldap) {
info(logopt, "connected to uri %s", this->uri);
uris_mutex_lock(ctxt);
+ ctxt->uri = this;
+ uris_mutex_unlock(ctxt);
break;
}
- uris_mutex_lock(ctxt);
p = p->next;
- list_del_init(&this->list);
- list_add_tail(&this->list, &tmp);
}
- /*
- * Successfuly connected uri (head of list) and untried uris are
- * in ctxt->uri list. Make list of remainder and failed uris with
- * failed uris at end and assign back to ctxt-uri.
- */
- list_splice(ctxt->uri, &tmp);
- INIT_LIST_HEAD(ctxt->uri);
- list_splice(&tmp, ctxt->uri);
- uris_mutex_unlock(ctxt);
return ldap;
}
@@ -677,23 +673,19 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt)
struct ldap_uri *this;
LDAP *ldap;
- if (ctxt->server || !ctxt->uri) {
+ if (ctxt->server || !ctxt->uris) {
ldap = do_connect(logopt, ctxt->server, ctxt);
return ldap;
}
uris_mutex_lock(ctxt);
- this = list_entry(ctxt->uri->next, struct ldap_uri, list);
+ this = ctxt->uri;
uris_mutex_unlock(ctxt);
ldap = do_connect(logopt, this->uri, ctxt);
if (ldap)
return ldap;
- /* Failed to connect, put at end of list */
- uris_mutex_lock(ctxt);
- list_del_init(&this->list);
- list_add_tail(&this->list, ctxt->uri);
- uris_mutex_unlock(ctxt);
+ /* Failed to connect, try to find a new server */
#ifdef WITH_SASL
autofs_sasl_dispose(ctxt);
@@ -1259,8 +1251,8 @@ static void free_context(struct lookup_context *ctxt)
free(ctxt->cur_host);
if (ctxt->base)
free(ctxt->base);
- if (ctxt->uri)
- defaults_free_uris(ctxt->uri);
+ if (ctxt->uris)
+ defaults_free_uris(ctxt->uris);
ret = pthread_mutex_destroy(&ctxt->uris_mutex);
if (ret)
fatal(ret);
@@ -1344,7 +1336,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
if (uris) {
validate_uris(uris);
if (!list_empty(uris))
- ctxt->uri = uris;
+ ctxt->uris = uris;
else {
error(LOGOPT_ANY,
"no valid uris found in config list"
@@ -1375,7 +1367,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
}
#endif
- if (ctxt->server || !ctxt->uri) {
+ if (ctxt->server || !ctxt->uris) {
ldap = connect_to_server(LOGOPT_NONE, ctxt->server, ctxt);
if (!ldap) {
free_context(ctxt);

View File

@ -1,49 +0,0 @@
autofs-5.0.4 - use CLOEXEC flag setmntent include fix
From: Ian Kent <raven@themaw.net>
Fix mntent.h not included before use of setmntent_r() in automount.h.
---
include/automount.h | 1 +
lib/dev-ioctl-lib.c | 1 -
lib/mounts.c | 1 -
3 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/include/automount.h b/include/automount.h
index 1f14d5b..615e07d 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -19,6 +19,7 @@
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
+#include <mntent.h>
#include "config.h"
#include "list.h"
diff --git a/lib/dev-ioctl-lib.c b/lib/dev-ioctl-lib.c
index 056a0a9..7c8c433 100644
--- a/lib/dev-ioctl-lib.c
+++ b/lib/dev-ioctl-lib.c
@@ -22,7 +22,6 @@
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
-#include <mntent.h>
#include <sys/vfs.h>
#include "automount.h"
diff --git a/lib/mounts.c b/lib/mounts.c
index 08ca4e3..4787bb6 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -14,7 +14,6 @@
#include <stdlib.h>
#include <string.h>
-#include <mntent.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>

View File

@ -1,90 +0,0 @@
autofs-5.0.4 - use CLOEXEC flag for setmntent
From: Ian Kent <raven@themaw.net>
Update use of CLOEXEC functionality to cover setmntent(3)
calls as well.
---
CHANGELOG | 1 +
include/automount.h | 20 ++++++++++++++++++++
lib/mounts.c | 8 ++++----
3 files changed, 25 insertions(+), 4 deletions(-)
--- autofs-5.0.4.orig/CHANGELOG
+++ autofs-5.0.4/CHANGELOG
@@ -8,6 +8,7 @@
- make hash table scale to thousands of entries (Paul Wankadia,
Valerie Aurora Henson).
- clear the quoted flag after each character from program map input.
+- use CLOEXEC flag for setmntent also.
4/11/2008 autofs-5.0.4
-----------------------
--- autofs-5.0.4.orig/include/automount.h
+++ autofs-5.0.4/include/automount.h
@@ -581,5 +581,25 @@ static inline FILE *open_fopen_r(const c
return f;
}
+static inline FILE *open_setmntent_r(const char *table)
+{
+ FILE *tab;
+
+#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC)
+ if (cloexec_works != -1) {
+ tab = setmntent(table, "re");
+ if (tab != NULL) {
+ check_cloexec(fileno(tab));
+ return tab;
+ }
+ }
+#endif
+ tab = fopen(table, "r");
+ if (tab == NULL)
+ return NULL;
+ check_cloexec(fileno(tab));
+ return tab;
+}
+
#endif
--- autofs-5.0.4.orig/lib/mounts.c
+++ autofs-5.0.4/lib/mounts.c
@@ -218,7 +218,7 @@ struct mnt_list *get_mnt_list(const char
if (!path || !pathlen || pathlen > PATH_MAX)
return NULL;
- tab = setmntent(table, "r");
+ tab = open_setmntent_r(table);
if (!tab) {
char *estr = strerror_r(errno, buf, PATH_MAX - 1);
logerr("setmntent: %s", estr);
@@ -415,7 +415,7 @@ static int table_is_mounted(const char *
if (!path || !pathlen || pathlen >= PATH_MAX)
return 0;
- tab = setmntent(table, "r");
+ tab = open_setmntent_r(table);
if (!tab) {
char *estr = strerror_r(errno, buf, PATH_MAX - 1);
logerr("setmntent: %s", estr);
@@ -489,7 +489,7 @@ int has_fstab_option(const char *opt)
if (!opt)
return 0;
- tab = setmntent(_PATH_MNTTAB, "r");
+ tab = open_setmntent_r(_PATH_MNTTAB);
if (!tab) {
char *estr = strerror_r(errno, buf, PATH_MAX - 1);
logerr("setmntent: %s", estr);
@@ -668,7 +668,7 @@ struct mnt_list *tree_make_mnt_tree(cons
size_t plen;
int eq;
- tab = setmntent(table, "r");
+ tab = open_setmntent_r(table);
if (!tab) {
char *estr = strerror_r(errno, buf, PATH_MAX - 1);
logerr("setmntent: %s", estr);

File diff suppressed because it is too large Load Diff

View File

@ -1,82 +0,0 @@
autofs-5.0.4 - use intr option as hosts mount default
From: Ian Kent <raven@themaw.net>
Use the "intr" option as default mount option for the hosts map
unless explicily overridden.
---
CHANGELOG | 1 +
man/auto.master.5.in | 5 +++--
modules/parse_sun.c | 11 +++++++----
3 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 8258e00..a42dd14 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -41,6 +41,7 @@
- reset flex scanner when setting buffer.
- zero s_magic is valid.
- use percent hack for master map keys.
+- use intr option as hosts mount default.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/man/auto.master.5.in b/man/auto.master.5.in
index aaa6324..7b7004f 100644
--- a/man/auto.master.5.in
+++ b/man/auto.master.5.in
@@ -208,8 +208,9 @@ For example, with an entry in the master map of
accessing /net/myserver will mount exports from myserver on directories below
/net/myserver.
.P
-NOTE: mounts done from a hosts map will be mounted with the "nosuid" and "nodev" options
-unless the options "suid" and "dev" are explicitly given in the master map entry.
+NOTE: mounts done from a hosts map will be mounted with the "nosuid,nodev,intr" options
+unless overridden by explicily specifying the "suid", "dev" or "nointr" options in the
+master map entry.
.SH LDAP MAPS
If the map type \fBldap\fP is specified the mapname is of the form
\fB[//servername/]dn\fP, where the optional \fBservername\fP is
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 65417e1..db36ae2 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -607,9 +607,10 @@ static int sun_mount(struct autofs_point *ap, const char *root,
int len = strlen(options);
int suid = strstr(options, "suid") ? 0 : 7;
int dev = strstr(options, "dev") ? 0 : 6;
+ int nointr = strstr(options, "nointr") ? 0 : 5;
- if (suid || dev) {
- char *tmp = alloca(len + suid + dev + 1);
+ if (suid || dev || nointr) {
+ char *tmp = alloca(len + suid + dev + nointr + 1);
if (!tmp) {
error(ap->logopt, MODPREFIX
"alloca failed for options");
@@ -623,10 +624,12 @@ static int sun_mount(struct autofs_point *ap, const char *root,
strcat(tmp, ",nosuid");
if (dev)
strcat(tmp, ",nodev");
+ if (nointr)
+ strcat(tmp, ",intr");
options = tmp;
}
} else {
- char *tmp = alloca(13);
+ char *tmp = alloca(18);
if (!tmp) {
error(ap->logopt,
MODPREFIX "alloca failed for options");
@@ -634,7 +637,7 @@ static int sun_mount(struct autofs_point *ap, const char *root,
return -1;
return 1;
}
- strcpy(tmp, "nosuid,nodev");
+ strcpy(tmp, "nosuid,nodev,intr");
options = tmp;
}
}

View File

@ -1,52 +0,0 @@
autofs-5.0.4 - use misc device
From: Ian Kent <raven@themaw.net>
Change default installed configuration to use the misc device ioctl
interface if available.
---
CHANGELOG | 1 +
redhat/autofs.sysconfig.in | 2 +-
samples/autofs.conf.default.in | 2 +-
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index da7ecbf..234e1e0 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -32,6 +32,7 @@
- another easy alloca replacements fix.
- add LSB init script parameter block.
- fix file map lookup when reading included or nsswitch sources.
+- use misc device ioctl interface by default, if available.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/redhat/autofs.sysconfig.in b/redhat/autofs.sysconfig.in
index 04e521c..97e20fe 100644
--- a/redhat/autofs.sysconfig.in
+++ b/redhat/autofs.sysconfig.in
@@ -110,7 +110,7 @@ BROWSE_MODE="no"
# If the kernel supports using the autofs miscellanous device
# and you wish to use it you must set this configuration option
# to "yes" otherwise it will not be used.
-#USE_MISC_DEVICE="no"
+USE_MISC_DEVICE="yes"
#
#OPTIONS=""
#
diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in
index 52d18ec..62084c2 100644
--- a/samples/autofs.conf.default.in
+++ b/samples/autofs.conf.default.in
@@ -110,7 +110,7 @@ BROWSE_MODE="no"
# If the kernel supports using the autofs miscellanous device
# and you wish to use it you must set this configuration option
# to "yes" otherwise it will not be used.
-#USE_MISC_DEVICE="no"
+USE_MISC_DEVICE="yes"
#
#OPTIONS=""
#

View File

@ -1,136 +0,0 @@
autofs-5.0.4 - use percent hack for master map keys
From: Ian Kent <raven@themaw.net>
The percent hack translation has been done for map keys but it
isn't used for master map keys.
---
CHANGELOG | 1 +
modules/lookup_ldap.c | 66 +++++++++++++++++++++++++++++++++++++++++++------
2 files changed, 59 insertions(+), 8 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 4ed80e0..8258e00 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -40,6 +40,7 @@
- fix st_remove_tasks() locking.
- reset flex scanner when setting buffer.
- zero s_magic is valid.
+- use percent hack for master map keys.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 9b1180c..8c6a8f2 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -60,6 +60,7 @@ struct ldap_search_params {
};
static LDAP *auth_init(unsigned logopt, const char *, struct lookup_context *);
+static int decode_percent_hack(const char *, char **);
#ifndef HAVE_LDAP_CREATE_PAGE_CONTROL
int ldap_create_page_control(LDAP *ldap, ber_int_t pagesize,
@@ -1508,6 +1509,9 @@ int lookup_read_master(struct master *master, time_t age, void *context)
debug(logopt, MODPREFIX "examining entries");
while (e) {
+ char *key = NULL;
+ int dec_len, i;
+
keyValue = ldap_get_values(ldap, e, entry);
if (!keyValue || !*keyValue) {
@@ -1519,19 +1523,63 @@ int lookup_read_master(struct master *master, time_t age, void *context)
* By definition keys must be unique within
* each map entry
*/
- if (ldap_count_values(keyValue) > 1) {
- error(logopt,
- MODPREFIX
- "key %s has duplicate entries - ignoring",
- *keyValue);
- goto next;
+ count = ldap_count_values(keyValue);
+ if (strcasecmp(class, "nisObject")) {
+ if (count > 1) {
+ error(logopt, MODPREFIX
+ "key %s has duplicates - ignoring",
+ *keyValue);
+ goto next;
+ }
+ key = strdup(keyValue[0]);
+ if (!key) {
+ error(logopt, MODPREFIX
+ "failed to dup map key %s - ignoring",
+ *keyValue);
+ goto next;
+ }
+ } else if (count == 1) {
+ dec_len = decode_percent_hack(keyValue[0], &key);
+ if (dec_len < 0) {
+ error(logopt, MODPREFIX
+ "invalid map key %s - ignoring",
+ *keyValue);
+ goto next;
+ }
+ } else {
+ dec_len = decode_percent_hack(keyValue[0], &key);
+ if (dec_len < 0) {
+ error(logopt, MODPREFIX
+ "invalid map key %s - ignoring",
+ *keyValue);
+ goto next;
+ }
+
+ for (i = 1; i < count; i++) {
+ char *k;
+ dec_len = decode_percent_hack(keyValue[i], &k);
+ if (dec_len < 0) {
+ error(logopt, MODPREFIX
+ "invalid map key %s - ignoring",
+ *keyValue);
+ goto next;
+ }
+ if (strcmp(key, k)) {
+ error(logopt, MODPREFIX
+ "key entry mismatch %s - ignoring",
+ *keyValue);
+ free(k);
+ goto next;
+ }
+ free(k);
+ }
}
/*
* Ignore keys beginning with '+' as plus map
* inclusion is only valid in file maps.
*/
- if (**keyValue == '+') {
+ if (*key == '+') {
warn(logopt,
MODPREFIX
"ignoreing '+' map entry - not in file map");
@@ -1558,7 +1606,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
}
if (snprintf(parse_buf, sizeof(parse_buf), "%s %s",
- *keyValue, *values) >= sizeof(parse_buf)) {
+ key, *values) >= sizeof(parse_buf)) {
error(logopt, MODPREFIX "map entry too long");
ldap_value_free(values);
goto next;
@@ -1568,6 +1616,8 @@ int lookup_read_master(struct master *master, time_t age, void *context)
master_parse_entry(parse_buf, timeout, logging, age);
next:
ldap_value_free(keyValue);
+ if (key)
+ free(key);
e = ldap_next_entry(ldap, e);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,47 +0,0 @@
autofs-5.0.4 - zero s_magic is valid
From: Ian Kent <raven@themaw.net>
When checking the super magic using the mount control ioctl
re-implementation an incorrect assumption is made that s_magic
field in the super block will not be zero.
---
CHANGELOG | 1 +
lib/dev-ioctl-lib.c | 10 ++++------
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 5f1cf7f..4ed80e0 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -39,6 +39,7 @@
- fix memory leak reading master map.
- fix st_remove_tasks() locking.
- reset flex scanner when setting buffer.
+- zero s_magic is valid.
4/11/2008 autofs-5.0.4
-----------------------
diff --git a/lib/dev-ioctl-lib.c b/lib/dev-ioctl-lib.c
index 7c8c433..a034a3d 100644
--- a/lib/dev-ioctl-lib.c
+++ b/lib/dev-ioctl-lib.c
@@ -764,12 +764,10 @@ static int dev_ioctl_ismountpoint(unsigned int logopt,
if (err) {
*mountpoint = DEV_IOCTL_IS_MOUNTED;
- if (param->ismountpoint.out.magic) {
- if (param->ismountpoint.out.magic == AUTOFS_SUPER_MAGIC)
- *mountpoint |= DEV_IOCTL_IS_AUTOFS;
- else
- *mountpoint |= DEV_IOCTL_IS_OTHER;
- }
+ if (param->ismountpoint.out.magic == AUTOFS_SUPER_MAGIC)
+ *mountpoint |= DEV_IOCTL_IS_AUTOFS;
+ else
+ *mountpoint |= DEV_IOCTL_IS_OTHER;
}
free_dev_ioctl_path(param);