* Tue Nov 8 2011 Ian Kent <ikent@redhat.com> - 1:5.0.6-3

- improve mount location error reporting.
- fix paged query more results check.
- fix dumpmaps not reading maps.
- fix result null check in read_one_map().
- Fix LDAP result leaks on error paths.
- code analysis fixes 1.
- fix not bind mounting local filesystem.
- update dir map-type patch for changed patch order.
- fix wait for master source mutex.
- fix submount shutdown race
- fix fix map source check in file lookup.
- add disable move mount configure option.
This commit is contained in:
Ian Kent 2011-11-08 13:13:22 +08:00
parent 4f7edcb12e
commit ca38f0b091
13 changed files with 1174 additions and 4 deletions

View File

@ -44,16 +44,29 @@ included or not: the file which name ends with ".autofs" is included.
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
---
CHANGELOG | 1
autofs.spec | 2
daemon/lookup.c | 3 -
man/auto.master.5.in | 10 ++
modules/Makefile | 6 +
modules/lookup_dir.c | 219 ++++++++++++++++++++++++++++++++++++++++++++++++++
samples/auto.master | 4 +
6 files changed, 239 insertions(+), 5 deletions(-)
7 files changed, 240 insertions(+), 5 deletions(-)
create mode 100644 modules/lookup_dir.c
diff --git a/CHANGELOG b/CHANGELOG
index 7e86c84..5b988d4 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -8,6 +8,7 @@
- fix LDAP result leaks on error paths.
- code analysis fixes part 1.
- fix not bind mounting local filesystem.
+- add "dir" map-type.
28/06/2011 autofs-5.0.6
-----------------------
diff --git a/autofs.spec b/autofs.spec
index 91d4f8b..82edd1e 100644
--- a/autofs.spec

View File

@ -0,0 +1,334 @@
autofs-5.0.6 - add disable move mount configure option
From: Ian Kent <ikent@redhat.com>
With the introduction of systemd the root filesystem is now usually
marked as shared instead of private as part of the systemd sandbox
functionality. As a consequence moving a mount from one mount point
to another is not allowed.
To resolve this a configure option (--disable-move-mount) to disable
autofs preparing mount tree and then moving it into place has been
added. The move mount use in autofs was needed for a small set of
automount types with older kernels (prior to 2.6.39). So to disable
the use of move mount it's necessary to use a recent kernel.
---
CHANGELOG | 1 +
autofs.spec | 2 +-
configure | 18 ++++++++++++++++++
configure.in | 10 ++++++++++
daemon/automount.c | 11 +++++++++++
include/config.h.in | 3 +++
modules/mount_nfs.c | 5 -----
modules/parse_sun.c | 40 +++++++++++++++++++++++++++++++++++-----
8 files changed, 79 insertions(+), 11 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 304b6a2..c682f94 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -12,6 +12,7 @@
- fix wait for master source mutex.
- fix submount shutdown race.
- fix fix map source check in file lookup.
+- add disable move mount configure option.
28/06/2011 autofs-5.0.6
-----------------------
diff --git a/autofs.spec b/autofs.spec
index 82edd1e..510ef76 100644
--- a/autofs.spec
+++ b/autofs.spec
@@ -57,7 +57,7 @@ inkludera n
echo %{version}-%{release} > .version
%build
-CFLAGS="$RPM_OPT_FLAGS -Wall" ./configure --libdir=%{_libdir} --disable-mount-locking --enable-ignore-busy --with-libtirpc
+CFLAGS="$RPM_OPT_FLAGS -Wall" ./configure --libdir=%{_libdir} --disable-mount-locking --enable-ignore-busy --with-libtirpc --disable-mount-move
CFLAGS="$RPM_OPT_FLAGS -Wall" make initdir=/etc/rc.d/init.d DONTSTRIP=1
%install
diff --git a/configure b/configure
index b5a3608..76b6d86 100755
--- a/configure
+++ b/configure
@@ -704,6 +704,7 @@ with_openldap
with_sasl
enable_ext_env
enable_mount_locking
+enable_mount_move
enable_forced_shutdown
enable_ignore_busy
'
@@ -1326,6 +1327,7 @@ Optional Features:
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--disable-ext-env disable search in environment for substitution variable
--disable-mount-locking disable use of locking when spawning mount command
+ --disable-mount-move disable use of mount move when when preparing tree of mounts
--enable-force-shutdown enable USR1 signal to force unlink umount of any
busy mounts during shutdown
--enable-ignore-busy enable exit without umounting busy mounts during
@@ -5349,6 +5351,22 @@ $as_echo "#define ENABLE_MOUNT_LOCKING 1" >>confdefs.h
fi
#
+# Disable use of mount move
+#
+# Check whether --enable-mount-move was given.
+if test "${enable_mount_move+set}" = set; then :
+ enableval=$enable_mount_move;
+else
+ enableval=yes
+fi
+
+if test x$enable_mount_move = xyes -o x$enableval = xyes; then
+
+$as_echo "#define ENABLE_MOUNT_MOVE 1" >>confdefs.h
+
+fi
+
+#
# Enable forced shutdown on USR1 signal (unlink umounts all mounts).
#
# Check whether --enable-forced-shutdown was given.
diff --git a/configure.in b/configure.in
index 46de65a..d3e4e54 100644
--- a/configure.in
+++ b/configure.in
@@ -324,6 +324,16 @@ if test x$enable_mount_locking = xyes -o x$enableval = xyes; then
fi
#
+# Disable use of mount move
+#
+AC_ARG_ENABLE(mount-move,
+[ --disable-mount-move disable use of mount move when when preparing tree of mounts],,
+ enableval=yes)
+if test x$enable_mount_move = xyes -o x$enableval = xyes; then
+ AC_DEFINE(ENABLE_MOUNT_MOVE, 1, [Disable use of mount move when preparing tree of mounts])
+fi
+
+#
# Enable forced shutdown on USR1 signal (unlink umounts all mounts).
#
AC_ARG_ENABLE(forced-shutdown,
diff --git a/daemon/automount.c b/daemon/automount.c
index 4f3151f..6bb5aa8 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -1743,9 +1743,20 @@ static void show_build_info(void)
count = 22;
#endif
+#ifndef ENABLE_MOUNT_MOVE
+ printf("DISABLE_MOUNT_MOVE ");
+ count = count + 19;
+#endif
+
#ifdef ENABLE_FORCED_SHUTDOWN
printf("ENABLE_FORCED_SHUTDOWN ");
count = count + 23;
+
+ if (count > 60) {
+ printf("\n ");
+ count = 0;
+ }
+
#endif
#ifdef ENABLE_IGNORE_BUSY_MOUNTS
diff --git a/include/config.h.in b/include/config.h.in
index 4a3a990..97a8d2d 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -12,6 +12,9 @@
/* Disable use of locking when spawning mount command */
#undef ENABLE_MOUNT_LOCKING
+/* Disable use of mount move when preparing tree of mounts */
+#undef ENABLE_MOUNT_MOVE
+
/* define if you have E2FSCK */
#undef HAVE_E2FSCK
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
index 8b567d2..7eab728 100644
--- a/modules/mount_nfs.c
+++ b/modules/mount_nfs.c
@@ -163,11 +163,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
if (root[len - 1] == '/') {
len = snprintf(fullpath, len, "%s", 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);
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 021850d..13b8af8 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -1028,6 +1028,7 @@ static int parse_mapent(const char *ent, char *g_options, char **options, char *
return (p - ent);
}
+#ifdef ENABLE_MOUNT_MOVE
static int move_mount(struct autofs_point *ap,
const char *mm_tmp_root, const char *mm_root,
unsigned int move)
@@ -1063,6 +1064,7 @@ static int move_mount(struct autofs_point *ap,
return 1;
}
+#endif
static void cleanup_multi_root(struct autofs_point *ap, const char *root,
const char *path, unsigned int move)
@@ -1145,6 +1147,7 @@ static void cleanup_multi_triggers(struct autofs_point *ap,
return;
}
+#ifdef ENABLE_MOUNT_MOVE
static int check_fstype_autofs_option(const char *options)
{
char *tok, *tokbuf;
@@ -1171,24 +1174,27 @@ static int check_fstype_autofs_option(const char *options)
return found;
}
+#endif
static int mount_subtree(struct autofs_point *ap, struct mapent *me,
const char *name, char *loc, char *options, void *ctxt)
{
struct mapent *mm;
struct mapent *ro;
- char t_dir[] = "/tmp/autoXXXXXX";
- char *mnt_tmp_root, *mm_root, *mm_base, *mm_key;
+ char *mm_root, *mm_base, *mm_key;
const char *mnt_root, *target;
unsigned int mm_root_len, mnt_root_len;
int start, ret = 0, rv;
- unsigned int move;
+ unsigned int move = MOUNT_MOVE_NONE;
+#ifdef ENABLE_MOUNT_MOVE
+ char t_dir[] = "/tmp/autoXXXXXX";
+ char *mnt_tmp_root = NULL;
+#endif
rv = 0;
mm = me->multi;
mm_key = mm->key;
- move = MOUNT_MOVE_NONE;
if (*mm_key == '/') {
mm_root = mm_key;
@@ -1202,7 +1208,10 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
}
mm_root_len = strlen(mm_root);
- mnt_tmp_root = NULL;
+#ifndef ENABLE_MOUNT_MOVE
+ mnt_root = mm_root;
+ mnt_root_len = mm_root_len;
+#else
if (ap->flags & MOUNT_FLAG_REMOUNT) {
mnt_root = mm_root;
mnt_root_len = mm_root_len;
@@ -1213,6 +1222,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
mnt_root_len = strlen(mnt_root);
mnt_tmp_root = (char *) mnt_root;
}
+#endif
if (me == me->multi) {
/* name = NULL */
@@ -1238,11 +1248,13 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
}
ro_len = strlen(ro_loc);
+#ifdef ENABLE_MOUNT_MOVE
if (!(ap->flags & MOUNT_FLAG_REMOUNT)) {
move = MOUNT_MOVE_OTHER;
if (check_fstype_autofs_option(myoptions))
move = MOUNT_MOVE_AUTOFS;
}
+#endif
tmp = alloca(mnt_root_len + 1);
strcpy(tmp, mnt_root);
@@ -1266,7 +1278,9 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
goto error_out;
}
} else if (rv <= 0) {
+#ifdef ENABLE_MOUNT_MOVE
move = MOUNT_MOVE_NONE;
+#endif
ret = mount_multi_triggers(ap, me, mm_root, start, mm_base);
if (ret == -1) {
error(ap->logopt, MODPREFIX
@@ -1279,11 +1293,21 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
int loclen = strlen(loc);
int namelen = strlen(name);
+#ifndef ENABLE_MOUNT_MOVE
+ /*
+ * When using move mount to mount offsets or direct mounts
+ * the base of the tree can be the base of the temporary
+ * mount point it needs to be the full path when not moving
+ * the mount after construction.
+ */
+ mnt_root = name;
+#else
if (!(ap->flags & MOUNT_FLAG_REMOUNT)) {
move = MOUNT_MOVE_OTHER;
if (check_fstype_autofs_option(options))
move = MOUNT_MOVE_AUTOFS;
}
+#endif
/* name = mm_root + mm_base */
/* destination = mm_root + mm_base = name */
@@ -1303,7 +1327,9 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
} else if (rv < 0) {
char *mm_root_base = alloca(strlen(mm_root) + strlen(mm_base) + 1);
+#ifdef ENABLE_MOUNT_MOVE
move = MOUNT_MOVE_NONE;
+#endif
strcpy(mm_root_base, mm_root);
strcat(mm_root_base, mm_base);
@@ -1318,6 +1344,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
}
}
+#ifdef ENABLE_MOUNT_MOVE
if (!move_mount(ap, mnt_root, target, move)) {
cleanup_multi_triggers(ap, me, mnt_root, start, mm_base);
cleanup_multi_root(ap, mnt_root, mm_root, move);
@@ -1326,6 +1353,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
if (mnt_tmp_root)
rmdir(mnt_tmp_root);
+#endif
/* Mount for base of tree failed */
if (rv > 0)
@@ -1341,8 +1369,10 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
return rv;
error_out:
+#ifdef ENABLE_MOUNT_MOVE
if (mnt_tmp_root)
rmdir(mnt_tmp_root);
+#endif
return 1;
}

View File

@ -0,0 +1,101 @@
autofs-5.0.6 - code analysis fixes 1
From: Ian Kent <ikent@redhat.com>
Code analysis defect fixes, installment 1.
- fix signed usage of unsigned variable in do_srv_query().
- make NULL check handling of variable dcs explicit in get_dc_list().
- adding an explicit NULL check for variable dcs gaurds against
future changes in get_srv_rrs() returning success while not
clearing the dcs variable.
- makes it explict for readers why we don't need to check for NULL
before free later in the loop.
- fix typo in do_reconnect()
- uri is never set now and, at this point, we need to try to connect
to the last server uri (ctxt->uri->uri) which is set in find_server()
when ctxt->uri is NULL.
---
CHANGELOG | 1 +
modules/dclist.c | 11 +++++------
modules/lookup_ldap.c | 3 +--
3 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index dc91c25..acc5f0c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -6,6 +6,7 @@
- fix dumpmaps not reading maps.
- fix result null check in read_one_map().
- fix LDAP result leaks on error paths.
+- code analysis fixes part 1.
28/06/2011 autofs-5.0.6
-----------------------
diff --git a/modules/dclist.c b/modules/dclist.c
index aeb107f..d16b913 100644
--- a/modules/dclist.c
+++ b/modules/dclist.c
@@ -69,7 +69,7 @@ static void dclist_mutex_unlock(void)
static int do_srv_query(unsigned int logopt, char *name, u_char **packet)
{
- unsigned int len = PACKETSZ;
+ int len = PACKETSZ;
unsigned int last_len = len;
char ebuf[MAX_ERR_BUF];
u_char *buf;
@@ -500,7 +500,8 @@ struct dclist *get_dc_list(unsigned int logopt, const char *uri)
}
dclist_mutex_lock();
- if (!get_srv_rrs(logopt, request, &dcs, &numdcs)) {
+ ret = get_srv_rrs(logopt, request, &dcs, &numdcs);
+ if (!ret | !dcs) {
error(logopt,
"DNS SRV query failed for domain %s", domain);
dclist_mutex_unlock();
@@ -526,8 +527,7 @@ struct dclist *get_dc_list(unsigned int logopt, const char *uri)
if (!tmp) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
error(logopt, "realloc: %s", estr);
- if (dcs)
- free_srv_rrs(dcs, numdcs);
+ free_srv_rrs(dcs, numdcs);
goto out_error;
}
@@ -548,8 +548,7 @@ struct dclist *get_dc_list(unsigned int logopt, const char *uri)
if (ret > 6) {
error(logopt,
"invalid port: %u", dcs[i].port);
- if (dcs)
- free_srv_rrs(dcs, numdcs);
+ free_srv_rrs(dcs, numdcs);
goto out_error;
}
strcat(tmp, port);
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 29323b2..67a6834 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -736,7 +736,6 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt)
{
LDAP *ldap = NULL;
- char *uri;
if (ctxt->server || !ctxt->uris) {
ldap = do_connect(logopt, ctxt->server, ctxt);
@@ -780,7 +779,7 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt)
*/
if (!ldap) {
autofs_sasl_dispose(ctxt);
- ldap = connect_to_server(logopt, uri, ctxt);
+ ldap = connect_to_server(logopt, ctxt->uri->uri, ctxt);
}
#endif
if (ldap)

View File

@ -0,0 +1,56 @@
autofs-5.0.6 - Fix LDAP result leaks on error paths
From: Leonardo Chiquitto <leonardo.lists@gmail.com>
According to ldap_search_s(3), the result structure must be freed
with ldap_msgfree() even when the search function returned failure.
---
CHANGELOG | 1 +
modules/lookup_ldap.c | 6 ++++++
2 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 66b804f..dc91c25 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -5,6 +5,7 @@
- fix paged query more results check.
- fix dumpmaps not reading maps.
- fix result null check in read_one_map().
+- fix LDAP result leaks on error paths.
28/06/2011 autofs-5.0.6
-----------------------
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 22ff355..29323b2 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -347,6 +347,8 @@ static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt
error(logopt,
MODPREFIX "query failed for %s: %s",
query, ldap_err2string(rv));
+ if (result)
+ ldap_msgfree(result);
free(query);
return 0;
}
@@ -1573,6 +1575,8 @@ int lookup_read_master(struct master *master, time_t age, void *context)
error(logopt, MODPREFIX "query failed for %s: %s",
query, ldap_err2string(rv));
unbind_ldap_connection(logging, ldap, ctxt);
+ if (result)
+ ldap_msgfree(result);
free(query);
return NSS_STATUS_NOTFOUND;
}
@@ -2586,6 +2590,8 @@ static int lookup_one(struct autofs_point *ap,
if ((rv != LDAP_SUCCESS) || !result) {
crit(ap->logopt, MODPREFIX "query failed for %s", query);
unbind_ldap_connection(ap->logopt, ldap, ctxt);
+ if (result)
+ ldap_msgfree(result);
free(query);
return CHE_FAIL;
}

View File

@ -0,0 +1,47 @@
autofs-5.0.6 - fix dumpmaps not reading maps
From: Ian Kent <raven@themaw.net>
The lookup modules won't read any indirect map entries (other than those
in a file map) unless unless the browse option is set. In order to list
the entries when tyhe dumpmap option is given the browse option needs to
be set.
---
CHANGELOG | 1 +
lib/master.c | 9 +++++++++
2 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 884a9ae..946a196 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -3,6 +3,7 @@
- fix ipv6 name for lookup fix.
- improve mount location error reporting.
- fix paged query more results check.
+- fix dumpmaps not reading maps.
28/06/2011 autofs-5.0.6
-----------------------
diff --git a/lib/master.c b/lib/master.c
index 153a38b..6c89e1d 100644
--- a/lib/master.c
+++ b/lib/master.c
@@ -1283,6 +1283,15 @@ int master_show_mounts(struct master *master)
printf("\nMount point: %s\n", ap->path);
printf("\nsource(s):\n");
+ /*
+ * Ensure we actually read indirect map entries so we can
+ * list them. The map reads won't read any indirect map
+ * entries (other than those in a file map) unless the
+ * browse option is set.
+ */
+ if (ap->type == LKP_INDIRECT)
+ ap->flags |= MOUNT_FLAG_GHOST;
+
/* Read the map content into the cache */
if (lookup_nss_read_map(ap, NULL, now))
lookup_prune_cache(ap, now);

View File

@ -0,0 +1,40 @@
autofs-5.0.6 - fix fix map source check in file lookup
From: Ian Kent <raven@themaw.net>
A recent change to correct a problem with included map entry removal
has broken a different case of included map key lookup. The check in
previous patch was too broad and caused map key lookup for keys in an
included multi-mount map entrys to not be found.
---
CHANGELOG | 1 +
modules/lookup_file.c | 2 +-
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index cb9ac75..304b6a2 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -11,6 +11,7 @@
- add "dir" map-type.
- fix wait for master source mutex.
- fix submount shutdown race.
+- fix fix map source check in file lookup.
28/06/2011 autofs-5.0.6
-----------------------
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index 8ead07c..63b5ae7 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -1046,7 +1046,7 @@ do_cache_lookup:
* instance (same map entry cache), not in a distinct source.
*/
if (me && (!me->mapent ||
- (ap->type == LKP_INDIRECT && me->source != source))) {
+ (me->source != source && *me->key != '/'))) {
while ((me = cache_lookup_key_next(me)))
if (me->source == source)
break;

View File

@ -0,0 +1,56 @@
autofs-5.0.6 - fix not bind mounting local filesystem
From: Ian Kent <ikent@redhat.com>
When the --random-multimount-selection (-r) option is used automount(8)
won't bind mount a local filesystem. If the filesystem that has been
requested is local it should always be used.
---
CHANGELOG | 1 +
modules/replicated.c | 12 +++++++-----
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index acc5f0c..7e86c84 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -7,6 +7,7 @@
- fix result null check in read_one_map().
- fix LDAP result leaks on error paths.
- code analysis fixes part 1.
+- fix not bind mounting local filesystem.
28/06/2011 autofs-5.0.6
-----------------------
diff --git a/modules/replicated.c b/modules/replicated.c
index a10a817..eee1a06 100644
--- a/modules/replicated.c
+++ b/modules/replicated.c
@@ -1068,18 +1068,20 @@ static int add_new_host(struct host **list,
* We can't use PROXIMITY_LOCAL or we won't perform an RPC ping
* to remove hosts that may be down.
*/
- if (options & MOUNT_FLAG_RANDOM_SELECT)
+ if (!host_addr)
prx = PROXIMITY_SUBNET;
else {
prx = get_proximity(host_addr->ai_addr);
/*
* If we want the weight to be the determining factor
- * when selecting a host then all hosts must have the
- * same proximity. However, if this is the local machine
- * it should always be used since it is certainly available.
+ * when selecting a host, or we are using random selection,
+ * then all hosts must have the same proximity. However,
+ * if this is the local machine it should always be used
+ * since it is certainly available.
*/
if (prx != PROXIMITY_LOCAL &&
- (options & MOUNT_FLAG_USE_WEIGHT_ONLY))
+ (options & (MOUNT_FLAG_USE_WEIGHT_ONLY |
+ MOUNT_FLAG_RANDOM_SELECT)))
prx = PROXIMITY_SUBNET;
}

View File

@ -0,0 +1,87 @@
autofs-5.0.6 - fix paged query more results check
From: Ian Kent <raven@themaw.net>
When getting paged results from an LDAP server the server returns an
opaque cookie (of type berval) that is used to retrieve the next page.
The criteria for deciding if there are more pages is that the berval
value is non-null and has a non-zero length.
To determine if the berval value has non-zero length autofs checks the
strlen() of the value but on ppc64 and s390x this can return 0 even if
the value has non-zero length causing a premature termination of the
query.
Fix this by also checking the berval length field.
Also make sure we free the opaque cookie when the query is finished.
---
CHANGELOG | 1 +
modules/lookup_ldap.c | 13 ++++++++++++-
2 files changed, 13 insertions(+), 1 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index a178b74..884a9ae 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,7 @@
=======================
- fix ipv6 name for lookup fix.
- improve mount location error reporting.
+- fix paged query more results check.
28/06/2011 autofs-5.0.6
-----------------------
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 719fed1..a25050a 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -2041,7 +2041,8 @@ do_paged:
rv = ldap_parse_page_control(sp->ldap,
returnedControls, &sp->totalCount,
&sp->cookie);
- if (sp->cookie && sp->cookie->bv_val && strlen(sp->cookie->bv_val))
+ if (sp->cookie && sp->cookie->bv_val &&
+ (strlen(sp->cookie->bv_val) || sp->cookie->bv_len))
sp->morePages = TRUE;
else
sp->morePages = FALSE;
@@ -2382,6 +2383,10 @@ static int read_one_map(struct autofs_point *ap,
rv == LDAP_SIZELIMIT_EXCEEDED) {
if (sp.result)
ldap_msgfree(sp.result);
+ if (sp.cookie) {
+ ber_bvfree(sp.cookie);
+ sp.cookie = NULL;
+ }
sp.pageSize = sp.pageSize / 2;
if (sp.pageSize < 5) {
debug(ap->logopt, MODPREFIX
@@ -2397,6 +2402,8 @@ static int read_one_map(struct autofs_point *ap,
if (rv != LDAP_SUCCESS || !sp.result) {
unbind_ldap_connection(ap->logopt, sp.ldap, ctxt);
*result_ldap = rv;
+ if (sp.cookie)
+ ber_bvfree(sp.cookie);
free(sp.query);
return NSS_STATUS_UNAVAIL;
}
@@ -2406,6 +2413,8 @@ static int read_one_map(struct autofs_point *ap,
ldap_msgfree(sp.result);
unbind_ldap_connection(ap->logopt, sp.ldap, ctxt);
*result_ldap = rv;
+ if (sp.cookie)
+ ber_bvfree(sp.cookie);
free(sp.query);
return NSS_STATUS_NOTFOUND;
}
@@ -2417,6 +2426,8 @@ static int read_one_map(struct autofs_point *ap,
unbind_ldap_connection(ap->logopt, sp.ldap, ctxt);
source->age = age;
+ if (sp.cookie)
+ ber_bvfree(sp.cookie);
free(sp.query);
return NSS_STATUS_SUCCESS;

View File

@ -0,0 +1,58 @@
autofs-5.0.6 - fix result null check in read_one_map()
From: Ian Kent <ikent@redhat.com>
Fix the check and reset to NULL of the LDAP library allocated result
within the loop to fetch paged query values.
---
CHANGELOG | 1 +
modules/lookup_ldap.c | 7 ++++++-
2 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 946a196..66b804f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -4,6 +4,7 @@
- improve mount location error reporting.
- fix paged query more results check.
- fix dumpmaps not reading maps.
+- fix result null check in read_one_map().
28/06/2011 autofs-5.0.6
-----------------------
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index a25050a..22ff355 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -2381,8 +2381,10 @@ static int read_one_map(struct autofs_point *ap,
if (rv == LDAP_ADMINLIMIT_EXCEEDED ||
rv == LDAP_SIZELIMIT_EXCEEDED) {
- if (sp.result)
+ if (sp.result) {
ldap_msgfree(sp.result);
+ sp.result = NULL;
+ }
if (sp.cookie) {
ber_bvfree(sp.cookie);
sp.cookie = NULL;
@@ -2402,6 +2404,8 @@ static int read_one_map(struct autofs_point *ap,
if (rv != LDAP_SUCCESS || !sp.result) {
unbind_ldap_connection(ap->logopt, sp.ldap, ctxt);
*result_ldap = rv;
+ if (sp.result)
+ ldap_msgfree(sp.result);
if (sp.cookie)
ber_bvfree(sp.cookie);
free(sp.query);
@@ -2419,6 +2423,7 @@ static int read_one_map(struct autofs_point *ap,
return NSS_STATUS_NOTFOUND;
}
ldap_msgfree(sp.result);
+ sp.result = NULL;
} while (sp.morePages == TRUE);
debug(ap->logopt, MODPREFIX "done updating map");

View File

@ -0,0 +1,141 @@
autofs-5.0.6 - fix submount shutdown race
From: Ian Kent <ikent@redhat.com>
Shutdown of submounts is problematic because the kernel doesn't
know when they are going away and so cannot block path walks
while they shut down. After aquiring the locks that cause mount
requests to wait, the daemon checks if the submount is active before
finally umounting it. If the mount is found to be busy the shutdown
is abandoned and the submount returned to a ready state.
But, if a mount request arrives at the same time as the daemon is
attempting to aquire these locks pthreads appears to become confused
and blocks. So change to using the try version of the lock call and
handling the return appropriately.
---
CHANGELOG | 1 +
daemon/automount.c | 76 ++++++++++++++++++++++++++++++++++++++++------------
2 files changed, 60 insertions(+), 17 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index cac450f..cb9ac75 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -10,6 +10,7 @@
- fix not bind mounting local filesystem.
- add "dir" map-type.
- fix wait for master source mutex.
+- fix submount shutdown race.
28/06/2011 autofs-5.0.6
-----------------------
diff --git a/daemon/automount.c b/daemon/automount.c
index 376e965..4f3151f 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -1495,6 +1495,41 @@ static void handle_mounts_cleanup(void *arg)
return;
}
+static int submount_source_writelock_nested(struct autofs_point *ap)
+{
+ struct autofs_point *parent = ap->parent;
+ int status;
+
+ status = pthread_rwlock_trywrlock(&parent->entry->source_lock);
+ if (status)
+ goto done;
+
+ mounts_mutex_lock(parent);
+
+ status = pthread_rwlock_trywrlock(&ap->entry->source_lock);
+ if (status) {
+ mounts_mutex_unlock(parent);
+ master_source_unlock(parent->entry);
+ }
+
+done:
+ if (status && status != EBUSY) {
+ logmsg("submount nested master_mapent source write lock failed");
+ fatal(status);
+ }
+
+ return status;
+}
+
+static void submount_source_unlock_nested(struct autofs_point *ap)
+{
+ struct autofs_point *parent = ap->parent;
+
+ master_source_unlock(ap->entry);
+ mounts_mutex_unlock(parent);
+ master_source_unlock(parent->entry);
+}
+
void *handle_mounts(void *arg)
{
struct startup_cond *suc;
@@ -1565,23 +1600,32 @@ void *handle_mounts(void *arg)
master_mutex_lock();
if (ap->submount) {
- master_source_writelock(ap->parent->entry);
- mounts_mutex_lock(ap->parent);
- }
-
- master_source_writelock(ap->entry);
+ /*
+ * If a mount request arrives before the locks are
+ * aquired just return to ready state.
+ */
+ ret = submount_source_writelock_nested(ap);
+ if (ret) {
+ warn(ap->logopt,
+ "can't shutdown submount: mount in progress");
+ /* Return to ST_READY is done immediately */
+ st_add_task(ap, ST_READY);
+ master_mutex_unlock();
+ pthread_setcancelstate(cur_state, NULL);
+ continue;
+ }
+ } else
+ master_source_writelock(ap->entry);
if (ap->state != ST_SHUTDOWN) {
if (!ap->submount)
alarm_add(ap, ap->exp_runfreq);
/* Return to ST_READY is done immediately */
st_add_task(ap, ST_READY);
- master_source_unlock(ap->entry);
- if (ap->submount) {
- mounts_mutex_unlock(ap->parent);
- master_source_unlock(ap->parent->entry);
- }
-
+ if (ap->submount)
+ submount_source_unlock_nested(ap);
+ else
+ master_source_unlock(ap->entry);
master_mutex_unlock();
pthread_setcancelstate(cur_state, NULL);
@@ -1621,12 +1665,10 @@ void *handle_mounts(void *arg)
alarm_add(ap, ap->exp_runfreq);
/* Return to ST_READY is done immediately */
st_add_task(ap, ST_READY);
- master_source_unlock(ap->entry);
- if (ap->submount) {
- mounts_mutex_unlock(ap->parent);
- master_source_unlock(ap->parent->entry);
- }
-
+ if (ap->submount)
+ submount_source_unlock_nested(ap);
+ else
+ master_source_unlock(ap->entry);
master_mutex_unlock();
pthread_setcancelstate(cur_state, NULL);

View File

@ -0,0 +1,84 @@
autofs-5.0.6 - fix wait for master source mutex
From: Ian Kent <ikent@redhat.com>
A previous change that was meant to handle the case where the master map
source mutex read lock count was exceeded was incorrectly done for the
write lock case instead of the read lock case.
---
CHANGELOG | 1 +
lib/master.c | 30 +++++++++++++++---------------
2 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 5b988d4..cac450f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -9,6 +9,7 @@
- code analysis fixes part 1.
- fix not bind mounting local filesystem.
- add "dir" map-type.
+- fix wait for master source mutex.
28/06/2011 autofs-5.0.6
-----------------------
diff --git a/lib/master.c b/lib/master.c
index 6c89e1d..87d1269 100644
--- a/lib/master.c
+++ b/lib/master.c
@@ -540,38 +540,38 @@ void send_map_update_request(struct autofs_point *ap)
void master_source_writelock(struct master_mapent *entry)
{
- int retries = 5; /* 1 second maximum */
int status;
- while (retries--) {
- status = pthread_rwlock_wrlock(&entry->source_lock);
- if (status != EAGAIN)
- break;
- else {
- struct timespec t = { 0, 200000000 };
- struct timespec r;
- while (nanosleep(&t, &r) == -1 && errno == EINTR)
- memcpy(&t, &r, sizeof(struct timespec));
- }
- }
-
+ status = pthread_rwlock_wrlock(&entry->source_lock);
if (status) {
logmsg("master_mapent source write lock failed");
fatal(status);
}
-
return;
}
void master_source_readlock(struct master_mapent *entry)
{
+ int retries = 5; /* 1 second maximum */
int status;
- status = pthread_rwlock_rdlock(&entry->source_lock);
+ while (retries--) {
+ status = pthread_rwlock_tryrdlock(&entry->source_lock);
+ if (status != EAGAIN && status != EBUSY)
+ break;
+ else {
+ struct timespec t = { 0, 200000000 };
+ struct timespec r;
+ while (nanosleep(&t, &r) == -1 && errno == EINTR)
+ memcpy(&t, &r, sizeof(struct timespec));
+ }
+ }
+
if (status) {
logmsg("master_mapent source read lock failed");
fatal(status);
}
+
return;
}

View File

@ -0,0 +1,117 @@
autofs-5.0.6 - improve mount location error reporting
From: Ian Kent <raven@themaw.net>
Try and report a more sensible error when an invalid location is
encountered.
---
CHANGELOG | 1 +
modules/parse_sun.c | 32 ++++++++++++++++++--------------
2 files changed, 19 insertions(+), 14 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index e5dfa83..a178b74 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
??/??/20?? autofs-5.0.7
=======================
- fix ipv6 name for lookup fix.
+- improve mount location error reporting.
28/06/2011 autofs-5.0.6
-----------------------
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 3242e3b..021850d 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -853,7 +853,7 @@ add_offset_entry(struct autofs_point *ap, const char *name,
return ret;
}
-static int validate_location(char *loc)
+static int validate_location(unsigned int logopt, char *loc)
{
char *ptr = loc;
@@ -867,14 +867,22 @@ static int validate_location(char *loc)
* and "@" in the host name part and ipv6 addresses that
* have ":", "[" and "]".
*/
- if (check_colon(ptr)) {
+ if (!check_colon(ptr)) {
+ error(logopt,
+ "expected colon delimeter not found in location %s",
+ loc);
+ return 0;
+ } else {
while (*ptr && strncmp(ptr, ":/", 2)) {
if (!(isalnum(*ptr) ||
*ptr == '-' || *ptr == '.' || *ptr == '_' ||
*ptr == ',' || *ptr == '(' || *ptr == ')' ||
*ptr == '#' || *ptr == '@' || *ptr == ':' ||
- *ptr == '[' || *ptr == ']'))
+ *ptr == '[' || *ptr == ']')) {
+ error(logopt, "invalid character \"%c\" "
+ "found in location %s", *ptr, loc);
return 0;
+ }
ptr++;
}
@@ -883,8 +891,10 @@ static int validate_location(char *loc)
}
/* Must always be something following */
- if (!*ptr)
+ if (!*ptr) {
+ error(logopt, "invalid location %s", loc);
return 0;
+ }
return 1;
}
@@ -951,8 +961,7 @@ static int parse_mapent(const char *ent, char *g_options, char **options, char *
return 0;
}
- if (!validate_location(loc)) {
- warn(logopt, MODPREFIX "invalid location %s", loc);
+ if (!validate_location(logopt, loc)) {
free(myoptions);
free(loc);
return 0;
@@ -985,9 +994,7 @@ static int parse_mapent(const char *ent, char *g_options, char **options, char *
return 0;
}
- if (!validate_location(ent_chunk)) {
- warn(logopt,
- MODPREFIX "invalid location %s", ent_chunk);
+ if (!validate_location(logopt, ent_chunk)) {
free(ent_chunk);
free(myoptions);
free(loc);
@@ -1688,8 +1695,7 @@ int parse_mount(struct autofs_point *ap, const char *name,
return 1;
}
- if (!validate_location(loc)) {
- warn(ap->logopt, MODPREFIX "invalid location %s", loc);
+ if (!validate_location(ap->logopt, loc)) {
free(loc);
free(options);
return 1;
@@ -1714,9 +1720,7 @@ int parse_mount(struct autofs_point *ap, const char *name,
return 1;
}
- if (!validate_location(ent)) {
- warn(ap->logopt,
- MODPREFIX "invalid location %s", loc);
+ if (!validate_location(ap->logopt, ent)) {
free(ent);
free(loc);
free(options);

View File

@ -4,13 +4,24 @@
Summary: A tool for automatically mounting and unmounting filesystems
Name: autofs
Version: 5.0.6
Release: 2%{?dist}
Release: 3%{?dist}
Epoch: 1
License: GPLv2+
Group: System Environment/Daemons
Source: ftp://ftp.kernel.org/pub/linux/daemons/autofs/v5/autofs-%{version}.tar.bz2
Patch1: autofs-5.0.6-fix-ipv6-name-for-lookup-fix.patch
Patch2: autofs-5.0.6-add-dir-map-type.patch
Patch2: autofs-5.0.6-improve-mount-location-error-reporting.patch
Patch3: autofs-5.0.6-fix-paged-query-more-results-check.patch
Patch4: autofs-5.0.6-fix-dumpmaps-not-reading-maps.patch
Patch5: autofs-5.0.6-fix-result-null-check-in-read_one_map.patch
Patch6: autofs-5.0.6-fix-LDAP-result-leaks-on-error-paths.patch
Patch7: autofs-5.0.6-code-analysis-fixes-1.patch
Patch8: autofs-5.0.6-fix-not-bind-mounting-local-filesystem.patch
Patch9: autofs-5.0.6-add-dir-map-type.patch
Patch10: autofs-5.0.6-fix-wait-for-master-source-mutex.patch
Patch11: autofs-5.0.6-fix-submount-shutdown-race.patch
Patch12: autofs-5.0.6-fix-fix-map-source-check-in-file-lookup.patch
Patch13: autofs-5.0.6-add-disable-move-mount-configure-option.patch
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, libxml2-devel, cyrus-sasl-devel, openssl-devel module-init-tools util-linux nfs-utils e2fsprogs libtirpc-devel
Conflicts: cyrus-sasl-lib < 2.1.23-9
@ -55,10 +66,21 @@ inkludera nätfilsystem, CD-ROM, floppydiskar, och så vidare.
echo %{version}-%{release} > .version
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%build
#CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir}
%configure --disable-mount-locking --enable-ignore-busy --with-libtirpc
%configure --disable-mount-locking --enable-ignore-busy --with-libtirpc --disable-mount-move
make initdir=%{_initrddir} DONTSTRIP=1
%install
@ -109,6 +131,20 @@ fi
%dir /etc/auto.master.d
%changelog
* Tue Nov 8 2011 Ian Kent <ikent@redhat.com> - 1:5.0.6-3
- improve mount location error reporting.
- fix paged query more results check.
- fix dumpmaps not reading maps.
- fix result null check in read_one_map().
- Fix LDAP result leaks on error paths.
- code analysis fixes 1.
- fix not bind mounting local filesystem.
- update dir map-type patch for changed patch order.
- fix wait for master source mutex.
- fix submount shutdown race
- fix fix map source check in file lookup.
- add disable move mount configure option.
* Wed Jul 6 2011 Ian Kent <ikent@redhat.com> - 1:5.0.6-2
- add missing spec file entries for dir-type change (bz719208).