Remove patches included in the 5.0.4 release.

This commit is contained in:
Ian Kent 2008-11-11 08:04:36 +00:00
parent 0ccc5b5da0
commit 226cfba247
60 changed files with 0 additions and 13697 deletions

View File

@ -1,137 +0,0 @@
diff -up autofs-5.0.3/include/lookup_ldap.h.init-cb-on-load autofs-5.0.3/include/lookup_ldap.h
--- autofs-5.0.3/include/lookup_ldap.h.init-cb-on-load 2008-01-14 13:39:16.000000000 +0900
+++ autofs-5.0.3/include/lookup_ldap.h 2008-03-24 14:10:09.000000000 +0900
@@ -99,10 +99,12 @@ int unbind_ldap_connection(unsigned logo
int authtype_requires_creds(const char *authtype);
/* cyrus-sasl.c */
+int autofs_sasl_client_init(unsigned logopt);
int autofs_sasl_init(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt);
int autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt);
void autofs_sasl_unbind(struct lookup_context *ctxt);
-void autofs_sasl_done(struct lookup_context *ctxt);
+void autofs_sasl_dispose(struct lookup_context *ctxt);
+void autofs_sasl_done(void);
#endif
#endif
diff -up autofs-5.0.3/modules/lookup_ldap.c.init-cb-on-load autofs-5.0.3/modules/lookup_ldap.c
--- autofs-5.0.3/modules/lookup_ldap.c.init-cb-on-load 2008-03-24 14:09:18.000000000 +0900
+++ autofs-5.0.3/modules/lookup_ldap.c 2008-03-24 14:10:09.000000000 +0900
@@ -599,7 +599,7 @@ static LDAP *connect_to_server(unsigned
if (!do_bind(logopt, ldap, ctxt)) {
unbind_ldap_connection(logopt, ldap, ctxt);
- autofs_sasl_done(ctxt);
+ autofs_sasl_dispose(ctxt);
error(logopt, MODPREFIX "cannot bind to server");
return NULL;
}
@@ -672,7 +672,7 @@ static LDAP *do_reconnect(unsigned logop
list_add_tail(&this->list, ctxt->uri);
#ifdef WITH_SASL
- autofs_sasl_done(ctxt);
+ autofs_sasl_dispose(ctxt);
#endif
/* Current server failed connect, try the rest */
@@ -1330,6 +1330,13 @@ int lookup_init(const char *mapfmt, int
free_context(ctxt);
return 1;
}
+
+ /* Init the sasl callbacks */
+ if (!autofs_sasl_client_init(LOGOPT_NONE)) {
+ error(LOGOPT_ANY, "failed to init sasl client");
+ free_context(ctxt);
+ return 1;
+ }
#endif
if (ctxt->server || !ctxt->uri) {
@@ -2640,7 +2647,8 @@ int lookup_done(void *context)
struct lookup_context *ctxt = (struct lookup_context *) context;
int rv = close_parse(ctxt->parse);
#ifdef WITH_SASL
- autofs_sasl_done(ctxt);
+ autofs_sasl_dispose(ctxt);
+ autofs_sasl_done();
#endif
free_context(ctxt);
return rv;
diff -up autofs-5.0.3/modules/cyrus-sasl.c.init-cb-on-load autofs-5.0.3/modules/cyrus-sasl.c
--- autofs-5.0.3/modules/cyrus-sasl.c.init-cb-on-load 2008-01-14 13:39:16.000000000 +0900
+++ autofs-5.0.3/modules/cyrus-sasl.c 2008-03-24 14:10:09.000000000 +0900
@@ -76,7 +76,6 @@ static const char *default_client = "aut
static pthread_mutex_t krb5cc_mutex = PTHREAD_MUTEX_INITIALIZER;
static unsigned int krb5cc_in_use = 0;
-static unsigned int init_callbacks = 1;
static int sasl_log_func(void *, int, const char *);
static int getpass_func(sasl_conn_t *, void *, int, sasl_secret_t **);
static int getuser_func(void *, int, const char **, unsigned *);
@@ -878,13 +877,6 @@ autofs_sasl_init(unsigned logopt, LDAP *
{
sasl_conn_t *conn;
- /* Start up Cyrus SASL--only needs to be done once. */
- if (init_callbacks && sasl_client_init(callbacks) != SASL_OK) {
- error(logopt, "sasl_client_init failed");
- return -1;
- }
- init_callbacks = 0;
-
sasl_auth_id = ctxt->user;
sasl_auth_secret = ctxt->secret;
@@ -916,8 +908,7 @@ autofs_sasl_init(unsigned logopt, LDAP *
* Destructor routine. This should be called when finished with an ldap
* session.
*/
-void
-autofs_sasl_done(struct lookup_context *ctxt)
+void autofs_sasl_dispose(struct lookup_context *ctxt)
{
int status, ret;
@@ -953,3 +944,28 @@ autofs_sasl_done(struct lookup_context *
ctxt->kinit_successful = 0;
}
}
+
+/*
+ * Initialize the sasl callbacks, which increments the global
+ * use counter.
+ */
+int autofs_sasl_client_init(unsigned logopt)
+{
+ /* Start up Cyrus SASL--only needs to be done at library load. */
+ if (sasl_client_init(callbacks) != SASL_OK) {
+ error(logopt, "sasl_client_init failed");
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * Decrement the library reference count and free resources if
+ * we are the last to close the library.
+ */
+void autofs_sasl_done(void)
+{
+ sasl_done();
+ return;
+}
+
diff -up autofs-5.0.3/CHANGELOG.init-cb-on-load autofs-5.0.3/CHANGELOG
--- autofs-5.0.3/CHANGELOG.init-cb-on-load 2008-03-24 14:09:18.000000000 +0900
+++ autofs-5.0.3/CHANGELOG 2008-03-24 14:10:09.000000000 +0900
@@ -9,6 +9,7 @@
- fix expire working harder than needed.
- fix unlink of mount tree incorrectly causing autofs mount fail.
- add missing check for zero length NIS key (Wengang Wang).
+- init SASL callbacks on every ldap lookup library load.
14/01/2008 autofs-5.0.3
-----------------------

File diff suppressed because it is too large Load Diff

View File

@ -1,129 +0,0 @@
autofs-5.0.3 - add missing uris list locking
From: Ian Kent <raven@themaw.net>
Add inadvertantly ommitted server list locking in LDAP module.
---
include/lookup_ldap.h | 1 +
modules/lookup_ldap.c | 39 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 39 insertions(+), 1 deletion(-)
--- autofs-5.0.3.orig/include/lookup_ldap.h
+++ autofs-5.0.3/include/lookup_ldap.h
@@ -54,6 +54,7 @@ struct lookup_context {
* sdns is the list of basdns to check, done in the order
* given in configuration.
*/
+ pthread_mutex_t uris_mutex;
struct list_head *uri;
char *cur_host;
struct ldap_searchdn *sdns;
--- autofs-5.0.3.orig/modules/lookup_ldap.c
+++ autofs-5.0.3/modules/lookup_ldap.c
@@ -122,6 +122,22 @@ int ldap_parse_page_control(LDAP *ldap,
}
#endif /* HAVE_LDAP_PARSE_PAGE_CONTROL */
+static void uris_mutex_lock(struct lookup_context *ctxt)
+{
+ int status = pthread_mutex_lock(&ctxt->uris_mutex);
+ if (status)
+ fatal(status);
+ return;
+}
+
+static void uris_mutex_unlock(struct lookup_context *ctxt)
+{
+ int status = pthread_mutex_unlock(&ctxt->uris_mutex);
+ if (status)
+ fatal(status);
+ return;
+}
+
int bind_ldap_anonymous(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
{
int rv;
@@ -627,16 +643,20 @@ static LDAP *find_server(unsigned logopt
LIST_HEAD(tmp);
/* Try each uri in list, add connect fails to tmp list */
+ uris_mutex_lock(ctxt);
p = ctxt->uri->next;
while(p != ctxt->uri) {
this = list_entry(p, struct ldap_uri, list);
- p = p->next;
+ 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);
break;
}
+ uris_mutex_lock(ctxt);
+ p = p->next;
list_del_init(&this->list);
list_add_tail(&this->list, &tmp);
}
@@ -648,6 +668,7 @@ static LDAP *find_server(unsigned logopt
list_splice(ctxt->uri, &tmp);
INIT_LIST_HEAD(ctxt->uri);
list_splice(&tmp, ctxt->uri);
+ uris_mutex_unlock(ctxt);
return ldap;
}
@@ -662,14 +683,18 @@ static LDAP *do_reconnect(unsigned logop
return ldap;
}
+ uris_mutex_lock(ctxt);
this = list_entry(ctxt->uri->next, struct ldap_uri, list);
+ 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);
#ifdef WITH_SASL
autofs_sasl_dispose(ctxt);
@@ -1203,6 +1228,8 @@ done:
static void free_context(struct lookup_context *ctxt)
{
+ int ret;
+
if (ctxt->schema) {
free(ctxt->schema->map_class);
free(ctxt->schema->map_attr);
@@ -1235,6 +1262,9 @@ static void free_context(struct lookup_c
free(ctxt->base);
if (ctxt->uri)
defaults_free_uris(ctxt->uri);
+ ret = pthread_mutex_destroy(&ctxt->uris_mutex);
+ if (ret)
+ fatal(ret);
if (ctxt->sdns)
defaults_free_searchdns(ctxt->sdns);
free(ctxt);
@@ -1286,6 +1316,13 @@ int lookup_init(const char *mapfmt, int
}
memset(ctxt, 0, sizeof(struct lookup_context));
+ ret = pthread_mutex_init(&ctxt->uris_mutex, NULL);
+ if (ret) {
+ error(LOGOPT_ANY, MODPREFIX "failed to init uris mutex");
+ free(ctxt);
+ return 1;
+ }
+
/* If a map type isn't explicitly given, parse it like sun entries. */
if (mapfmt == NULL)
mapfmt = MAPFMT_DEFAULT;

View File

@ -1,189 +0,0 @@
autofs-5.0.3 - add replicated server selection debug logging
From: Ian Kent <raven@themaw.net>
Add some debug logging to the replicated server selection code.
---
CHANGELOG | 1 +
modules/replicated.c | 86 ++++++++++++++++++++++++++++++++++++++------------
2 files changed, 67 insertions(+), 20 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index a7b41ec..af3318a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -30,6 +30,7 @@
- avoid stat of possibly dead mount points and limit time to wait for
umount during expire.
- make mount of multi-mounts wuth a root offset atomic.
+- add replicated server selection debug logging.
14/01/2008 autofs-5.0.3
-----------------------
diff --git a/modules/replicated.c b/modules/replicated.c
index 271907c..e41713e 100644
--- a/modules/replicated.c
+++ b/modules/replicated.c
@@ -404,6 +404,10 @@ static unsigned int get_nfs_info(unsigned logopt, struct host *host,
double taken = 0;
int status, count = 0;
+ debug(logopt,
+ "called for host %s proto %s version 0x%x",
+ host->name, proto, version);
+
memset(&parms, 0, sizeof(struct pmap));
parms.pm_prog = NFS_PROGRAM;
@@ -428,11 +432,17 @@ static unsigned int get_nfs_info(unsigned logopt, struct host *host,
status = rpc_ping_proto(rpc_info);
gettimeofday(&end, &tz);
if (status) {
- if (random_selection)
+ double reply;
+ if (random_selection) {
/* Random value between 0 and 1 */
- taken += ((float) random())/((float) RAND_MAX+1);
- else
- taken += elapsed(start, end);;
+ reply = ((float) random())/((float) RAND_MAX+1);
+ debug(logopt,
+ "nfs v4 random selection time: %f", reply);
+ } else {
+ reply = elapsed(start, end);
+ debug(logopt, "nfs v4 rpc ping time: %f", reply);
+ }
+ taken += reply;
count++;
supported = NFS4_SUPPORTED;
}
@@ -470,11 +480,17 @@ v3_ver:
status = rpc_ping_proto(rpc_info);
gettimeofday(&end, &tz);
if (status) {
- if (random_selection)
+ double reply;
+ if (random_selection) {
/* Random value between 0 and 1 */
- taken += ((float) random())/((float) RAND_MAX+1);
- else
- taken += elapsed(start, end);;
+ reply = ((float) random())/((float) RAND_MAX+1);
+ debug(logopt,
+ "nfs v3 random selection time: %f", reply);
+ } else {
+ reply = elapsed(start, end);
+ debug(logopt, "nfs v3 rpc ping time: %f", reply);
+ }
+ taken += reply;
count++;
supported |= NFS3_SUPPORTED;
}
@@ -504,11 +520,17 @@ v2_ver:
status = rpc_ping_proto(rpc_info);
gettimeofday(&end, &tz);
if (status) {
- if (random_selection)
+ double reply;
+ if (random_selection) {
/* Random value between 0 and 1 */
- taken += ((float) random())/((float) RAND_MAX+1);
- else
- taken += elapsed(start, end);;
+ reply = ((float) random())/((float) RAND_MAX+1);
+ debug(logopt,
+ "nfs v2 random selection time: %f", reply);
+ } else {
+ reply = elapsed(start, end);;
+ debug(logopt, "nfs v2 rpc ping time: %f", reply);
+ }
+ taken += reply;
count++;
supported |= NFS2_SUPPORTED;
}
@@ -533,6 +555,9 @@ done_ver:
/* Allow for user bias */
if (host->weight)
host->cost *= (host->weight + 1);
+
+ debug(logopt, "host %s cost %ld weight %d",
+ host->name, host->cost, host->weight);
}
return supported;
@@ -603,6 +628,9 @@ static int get_supported_ver_and_cost(unsigned logopt, struct host *host,
time_t timeout = RPC_TIMEOUT;
int status;
+ debug(logopt,
+ "called with host %s version 0x%x", host->name, version);
+
memset(&pm_info, 0, sizeof(struct conn_info));
memset(&rpc_info, 0, sizeof(struct conn_info));
memset(&parms, 0, sizeof(struct pmap));
@@ -681,11 +709,14 @@ static int get_supported_ver_and_cost(unsigned logopt, struct host *host,
status = rpc_ping_proto(&rpc_info);
gettimeofday(&end, &tz);
if (status) {
- if (random_selection)
+ if (random_selection) {
/* Random value between 0 and 1 */
taken = ((float) random())/((float) RAND_MAX+1);
- else
+ debug(logopt, "random selection time %f", taken);
+ } else {
taken = elapsed(start, end);
+ debug(logopt, "rpc ping time %f", taken);
+ }
}
}
done:
@@ -705,6 +736,8 @@ done:
if (host->weight)
host->cost *= (host->weight + 1);
+ debug(logopt, "cost %ld weight %d", host->cost, host->weight);
+
return 1;
}
@@ -811,18 +844,31 @@ int prune_host_list(unsigned logopt, struct host **list,
max_udp_count = mmax(v4_udp_count, v3_udp_count, v2_udp_count);
max_count = max(max_tcp_count, max_udp_count);
- if (max_count == v4_tcp_count)
+ if (max_count == v4_tcp_count) {
selected_version = NFS4_TCP_SUPPORTED;
- else if (max_count == v3_tcp_count)
+ debug(logopt,
+ "selected subset of hosts that support NFS4 over TCP");
+ } else if (max_count == v3_tcp_count) {
selected_version = NFS3_TCP_SUPPORTED;
- else if (max_count == v2_tcp_count)
+ debug(logopt,
+ "selected subset of hosts that support NFS3 over TCP");
+ } else if (max_count == v2_tcp_count) {
selected_version = NFS2_TCP_SUPPORTED;
- else if (max_count == v4_udp_count)
+ debug(logopt,
+ "selected subset of hosts that support NFS2 over TCP");
+ } else if (max_count == v4_udp_count) {
selected_version = NFS4_UDP_SUPPORTED;
- else if (max_count == v3_udp_count)
+ debug(logopt,
+ "selected subset of hosts that support NFS4 over UDP");
+ } else if (max_count == v3_udp_count) {
selected_version = NFS3_UDP_SUPPORTED;
- else if (max_count == v2_udp_count)
+ debug(logopt,
+ "selected subset of hosts that support NFS3 over UDP");
+ } else if (max_count == v2_udp_count) {
selected_version = NFS2_UDP_SUPPORTED;
+ debug(logopt,
+ "selected subset of hosts that support NFS2 over UDP");
+ }
/* Add local and hosts with selected version to new list */
this = *list;

View File

@ -1,138 +0,0 @@
autofs-5.0.3 - add configuration paramter UMOUNT_WAIT
From: Ian Kent <raven@themaw.net>
To try and prevent expire delays when trying to umount from a server
that is not available we limit the time that we wait for a response
from the spawned umount process before sending it a SIGTERM signal.
This patch adds a configuration parameter to allow this wait to be
changed if needed.
---
daemon/spawn.c | 2 +-
include/defaults.h | 2 ++
lib/defaults.c | 13 +++++++++++++
man/auto.master.5.in | 6 ++++++
redhat/autofs.sysconfig.in | 4 ++++
samples/autofs.conf.default.in | 4 ++++
6 files changed, 30 insertions(+), 1 deletions(-)
diff --git a/daemon/spawn.c b/daemon/spawn.c
index e3c355e..6b26c41 100644
--- a/daemon/spawn.c
+++ b/daemon/spawn.c
@@ -502,7 +502,7 @@ int spawn_umount(unsigned logopt, ...)
unsigned int options;
unsigned int retries = MTAB_LOCK_RETRIES;
int ret, printed = 0;
- unsigned int wait = 12;
+ unsigned int wait = defaults_get_umount_wait();
#ifdef ENABLE_MOUNT_LOCKING
options = SPAWN_OPT_LOCK;
diff --git a/include/defaults.h b/include/defaults.h
index 6e4f52a..12534ec 100644
--- a/include/defaults.h
+++ b/include/defaults.h
@@ -24,6 +24,7 @@
#define DEFAULT_TIMEOUT 600
#define DEFAULT_NEGATIVE_TIMEOUT 60
+#define DEFAULT_UMOUNT_WAIT 12
#define DEFAULT_BROWSE_MODE 1
#define DEFAULT_LOGGING 0
@@ -59,6 +60,7 @@ 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_append_options(void);
+unsigned int defaults_get_umount_wait(void);
const char *defaults_get_auth_conf_file(void);
#endif
diff --git a/lib/defaults.c b/lib/defaults.c
index 8149549..21d76d2 100644
--- a/lib/defaults.c
+++ b/lib/defaults.c
@@ -45,6 +45,7 @@
#define ENV_NAME_VALUE_ATTR "VALUE_ATTRIBUTE"
#define ENV_APPEND_OPTIONS "APPEND_OPTIONS"
+#define ENV_UMOUNT_WAIT "UMOUNT_WAIT"
#define ENV_AUTH_CONF_FILE "AUTH_CONF_FILE"
static const char *default_master_map_name = DEFAULT_MASTER_MAP_NAME;
@@ -320,6 +321,7 @@ unsigned int defaults_read_config(unsigned int to_syslog)
check_set_config_value(key, ENV_NAME_ENTRY_ATTR, value, 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))
;
}
@@ -647,6 +649,17 @@ unsigned int defaults_get_append_options(void)
return res;
}
+unsigned int defaults_get_umount_wait(void)
+{
+ long wait;
+
+ wait = get_env_number(ENV_UMOUNT_WAIT);
+ if (wait < 0)
+ wait = DEFAULT_UMOUNT_WAIT;
+
+ return (unsigned int) wait;
+}
+
const char *defaults_get_auth_conf_file(void)
{
char *cf;
diff --git a/man/auto.master.5.in b/man/auto.master.5.in
index 49a711c..9cc5f02 100644
--- a/man/auto.master.5.in
+++ b/man/auto.master.5.in
@@ -174,6 +174,12 @@ Set the default timeout for caching failed key lookups (program default
60). If the equivalent command line option is given it will override this
setting.
.TP
+.B UMOUNT_WAIT
+Set the default time to wait for a response from a spawned umount(8)
+before sending it a SIGTERM. Note that we still need to wait for the
+RPC layer to timeout before the sub-process exits so this isn't ideal
+but it is the best we can do.
+.TP
.B BROWSE_MODE
Maps are browsable by default (program default "yes").
.TP
diff --git a/redhat/autofs.sysconfig.in b/redhat/autofs.sysconfig.in
index 636763a..ce64feb 100644
--- a/redhat/autofs.sysconfig.in
+++ b/redhat/autofs.sysconfig.in
@@ -14,6 +14,10 @@ TIMEOUT=300
#
#NEGATIVE_TIMEOUT=60
#
+# UMOUNT_WAIT - time to wait for a response from umount(8).
+#
+#UMOUNT_WAIT=12
+#
# BROWSE_MODE - maps are browsable by default.
#
BROWSE_MODE="no"
diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in
index 086ba4f..0231e1d 100644
--- a/samples/autofs.conf.default.in
+++ b/samples/autofs.conf.default.in
@@ -14,6 +14,10 @@ TIMEOUT=300
#
#NEGATIVE_TIMEOUT=60
#
+# UMOUNT_WAIT - time to wait for a response from umount(8).
+#
+#UMOUNT_WAIT=12
+#
# BROWSE_MODE - maps are browsable by default.
#
BROWSE_MODE="no"

View File

@ -1,48 +0,0 @@
autofs-5.0.3 - allow directory create on NFS root
From: Matthias Koenig <mkoenig@suse.de>
autofs will not create the autofs mountpoint path if the filesystem is
not a locally mounted filesystem (e.g. a NFS mounted filesystem).
contained_in_local_fs() returns false in this case. This is intentional
but breaks clients that have an NFS root filesystem. In this case we
shouldn't impose this restriction.
---
CHANGELOG | 1 +
lib/mounts.c | 8 +++++++-
2 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index f7aa839..2553f26 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -19,6 +19,7 @@
- check for map key in (possible) alternate map sources when doing lookup.
- eliminate redundant DNS name lookups.
- additional fix incorrect pthreads condition handling for mount requests.
+- allow mount point directory creation for clients with an NFS root.
14/01/2008 autofs-5.0.3
-----------------------
diff --git a/lib/mounts.c b/lib/mounts.c
index 425a65a..b987fbb 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -363,7 +363,13 @@ int contained_in_local_fs(const char *path)
if (!strncmp(path, this->path, len)) {
if (len > 1 && pathlen > len && path[len] != '/')
continue;
- else if (this->fs_name[0] == '/') {
+ else if (len == 1 && this->path[0] == '/') {
+ /*
+ * always return true on rootfs, we don't
+ * want to break diskless clients.
+ */
+ ret = 1;
+ } else if (this->fs_name[0] == '/') {
if (strlen(this->fs_name) > 1) {
if (this->fs_name[1] != '/')
ret = 1;

View File

@ -1,25 +0,0 @@
diff --git a/CHANGELOG b/CHANGELOG
index 8d09e93..b172579 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,7 @@
-----------------------
- correct configure test for ldapr page control functions.
- catch "-xfn" map type and issue "no supported" message.
+- correction for handling of LDAP base dns with spaces.
14/01/2008 autofs-5.0.3
-----------------------
diff --git a/lib/master_tok.l b/lib/master_tok.l
index 2a6fdf9..7f1de90 100644
--- a/lib/master_tok.l
+++ b/lib/master_tok.l
@@ -289,7 +289,7 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeo
return EQUAL;
}
- {DNNAMESTR1}/"," {
+ {DNNAMESTR1}/","{DNATTRSTR}"=" {
strcpy(master_lval.strtype, master_text);
return DNNAME;
}

View File

@ -1,89 +0,0 @@
autofs-5.0.3 - check direct mount path length
From: Ian Kent <raven@themaw.net>
The length of the path corresponding to a direct mount can't be
checked in the kernel so we need to check it will fit into the
request structire before going ahead with the mount. The name
field of the request structure is also to short and so is increased
to PATH_MAX.
---
CHANGELOG | 1 +
daemon/direct.c | 15 +++++++++++++--
include/automount.h | 2 +-
3 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 2553f26..82b080c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -20,6 +20,7 @@
- eliminate redundant DNS name lookups.
- additional fix incorrect pthreads condition handling for mount requests.
- allow mount point directory creation for clients with an NFS root.
+- fix direct mount path length not being checked.
14/01/2008 autofs-5.0.3
-----------------------
diff --git a/daemon/direct.c b/daemon/direct.c
index 768fbf9..98590ec 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -1411,7 +1411,7 @@ static void *do_mount_direct(void *arg)
}
cont:
- status = lookup_nss_mount(ap, NULL, mt.name, strlen(mt.name));
+ status = lookup_nss_mount(ap, NULL, mt.name, mt.len);
/*
* Direct mounts are always a single mount. If it fails there's
* nothing to undo so just complain
@@ -1454,7 +1454,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
struct pending_args *mt;
char buf[MAX_ERR_BUF];
int status = 0;
- int ioctlfd, cl_flags, state;
+ int ioctlfd, len, cl_flags, state;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
@@ -1525,6 +1525,16 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
return 1;
}
+ len = strlen(me->key);
+ if (len >= PATH_MAX) {
+ error(ap->logopt, "direct mount path too long %s", me->key);
+ send_fail(ap->logopt, ioctlfd, pkt->wait_queue_token);
+ close(ioctlfd);
+ cache_unlock(mc);
+ pthread_setcancelstate(state, NULL);
+ return 1;
+ }
+
mt = malloc(sizeof(struct pending_args));
if (!mt) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
@@ -1553,6 +1563,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
mt->ioctlfd = ioctlfd;
mt->mc = mc;
strcpy(mt->name, me->key);
+ mt->len = len;
mt->dev = me->dev;
mt->type = NFY_MOUNT;
mt->uid = pkt->uid;
diff --git a/include/automount.h b/include/automount.h
index d59be77..72e2457 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -409,7 +409,7 @@ struct pending_args {
int type; /* Type of packet */
int ioctlfd; /* Mount ioctl fd */
struct mapent_cache *mc; /* Cache Containing entry */
- char name[KEY_MAX_LEN]; /* Name field of the request */
+ char name[PATH_MAX]; /* Name field of the request */
dev_t dev; /* device number of mount */
unsigned int len; /* Name field len */
uid_t uid; /* uid of requestor */

View File

@ -1,25 +0,0 @@
autofs-5.0.3 - check for kernel automount fix
From: Ian Kent <raven@themaw.net>
Look in the correct mount table for kernel automounted "nohide"
mounts.
---
daemon/direct.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/daemon/direct.c b/daemon/direct.c
index afb354e..13f572c 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -709,7 +709,7 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char *
* the kernel NFS client.
*/
if (me->multi != me &&
- is_mounted(_PATH_MOUNTED, mountpoint, MNTS_REAL))
+ is_mounted(_PROC_MOUNTS, mountpoint, MNTS_REAL))
return MOUNT_OFFSET_IGNORE;
/*

View File

@ -1,200 +0,0 @@
autofs 5.0.3 - check for exported mounts automatically mounted by kernel
From: Ian Kent <raven@themaw.net>
If a server exports file systems that are automatically mounted by
the kernel client autofs will mistakenly over mount them when it
constructs and mounts its multi-mount triggers.
This patch makes autofs check for this case and ignores them if the
kernel mounts them while it mounts multi-mount triggers.
We don't want to fight with NFS over mounting these because it
confuses autofs and they magically go away when the owner mount is
umounted. This isn't ideal because autofs will mount these mounts
while constructing its multi-mount triggers but it is unavoidable
at the moment.
---
CHANGELOG | 1 +
daemon/direct.c | 26 ++++++++++++++++++--------
include/automount.h | 4 ++++
lib/parse_subs.c | 26 ++++++++++++++++++--------
4 files changed, 41 insertions(+), 16 deletions(-)
--- autofs-5.0.3.orig/CHANGELOG
+++ autofs-5.0.3/CHANGELOG
@@ -12,6 +12,7 @@
- init SASL callbacks on every ldap lookup library load.
- fix incorrect match of map type name when included in map name.
- fix incorrect pthreads condition handling for mount requests.
+- add check for exports automatically mounted by NFS kernel client.
14/01/2008 autofs-5.0.3
-----------------------
--- autofs-5.0.3.orig/daemon/direct.c
+++ autofs-5.0.3/daemon/direct.c
@@ -664,12 +664,12 @@ int mount_autofs_offset(struct autofs_po
if (ap->state != ST_READMAP)
warn(ap->logopt,
"trigger %s already mounted", me->key);
- return 0;
+ return MOUNT_OFFSET_OK;
}
if (me->ioctlfd != -1) {
error(ap->logopt, "active offset mount %s", me->key);
- return -1;
+ return MOUNT_OFFSET_FAIL;
}
status = pthread_once(&key_mnt_params_once, key_mnt_params_init);
@@ -683,7 +683,7 @@ int mount_autofs_offset(struct autofs_po
crit(ap->logopt,
"mnt_params value create failed for offset mount %s",
me->key);
- return 0;
+ return MOUNT_OFFSET_OK;
}
mp->options = NULL;
@@ -697,12 +697,22 @@ int mount_autofs_offset(struct autofs_po
if (!mp->options) {
mp->options = make_options_string(ap->path, ap->kpipefd, "offset");
if (!mp->options)
- return 0;
+ return MOUNT_OFFSET_OK;
}
/* In case the directory doesn't exist, try to mkdir it */
if (mkdir_path(me->key, 0555) < 0) {
if (errno == EEXIST) {
+ /*
+ * If the mount point directory is a real mount
+ * and it isn't the root offset then it must be
+ * a mount that has been automatically mounted by
+ * the kernel NFS client.
+ */
+ if (me->multi != me &&
+ is_mounted(_PROC_MOUNTS, me->key, MNTS_REAL))
+ return MOUNT_OFFSET_IGNORE;
+
/*
* If we recieve an error, and it's EEXIST
* we know the directory was not created.
@@ -721,13 +731,13 @@ int mount_autofs_offset(struct autofs_po
debug(ap->logopt,
"can't create mount directory: %s, %s",
me->key, estr);
- return -1;
+ return MOUNT_OFFSET_FAIL;
} else {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
crit(ap->logopt,
"failed to create mount directory: %s, %s",
me->key, estr);
- return -1;
+ return MOUNT_OFFSET_FAIL;
}
} else {
/* No errors so the directory was successfully created */
@@ -787,7 +797,7 @@ int mount_autofs_offset(struct autofs_po
debug(ap->logopt, "mounted trigger %s", me->key);
- return 0;
+ return MOUNT_OFFSET_OK;
out_close:
close(ioctlfd);
@@ -797,7 +807,7 @@ out_err:
if (stat(me->key, &st) == 0 && me->dir_created)
rmdir_path(ap, me->key, st.st_dev);
- return -1;
+ return MOUNT_OFFSET_FAIL;
}
static int expire_direct(int ioctlfd, const char *path, unsigned int when, unsigned int logopt)
--- autofs-5.0.3.orig/include/automount.h
+++ autofs-5.0.3/include/automount.h
@@ -468,6 +468,10 @@ struct autofs_point {
/* Standard functions used by daemon or modules */
+#define MOUNT_OFFSET_OK 0
+#define MOUNT_OFFSET_FAIL -1
+#define MOUNT_OFFSET_IGNORE -2
+
void *handle_mounts(void *arg);
int umount_multi(struct autofs_point *ap, const char *path, int incl);
int send_ready(unsigned logopt, int ioctlfd, unsigned int wait_queue_token);
--- autofs-5.0.3.orig/lib/parse_subs.c
+++ autofs-5.0.3/lib/parse_subs.c
@@ -390,7 +390,7 @@ int mount_multi_triggers(struct autofs_p
struct list_head *pos = NULL;
unsigned int fs_path_len;
unsigned int mounted;
- int start;
+ int ret, start;
fs_path_len = strlen(root) + strlen(base);
if (fs_path_len > PATH_MAX)
@@ -411,15 +411,25 @@ int mount_multi_triggers(struct autofs_p
}
oe = cache_lookup_offset(base, offset, start, &me->multi_list);
- if (!oe)
+ if (!oe || !oe->mapent)
goto cont;
debug(ap->logopt, "mount offset %s", oe->key);
- if (mount_autofs_offset(ap, oe) < 0)
- warn(ap->logopt, "failed to mount offset");
- else
+ ret = mount_autofs_offset(ap, oe);
+ if (ret >= MOUNT_OFFSET_OK)
mounted++;
+ else {
+ if (ret != MOUNT_OFFSET_IGNORE)
+ warn(ap->logopt, "failed to mount offset");
+ else {
+ debug(ap->logopt,
+ "ignoring \"nohide\" trigger %s",
+ oe->key);
+ free(oe->mapent);
+ oe->mapent = NULL;
+ }
+ }
cont:
offset = cache_get_offset(base,
offset, start, &me->multi_list, &pos);
@@ -457,7 +467,7 @@ int umount_multi_triggers(struct autofs_
oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list);
/* root offset is a special case */
- if (!oe || (strlen(oe->key) - start) == 1)
+ if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1)
continue;
/*
@@ -481,7 +491,7 @@ int umount_multi_triggers(struct autofs_
while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list);
/* root offset is a special case */
- if (!oe || (strlen(oe->key) - start) == 1)
+ if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1)
continue;
debug(ap->logopt, "umount offset %s", oe->key);
@@ -505,7 +515,7 @@ int umount_multi_triggers(struct autofs_
if (is_mounted(_PATH_MOUNTED, root, MNTS_REAL)) {
info(ap->logopt, "unmounting dir = %s", root);
if (umount_ent(ap, root)) {
- if (!mount_multi_triggers(ap, root, me, "/"))
+ if (mount_multi_triggers(ap, root, me, "/") < 0)
warn(ap->logopt,
"failed to remount offset triggers");
return left++;

View File

@ -1,33 +0,0 @@
autofs-5.0.3 - check replicated list after probe
From: Ian Kent <raven@themaw.net>
When checking a list of servers for proximity and NFS version
the list may become empty after after the initial probe. This
case isn't handled and this patch adds it.
---
modules/replicated.c | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/modules/replicated.c b/modules/replicated.c
index 925f641..271907c 100644
--- a/modules/replicated.c
+++ b/modules/replicated.c
@@ -768,6 +768,15 @@ int prune_host_list(unsigned logopt, struct host **list,
this = next;
}
+ /*
+ * The list of hosts that aren't proximity local may now
+ * be empty if we haven't been able probe any so we need
+ * to check again for a list containing only proximity
+ * local hosts.
+ */
+ if (!first)
+ return 1;
+
last = this;
/* Select NFS version of highest number of closest servers */

View File

@ -1,29 +0,0 @@
autofs-5.0.3 - clear stale flag on map read
From: Ian Kent <raven@themaw.net>
We're not properly clearing the map stale flag after a map re-read
which causes a re-read after every lookup for master map entries
that have the "browse" option set. I removed the line that did
this at some point in the past and I must have had a reason to
do so. We'll have to wait and see what shows up after fixing
it.
---
daemon/lookup.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/daemon/lookup.c b/daemon/lookup.c
index d33aadc..2277623 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -298,6 +298,8 @@ static int do_read_map(struct autofs_point *ap, struct map_source *map, time_t a
status = lookup->lookup_read_map(ap, age, lookup->context);
+ map->stale = 0;
+
/*
* For maps that don't support enumeration return success
* and do whatever we must to have autofs function with an

View File

@ -1,78 +0,0 @@
diff --git a/CHANGELOG b/CHANGELOG
index 5a85a8e..e393f33 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -4,6 +4,7 @@
- catch "-xfn" map type and issue "no supported" message.
- correction for handling of LDAP base dns with spaces.
- avoid using UDP for probing NFSv4 mount requests.
+- use libldap instead of libldap_r (Guillaume Rousse).
14/01/2008 autofs-5.0.3
-----------------------
diff --git a/aclocal.m4 b/aclocal.m4
index f24e076..a1105ae 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -232,7 +232,7 @@ AC_DEFUN([AF_CHECK_FUNC_LDAP_CREATE_PAGE_CONTROL],
# save current ldflags
af_check_ldap_create_page_control_save_ldflags="$LDFLAGS"
-LDFLAGS="$LDFLAGS -lldap_r"
+LDFLAGS="$LDFLAGS -lldap"
AC_TRY_LINK(
[ #include <ldap.h> ],
@@ -265,7 +265,7 @@ AC_DEFUN([AF_CHECK_FUNC_LDAP_PARSE_PAGE_CONTROL],
# save current ldflags
af_check_ldap_parse_page_control_save_ldflags="$LDFLAGS"
-LDFLAGS="$LDFLAGS -lldap_r"
+LDFLAGS="$LDFLAGS -lldap"
AC_TRY_LINK(
[ #include <ldap.h> ],
diff --git a/configure b/configure
index e872392..0d3268c 100755
--- a/configure
+++ b/configure
@@ -4563,7 +4563,7 @@ fi
{ echo "$as_me:$LINENO: result: $ac_cv_lib_ldap_ldap_initialize" >&5
echo "${ECHO_T}$ac_cv_lib_ldap_ldap_initialize" >&6; }
if test $ac_cv_lib_ldap_ldap_initialize = yes; then
- HAVE_LDAP=1 LIBLDAP="$LIBLDAP -lldap_r -llber -lresolv"
+ HAVE_LDAP=1 LIBLDAP="$LIBLDAP -lldap -llber -lresolv"
fi
if test "$HAVE_LDAP" = "1"; then
@@ -4578,7 +4578,7 @@ 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_r"
+LDFLAGS="$LDFLAGS -lldap"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
@@ -4648,7 +4648,7 @@ 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_r"
+LDFLAGS="$LDFLAGS -lldap"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
diff --git a/configure.in b/configure.in
index a9c86dd..27b9bec 100644
--- a/configure.in
+++ b/configure.in
@@ -197,7 +197,7 @@ AC_ARG_WITH(openldap,
if test -z "$HAVE_LDAP" -o "$HAVE_LDAP" != "0"; then
HAVE_LDAP=0
LDAP_FLAGS="$LDAP_FLAGS -DLDAP_DEPRECATED=1"
- AC_CHECK_LIB(ldap, ldap_initialize, HAVE_LDAP=1 LIBLDAP="$LIBLDAP -lldap_r -llber -lresolv", ,
+ AC_CHECK_LIB(ldap, ldap_initialize, HAVE_LDAP=1 LIBLDAP="$LIBLDAP -lldap -llber -lresolv", ,
-llber -lresolv $LIBS)
if test "$HAVE_LDAP" = "1"; then
AC_DEFINE(WITH_LDAP,1,

View File

@ -1,81 +0,0 @@
autofs-5.0.3 - don't abuse the ap->ghost field on NFS mount
From: Ian Kent <raven@themaw.net>
Using the ap->ghost field in the autofs mount point struct, to prevent
the mount point directory from being removed, when attempting a bind
mount when an NFS mount is local may lead to incorrectly reading and
ghosting the map. This can happen if a mount request comes in during
a map re-read when the autofs map doesn't have the browse option set.
This patch corrects that by using the existence check in the bind mount
module instead of the hack of changing the struct field.
---
modules/mount_bind.c | 2 +-
modules/mount_nfs.c | 11 -----------
2 files changed, 1 insertions(+), 12 deletions(-)
diff --git a/modules/mount_bind.c b/modules/mount_bind.c
index ef973e1..e4a04d0 100644
--- a/modules/mount_bind.c
+++ b/modules/mount_bind.c
@@ -144,7 +144,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
if (ap->type != LKP_INDIRECT)
return 1;
- if ((!ap->ghost && name_len) || !existed)
+ if ((!ap->ghost && name_len) && !existed)
rmdir_path(ap, fullpath, ap->dev);
return err;
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
index 1855ea9..d7f42a7 100644
--- a/modules/mount_nfs.c
+++ b/modules/mount_nfs.c
@@ -62,7 +62,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
{
char *fullpath, buf[MAX_ERR_BUF];
struct host *this, *hosts = NULL;
- unsigned int save_ghost = ap->ghost;
unsigned int vers;
char *nfsoptions = NULL;
int len, rlen, status, err, existed = 1;
@@ -186,13 +185,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
if (!status)
existed = 0;
- /*
- * We need to stop the bind mount module from removing the
- * mount point directory if a bind attempt fails so abuse
- * the ap->ghost field for this.
- */
- ap->ghost = 1;
-
this = hosts;
while (this) {
char *loc, *port_opt = NULL;
@@ -229,7 +221,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
/* Success - we're done */
if (!err) {
free_host_list(&hosts);
- ap->ghost = save_ghost;
return 0;
}
@@ -271,7 +262,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
info(ap->logopt, MODPREFIX "mounted %s on %s", loc, fullpath);
free(loc);
free_host_list(&hosts);
- ap->ghost = save_ghost;
return 0;
}
@@ -281,7 +271,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
forced_fail:
free_host_list(&hosts);
- ap->ghost = save_ghost;
/* If we get here we've failed to complete the mount */

View File

@ -1,495 +0,0 @@
autofs-5.0.3 - try not to block on expire
From: Ian Kent <raven@themaw.net>
When a server is not available umount and any stat statfs and related
function calls may block for a significant amount of time. This effects
expire timeouts a lot due to their synchronous nature. This patch limits
the time we wait on spawned umounts and elininates calls to functions
that would block. This allows us to retry the umount on the next expire
event and continue the expire of remaining mounts.
---
CHANGELOG | 2 ++
daemon/automount.c | 34 ++++++++++++++++++------------
daemon/direct.c | 29 +++++---------------------
daemon/indirect.c | 26 +++++++++--------------
daemon/spawn.c | 59 ++++++++++++++++++++++++++++++++++++++++++----------
include/master.h | 1 +
lib/master.c | 23 ++++++++++++++++++++
lib/mounts.c | 48 ++----------------------------------------
8 files changed, 112 insertions(+), 110 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index ff04985..ff44cc7 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -27,6 +27,8 @@
- don't use proc file system when checking if the daemon is running.
- make handle_mounts startup condition distinct.
- fix submount shutdown recovery handling.
+- avoid stat of possibly dead mount points and limit time to wait for
+ umount during expire.
14/01/2008 autofs-5.0.3
-----------------------
diff --git a/daemon/automount.c b/daemon/automount.c
index 68bf1d3..5bd5f6d 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -247,9 +247,17 @@ static int walk_tree(const char *base, int (*fn) (unsigned logopt,
int, void *), int incl, unsigned logopt, void *arg)
{
char buf[PATH_MAX + 1];
- struct stat st;
+ struct stat st, *pst = &st;
+ int ret;
+
+ if (!is_mounted(_PATH_MOUNTED, base, MNTS_REAL))
+ ret = lstat(base, pst);
+ else {
+ pst = NULL;
+ ret = 0;
+ }
- if (lstat(base, &st) != -1 && (fn) (logopt, base, &st, 0, arg)) {
+ if (ret != -1 && (fn) (logopt, base, pst, 0, arg)) {
if (S_ISDIR(st.st_mode)) {
struct dirent **de;
int n;
@@ -283,7 +291,7 @@ static int walk_tree(const char *base, int (*fn) (unsigned logopt,
free(de);
}
if (incl)
- (fn) (logopt, base, &st, 1, arg);
+ (fn) (logopt, base, pst, 1, arg);
}
return 0;
}
@@ -294,6 +302,9 @@ static int rm_unwanted_fn(unsigned logopt, const char *file, const struct stat *
char buf[MAX_ERR_BUF];
struct stat newst;
+ if (!st)
+ return 0;
+
if (when == 0) {
if (st->st_dev != dev)
return 0;
@@ -344,8 +355,8 @@ static int counter_fn(unsigned logopt, const char *file, const struct stat *st,
{
struct counter_args *counter = (struct counter_args *) arg;
- if (S_ISLNK(st->st_mode) || (S_ISDIR(st->st_mode)
- && st->st_dev != counter->dev)) {
+ if (!st || (S_ISLNK(st->st_mode) || (S_ISDIR(st->st_mode)
+ && st->st_dev != counter->dev))) {
counter->count++;
return 0;
}
@@ -512,9 +523,8 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
int umount_multi(struct autofs_point *ap, const char *path, int incl)
{
struct mapent_cache *nc;
- struct statfs fs;
int is_autofs_fs;
- int ret, left;
+ int left;
debug(ap->logopt, "path %s incl %d", path, incl);
@@ -526,13 +536,9 @@ int umount_multi(struct autofs_point *ap, const char *path, int incl)
}
cache_unlock(nc);
- ret = statfs(path, &fs);
- if (ret == -1) {
- error(ap->logopt, "could not stat fs of %s", path);
- return 1;
- }
-
- is_autofs_fs = fs.f_type == (__SWORD_TYPE) AUTOFS_SUPER_MAGIC ? 1 : 0;
+ is_autofs_fs = 0;
+ if (master_find_submount(ap, path))
+ is_autofs_fs = 1;
left = 0;
diff --git a/daemon/direct.c b/daemon/direct.c
index 334a4b6..7fb78a3 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -152,7 +152,7 @@ int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, stru
retries = UMOUNT_RETRIES;
while ((rv = umount(me->key)) == -1 && retries--) {
- struct timespec tm = {0, 100000000};
+ struct timespec tm = {0, 200000000};
if (errno != EBUSY)
break;
nanosleep(&tm, NULL);
@@ -604,7 +604,7 @@ int umount_autofs_offset(struct autofs_point *ap, struct mapent *me)
retries = UMOUNT_RETRIES;
while ((rv = umount(me->key)) == -1 && retries--) {
- struct timespec tm = {0, 100000000};
+ struct timespec tm = {0, 200000000};
if (errno != EBUSY)
break;
nanosleep(&tm, NULL);
@@ -705,7 +705,7 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me)
* the kernel NFS client.
*/
if (me->multi != me &&
- is_mounted(_PROC_MOUNTS, me->key, MNTS_REAL))
+ is_mounted(_PATH_MOUNTED, me->key, MNTS_REAL))
return MOUNT_OFFSET_IGNORE;
/*
@@ -807,17 +807,7 @@ out_err:
static int expire_direct(int ioctlfd, const char *path, unsigned int when, unsigned int logopt)
{
- char buf[MAX_ERR_BUF];
- int ret, retries;
- struct stat st;
-
- if (fstat(ioctlfd, &st) == -1) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- debug(logopt, "fstat failed: %s", estr);
- return 0;
- }
-
- retries = (count_mounts(logopt, path, st.st_dev) + 1) * EXPIRE_RETRIES;
+ int ret, retries = EXPIRE_RETRIES;
while (retries--) {
struct timespec tm = {0, 100000000};
@@ -911,7 +901,6 @@ void *expire_proc_direct(void *arg)
if (!strcmp(next->fs_type, "autofs")) {
struct stat st;
- struct statfs fs;
int ioctlfd;
cache_unlock(me->mc);
@@ -932,14 +921,8 @@ void *expire_proc_direct(void *arg)
continue;
}
- if (statfs(next->path, &fs) == -1) {
- pthread_setcancelstate(cur_state, NULL);
- warn(ap->logopt,
- "fstatfs failed for %s", next->path);
- continue;
- }
-
- if (fs.f_type != (__SWORD_TYPE) AUTOFS_SUPER_MAGIC) {
+ /* It's got a mount, deal with in the outer loop */
+ if (tree_is_mounted(mnts, me->key, MNTS_REAL)) {
pthread_setcancelstate(cur_state, NULL);
continue;
}
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 17bed3e..e832cd4 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -285,7 +285,7 @@ int umount_autofs_indirect(struct autofs_point *ap)
retries = UMOUNT_RETRIES;
while ((rv = umount(ap->path)) == -1 && retries--) {
- struct timespec tm = {0, 100000000};
+ struct timespec tm = {0, 200000000};
if (errno != EBUSY)
break;
nanosleep(&tm, NULL);
@@ -368,17 +368,7 @@ force_umount:
static int expire_indirect(struct autofs_point *ap, int ioctlfd, const char *path, unsigned int when)
{
- char buf[MAX_ERR_BUF];
- int ret, retries;
- struct stat st;
-
- if (fstat(ioctlfd, &st) == -1) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- debug(ap->logopt, "fstat failed: %s", estr);
- return 0;
- }
-
- retries = (count_mounts(ap->logopt, path, st.st_dev) + 1) * EXPIRE_RETRIES;
+ int ret, retries = EXPIRE_RETRIES;
while (retries--) {
struct timespec tm = {0, 100000000};
@@ -512,7 +502,6 @@ void *expire_proc_indirect(void *arg)
left++;
pthread_setcancelstate(cur_state, NULL);
}
- pthread_cleanup_pop(1);
/*
* If there are no more real mounts left we could still
@@ -520,12 +509,17 @@ void *expire_proc_indirect(void *arg)
* umount them here.
*/
if (mnts) {
+ int retries;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
- ret = expire_indirect(ap, ap->ioctlfd, ap->path, now);
- if (!ret)
- left++;
+ retries = (count_mounts(ap->logopt, ap->path, ap->dev) + 1);
+ while (retries--) {
+ ret = expire_indirect(ap, ap->ioctlfd, ap->path, now);
+ if (!ret)
+ left++;
+ }
pthread_setcancelstate(cur_state, NULL);
}
+ pthread_cleanup_pop(1);
count = offsets = submnts = 0;
mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 0);
diff --git a/daemon/spawn.c b/daemon/spawn.c
index 78d69c6..e3c355e 100644
--- a/daemon/spawn.c
+++ b/daemon/spawn.c
@@ -89,13 +89,43 @@ void reset_signals(void)
#define ERRBUFSIZ 2047 /* Max length of error string excl \0 */
-static int do_spawn(unsigned logopt, unsigned int options, const char *prog, const char *const *argv)
+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;
+ int ret;
+
+ FD_ZERO(&rset);
+ FD_SET(pipe, &rset);
+ wset = rset;
+
+ if (time != -1) {
+ timeout.tv_sec = time;
+ tout = &timeout;
+ }
+
+ ret = select(pipe + 1, &rset, &wset, NULL, tout);
+ if (ret <= 0) {
+ if (ret == 0)
+ ret = -ETIMEDOUT;
+ return ret;
+ }
+
+ while ((ret = read(pipe, buf, len)) == -1 && errno == EINTR);
+
+ return ret;
+}
+
+static int do_spawn(unsigned logopt, unsigned int wait,
+ unsigned int options, const char *prog,
+ const char *const *argv)
{
pid_t f;
int ret, status, pipefd[2];
char errbuf[ERRBUFSIZ + 1], *p, *sp;
int errp, errn;
- int cancel_state;
+ int flags, cancel_state;
unsigned int use_lock = options & SPAWN_OPT_LOCK;
unsigned int use_access = options & SPAWN_OPT_ACCESS;
sigset_t allsigs, tmpsig, oldsig;
@@ -183,12 +213,15 @@ static int do_spawn(unsigned logopt, unsigned int options, const char *prog, con
return -1;
}
+ if ((flags = fcntl(pipefd[0], F_GETFD, 0)) != -1) {
+ flags |= FD_CLOEXEC;
+ fcntl(pipefd[0], F_SETFD, flags);
+ }
+
errp = 0;
do {
- while ((errn =
- read(pipefd[0], errbuf + errp, ERRBUFSIZ - errp)) == -1
- && errno == EINTR);
-
+ errn = timed_read(pipefd[0],
+ errbuf + errp, ERRBUFSIZ - errp, wait);
if (errn > 0) {
errp += errn;
@@ -213,6 +246,9 @@ static int do_spawn(unsigned logopt, unsigned int options, const char *prog, con
}
} while (errn > 0);
+ if (errn == -ETIMEDOUT)
+ kill(f, SIGTERM);
+
close(pipefd[0]);
if (errp > 0) {
@@ -238,7 +274,7 @@ static int do_spawn(unsigned logopt, unsigned int options, const char *prog, con
int spawnv(unsigned logopt, const char *prog, const char *const *argv)
{
- return do_spawn(logopt, SPAWN_OPT_NONE, prog, argv);
+ return do_spawn(logopt, -1, SPAWN_OPT_NONE, prog, argv);
}
int spawnl(unsigned logopt, const char *prog, ...)
@@ -259,7 +295,7 @@ int spawnl(unsigned logopt, const char *prog, ...)
while ((*p++ = va_arg(arg, char *)));
va_end(arg);
- return do_spawn(logopt, SPAWN_OPT_NONE, prog, (const char **) argv);
+ return do_spawn(logopt, -1, SPAWN_OPT_NONE, prog, (const char **) argv);
}
int spawn_mount(unsigned logopt, ...)
@@ -307,7 +343,7 @@ int spawn_mount(unsigned logopt, ...)
va_end(arg);
while (retries--) {
- ret = do_spawn(logopt, options, prog, (const char **) argv);
+ ret = do_spawn(logopt, -1, options, prog, (const char **) argv);
if (ret & MTAB_NOTUPDATED) {
struct timespec tm = {3, 0};
@@ -406,7 +442,7 @@ int spawn_bind_mount(unsigned logopt, ...)
va_end(arg);
while (retries--) {
- ret = do_spawn(logopt, options, prog, (const char **) argv);
+ ret = do_spawn(logopt, -1, options, prog, (const char **) argv);
if (ret & MTAB_NOTUPDATED) {
struct timespec tm = {3, 0};
@@ -466,6 +502,7 @@ int spawn_umount(unsigned logopt, ...)
unsigned int options;
unsigned int retries = MTAB_LOCK_RETRIES;
int ret, printed = 0;
+ unsigned int wait = 12;
#ifdef ENABLE_MOUNT_LOCKING
options = SPAWN_OPT_LOCK;
@@ -488,7 +525,7 @@ int spawn_umount(unsigned logopt, ...)
va_end(arg);
while (retries--) {
- ret = do_spawn(logopt, options, prog, (const char **) argv);
+ ret = do_spawn(logopt, wait, options, prog, (const char **) argv);
if (ret & MTAB_NOTUPDATED) {
/*
* If the mount succeeded but the mtab was not
diff --git a/include/master.h b/include/master.h
index 86ae045..a397a75 100644
--- a/include/master.h
+++ b/include/master.h
@@ -91,6 +91,7 @@ void master_source_lock_cleanup(void *);
void master_source_current_wait(struct master_mapent *);
void master_source_current_signal(struct master_mapent *);
struct master_mapent *master_find_mapent(struct master *, const char *);
+struct autofs_point *master_find_submount(struct autofs_point *, const char *);
struct master_mapent *master_new_mapent(struct master *, const char *, time_t);
void master_add_mapent(struct master *, struct master_mapent *);
void master_remove_mapent(struct master_mapent *);
diff --git a/lib/master.c b/lib/master.c
index 522b919..71ba04a 100644
--- a/lib/master.c
+++ b/lib/master.c
@@ -602,6 +602,29 @@ struct master_mapent *master_find_mapent(struct master *master, const char *path
return NULL;
}
+struct autofs_point *master_find_submount(struct autofs_point *ap, const char *path)
+{
+ struct list_head *head, *p;
+
+ mounts_mutex_lock(ap);
+
+ head = &ap->submounts;
+ list_for_each(p, head) {
+ struct autofs_point *submount;
+
+ submount = list_entry(p, struct autofs_point, mounts);
+
+ if (!strcmp(submount->path, path)) {
+ mounts_mutex_unlock(ap);
+ return submount;
+ }
+ }
+
+ mounts_mutex_unlock(ap);
+
+ return NULL;
+}
+
struct master_mapent *master_new_mapent(struct master *master, const char *path, time_t age)
{
struct master_mapent *entry;
diff --git a/lib/mounts.c b/lib/mounts.c
index a4bf86c..d77a6b0 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1073,55 +1073,11 @@ free_tsv:
int umount_ent(struct autofs_point *ap, const char *path)
{
- struct stat st;
- struct statfs fs;
- int sav_errno;
- int status, is_smbfs = 0;
- int ret, rv = 1;
-
- ret = statfs(path, &fs);
- if (ret == -1) {
- warn(ap->logopt, "could not stat fs of %s", path);
- is_smbfs = 0;
- } else {
- int cifsfs = fs.f_type == (__SWORD_TYPE) CIFS_MAGIC_NUMBER;
- int smbfs = fs.f_type == (__SWORD_TYPE) SMB_SUPER_MAGIC;
- is_smbfs = (cifsfs | smbfs) ? 1 : 0;
- }
-
- status = lstat(path, &st);
- sav_errno = errno;
-
- if (status < 0)
- warn(ap->logopt, "lstat of %s failed with %d", path, status);
-
- /*
- * lstat failed and we're an smbfs fs returning an error that is not
- * EIO or EBADSLT or the lstat failed so it's a bad path. Return
- * a fail.
- *
- * EIO appears to correspond to an smb mount that has gone away
- * and EBADSLT relates to CD changer not responding.
- */
- if (!status && (S_ISDIR(st.st_mode) && st.st_dev != ap->dev)) {
- rv = spawn_umount(ap->logopt, path, NULL);
- } else if (is_smbfs && (sav_errno == EIO || sav_errno == EBADSLT)) {
- rv = spawn_umount(ap->logopt, path, NULL);
- }
+ int rv;
+ rv = spawn_umount(ap->logopt, path, NULL);
/* We are doing a forced shutcwdown down so unlink busy mounts */
if (rv && (ap->state == ST_SHUTDOWN_FORCE || ap->state == ST_SHUTDOWN)) {
- ret = stat(path, &st);
- if (ret == -1 && errno == ENOENT) {
- warn(ap->logopt, "mount point does not exist");
- return 0;
- }
-
- if (ret == 0 && !S_ISDIR(st.st_mode)) {
- warn(ap->logopt, "mount point is not a directory");
- return 0;
- }
-
if (ap->state == ST_SHUTDOWN_FORCE) {
info(ap->logopt, "forcing umount of %s", path);
rv = spawn_umount(ap->logopt, "-l", path, NULL);

View File

@ -1,52 +0,0 @@
diff --git a/CHANGELOG b/CHANGELOG
index e393f33..033923d 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -5,6 +5,7 @@
- correction for handling of LDAP base dns with spaces.
- avoid using UDP for probing NFSv4 mount requests.
- use libldap instead of libldap_r (Guillaume Rousse).
+- another fix for don't fail on empty master map.
14/01/2008 autofs-5.0.3
-----------------------
diff --git a/lib/master.c b/lib/master.c
index ed82131..4a34dd4 100644
--- a/lib/master.c
+++ b/lib/master.c
@@ -799,21 +799,13 @@ int master_read_master(struct master *master, time_t age, int readall)
master_init_scan();
- if (!lookup_nss_read_master(master, age)) {
- error(logopt,
- "can't read master map %s", master->name);
- return 0;
- }
-
+ lookup_nss_read_master(master, age);
master_mount_mounts(master, age, readall);
master_mutex_lock();
- if (list_empty(&master->mounts)) {
- master_mutex_unlock();
+ if (list_empty(&master->mounts))
warn(logopt, "no mounts in table");
- return 1;
- }
master_mutex_unlock();
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index b01eea6..466690a 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -475,6 +475,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
"failed to read included master map %s",
master->name);
if (!master->recurse) {
+ master->name = save_name;
master->depth--;
master->recurse = 0;
fclose(f);

View File

@ -1,39 +0,0 @@
autofs-5.0.3 - don't readmap on HUP for new mount
From: Ian Kent <raven@themaw.net>
If we're performing a new mount during a HUP signal then
we will read the map during the mount.
---
lib/master.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
--- autofs-5.0.3.orig/lib/master.c
+++ autofs-5.0.3/lib/master.c
@@ -1108,8 +1108,6 @@ int master_mount_mounts(struct master *m
}
cache_unlock(nc);
- check_update_map_sources(this, readall);
-
st_mutex_lock();
state_pipe = this->ap->state_pipe[1];
@@ -1120,11 +1118,14 @@ int master_mount_mounts(struct master *m
st_mutex_unlock();
- if (ret == -1 && save_errno == EBADF)
+ if (!ret)
+ check_update_map_sources(this, readall);
+ else if (ret == -1 && save_errno == EBADF) {
if (!master_do_mount(this)) {
list_del_init(&this->list);
master_free_mapent_sources(ap->entry, 1);
master_free_mapent(ap->entry);
+ }
}
}

View File

@ -1,619 +0,0 @@
autofs-5.0.3 - don't use proc for is running check
From: Ian Kent <raven@themaw.net>
Using /proc/<pid>/cmdline to check if the daemon is running allows
any user to create a trivial program called "automount" and prevent
the system automounter from running simply by executing it and
leaving it running. This patch makes autofs use a flag file for this
check instead.
---
CHANGELOG | 1
Makefile.conf.in | 3 +
aclocal.m4 | 16 ++++
configure | 35 +++++++++
configure.in | 17 +++++
daemon/Makefile | 5 +
daemon/automount.c | 95 ++++++++------------------
daemon/flag.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++++
8 files changed, 294 insertions(+), 70 deletions(-)
create mode 100644 daemon/flag.c
diff --git a/CHANGELOG b/CHANGELOG
index f40a941..3921552 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -24,6 +24,7 @@
- fix incorrect if check in get user info.
- fix couple of memory leaks.
- add command line option to override check for daemon already running.
+- don't use proc file system when checking if the daemon is running.
14/01/2008 autofs-5.0.3
-----------------------
diff --git a/Makefile.conf.in b/Makefile.conf.in
index 09c3129..d88f5ee 100644
--- a/Makefile.conf.in
+++ b/Makefile.conf.in
@@ -74,6 +74,9 @@ autofsmapdir = @mapdir@
# Location for autofs fifos
autofsfifodir = @fifodir@
+# Location for autofs flag file
+autofsflagdir = @flagdir@
+
# Where to install the automount program
sbindir = @sbindir@
diff --git a/aclocal.m4 b/aclocal.m4
index a1105ae..9ef4050 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -136,6 +136,22 @@ AC_DEFUN(AF_FIFO_D,
done
fi])
+dnl --------------------------------------------------------------------------
+dnl AF_FLAG_D
+dnl
+dnl Check the location of the autofs flag file directory
+dnl --------------------------------------------------------------------------
+AC_DEFUN(AF_FLAG_D,
+[if test -z "$flagdir"; then
+ for flag_d in /var/run /tmp; do
+ if test -z "$flagdir"; then
+ if test -d "$flag_d"; then
+ flagdir="$flag_d"
+ fi
+ fi
+ done
+fi])
+
dnl ----------------------------------- ## -*- Autoconf -*-
dnl Check if --with-dmalloc was given. ##
dnl From Franc,ois Pinard ##
diff --git a/configure b/configure
index 0d3268c..9278196 100755
--- a/configure
+++ b/configure
@@ -655,6 +655,7 @@ initdir
confdir
mapdir
fifodir
+flagdir
DMALLOCLIB
MOUNT
HAVE_MOUNT
@@ -1295,6 +1296,7 @@ Optional Packages:
--with-confdir=DIR use DIR for autofs configuration files
--with-mapdir=PATH look in PATH for mount maps used by the automounter
--with-fifodir=PATH use PATH as the directory for fifos used by the automounter
+ --with-flagdir=PATH use PATH as the directory for the flag file used by the automounter
--with-dmalloc use dmalloc, as in
http://www.dmalloc.com/dmalloc.tar.gz
--with-hesiod=DIR enable Hesiod support (libs and includes in DIR)
@@ -1876,6 +1878,36 @@ echo "${ECHO_T}$fifodir" >&6; }
#
+# The user can specify --with-flagdir=PATH to specify where autofs flag file goes
+#
+if test -z "$flagdir"; then
+ for flag_d in /var/run /tmp; do
+ if test -z "$flagdir"; then
+ if test -d "$flag_d"; then
+ flagdir="$flag_d"
+ fi
+ fi
+ done
+fi
+
+# Check whether --with-flagdir was given.
+if test "${with_flagdir+set}" = set; then
+ withval=$with_flagdir; if test -z "$withval" -o "$withval" = "yes" -o "$withval" = "no"
+ then
+ :
+ else
+ filagdir="${withval}"
+ fi
+
+fi
+
+{ echo "$as_me:$LINENO: checking for autofs flag file directory" >&5
+echo $ECHO_N "checking for autofs flag file directory... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: result: $flagdir" >&5
+echo "${ECHO_T}$flagdir" >&6; }
+
+
+#
# Optional include dmalloc
#
{ echo "$as_me:$LINENO: checking if malloc debugging is wanted" >&5
@@ -6247,6 +6279,7 @@ initdir!$initdir$ac_delim
confdir!$confdir$ac_delim
mapdir!$mapdir$ac_delim
fifodir!$fifodir$ac_delim
+flagdir!$flagdir$ac_delim
DMALLOCLIB!$DMALLOCLIB$ac_delim
MOUNT!$MOUNT$ac_delim
HAVE_MOUNT!$HAVE_MOUNT$ac_delim
@@ -6297,7 +6330,7 @@ LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 89; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 90; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
diff --git a/configure.in b/configure.in
index 27b9bec..5ba3a49 100644
--- a/configure.in
+++ b/configure.in
@@ -96,6 +96,23 @@ AC_MSG_RESULT([$fifodir])
AC_SUBST(fifodir)
#
+# The user can specify --with-flagdir=PATH to specify where autofs flag file goes
+#
+AF_FLAG_D()
+AC_ARG_WITH(flagdir,
+[ --with-flagdir=PATH use PATH as the directory for the flag file used by the automounter],
+ if test -z "$withval" -o "$withval" = "yes" -o "$withval" = "no"
+ then
+ :
+ else
+ filagdir="${withval}"
+ fi
+)
+AC_MSG_CHECKING([for autofs flag file directory])
+AC_MSG_RESULT([$flagdir])
+AC_SUBST(flagdir)
+
+#
# Optional include dmalloc
#
AM_WITH_DMALLOC()
diff --git a/daemon/Makefile b/daemon/Makefile
index 528a684..9c2d858 100644
--- a/daemon/Makefile
+++ b/daemon/Makefile
@@ -6,9 +6,9 @@
include ../Makefile.rules
SRCS = automount.c indirect.c direct.c spawn.c module.c mount.c \
- lookup.c state.c
+ lookup.c state.c flag.c
OBJS = automount.o indirect.o direct.o spawn.o module.o mount.o \
- lookup.o state.o
+ lookup.o state.o flag.o
version := $(shell cat ../.version)
@@ -17,6 +17,7 @@ CFLAGS += -DAUTOFS_LIB_DIR=\"$(autofslibdir)\"
CFLAGS += -DAUTOFS_MAP_DIR=\"$(autofsmapdir)\"
CFLAGS += -DAUTOFS_CONF_DIR=\"$(autofsconfdir)\"
CFLAGS += -DAUTOFS_FIFO_DIR=\"$(autofsfifodir)\"
+CFLAGS += -DAUTOFS_FLAG_DIR=\"$(autofsflagdir)\"
CFLAGS += -DVERSION_STRING=\"$(version)\"
LDFLAGS += -rdynamic
LIBS = -ldl
diff --git a/daemon/automount.c b/daemon/automount.c
index 48ac30a..dbf267c 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -81,6 +81,8 @@ pthread_key_t key_thread_stdenv_vars;
#define MAX_OPEN_FILES 10240
+int aquire_flag_file(void);
+void release_flag_file(void);
static int umount_all(struct autofs_point *ap, int force);
extern pthread_mutex_t master_mutex;
@@ -1098,7 +1100,7 @@ static int handle_packet(struct autofs_point *ap)
return -1;
}
-static void become_daemon(unsigned foreground)
+static void become_daemon(unsigned foreground, unsigned daemon_check)
{
FILE *pidfp;
char buf[MAX_ERR_BUF];
@@ -1118,9 +1120,14 @@ static void become_daemon(unsigned foreground)
}
/* Detach from foreground process */
- if (foreground)
+ if (foreground) {
+ if (daemon_check && !aquire_flag_file()) {
+ fprintf(stderr, "%s: program is already running.\n",
+ program);
+ exit(1);
+ }
log_to_stderr();
- else {
+ } else {
pid = fork();
if (pid > 0) {
int r;
@@ -1136,6 +1143,13 @@ static void become_daemon(unsigned foreground)
}
close(start_pipefd[0]);
+ if (daemon_check && !aquire_flag_file()) {
+ fprintf(stderr, "%s: program is already running.\n",
+ program);
+ close(start_pipefd[1]);
+ exit(1);
+ }
+
/*
* Make our own process group for "magic" reason: processes that share
* our pgrp see the raw filesystem behind the magic.
@@ -1143,6 +1157,7 @@ static void become_daemon(unsigned foreground)
if (setsid() == -1) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
fprintf(stderr, "setsid: %s", estr);
+ close(start_pipefd[1]);
exit(1);
}
log_to_syslog();
@@ -1617,64 +1632,6 @@ static void key_thread_stdenv_vars_destroy(void *arg)
return;
}
-static int is_automount_running(void)
-{
- FILE *fp;
- DIR *dir;
- struct dirent entry;
- struct dirent *result;
- char path[PATH_MAX + 1], buf[PATH_MAX];
-
- if ((dir = opendir("/proc")) == NULL) {
- fprintf(stderr, "cannot opendir(/proc)\n");
- exit(1);
- }
-
- while (readdir_r(dir, &entry, &result) == 0) {
- int path_len, pid = 0;
-
- if (!result)
- break;
-
- if (*entry.d_name == '.')
- continue;
-
- if (!strcmp(entry.d_name, "self"))
- continue;
-
- if (!isdigit(*entry.d_name))
- continue;
-
- pid = atoi(entry.d_name);
- if (pid == getpid())
- continue;
-
- path_len = sprintf(path, "/proc/%s/cmdline", entry.d_name);
- if (path_len >= PATH_MAX) {
- fprintf(stderr,
- "buffer to small for /proc path\n");
- return -1;
- }
- path[path_len] = '\0';
-
- fp = fopen(path, "r");
- if (fp) {
- int c, len = 0;
-
- while (len < 127 && (c = fgetc(fp)) != EOF && c)
- buf[len++] = c;
- buf[len] = '\0';
-
- if (strstr(buf, "automount"))
- return pid;
- fclose(fp);
- }
- }
- closedir(dir);
-
- return 0;
-}
-
static void usage(void)
{
fprintf(stderr,
@@ -1973,11 +1930,6 @@ int main(int argc, char *argv[])
exit(exit_code);
}
- if (daemon_check && is_automount_running() > 0) {
- fprintf(stderr, "%s: program is already running.\n",
- program);
- exit(1);
- }
#if 0
if (!load_autofs4_module()) {
fprintf(stderr, "%s: can't load %s filesystem module.\n",
@@ -2009,7 +1961,7 @@ int main(int argc, char *argv[])
"can't increase core file limit - continuing");
#endif
- become_daemon(foreground);
+ become_daemon(foreground, daemon_check);
if (argc == 0)
master_list = master_new(NULL, timeout, ghost);
@@ -2020,6 +1972,7 @@ int main(int argc, char *argv[])
logerr("%s: can't create master map %s",
program, argv[0]);
close(start_pipefd[1]);
+ release_flag_file();
exit(1);
}
@@ -2027,6 +1980,7 @@ int main(int argc, char *argv[])
logerr("%s: failed to init thread attribute struct!",
program);
close(start_pipefd[1]);
+ release_flag_file();
exit(1);
}
@@ -2035,6 +1989,7 @@ int main(int argc, char *argv[])
logerr("%s: failed to set detached thread attribute!",
program);
close(start_pipefd[1]);
+ release_flag_file();
exit(1);
}
@@ -2044,6 +1999,7 @@ int main(int argc, char *argv[])
logerr("%s: failed to set stack size thread attribute!",
program);
close(start_pipefd[1]);
+ release_flag_file();
exit(1);
}
#endif
@@ -2060,6 +2016,7 @@ int main(int argc, char *argv[])
program);
master_kill(master_list);
close(start_pipefd[1]);
+ release_flag_file();
exit(1);
}
@@ -2067,6 +2024,7 @@ int main(int argc, char *argv[])
logerr("%s: failed to create alarm handler thread!", program);
master_kill(master_list);
close(start_pipefd[1]);
+ release_flag_file();
exit(1);
}
@@ -2074,6 +2032,7 @@ int main(int argc, char *argv[])
logerr("%s: failed to create FSM handler thread!", program);
master_kill(master_list);
close(start_pipefd[1]);
+ release_flag_file();
exit(1);
}
@@ -2086,6 +2045,7 @@ int main(int argc, char *argv[])
*pst_stat = 3;
res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
close(start_pipefd[1]);
+ release_flag_file();
exit(3);
}
@@ -2102,6 +2062,7 @@ int main(int argc, char *argv[])
pid_file = NULL;
}
closelog();
+ release_flag_file();
#ifdef LIBXML2_WORKAROUND
if (dh)
diff --git a/daemon/flag.c b/daemon/flag.c
new file mode 100644
index 0000000..d8ca61b
--- /dev/null
+++ b/daemon/flag.c
@@ -0,0 +1,192 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * flag.c - autofs flag file management
+ *
+ * Copyright 2008 Red Hat, Inc. All rights reserved.
+ * Copyright 2008 Ian Kent <raven@themaw.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
+ * USA; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+#include <alloca.h>
+#include <stdio.h>
+#include <signal.h>
+#include <errno.h>
+
+#define MAX_PIDSIZE 20
+#define FLAG_FILE AUTOFS_FLAG_DIR "/autofs-running"
+
+/* Flag for already existing flag file. */
+static int we_created_flagfile = 0;
+
+/* file descriptor of flag file */
+static int fd = -1;
+
+static int flag_is_owned(int fd)
+{
+ int pid = 0, tries = 3;
+
+ while (tries--) {
+ char pidbuf[MAX_PIDSIZE + 1];
+ int got;
+
+ lseek(fd, 0, SEEK_SET);
+ got = read(fd, pidbuf, MAX_PIDSIZE);
+ /*
+ * We add a terminator to the pid to verify write complete.
+ * If the write isn't finished in 300 milliseconds then it's
+ * probably a stale lock file.
+ */
+ if (got > 0 && pidbuf[got - 1] == '\n') {
+ sscanf(pidbuf, "%d", &pid);
+ break;
+ } else {
+ struct timespec t = { 0, 100000000 };
+ struct timespec r;
+
+ while (nanosleep(&t, &r) == -1 && errno == EINTR)
+ memcpy(&t, &r, sizeof(struct timespec));
+
+ continue;
+ }
+
+ /* Stale flagfile */
+ if (!tries)
+ return 0;
+ }
+
+
+ if (pid) {
+ int ret;
+
+ ret = kill(pid, 0);
+ /*
+ * If lock file exists but is not owned by a process
+ * we return unowned status so we can get rid of it
+ * and continue.
+ */
+ if (ret == -1 && errno == ESRCH)
+ return 0;
+ } else {
+ /*
+ * Odd, no pid in file - so what should we do?
+ * Assume something bad happened to owner and
+ * return unowned status.
+ */
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Remove flag file. */
+void release_flag_file(void)
+{
+ if (fd > 0) {
+ close(fd);
+ fd = -1;
+ }
+
+ if (we_created_flagfile) {
+ unlink(FLAG_FILE);
+ we_created_flagfile = 0;
+ }
+}
+
+/* * Try to create flag file */
+int aquire_flag_file(void)
+{
+ char *linkf;
+ int len;
+
+ len = strlen(FLAG_FILE) + MAX_PIDSIZE;
+ linkf = alloca(len + 1);
+ snprintf(linkf, len, "%s.%d", FLAG_FILE, getpid());
+
+ /*
+ * Repeat until it was us who made the link or we find the
+ * flag file already exists. If an unexpected error occurs
+ * we return 0 claiming the flag file exists which may not
+ * really be the case.
+ */
+ while (!we_created_flagfile) {
+ int errsv, i, j;
+
+ i = open(linkf, O_WRONLY|O_CREAT, 0);
+ if (i < 0) {
+ release_flag_file();
+ return 0;
+ }
+ close(i);
+
+ j = link(linkf, FLAG_FILE);
+ errsv = errno;
+
+ (void) unlink(linkf);
+
+ if (j < 0 && errsv != EEXIST) {
+ release_flag_file();
+ return 0;
+ }
+
+ fd = open(FLAG_FILE, O_RDWR);
+ if (fd < 0) {
+ /* Maybe the file was just deleted? */
+ if (errno == ENOENT)
+ continue;
+ release_flag_file();
+ return 0;
+ }
+
+ if (j == 0) {
+ char pidbuf[MAX_PIDSIZE + 1];
+ int pidlen;
+
+ pidlen = sprintf(pidbuf, "%d\n", getpid());
+ if (write(fd, pidbuf, pidlen) != pidlen) {
+ release_flag_file();
+ return 0;
+ }
+
+ we_created_flagfile = 1;
+ } else {
+ /*
+ * Someone else made the link.
+ * If the flag file is not owned by anyone clean
+ * it up and try again, otherwise return fail.
+ */
+ if (!flag_is_owned(fd)) {
+ close(fd);
+ fd = -1;
+ unlink(FLAG_FILE);
+ continue;
+ }
+
+ release_flag_file();
+ return 0;
+ }
+
+ close(fd);
+ fd = -1;
+ }
+
+ return 1;
+}
+

View File

@ -1,179 +0,0 @@
autofs-5.0.3 - fix incorrect pthreads condition handling for expire requests.
From: Ian Kent <raven@themaw.net>
Occassionally, when starting an expire thread we can attempt to use the
structure for parameter communication after it has been freed. This patch
resolves this issue.
---
daemon/direct.c | 40 +++++++++++++++++++++-------------------
daemon/indirect.c | 28 +++++++++++++++-------------
2 files changed, 36 insertions(+), 32 deletions(-)
--- autofs-5.0.3.orig/daemon/direct.c
+++ autofs-5.0.3/daemon/direct.c
@@ -1033,55 +1033,53 @@ static void expire_mutex_unlock(void *ar
static void *do_expire_direct(void *arg)
{
- struct pending_args *mt;
+ struct pending_args *args, mt;
struct autofs_point *ap;
size_t len;
int status, state;
- mt = (struct pending_args *) arg;
+ args = (struct pending_args *) arg;
status = pthread_mutex_lock(&ea_mutex);
if (status)
fatal(status);
- ap = mt->ap;
+ memcpy(&mt, args, sizeof(struct pending_args));
+
+ ap = mt.ap;
- mt->signaled = 1;
- status = pthread_cond_signal(&mt->cond);
+ args->signaled = 1;
+ status = pthread_cond_signal(&args->cond);
if (status)
fatal(status);
expire_mutex_unlock(NULL);
- pthread_cleanup_push(free_pending_args, mt);
- pthread_cleanup_push(pending_cond_destroy, mt);
- pthread_cleanup_push(expire_send_fail, mt);
+ pthread_cleanup_push(expire_send_fail, &mt);
- len = _strlen(mt->name, KEY_MAX_LEN);
+ len = _strlen(mt.name, KEY_MAX_LEN);
if (!len) {
- warn(ap->logopt, "direct key path too long %s", mt->name);
+ warn(ap->logopt, "direct key path too long %s", mt.name);
/* TODO: force umount ?? */
pthread_exit(NULL);
}
- status = do_expire(ap, mt->name, len);
+ status = do_expire(ap, mt.name, len);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
if (status)
- send_fail(ap->logopt, mt->ioctlfd, mt->wait_queue_token);
+ send_fail(ap->logopt, mt.ioctlfd, mt.wait_queue_token);
else {
struct mapent *me;
- cache_readlock(mt->mc);
- me = cache_lookup_distinct(mt->mc, mt->name);
+ cache_readlock(mt.mc);
+ me = cache_lookup_distinct(mt.mc, mt.name);
me->ioctlfd = -1;
- cache_unlock(mt->mc);
- send_ready(ap->logopt, mt->ioctlfd, mt->wait_queue_token);
- close(mt->ioctlfd);
+ cache_unlock(mt.mc);
+ send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token);
+ close(mt.ioctlfd);
}
pthread_setcancelstate(state, NULL);
pthread_cleanup_pop(0);
- pthread_cleanup_pop(1);
- pthread_cleanup_pop(1);
return NULL;
}
@@ -1198,6 +1196,8 @@ int handle_packet_expire_direct(struct a
cache_unlock(mc);
master_source_unlock(ap->entry);
+ pthread_cleanup_push(free_pending_args, mt);
+ pthread_cleanup_push(pending_cond_destroy, mt);
pthread_cleanup_push(expire_mutex_unlock, NULL);
pthread_setcancelstate(state, NULL);
@@ -1212,6 +1212,8 @@ int handle_packet_expire_direct(struct a
}
pthread_cleanup_pop(1);
+ pthread_cleanup_pop(1);
+ pthread_cleanup_pop(1);
return 0;
}
--- autofs-5.0.3.orig/daemon/indirect.c
+++ autofs-5.0.3/daemon/indirect.c
@@ -596,40 +596,38 @@ static void expire_mutex_unlock(void *ar
static void *do_expire_indirect(void *arg)
{
- struct pending_args *mt;
+ struct pending_args *args, mt;
struct autofs_point *ap;
int status, state;
- mt = (struct pending_args *) arg;
+ args = (struct pending_args *) arg;
status = pthread_mutex_lock(&ea_mutex);
if (status)
fatal(status);
- ap = mt->ap;
+ memcpy(&mt, args, sizeof(struct pending_args));
- mt->signaled = 1;
- status = pthread_cond_signal(&mt->cond);
+ ap = mt.ap;
+
+ args->signaled = 1;
+ status = pthread_cond_signal(&args->cond);
if (status)
fatal(status);
expire_mutex_unlock(NULL);
- pthread_cleanup_push(free_pending_args, mt);
- pthread_cleanup_push(pending_cond_destroy, mt);
- pthread_cleanup_push(expire_send_fail, mt);
+ pthread_cleanup_push(expire_send_fail, &mt);
- status = do_expire(mt->ap, mt->name, mt->len);
+ status = do_expire(mt.ap, mt.name, mt.len);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
if (status)
- send_fail(ap->logopt, ap->ioctlfd, mt->wait_queue_token);
+ send_fail(ap->logopt, ap->ioctlfd, mt.wait_queue_token);
else
- send_ready(ap->logopt, ap->ioctlfd, mt->wait_queue_token);
+ send_ready(ap->logopt, ap->ioctlfd, mt.wait_queue_token);
pthread_setcancelstate(state, NULL);
pthread_cleanup_pop(0);
- pthread_cleanup_pop(1);
- pthread_cleanup_pop(1);
return NULL;
}
@@ -682,6 +680,8 @@ int handle_packet_expire_indirect(struct
return 1;
}
+ pthread_cleanup_push(free_pending_args, mt);
+ pthread_cleanup_push(pending_cond_destroy, mt);
pthread_cleanup_push(expire_mutex_unlock, NULL);
pthread_setcancelstate(state, NULL);
@@ -696,6 +696,8 @@ int handle_packet_expire_indirect(struct
}
pthread_cleanup_pop(1);
+ pthread_cleanup_pop(1);
+ pthread_cleanup_pop(1);
return 0;
}

View File

@ -1,74 +0,0 @@
diff -up autofs-5.0.3/daemon/direct.c.expire-works-too-hard autofs-5.0.3/daemon/direct.c
--- autofs-5.0.3/daemon/direct.c.expire-works-too-hard 2008-01-14 13:39:16.000000000 +0900
+++ autofs-5.0.3/daemon/direct.c 2008-02-25 08:48:08.000000000 +0900
@@ -808,7 +808,7 @@ static int expire_direct(int ioctlfd, co
if (fstat(ioctlfd, &st) == -1) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- error(logopt, "fstat failed: %s", estr);
+ debug(logopt, "fstat failed: %s", estr);
return 0;
}
@@ -824,11 +824,16 @@ static int expire_direct(int ioctlfd, co
if (errno == EBADF || errno == EINVAL)
return 1;
- /* Other than need to wait for the kernel ? */
- if (errno != EAGAIN)
- return 0;
+ /*
+ * Other than EAGAIN is an expire error so continue.
+ * Kernel try the same mount again, limited by
+ * retries (ie. number of mounts directly under
+ * mount point, should always be one for direct
+ * mounts).
+ */
+ if (errno == EAGAIN)
+ break;
}
-
nanosleep(&tm, NULL);
}
diff -up autofs-5.0.3/daemon/indirect.c.expire-works-too-hard autofs-5.0.3/daemon/indirect.c
--- autofs-5.0.3/daemon/indirect.c.expire-works-too-hard 2008-01-14 13:39:16.000000000 +0900
+++ autofs-5.0.3/daemon/indirect.c 2008-02-25 08:48:53.000000000 +0900
@@ -328,7 +328,7 @@ static int expire_indirect(struct autofs
if (fstat(ioctlfd, &st) == -1) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- error(ap->logopt, "fstat failed: %s", estr);
+ debug(ap->logopt, "fstat failed: %s", estr);
return 0;
}
@@ -344,11 +344,13 @@ static int expire_indirect(struct autofs
if (errno == EBADF || errno == EINVAL)
return 1;
- /* Other than need to wait for the kernel ? */
- if (errno != EAGAIN)
- return 0;
+ /*
+ * Other than EAGAIN is an expire error so continue.
+ * Kernel will try the next mount.
+ */
+ if (errno == EAGAIN)
+ break;
}
-
nanosleep(&tm, NULL);
}
diff -up autofs-5.0.3/CHANGELOG.expire-works-too-hard autofs-5.0.3/CHANGELOG
--- autofs-5.0.3/CHANGELOG.expire-works-too-hard 2008-02-25 08:44:54.000000000 +0900
+++ autofs-5.0.3/CHANGELOG 2008-02-25 08:48:08.000000000 +0900
@@ -6,6 +6,7 @@
- avoid using UDP for probing NFSv4 mount requests.
- use libldap instead of libldap_r (Guillaume Rousse).
- another fix for don't fail on empty master map.
+- fix expire working harder than needed.
14/01/2008 autofs-5.0.3
-----------------------

View File

@ -1,48 +0,0 @@
autofs-5.0.3 - fix bad alloca usage
From: Ian Kent <raven@themaw.net>
In the lookup_ghost() function alloca is used within a loop which can
lead to stack overflow.
---
daemon/lookup.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- autofs-5.0.3.orig/daemon/lookup.c
+++ autofs-5.0.3/daemon/lookup.c
@@ -608,7 +608,7 @@ int lookup_ghost(struct autofs_point *ap
goto next;
}
- fullpath = alloca(strlen(me->key) + strlen(root) + 3);
+ fullpath = malloc(strlen(me->key) + strlen(root) + 3);
if (!fullpath) {
warn(ap->logopt, "failed to allocate full path");
goto next;
@@ -619,6 +619,7 @@ int lookup_ghost(struct autofs_point *ap
if (ret == -1 && errno != ENOENT) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
warn(ap->logopt, "stat error %s", estr);
+ free(fullpath);
goto next;
}
@@ -627,6 +628,7 @@ int lookup_ghost(struct autofs_point *ap
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
warn(ap->logopt,
"mkdir_path %s failed: %s", fullpath, estr);
+ free(fullpath);
goto next;
}
@@ -634,6 +636,8 @@ int lookup_ghost(struct autofs_point *ap
me->dev = st.st_dev;
me->ino = st.st_ino;
}
+
+ free(fullpath);
next:
me = cache_enumerate(mc, me);
}

View File

@ -1,69 +0,0 @@
autofs-5.0.3 - fix a couple of memory leaks
From: Ian Kent <raven@themaw.net>
---
CHANGELOG | 2 ++
daemon/lookup.c | 5 ++++-
modules/parse_sun.c | 14 ++++++++++----
3 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 82b080c..5901c75 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -21,6 +21,8 @@
- additional fix incorrect pthreads condition handling for mount requests.
- allow mount point directory creation for clients with an NFS root.
- fix direct mount path length not being checked.
+- fix incorrect if check in get user info.
+- fix couple of memory leaks.
14/01/2008 autofs-5.0.3
-----------------------
diff --git a/daemon/lookup.c b/daemon/lookup.c
index eac6053..29a1491 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -996,8 +996,11 @@ int lookup_prune_cache(struct autofs_point *ap, time_t age)
key = strdup(me->key);
me = cache_enumerate(mc, me);
- if (!key || *key == '*')
+ if (!key || *key == '*') {
+ if (key)
+ free(key);
continue;
+ }
path = make_fullpath(ap->path, key);
if (!path) {
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 4241f16..d839694 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -462,11 +462,17 @@ static char *concat_options(char *left, char *right)
char buf[MAX_ERR_BUF];
char *ret;
- if (left == NULL || *left == '\0')
- return strdup(right);
+ if (left == NULL || *left == '\0') {
+ ret = strdup(right);
+ free(right);
+ return ret;
+ }
- if (right == NULL || *right == '\0')
- return strdup(left);
+ if (right == NULL || *right == '\0') {
+ ret = strdup(left);
+ free(left);
+ return ret;
+ }
ret = malloc(strlen(left) + strlen(right) + 2);

View File

@ -1,39 +0,0 @@
autofs-5.0.3 - fix fd leak at multi-mount fail
From: Ian Kent <raven@themaw.net>
Fix file handle being left open following a multi-mount non-fatal mount
fail.
---
daemon/direct.c | 12 ++++++++++--
1 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/daemon/direct.c b/daemon/direct.c
index 13f572c..b94601a 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -1303,12 +1303,20 @@ static void *do_mount_direct(void *arg)
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
if (status) {
struct mapent *me;
+ struct statfs fs;
+ unsigned int close_fd = 0;
+
+ if (statfs(mt.name, &fs) == -1 ||
+ (fs.f_type == AUTOFS_SUPER_MAGIC &&
+ !master_find_submount(ap, mt.name)))
+ close_fd = 1;
cache_writelock(mt.mc);
- me = cache_lookup_distinct(mt.mc, mt.name);
- if (me)
+ if (!close_fd && (me = cache_lookup_distinct(mt.mc, mt.name)))
me->ioctlfd = mt.ioctlfd;
send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token);
cache_unlock(mt.mc);
+ if (close_fd)
+ close(mt.ioctlfd);
info(ap->logopt, "mounted %s", mt.name);
} else {
send_fail(ap->logopt, mt.ioctlfd, mt.wait_queue_token);

View File

@ -1,38 +0,0 @@
autofs-5.0.3 - fix incorrect if check in get user info
From: Ian Kent <raven@themaw.net>
Fix an if statement checking the wrong value in the get user info code.
---
daemon/direct.c | 2 +-
daemon/indirect.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/daemon/direct.c b/daemon/direct.c
index 98590ec..072ef97 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -1337,7 +1337,7 @@ static void *do_mount_direct(void *arg)
}
tsv->home = strdup(pw.pw_dir);
- if (!tsv->user) {
+ if (!tsv->home) {
error(ap->logopt, "failed to malloc buffer for home");
free(pw_tmp);
free(tsv->user);
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 9f22ec9..ccdd8bf 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -768,7 +768,7 @@ static void *do_mount_indirect(void *arg)
}
tsv->home = strdup(pw.pw_dir);
- if (!tsv->user) {
+ if (!tsv->home) {
error(ap->logopt, "failed to malloc buffer for home");
free(pw_tmp);
free(tsv->user);

View File

@ -1,59 +0,0 @@
autofs-5.0.3 - fix ifc buff size fix 2
From: Ian Kent <raven@themaw.net>
For the case of a large number of interfaces there can be
a lot of malloc(3)s for every mount which could slow things
down. So we remember the maximum allocation size and use it
in subsequent allocations.
---
modules/replicated.c | 12 ++++++++++--
1 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/modules/replicated.c b/modules/replicated.c
index 35a6675..b435f4b 100644
--- a/modules/replicated.c
+++ b/modules/replicated.c
@@ -62,7 +62,10 @@
#ifndef MAX_ERR_BUF
#define MAX_ERR_BUF 512
#endif
+
#define MAX_IFC_BUF 2048
+static int volatile ifc_buf_len = MAX_IFC_BUF;
+static int volatile ifc_last_len = 0;
#define MASK_A 0x7F000000
#define MASK_B 0xBFFF0000
@@ -97,7 +100,7 @@ void seed_random(void)
static int alloc_ifreq(struct ifconf *ifc, int sock)
{
- int ret, lastlen = 0, len = MAX_IFC_BUF;
+ int ret, lastlen = ifc_last_len, len = ifc_buf_len;
char err_buf[MAX_ERR_BUF], *buf;
while (1) {
@@ -119,7 +122,7 @@ static int alloc_ifreq(struct ifconf *ifc, int sock)
return 0;
}
- if (ifc->ifc_len == lastlen)
+ if (ifc->ifc_len <= lastlen)
break;
lastlen = ifc->ifc_len;
@@ -127,6 +130,11 @@ static int alloc_ifreq(struct ifconf *ifc, int sock)
free(buf);
}
+ if (lastlen != ifc_last_len) {
+ ifc_last_len = lastlen;
+ ifc_buf_len = len;
+ }
+
return 1;
}

View File

@ -1,144 +0,0 @@
autofs-5.0.3 - fix interface config buffer size
From: Ian Kent <raven@themaw.net>
When getting the interface configuration information autofs uses a
fixed size buffer for the interface information. If there are many
interfaces this causes the check to fail.
---
CHANGELOG | 1 +
modules/replicated.c | 51 ++++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 44 insertions(+), 8 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index d2fe0a6..5b0f265 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -34,6 +34,7 @@
- update replicated server selection documentation.
- use /dev/urandom instead of /dev/random.
- check for mtab pointing to /proc/mounts.
+- dynamically allocate interface config buffer.
14/01/2008 autofs-5.0.3
-----------------------
diff --git a/modules/replicated.c b/modules/replicated.c
index 362ab1b..ad1ede2 100644
--- a/modules/replicated.c
+++ b/modules/replicated.c
@@ -95,6 +95,41 @@ void seed_random(void)
return;
}
+static int alloc_ifreq(struct ifconf *ifc, int sock)
+{
+ int ret, lastlen = 0, len = MAX_IFC_BUF;
+ char err_buf[MAX_ERR_BUF], *buf;
+
+ while (1) {
+ buf = malloc(len);
+ if (!buf) {
+ char *estr = strerror_r(errno, err_buf, MAX_ERR_BUF);
+ logerr("malloc: %s", estr);
+ return 0;
+ }
+
+ ifc->ifc_len = len;
+ ifc->ifc_req = (struct ifreq *) buf;
+
+ ret = ioctl(sock, SIOCGIFCONF, ifc);
+ if (ret == -1) {
+ char *estr = strerror_r(errno, err_buf, MAX_ERR_BUF);
+ logerr("ioctl: %s", estr);
+ free(buf);
+ return 0;
+ }
+
+ if (ifc->ifc_len == lastlen)
+ break;
+
+ lastlen = ifc->ifc_len;
+ len += MAX_IFC_BUF;
+ free(buf);
+ }
+
+ return 1;
+}
+
static unsigned int get_proximity(const char *host_addr, int addr_len)
{
struct sockaddr_in *msk_addr, *if_addr;
@@ -122,12 +157,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len)
fcntl(sock, F_SETFD, cl_flags);
}
- ifc.ifc_len = sizeof(buf);
- ifc.ifc_req = (struct ifreq *) buf;
- ret = ioctl(sock, SIOCGIFCONF, &ifc);
- if (ret == -1) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- logerr("ioctl: %s", estr);
+ if (!alloc_ifreq(&ifc, sock)) {
close(sock);
return PROXIMITY_ERROR;
}
@@ -138,7 +168,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len)
i = 0;
ptr = (char *) &ifc.ifc_buf[0];
- while (ptr < buf + ifc.ifc_len) {
+ while (ptr < (char *) ifc.ifc_req + ifc.ifc_len) {
ifr = (struct ifreq *) ptr;
switch (ifr->ifr_addr.sa_family) {
@@ -147,6 +177,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len)
ret = memcmp(&if_addr->sin_addr, hst_addr, addr_len);
if (!ret) {
close(sock);
+ free(ifc.ifc_req);
return PROXIMITY_LOCAL;
}
break;
@@ -162,7 +193,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len)
i = 0;
ptr = (char *) &ifc.ifc_buf[0];
- while (ptr < buf + ifc.ifc_len) {
+ while (ptr < (char *) ifc.ifc_req + ifc.ifc_len) {
ifr = (struct ifreq *) ptr;
switch (ifr->ifr_addr.sa_family) {
@@ -178,6 +209,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len)
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
logerr("ioctl: %s", estr);
close(sock);
+ free(ifc.ifc_req);
return PROXIMITY_ERROR;
}
@@ -186,6 +218,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len)
if ((ia & mask) == (ha & mask)) {
close(sock);
+ free(ifc.ifc_req);
return PROXIMITY_SUBNET;
}
@@ -208,6 +241,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len)
if ((ia & mask) == (ha & mask)) {
close(sock);
+ free(ifc.ifc_req);
return PROXIMITY_NET;
}
break;
@@ -221,6 +255,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len)
}
close(sock);
+ free(ifc.ifc_req);
return PROXIMITY_OTHER;
}

View File

@ -1,26 +0,0 @@
autofs-5.0.3 - fix fail on included browse map not found
From: Ian Kent <raven@themaw.net>
When looking up nsswitch sources, if nsswitch action check tells us
to continue we need to set the returned result to success so we
don't return a false failure.
---
daemon/lookup.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/daemon/lookup.c b/daemon/lookup.c
index 29a1491..3c22a35 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -545,6 +545,8 @@ int lookup_nss_read_map(struct autofs_point *ap, struct map_source *source, time
map = NULL;
break;
}
+
+ result = NSS_STATUS_SUCCESS;
}
pthread_cleanup_pop(1);

View File

@ -1,32 +0,0 @@
autofs-5.0.3 - fix incorrect multi-mount mountpoint
From: Ian Kent <raven@themaw.net>
Fix case where an incorrect mount point path was being used when
mounting a multi-mount component.
---
modules/parse_sun.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 333f8a5..5a39113 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -1248,8 +1248,14 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
return 1;
}
} else if (rv < 0) {
+ char *mm_root_base = alloca(strlen(mm_root) + strlen(mm_base) + 1);
+
move = MOUNT_MOVE_NONE;
- ret = mount_multi_triggers(ap, me->multi, mm_root, start, mm_base);
+
+ strcpy(mm_root_base, mm_root);
+ strcat(mm_root_base, mm_base);
+
+ ret = mount_multi_triggers(ap, me->multi, mm_root_base, start, mm_base);
if (ret == -1) {
error(ap->logopt, MODPREFIX
"failed to mount offset triggers");

View File

@ -1,33 +0,0 @@
autofs-5.0.3 - fix master map lexer eval order
From: Ian Kent <raven@themaw.net>
Two compound regular expressions in the master map lexical
analyser lack brackets which leads to an evaluation order
error in some versions of flex.
---
lib/master_tok.l | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- autofs-5.0.3.orig/lib/master_tok.l
+++ autofs-5.0.3/lib/master_tok.l
@@ -99,7 +99,7 @@ DNSERVSTR1 ([[:alpha:]][[:alnum:]\-.]*(:
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}
+DNSERVERSTR ({DNSERVSTR1}|{DNSERVSTR2}|{DNSERVSTR3}|{DNSERVSTR4})
AT_CN ([cC][[nN])
AT_NMN ([nN][iI][sS][Mm][aA][pP][Nn][aA][mM][eE])
@@ -108,7 +108,7 @@ AT_OU ([oO][[uU])
AT_DC ([dD][[cC])
AT_O ([oO])
AT_C ([cC])
-DNATTRSTR {AT_CN}|{AT_NMN}|{AT_AMN}|{AT_OU}|{AT_DC}|{AT_O}|{AT_C}
+DNATTRSTR ({AT_CN}|{AT_NMN}|{AT_AMN}|{AT_OU}|{AT_DC}|{AT_O}|{AT_C})
DNNAMESTR1 ([[:alnum:]_.\- ]+)
DNNAMESTR2 ([[:alnum:]_.\-]+)

File diff suppressed because it is too large Load Diff

View File

@ -1,182 +0,0 @@
autofs-5.0.3 - fix multi source messages
From: Ian Kent <raven@themaw.net>
There are incorrect "key not found" messages seen for master map
entries that have multiple sources (direct mounts).
For example, for the direct mount entries:
/- auto.one
/- auto.two
if a mount lookup is done and is not found in auto.one we see a
not found message even though it may be found in auto.two.
This patch moves the "key not found" reporting out to the higher
level lookup and reports status at the end of the lookup.
---
daemon/lookup.c | 3 +++
modules/lookup_file.c | 11 ++---------
modules/lookup_ldap.c | 10 ++--------
modules/lookup_nisplus.c | 12 +++---------
modules/lookup_program.c | 2 +-
modules/lookup_yp.c | 10 ++--------
6 files changed, 13 insertions(+), 35 deletions(-)
diff --git a/daemon/lookup.c b/daemon/lookup.c
index 3c22a35..d33aadc 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -903,6 +903,9 @@ 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);
+
return !result;
}
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index 894f6fd..807ceab 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -1074,7 +1074,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
me = cache_lookup_distinct(mc, key);
if (me && me->status >= time(NULL)) {
cache_unlock(mc);
- return NSS_STATUS_NOTFOUND;
+ return NSS_STATUS_UNAVAIL;
}
cache_unlock(mc);
@@ -1105,11 +1105,6 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
if (status) {
if (status == NSS_STATUS_COMPLETED)
return NSS_STATUS_SUCCESS;
-
- error(ap->logopt,
- MODPREFIX "key \"%s\" not found in map",
- name);
-
return NSS_STATUS_NOTFOUND;
}
}
@@ -1154,9 +1149,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
}
cache_unlock(mc);
}
- } else
- error(ap->logopt,
- MODPREFIX "key \"%s\" not found in map.", name);
+ }
if (ret)
return NSS_STATUS_TRYAGAIN;
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 5cc2148..7777e90 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -2586,12 +2586,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
status = check_map_indirect(ap, lkp_key, strlen(lkp_key), ctxt);
free(lkp_key);
- if (status) {
- error(ap->logopt,
- MODPREFIX "key \"%s\" not found in map",
- name);
+ if (status)
return status;
- }
}
cache_readlock(mc);
@@ -2633,9 +2629,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
}
cache_unlock(mc);
}
- } else
- error(ap->logopt,
- MODPREFIX "key \"%s\" not found in map", name);
+ }
if (ret)
return NSS_STATUS_TRYAGAIN;
diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
index 3c19fd3..4666161 100644
--- a/modules/lookup_nisplus.c
+++ b/modules/lookup_nisplus.c
@@ -520,12 +520,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
ap->entry->current = source;
status = check_map_indirect(ap, lkp_key, strlen(lkp_key), ctxt);
- if (status) {
- error(ap->logopt,
- MODPREFIX "key \"%s\" not found in map",
- name);
+ if (status)
return status;
- }
}
cache_readlock(mc);
@@ -566,12 +562,10 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
}
cache_unlock(mc);
}
- } else
- error(ap->logopt,
- MODPREFIX "key \"%s\" not found in map", name);
+ }
if (ret)
- return NSS_STATUS_NOTFOUND;
+ return NSS_STATUS_TRYAGAIN;
return NSS_STATUS_SUCCESS;
}
diff --git a/modules/lookup_program.c b/modules/lookup_program.c
index 7c266d6..daf874d 100644
--- a/modules/lookup_program.c
+++ b/modules/lookup_program.c
@@ -390,7 +390,7 @@ out_free:
me->status = now + ap->negative_timeout;
}
cache_unlock(mc);
- return NSS_STATUS_UNAVAIL;
+ return NSS_STATUS_TRYAGAIN;
}
return NSS_STATUS_SUCCESS;
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
index 14f981c..ee06551 100644
--- a/modules/lookup_yp.c
+++ b/modules/lookup_yp.c
@@ -626,12 +626,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
status = check_map_indirect(ap, lkp_key, strlen(lkp_key), ctxt);
free(lkp_key);
- if (status) {
- error(ap->logopt,
- MODPREFIX "key \"%s\" not found in map",
- name);
+ if (status)
return status;
- }
}
cache_readlock(mc);
@@ -672,9 +668,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
}
cache_unlock(mc);
}
- } else
- error(ap->logopt,
- MODPREFIX "key \"%s\" not found in map", name);
+ }
if (ret)
return NSS_STATUS_TRYAGAIN;

View File

@ -1,28 +0,0 @@
autofs-5.0.3 - fix nfs4 colon escape handling
From: Ian Kent <raven@themaw.net>
When fstype=nfs4 is given for a mount entry that should be bind
mounted because it has a ":" escaped location the colon can be
discarded before the mount module is called. This causes an
incorrect mount fail return since the replicated selection code
expects the colon to be present for parsing.
---
modules/parse_sun.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index b548520..333f8a5 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -638,7 +638,7 @@ static int sun_mount(struct autofs_point *ap, const char *root,
}
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
- if (!strcmp(fstype, "nfs")) {
+ if (!strcmp(fstype, "nfs") || !strcmp(fstype, "nfs4")) {
what = alloca(loclen + 1);
memcpy(what, loc, loclen);
what[loclen] = '\0';

View File

@ -1,369 +0,0 @@
From jmoyer@redhat.com Thu Jul 17 10:12:13 2008
From: Ian Kent <raven@themaw.net>
Hi, Ian,
As I mentioned, the encode and decode routines for the % hack were
corrupting heap space. I put together a patch to fix things as they
stand today. The comments document the assumptions I made.
I tested this code by compiling a program that only included
these functions and passing them arbitrary input and validating the
reuslts. I then compiled them into the automounter and verified that
no heap corruption occurred (by running automount -f on a fedora
system where such things are reported).
Now, I don't think that we should ever have to encode the percent
hack. Shouldn't we just need to decode it, walking through all of the
returned entries until we find an exact match for the key being looked
up?
Comments welcome.
IMK: You're right, but we'll keep it for the moment.
Cheers,
Jeff
---
modules/lookup_ldap.c | 267 +++++++++++++++++++++++++++++++++++--------------
1 files changed, 193 insertions(+), 74 deletions(-)
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 7777e90..3990f8c 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -1512,6 +1512,65 @@ next:
return NSS_STATUS_SUCCESS;
}
+static int get_percent_decoded_len(const char *name)
+{
+ int escapes = 0;
+ int escaped = 0;
+ char *tmp = name;
+ int look_for_close = 0;
+
+ while (*tmp) {
+ if (*tmp == '%') {
+ /* assume escapes aren't interpreted inside brackets */
+ if (look_for_close) {
+ tmp++;
+ continue;
+ }
+ /* check for escaped % */
+ if (escaped) {
+ tmp++;
+ escaped = 0;
+ continue;
+ }
+ escapes++;
+ tmp++;
+ if (*tmp == '[') {
+ escapes++;
+ tmp++;
+ look_for_close = 1;
+ } else
+ escaped = 1;
+ } else if (*tmp == ']' && look_for_close) {
+ escaped = 0;
+ escapes++;
+ tmp++;
+ look_for_close = 0;
+ } else {
+ tmp++;
+ escaped = 0;
+ }
+ }
+
+ assert(strlen(name) > escapes);
+ return strlen(name) - escapes;
+}
+
+/*
+ * Try to catch heap corruption if our logic happens to be incorrect.
+ */
+static void validate_string_len(const char *orig, char *start,
+ char *end, unsigned int len)
+{
+ debug(LOGOPT_NONE, MODPREFIX "string %s encoded as %s", orig, start);
+ /* make sure we didn't overflow the allocated space */
+ if (end - start > len + 1) {
+ crit(LOGOPT_ANY, MODPREFIX "orig %s, len %d", orig, len);
+ crit(LOGOPT_ANY, MODPREFIX "en/decoded %s, len %d", start,
+ end - start);
+ }
+ assert(end-start <= len + 1);
+}
+
/*
* Deal with encode and decode of % hack.
* Return
@@ -1519,131 +1578,191 @@ next:
* -1 => syntax error or alloc fail.
* 1 transofrmed value returned.
*/
+/*
+ * Assumptions: %'s must be escaped by %'s. %'s are not used to escape
+ * anything else except capital letters (so you can't escape a closing
+ * bracket, for example).
+ */
static int decode_percent_hack(const char *name, char **key)
{
const char *tmp;
char *ptr, *new;
+ unsigned int len;
+ int escaped = 0, look_for_close = 0;
if (!key)
return -1;
*key = NULL;
- tmp = name;
- while (*tmp && *tmp != '%' && *tmp != '[' && *tmp != ']')
- tmp++;
- if (!*tmp)
- return 0;
+ len = get_percent_decoded_len(name);
+ new = malloc(len + 1);
+ if (!new)
+ return -1;
+ ptr = new;
tmp = name;
while (*tmp) {
if (*tmp == '%') {
- tmp++;
- if (!*tmp)
- return -1;
- if (*tmp != '[')
+ if (escaped) {
+ *ptr++ = *tmp++;
+ if (!look_for_close)
+ escaped = 0;
continue;
+ }
tmp++;
- while (*tmp && *tmp != ']') {
- if (*tmp == '%')
- tmp++;
+ if (*tmp == '[') {
tmp++;
- }
- if (!tmp)
- return -1;
- }
- tmp++;
- }
-
- new = malloc(strlen(name) + 1);
- if (!new)
- return -1;
-
- ptr = new;
- tmp = name;
- while (*tmp) {
- if (*tmp == '%' || *tmp == '[' || *tmp == ']') {
+ look_for_close = 1;
+ escaped = 1;
+ } else
+ escaped = 1;
+ } else if (*tmp == ']' && look_for_close) {
tmp++;
- if (*tmp && *tmp != '%')
- continue;
+ look_for_close = 0;
+ } else {
+ escaped = 0;
+ *ptr++ = *tmp++;
}
- *ptr++ = *tmp++;
}
*ptr = '\0';
-
*key = new;
+ validate_string_len(name, new, ptr, len);
return strlen(new);
}
-static int encode_percent_hack(const char *name, char **key, unsigned int use_class)
+/*
+ * Calculate the length of a string replacing all capital letters with %letter.
+ * For example:
+ * Sale -> %Sale
+ * SALE -> %S%A%L%E
+ */
+static int get_encoded_len_escaping_every_cap(const char *name)
{
const char *tmp;
- unsigned int len = 0;
- char *ptr, *new;
+ unsigned int escapes = 0; /* number of % escape characters */
- if (!key)
- return -1;
+ tmp = name;
+ while (*tmp) {
+ /* We'll need to escape percents */
+ if (*tmp == '%' || isupper(*tmp))
+ escapes++;
+ tmp++;
+ }
- *key = NULL;
+ return strlen(name) + escapes;
+}
+
+/*
+ * Calculate the length of a string replacing sequences (1 or more) of capital
+ * letters with %[letters]. For example:
+ * FOO -> %[FOO]
+ * Work -> %[W]ork
+ * WorksForMe -> %[W]orks%[F]or%[M]e
+ * aaBBaa -> aa%[BB]aa
+ */
+static int get_encoded_len_escaping_sequences(const char *name)
+{
+ const char *tmp;
+ unsigned int escapes = 0;
tmp = name;
while (*tmp) {
+ /* escape percents */
if (*tmp == '%')
- len++;
+ escapes++;
else if (isupper(*tmp)) {
- tmp++;
- len++;
- if (!use_class)
- len++;
- else {
- if (*tmp && isupper(*tmp))
- len += 2;
- else
- return 0;
- while (*tmp && isupper(*tmp)) {
- len++;
- tmp++;
- }
- }
+ /* start an escape block %[...] */
+ escapes += 3; /* %[] */
+ while (*tmp && isupper(*tmp))
+ tmp++;
continue;
}
- len++;
tmp++;
}
- if (len == strlen(name))
- return 0;
- new = malloc(len + 1);
- if (!new)
- return -1;
+ return strlen(name) + escapes;
+}
+
+static void encode_individual(const char *name, char *new, unsigned int len)
+{
+ const char *tmp;
+ char *ptr;
ptr = new;
tmp = name;
while (*tmp) {
- if (*tmp == '%')
+ if (*tmp == '%' || isupper(*tmp))
*ptr++ = '%';
- else if (isupper(*tmp)) {
- char next = *tmp++;
+ *ptr++ = *tmp++;
+ }
+ *ptr = '\0';
+ validate_string_len(name, new, ptr, len);
+}
+
+static void encode_sequence(const char *name, char *new, unsigned int len)
+{
+ const char *tmp;
+ char *ptr;
+
+ ptr = new;
+ tmp = name;
+ while (*tmp) {
+ if (*tmp == '%') {
*ptr++ = '%';
- if (*tmp && (!isupper(*tmp) || !use_class))
- *ptr++ = next;
- else {
- *ptr++ = '[';
- *ptr++ = next;
- while (*tmp && isupper(*tmp))
- *ptr++ = *tmp++;
- *ptr++ = ']';
+ *ptr++ = *tmp++;
+ } else if (isupper(*tmp)) {
+ *ptr++ = '%';
+ *ptr++ = '[';
+ *ptr++ = *tmp++;
+
+ while (*tmp && isupper(*tmp)) {
+ *ptr++ = *tmp;
+ tmp++;
}
- continue;
- }
- *ptr++ = *tmp++;
+ *ptr++ = ']';
+ } else
+ *ptr++ = *tmp++;
}
*ptr = '\0';
+ validate_string_len(name, new, ptr, len);
+}
- *key = new;
+/*
+ * use_class: 1 means encode string as %[CAPITALS], 0 means encode as
+ * %C%A%P%I%T%A%L%S
+ */
+static int encode_percent_hack(const char *name, char **key, unsigned int use_class)
+{
+ unsigned int len = 0;
- return strlen(new);
+ if (!key)
+ return -1;
+
+ if (use_class)
+ len = get_encoded_len_escaping_sequences(name);
+ else
+ len = get_encoded_len_escaping_every_cap(name);
+
+ /* If there is no escaping to be done, return 0 */
+ if (len == strlen(name))
+ return 0;
+
+ *key = malloc(len + 1);
+ if (!*key)
+ return -1;
+
+ if (use_class)
+ encode_sequence(name, *key, len);
+ else
+ encode_individual(name, *key, len);
+
+ if (strlen(*key) != len)
+ crit(LOGOPT_ANY, MODPREFIX "encoded key length mismatch: key "
+ "%s len %d strlen %d", *key, len, strlen(*key));
+
+ return strlen(*key);
}
static int do_paged_query(struct ldap_search_params *sp, struct lookup_context *ctxt)

View File

@ -1,36 +0,0 @@
autofs-5.0.3 - fix proximity other rpc ping timeout
From: Ian Kent <raven@themaw.net>
The timeout for the RCP ping for hosts that are on a network other
than the local subnet or network is mistakenly set quite short. This
can lead to unexplained intermittent failures for hosts on remote
networks.
---
modules/replicated.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/modules/replicated.c b/modules/replicated.c
index efbe6b4..925f641 100644
--- a/modules/replicated.c
+++ b/modules/replicated.c
@@ -552,7 +552,7 @@ static int get_vers_and_cost(unsigned logopt, struct host *host,
if (host->proximity == PROXIMITY_NET)
timeout = RPC_TIMEOUT * 2;
- else if (host->proximity == PROXIMITY_NET)
+ else if (host->proximity == PROXIMITY_OTHER)
timeout = RPC_TIMEOUT * 8;
rpc_info.host = host->name;
@@ -609,7 +609,7 @@ static int get_supported_ver_and_cost(unsigned logopt, struct host *host,
if (host->proximity == PROXIMITY_NET)
timeout = RPC_TIMEOUT * 2;
- else if (host->proximity == PROXIMITY_NET)
+ else if (host->proximity == PROXIMITY_OTHER)
timeout = RPC_TIMEOUT * 8;
rpc_info.host = host->name;

View File

@ -1,36 +0,0 @@
autofs-5.0.3 - don't close direct root
From: Ian Kent <raven@themaw.net>
For direct mount multi-mounts with no real mount at their base we
need to leave the file handle open so they will be expired. This
patch corrects the check done at mount completion to do this so
they will be expired.
---
daemon/direct.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
--- autofs-5.0.3.orig/daemon/direct.c
+++ autofs-5.0.3/daemon/direct.c
@@ -1311,8 +1311,17 @@ static void *do_mount_direct(void *arg)
!master_find_submount(ap, mt.name)))
close_fd = 1;
cache_writelock(mt.mc);
- if (!close_fd && (me = cache_lookup_distinct(mt.mc, mt.name)))
- me->ioctlfd = mt.ioctlfd;
+ if ((me = cache_lookup_distinct(mt.mc, mt.name))) {
+ /*
+ * Careful here, we need to leave the file handle open
+ * for direct mount multi-mounts with no real mount at
+ * their base so they will be expired.
+ */
+ if (close_fd && me == me->multi)
+ close_fd = 0;
+ if (!close_fd)
+ me->ioctlfd = mt.ioctlfd;
+ }
send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token);
cache_unlock(mt.mc);
if (close_fd)

View File

@ -1,57 +0,0 @@
autofs-5.0.3 - handle zero length nis key update
From: Ian Kent <raven@themaw.net>
A zero length key is invalid but so is a single character
non-printable key and it causes the parser to get confused
as well.
---
modules/lookup_yp.c | 17 +++++++++++++----
1 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
index ee06551..8b6408b 100644
--- a/modules/lookup_yp.c
+++ b/modules/lookup_yp.c
@@ -19,6 +19,7 @@
#include <unistd.h>
#include <time.h>
#include <signal.h>
+#include <ctype.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -168,9 +169,13 @@ int yp_all_master_callback(int status, char *ypkey, int ypkeylen,
if (status != YP_TRUE)
return status;
- /* Ignore zero length keys */
- if (ypkeylen == 0)
+ /* Ignore zero length and single non-printable char keys */
+ if (ypkeylen == 0 || (ypkeylen == 1 && !isprint(*ypkey))) {
+ warn(logopt, MODPREFIX
+ "ignoring invalid map entry, zero length or "
+ "single character non-printable key");
return 0;
+ }
/*
* Ignore keys beginning with '+' as plus map
@@ -267,9 +272,13 @@ int yp_all_callback(int status, char *ypkey, int ypkeylen,
if (status != YP_TRUE)
return status;
- /* Ignore zero length keys */
- if (ypkeylen == 0)
+ /* Ignore zero length and single non-printable char keys */
+ if (ypkeylen == 0 || (ypkeylen == 1 && !isprint(*ypkey))) {
+ warn(logopt, MODPREFIX
+ "ignoring invalid map entry, zero length or "
+ "single character non-printable key");
return 0;
+ }
/*
* Ignore keys beginning with '+' as plus map

View File

@ -1,36 +0,0 @@
diff -up autofs-5.0.3/CHANGELOG.handle-zero-length-nis-key autofs-5.0.3/CHANGELOG
--- autofs-5.0.3/CHANGELOG.handle-zero-length-nis-key 2008-03-24 14:07:30.000000000 +0900
+++ autofs-5.0.3/CHANGELOG 2008-03-24 14:08:08.000000000 +0900
@@ -8,6 +8,7 @@
- another fix for don't fail on empty master map.
- fix expire working harder than needed.
- fix unlink of mount tree incorrectly causing autofs mount fail.
+- add missing check for zero length NIS key (Wengang Wang).
14/01/2008 autofs-5.0.3
-----------------------
diff -up autofs-5.0.3/modules/lookup_yp.c.handle-zero-length-nis-key autofs-5.0.3/modules/lookup_yp.c
--- autofs-5.0.3/modules/lookup_yp.c.handle-zero-length-nis-key 2008-01-14 13:39:16.000000000 +0900
+++ autofs-5.0.3/modules/lookup_yp.c 2008-03-24 14:07:45.000000000 +0900
@@ -168,6 +168,10 @@ int yp_all_master_callback(int status, c
if (status != YP_TRUE)
return status;
+ /* Ignore zero length keys */
+ if (ypkeylen == 0)
+ return 0;
+
/*
* Ignore keys beginning with '+' as plus map
* inclusion is only valid in file maps.
@@ -263,6 +267,10 @@ int yp_all_callback(int status, char *yp
if (status != YP_TRUE)
return status;
+ /* Ignore zero length keys */
+ if (ypkeylen == 0)
+ return 0;
+
/*
* Ignore keys beginning with '+' as plus map
* inclusion is only valid in file maps.

View File

@ -1,406 +0,0 @@
diff --git a/CHANGELOG b/CHANGELOG
index 624fe9e..98855f5 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,7 @@
+??/??/2008 autofs-5.0.4
+-----------------------
+- correct configure test for ldapr page control functions.
+
14/01/2008 autofs-5.0.3
-----------------------
- include krb5.h in lookup_ldap.h (some openssl doesn't implicitly include it).
diff --git a/aclocal.m4 b/aclocal.m4
index 118ef0d..f24e076 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -222,3 +222,69 @@ AC_TRY_LINK(
LDFLAGS="$af_check_hesiod_save_ldflags"
])
+dnl --------------------------------------------------------------------------
+dnl AF_CHECK_FUNC_LDAP_CREATE_PAGE_CONTROL
+dnl
+dnl Check for function ldap_create_page_control
+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_r"
+
+AC_TRY_LINK(
+ [ #include <ldap.h> ],
+ [ LDAP *ld;
+ ber_int_t ps;
+ struct berval *c;
+ int ic, ret;
+ LDAPControl **clp;
+ ret = ldap_create_page_control(ld,ps,c,ic,clp); ],
+ [ af_have_ldap_create_page_control=yes
+ AC_MSG_RESULT(yes) ],
+ [ AC_MSG_RESULT(no) ])
+
+if test "$af_have_ldap_create_page_control" = "yes"; then
+ AC_DEFINE(HAVE_LDAP_CREATE_PAGE_CONTROL, 1,
+ [Define to 1 if you have the `ldap_create_page_control' function.])
+fi
+
+# restore ldflags
+LDFLAGS="$af_check_ldap_create_page_control_save_ldflags"
+])
+
+dnl --------------------------------------------------------------------------
+dnl AF_CHECK_FUNC_LDAP_PARSE_PAGE_CONTROL
+dnl
+dnl Check for function ldap_parse_page_control
+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_r"
+
+AC_TRY_LINK(
+ [ #include <ldap.h> ],
+ [ LDAP *ld;
+ ber_int_t ct;
+ struct berval *c;
+ int ret;
+ LDAPControl **clp;
+ ret = ldap_parse_page_control(ld,clp,ct,c); ],
+ [ af_have_ldap_parse_page_control=yes
+ AC_MSG_RESULT(yes) ],
+ [ AC_MSG_RESULT(no) ])
+
+if test "$af_have_ldap_create_page_control" = "yes"; then
+ AC_DEFINE(HAVE_LDAP_PARSE_PAGE_CONTROL, 1,
+ [Define to 1 if you have the `ldap_parse_page_control' function.])
+fi
+
+# restore ldflags
+LDFLAGS="$af_check_ldap_parse_page_control_save_ldflags"
+])
+
diff --git a/configure b/configure
index d212b05..e872392 100755
--- a/configure
+++ b/configure
@@ -3631,7 +3631,7 @@ if test "${with_hesiod+set}" = set; then
fi
-if test -z "$HAVE_HESIOD"
+if test -z "$HAVE_HESIOD" -o "$HAVE_HESIOD" != "0"
then
HAVE_HESIOD=0
{ echo "$as_me:$LINENO: checking for libhesiod" >&5
@@ -4498,7 +4498,7 @@ if test "${with_openldap+set}" = set; then
fi
-if test -z "$HAVE_LDAP"; then
+if test -z "$HAVE_LDAP" -o "$HAVE_LDAP" != "0"; then
HAVE_LDAP=0
LDAP_FLAGS="$LDAP_FLAGS -DLDAP_DEPRECATED=1"
{ echo "$as_me:$LINENO: checking for ldap_initialize in -lldap" >&5
@@ -4566,71 +4566,106 @@ if test $ac_cv_lib_ldap_ldap_initialize = yes; then
HAVE_LDAP=1 LIBLDAP="$LIBLDAP -lldap_r -llber -lresolv"
fi
- if test "$HAVE_LDAP" == "1"; then
+ if test "$HAVE_LDAP" = "1"; then
cat >>confdefs.h <<\_ACEOF
#define WITH_LDAP 1
_ACEOF
fi
+ { 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_r"
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+ #include <ldap.h>
+int
+main ()
+{
+ LDAP *ld;
+ ber_int_t ps;
+ struct berval *c;
+ int ic, ret;
+ LDAPControl **clp;
+ ret = ldap_create_page_control(ld,ps,c,ic,clp);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+ af_have_ldap_create_page_control=yes
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
fi
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+if test "$af_have_ldap_create_page_control" = "yes"; then
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LDAP_CREATE_PAGE_CONTROL 1
+_ACEOF
-LDFLAGS="${AF_tmp_ldflags}"
+fi
+# restore ldflags
+LDFLAGS="$af_check_ldap_create_page_control_save_ldflags"
+ { 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; }
-for ac_func in ldap_create_page_control ldap_parse_page_control
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
-if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
+# save current ldflags
+af_check_ldap_parse_page_control_save_ldflags="$LDFLAGS"
+LDFLAGS="$LDFLAGS -lldap_r"
+
+cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined __stub_$ac_func || defined __stub___$ac_func
-choke me
-#endif
-
+ #include <ldap.h>
int
main ()
{
-return $ac_func ();
+ LDAP *ld;
+ ber_int_t ct;
+ struct berval *c;
+ int ret;
+ LDAPControl **clp;
+ ret = ldap_parse_page_control(ld,clp,ct,c);
;
return 0;
}
@@ -4653,28 +4688,37 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
test ! -s conftest.err
} && test -s conftest$ac_exeext &&
$as_test_x conftest$ac_exeext; then
- eval "$as_ac_var=yes"
+ af_have_ldap_parse_page_control=yes
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
- eval "$as_ac_var=no"
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
conftest$ac_exeext conftest.$ac_ext
-fi
-ac_res=`eval echo '${'$as_ac_var'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_var'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+
+if test "$af_have_ldap_create_page_control" = "yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LDAP_PARSE_PAGE_CONTROL 1
_ACEOF
fi
-done
+# restore ldflags
+LDFLAGS="$af_check_ldap_parse_page_control_save_ldflags"
+
+fi
+
+
+
+
+LDFLAGS="${AF_tmp_ldflags}"
#
# SASL support
@@ -4703,7 +4747,7 @@ if test "${with_sasl+set}" = set; then
fi
-if test -z "$HAVE_SASL" -a "$HAVE_LIBXML" == "1"
+if test -z "$HAVE_SASL" -o "$HAVE_SASL" != "0" -a "$HAVE_LIBXML" == "1"
then
HAVE_SASL=0
{ echo "$as_me:$LINENO: checking for sasl_client_start in -lsasl2" >&5
diff --git a/configure.in b/configure.in
index 952d040..a9c86dd 100644
--- a/configure.in
+++ b/configure.in
@@ -155,7 +155,7 @@ AC_ARG_WITH(hesiod,
fi
)
-if test -z "$HAVE_HESIOD"
+if test -z "$HAVE_HESIOD" -o "$HAVE_HESIOD" != "0"
then
HAVE_HESIOD=0
AF_CHECK_LIBHESIOD()
@@ -194,15 +194,17 @@ AC_ARG_WITH(openldap,
LDAP_FLAGS="-I${withval}/include"
fi
)
-if test -z "$HAVE_LDAP"; then
+if test -z "$HAVE_LDAP" -o "$HAVE_LDAP" != "0"; then
HAVE_LDAP=0
LDAP_FLAGS="$LDAP_FLAGS -DLDAP_DEPRECATED=1"
AC_CHECK_LIB(ldap, ldap_initialize, HAVE_LDAP=1 LIBLDAP="$LIBLDAP -lldap_r -llber -lresolv", ,
-llber -lresolv $LIBS)
- if test "$HAVE_LDAP" == "1"; then
+ if test "$HAVE_LDAP" = "1"; then
AC_DEFINE(WITH_LDAP,1,
[Define if using LDAP as a source of automount maps])
fi
+ AF_CHECK_FUNC_LDAP_CREATE_PAGE_CONTROL()
+ AF_CHECK_FUNC_LDAP_PARSE_PAGE_CONTROL()
fi
AC_SUBST(LDAP_FLAGS)
@@ -210,8 +212,6 @@ AC_SUBST(HAVE_LDAP)
AC_SUBST(LIBLDAP)
LDFLAGS="${AF_tmp_ldflags}"
-AC_CHECK_FUNCS(ldap_create_page_control ldap_parse_page_control)
-
#
# SASL support
# configure magic taken from:
@@ -236,7 +236,7 @@ AC_ARG_WITH(sasl,
SASL_FLAGS="-I${withval}/include"
fi
)
-if test -z "$HAVE_SASL" -a "$HAVE_LIBXML" == "1"
+if test -z "$HAVE_SASL" -o "$HAVE_SASL" != "0" -a "$HAVE_LIBXML" == "1"
then
HAVE_SASL=0
AC_CHECK_LIB(sasl2, sasl_client_start, HAVE_SASL=1 LIBSASL="$LIBSASL -lsasl2", , -lsasl2 $LIBS)
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 0723fd8..e8530f6 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -55,7 +55,7 @@ struct ldap_search_params {
char *query, **attrs;
struct berval *cookie;
int morePages;
- unsigned int totalCount;
+ ber_int_t totalCount;
LDAPMessage *result;
time_t age;
};
@@ -63,7 +63,7 @@ struct ldap_search_params {
static LDAP *auth_init(unsigned logopt, const char *, struct lookup_context *);
#ifndef HAVE_LDAP_CREATE_PAGE_CONTROL
-int ldap_create_page_control(LDAP *ldap, unsigned int pagesize,
+int ldap_create_page_control(LDAP *ldap, ber_int_t pagesize,
struct berval *cookie, char isCritical,
LDAPControl **output)
{
@@ -93,7 +93,7 @@ int ldap_create_page_control(LDAP *ldap, unsigned int pagesize,
#ifndef HAVE_LDAP_PARSE_PAGE_CONTROL
int ldap_parse_page_control(LDAP *ldap, LDAPControl **controls,
- unsigned int *totalcount, struct berval **cookie)
+ ber_int_t *totalcount, struct berval **cookie)
{
int i, rc;
BerElement *theBer;
@@ -1644,7 +1644,7 @@ static int do_paged_query(struct ldap_search_params *sp, struct lookup_context *
struct autofs_point *ap = sp->ap;
LDAPControl *pageControl=NULL, *controls[2] = { NULL, NULL };
LDAPControl **returnedControls = NULL;
- static unsigned long pageSize = 1000;
+ static ber_int_t pageSize = 1000;
static char pagingCriticality = 'T';
int rv, scope = LDAP_SCOPE_SUBTREE;

View File

@ -1,164 +0,0 @@
autofs-5.0.3 - library reload fix
From: Ian Kent <raven@themaw.net>
During a map re-read autofs needs to re-open its lookup libraries but
dependent shared libraries can't handle being unloaded and then re-loaded
by the same process. This patch preventis dependent libraries from being
unloaded during this re-open.
---
daemon/automount.c | 1 -
daemon/lookup.c | 21 +++++++++------------
daemon/state.c | 3 +++
include/master.h | 17 +++--------------
lib/master.c | 28 ++++++++++++++++++++++------
5 files changed, 37 insertions(+), 33 deletions(-)
--- autofs-5.0.3.orig/daemon/automount.c
+++ autofs-5.0.3/daemon/automount.c
@@ -85,7 +85,6 @@ int aquire_flag_file(void);
void release_flag_file(void);
static int umount_all(struct autofs_point *ap, int force);
-extern pthread_mutex_t master_mutex;
extern struct master *master_list;
static int do_mkdir(const char *parent, const char *path, mode_t mode)
--- autofs-5.0.3.orig/daemon/lookup.c
+++ autofs-5.0.3/daemon/lookup.c
@@ -267,17 +267,17 @@ static int do_read_map(struct autofs_poi
struct lookup_mod *lookup;
int status;
- if (!map->lookup) {
- lookup = open_lookup(map->type, "",
- map->format, map->argc, map->argv);
- if (!lookup) {
- debug(ap->logopt, "lookup module %s failed", map->type);
- return NSS_STATUS_UNAVAIL;
- }
- map->lookup = lookup;
+ lookup = open_lookup(map->type, "", map->format, map->argc, map->argv);
+ if (!lookup) {
+ debug(ap->logopt, "lookup module %s failed", map->type);
+ return NSS_STATUS_UNAVAIL;
}
- lookup = map->lookup;
+ master_source_writelock(ap->entry);
+ if (map->lookup)
+ close_lookup(map->lookup);
+ 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
@@ -463,8 +463,6 @@ int lookup_nss_read_map(struct autofs_po
* point in the master map) do the nss lookup to
* locate the map and read it.
*/
- pthread_cleanup_push(master_source_lock_cleanup, entry);
- master_source_readlock(entry);
if (source)
map = source;
else
@@ -557,7 +555,6 @@ int lookup_nss_read_map(struct autofs_po
map = map->next;
}
- pthread_cleanup_pop(1);
if (!result || at_least_one)
return 1;
--- autofs-5.0.3.orig/daemon/state.c
+++ autofs-5.0.3/daemon/state.c
@@ -387,9 +387,12 @@ static void *do_readmap(void *arg)
info(ap->logopt, "re-reading map for %s", ap->path);
+ pthread_cleanup_push(master_mutex_lock_cleanup, NULL);
+ master_mutex_lock();
status = lookup_nss_read_map(ap, NULL, now);
if (!status)
pthread_exit(NULL);
+ pthread_cleanup_pop(1);
if (ap->type == LKP_INDIRECT) {
lookup_prune_cache(ap, now);
--- autofs-5.0.3.orig/include/master.h
+++ autofs-5.0.3/include/master.h
@@ -70,6 +70,9 @@ int master_parse_entry(const char *, uns
/* From master.c master parser utility routines */
+void master_mutex_lock(void);
+void master_mutex_unlock(void);
+void master_mutex_lock_cleanup(void *);
void master_set_default_timeout(void);
void master_set_default_ghost_mode(void);
int master_add_autofs_point(struct master_mapent *, time_t, unsigned, unsigned, int);
@@ -108,18 +111,4 @@ extern inline unsigned int master_get_lo
int master_list_empty(struct master *);
int master_kill(struct master *);
-#define master_mutex_lock() \
-do { \
- int status = pthread_mutex_lock(&master_mutex); \
- if (status) \
- fatal(status); \
-} while (0)
-
-#define master_mutex_unlock() \
-do { \
- int status = pthread_mutex_unlock(&master_mutex); \
- if (status) \
- fatal(status); \
-} while (0)
-
#endif
--- autofs-5.0.3.orig/lib/master.c
+++ autofs-5.0.3/lib/master.c
@@ -41,8 +41,28 @@ static struct map_source *
__master_find_map_source(struct master_mapent *,
const char *, const char *, int, const char **);
-pthread_mutex_t master_mutex = PTHREAD_MUTEX_INITIALIZER;
-pthread_mutex_t instance_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t master_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t instance_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+void master_mutex_lock(void)
+{
+ int status = pthread_mutex_lock(&master_mutex);
+ if (status)
+ fatal(status);
+}
+
+void master_mutex_unlock(void)
+{
+ int status = pthread_mutex_unlock(&master_mutex);
+ if (status)
+ fatal(status);
+}
+
+void master_mutex_lock_cleanup(void *arg)
+{
+ master_mutex_unlock();
+ return;
+}
int master_add_autofs_point(struct master_mapent *entry,
time_t timeout, unsigned logopt, unsigned ghost, int submount)
@@ -1109,10 +1129,6 @@ int master_mount_mounts(struct master *m
continue;
}
- master_source_writelock(ap->entry);
- lookup_close_lookup(ap);
- master_source_unlock(ap->entry);
-
cache_readlock(nc);
ne = cache_lookup_distinct(nc, this->path);
if (ne && this->age > ne->age) {

View File

@ -1,131 +0,0 @@
autofs-5.0.3 - multi-map doesn't pickup NIS updates automatically
From: Ian Kent <raven@themaw.net>
In a multi-map configuration, autofs doesn't pick up NIS updates
automatically. This is caused by the lookup not checking alternate
sources for the given key (or wildcard) when doing a key lookup.
---
CHANGELOG | 1 +
lib/cache.c | 2 ++
modules/lookup_file.c | 11 ++++++++---
modules/lookup_ldap.c | 11 ++++++++---
modules/lookup_nisplus.c | 11 ++++++++---
modules/lookup_yp.c | 11 ++++++++---
6 files changed, 35 insertions(+), 12 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 268fca6..3ed84d3 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -16,6 +16,7 @@
- fix incorrect pthreads condition handling for mount requests.
- add check for exports automatically mounted by NFS kernel client.
- update nsswitch parser to ignore nsswitch sources that aren't supported.
+- check for map key in (possible) alternate map sources when doing lookup.
14/01/2008 autofs-5.0.3
-----------------------
diff --git a/lib/cache.c b/lib/cache.c
index 55586a3..d5abab0 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -700,6 +700,8 @@ int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key
int ret = CHE_OK;
me = cache_lookup(mc, key);
+ while (me && me->source != ms)
+ me = cache_lookup_key_next(me);
if (!me || (*me->key == '*' && *key != '*')) {
ret = cache_add(mc, ms, key, mapent, age);
if (!ret) {
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index 466690a..894f6fd 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -1116,9 +1116,14 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
cache_readlock(mc);
me = cache_lookup(mc, key);
- /* Stale mapent => check for wildcard */
- if (me && !me->mapent)
- me = cache_lookup_distinct(mc, "*");
+ /* Stale mapent => check for entry in alternate source or wildcard */
+ if (me && !me->mapent) {
+ while ((me = cache_lookup_key_next(me)))
+ if (me->source == source)
+ break;
+ if (!me)
+ me = cache_lookup_distinct(mc, "*");
+ }
if (me && (me->source == source || *me->key == '/')) {
pthread_cleanup_push(cache_lock_cleanup, mc);
mapent_len = strlen(me->mapent);
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index ded26f7..5cc2148 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -2596,9 +2596,14 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
cache_readlock(mc);
me = cache_lookup(mc, key);
- /* Stale mapent => check for wildcard */
- if (me && !me->mapent)
- me = cache_lookup_distinct(mc, "*");
+ /* Stale mapent => check for entry in alternate source or wildcard */
+ if (me && !me->mapent) {
+ while ((me = cache_lookup_key_next(me)))
+ if (me->source == source)
+ break;
+ if (!me)
+ me = cache_lookup_distinct(mc, "*");
+ }
if (me && (me->source == source || *me->key == '/')) {
mapent_len = strlen(me->mapent);
mapent = alloca(mapent_len + 1);
diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
index 628ffcf..3c19fd3 100644
--- a/modules/lookup_nisplus.c
+++ b/modules/lookup_nisplus.c
@@ -530,9 +530,14 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
cache_readlock(mc);
me = cache_lookup(mc, key);
- /* Stale mapent => check for wildcard */
- if (me && !me->mapent)
- me = cache_lookup_distinct(mc, "*");
+ /* Stale mapent => check for entry in alternate source or wildcard */
+ if (me && !me->mapent) {
+ while ((me = cache_lookup_key_next(me)))
+ if (me->source == source)
+ break;
+ if (!me)
+ me = cache_lookup_distinct(mc, "*");
+ }
if (me && (me->source == source || *me->key == '/')) {
mapent_len = strlen(me->mapent);
mapent = alloca(mapent_len + 1);
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
index 0fc84f8..14f981c 100644
--- a/modules/lookup_yp.c
+++ b/modules/lookup_yp.c
@@ -636,9 +636,14 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
cache_readlock(mc);
me = cache_lookup(mc, key);
- /* Stale mapent => check for wildcard */
- if (me && !me->mapent)
- me = cache_lookup_distinct(mc, "*");
+ /* Stale mapent => check for entry in alternate source or wildcard */
+ if (me && !me->mapent) {
+ while ((me = cache_lookup_key_next(me)))
+ if (me->source == source)
+ break;
+ if (!me)
+ me = cache_lookup_distinct(mc, "*");
+ }
if (me && (me->source == source || *me->key == '/')) {
mapent_len = strlen(me->mapent);
mapent = alloca(mapent_len + 1);

View File

@ -1,309 +0,0 @@
autofs-5.0.3 - make handle_mounts startup condition distinct
From: Ian Kent <raven@themaw.net>
When starting a number of mounts we can get contention for the startup
condition used to synchronize the handle_mounts thread completion. This
patch makes the condition used distinct for each thread creation.
---
CHANGELOG | 1 +
daemon/automount.c | 62 ++++++++++++++++++++++++++++++++++++++++++++----
include/automount.h | 4 +++
lib/master.c | 29 +++++++++++-----------
modules/mount_autofs.c | 35 +++++++++++++--------------
5 files changed, 93 insertions(+), 38 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 3921552..9da7be3 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -25,6 +25,7 @@
- fix couple of memory leaks.
- add command line option to override check for daemon already running.
- don't use proc file system when checking if the daemon is running.
+- make handle_mounts startup condition distinct.
14/01/2008 autofs-5.0.3
-----------------------
diff --git a/daemon/automount.c b/daemon/automount.c
index dbf267c..086affb 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -1461,6 +1461,55 @@ static void mutex_operation_wait(pthread_mutex_t *mutex)
return;
}
+int handle_mounts_startup_cond_init(struct startup_cond *suc)
+{
+ int status;
+
+ status = pthread_mutex_init(&suc->mutex, NULL);
+ if (status)
+ return status;
+
+ status = pthread_cond_init(&suc->cond, NULL);
+ if (status) {
+ status = pthread_mutex_destroy(&suc->mutex);
+ if (status)
+ fatal(status);
+ return status;
+ }
+
+ status = pthread_mutex_lock(&suc->mutex);
+ if (status) {
+ status = pthread_mutex_destroy(&suc->mutex);
+ if (status)
+ fatal(status);
+ status = pthread_cond_destroy(&suc->cond);
+ if (status)
+ fatal(status);
+ }
+
+ return 0;
+}
+
+void handle_mounts_startup_cond_destroy(void *arg)
+{
+ struct startup_cond *suc = (struct startup_cond *) arg;
+ int status;
+
+ status = pthread_mutex_unlock(&suc->mutex);
+ if (status)
+ fatal(status);
+
+ status = pthread_mutex_destroy(&suc->mutex);
+ if (status)
+ fatal(status);
+
+ status = pthread_cond_destroy(&suc->cond);
+ if (status)
+ fatal(status);
+
+ return;
+}
+
static void handle_mounts_cleanup(void *arg)
{
struct autofs_point *ap;
@@ -1512,17 +1561,20 @@ static void handle_mounts_cleanup(void *arg)
void *handle_mounts(void *arg)
{
+ struct startup_cond *suc;
struct autofs_point *ap;
int cancel_state, status = 0;
- ap = (struct autofs_point *) arg;
+ suc = (struct startup_cond *) arg;
+
+ ap = suc->ap;
- pthread_cleanup_push(return_start_status, &suc);
+ pthread_cleanup_push(return_start_status, suc);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state);
state_mutex_lock(ap);
- status = pthread_mutex_lock(&suc.mutex);
+ status = pthread_mutex_lock(&suc->mutex);
if (status) {
logerr("failed to lock startup condition mutex!");
fatal(status);
@@ -1530,7 +1582,7 @@ void *handle_mounts(void *arg)
if (mount_autofs(ap) < 0) {
crit(ap->logopt, "mount of %s failed!", ap->path);
- suc.status = 1;
+ suc->status = 1;
state_mutex_unlock(ap);
umount_autofs(ap, 1);
pthread_setcancelstate(cancel_state, NULL);
@@ -1540,7 +1592,7 @@ void *handle_mounts(void *arg)
if (ap->ghost && ap->type != LKP_DIRECT)
info(ap->logopt, "ghosting enabled");
- suc.status = 0;
+ suc->status = 0;
pthread_cleanup_pop(1);
/* We often start several automounters at the same time. Add some
diff --git a/include/automount.h b/include/automount.h
index da1bf8f..1a20cd9 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -331,10 +331,14 @@ int ncat_path(char *buf, size_t len,
struct startup_cond {
pthread_mutex_t mutex;
pthread_cond_t cond;
+ struct autofs_point *ap;
unsigned int done;
unsigned int status;
};
+int handle_mounts_startup_cond_init(struct startup_cond *suc);
+void handle_mounts_startup_cond_destroy(void *arg);
+
struct master_readmap_cond {
pthread_mutex_t mutex;
pthread_cond_t cond;
diff --git a/lib/master.c b/lib/master.c
index 4a34dd4..edd3bdc 100644
--- a/lib/master.c
+++ b/lib/master.c
@@ -997,28 +997,31 @@ next:
static int master_do_mount(struct master_mapent *entry)
{
+ struct startup_cond suc;
struct autofs_point *ap;
pthread_t thid;
int status;
- status = pthread_mutex_lock(&suc.mutex);
- if (status)
- fatal(status);
+ ap = entry->ap;
+
+ if (handle_mounts_startup_cond_init(&suc)) {
+ crit(ap->logopt,
+ "failed to init startup cond for mount %s", entry->path);
+ return 0;
+ }
+ suc.ap = ap;
suc.done = 0;
suc.status = 0;
- ap = entry->ap;
-
debug(ap->logopt, "mounting %s", entry->path);
- if (pthread_create(&thid, &thread_attr, handle_mounts, ap)) {
+ status = pthread_create(&thid, &thread_attr, handle_mounts, &suc);
+ if (status) {
crit(ap->logopt,
"failed to create mount handler thread for %s",
entry->path);
- status = pthread_mutex_unlock(&suc.mutex);
- if (status)
- fatal(status);
+ handle_mounts_startup_cond_destroy(&suc);
return 0;
}
entry->thid = thid;
@@ -1031,15 +1034,11 @@ static int master_do_mount(struct master_mapent *entry)
if (suc.status) {
error(ap->logopt, "failed to startup mount");
- status = pthread_mutex_unlock(&suc.mutex);
- if (status)
- fatal(status);
+ handle_mounts_startup_cond_destroy(&suc);
return 0;
}
- status = pthread_mutex_unlock(&suc.mutex);
- if (status)
- fatal(status);
+ handle_mounts_startup_cond_destroy(&suc);
return 1;
}
diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c
index 356fb14..6f66564 100644
--- a/modules/mount_autofs.c
+++ b/modules/mount_autofs.c
@@ -46,6 +46,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
int name_len, const char *what, const char *fstype,
const char *c_options, void *context)
{
+ struct startup_cond suc;
pthread_t thid;
char *fullpath;
const char **argv;
@@ -210,34 +211,34 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
source->mc = cache_init(entry->ap, source);
if (!source->mc) {
error(ap->logopt, MODPREFIX "failed to init source cache");
+ master_free_map_source(source, 0);
master_free_mapent(entry);
return 1;
}
mounts_mutex_lock(ap);
- status = pthread_mutex_lock(&suc.mutex);
- if (status) {
- crit(ap->logopt,
- MODPREFIX "failed to lock startup condition mutex!");
- cache_release(source);
+ if (handle_mounts_startup_cond_init(&suc)) {
+ crit(ap->logopt, MODPREFIX
+ "failed to init startup cond for mount %s", entry->path);
+ mounts_mutex_unlock(ap);
+ master_free_map_source(source, 1);
master_free_mapent(entry);
return 1;
}
+ suc.ap = nap;
suc.done = 0;
suc.status = 0;
- if (pthread_create(&thid, NULL, handle_mounts, nap)) {
+ if (pthread_create(&thid, &thread_attr, handle_mounts, &suc)) {
crit(ap->logopt,
MODPREFIX
"failed to create mount handler thread for %s",
fullpath);
+ handle_mounts_startup_cond_destroy(&suc);
mounts_mutex_unlock(ap);
- status = pthread_mutex_unlock(&suc.mutex);
- if (status)
- fatal(status);
- cache_release(source);
+ master_free_map_source(source, 1);
master_free_mapent(entry);
return 1;
}
@@ -246,8 +247,10 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
while (!suc.done) {
status = pthread_cond_wait(&suc.cond, &suc.mutex);
if (status) {
+ handle_mounts_startup_cond_destroy(&suc);
mounts_mutex_unlock(ap);
- pthread_mutex_unlock(&suc.mutex);
+ master_free_map_source(source, 1);
+ master_free_mapent(entry);
fatal(status);
}
}
@@ -255,10 +258,9 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
if (suc.status) {
crit(ap->logopt,
MODPREFIX "failed to create submount for %s", fullpath);
+ handle_mounts_startup_cond_destroy(&suc);
mounts_mutex_unlock(ap);
- status = pthread_mutex_unlock(&suc.mutex);
- if (status)
- fatal(status);
+ master_free_map_source(source, 1);
master_free_mapent(entry);
return 1;
}
@@ -266,12 +268,9 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
ap->submnt_count++;
list_add(&nap->mounts, &ap->submounts);
+ handle_mounts_startup_cond_destroy(&suc);
mounts_mutex_unlock(ap);
- status = pthread_mutex_unlock(&suc.mutex);
- if (status)
- fatal(status);
-
return 0;
}

View File

@ -1,27 +0,0 @@
autofs-5.0.3 - map type in map name fix
From: Ian Kent <raven@themaw.net>
Fix incorrect match of map type as a host name.
Actually the original patch didn't match upstream or RHEL
so this syncs the source with those. It appears the problem
was fixed here some time ago but slightly differently.
---
lib/master_tok.l | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- autofs-5.0.3.orig/lib/master_tok.l
+++ autofs-5.0.3/lib/master_tok.l
@@ -202,7 +202,9 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--
}
}
- {MTYPE}/({DNSERVERSTR}|{DNATTRSTR}=)? {
+ {MTYPE} |
+ {MTYPE}/{DNSERVERSTR}{DNATTRSTR} |
+ {MTYPE}/{DNATTRSTR}= {
tlen = master_leng - 1;
if (bptr != buff && isblank(master_text[tlen])) {
strncat(buff, master_text, tlen);

View File

@ -1,65 +0,0 @@
diff -up autofs-5.0.3/lib/master_tok.l.map-type-in-map-name autofs-5.0.3/lib/master_tok.l
--- autofs-5.0.3/lib/master_tok.l.map-type-in-map-name 2008-04-01 11:14:00.000000000 +0800
+++ autofs-5.0.3/lib/master_tok.l 2008-04-01 11:14:00.000000000 +0800
@@ -77,6 +77,7 @@ int my_yyinput(char *, int);
char buff[1024];
char *bptr;
char *optr = buff;
+unsigned int tlen;
%}
@@ -190,13 +191,27 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--
{OPTWS}\\\n{OPTWS} {}
{MULTI} {
- strcpy(master_lval.strtype, master_text);
- return(MULTITYPE);
+ tlen = master_leng - 1;
+ if (bptr != buff && isblank(master_text[tlen])) {
+ strncat(buff, master_text, tlen);
+ bptr += tlen;
+ yyless(tlen);
+ } else {
+ strcpy(master_lval.strtype, master_text);
+ return(MULTITYPE);
+ }
}
- {MTYPE} {
- strcpy(master_lval.strtype, master_text);
- return(MAPTYPE);
+ {MTYPE}/({DNSERVERSTR}|{DNATTRSTR}=)? {
+ tlen = master_leng - 1;
+ if (bptr != buff && isblank(master_text[tlen])) {
+ strncat(buff, master_text, tlen);
+ bptr += tlen;
+ yyless(tlen);
+ } else {
+ strcpy(master_lval.strtype, master_text);
+ return(MAPTYPE);
+ }
}
{MULTISEP} { return(DDASH); }
@@ -226,7 +241,7 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--
yyless(0);
}
- {DNSERVERSTR} {
+ {DNSERVERSTR}{DNATTRSTR} {
BEGIN(DNSTR);
yyless(0);
}
diff -up autofs-5.0.3/lib/master_parse.y.map-type-in-map-name autofs-5.0.3/lib/master_parse.y
diff -up autofs-5.0.3/CHANGELOG.map-type-in-map-name autofs-5.0.3/CHANGELOG
--- autofs-5.0.3/CHANGELOG.map-type-in-map-name 2008-04-01 11:14:00.000000000 +0800
+++ autofs-5.0.3/CHANGELOG 2008-04-01 11:14:00.000000000 +0800
@@ -10,6 +10,7 @@
- fix unlink of mount tree incorrectly causing autofs mount fail.
- add missing check for zero length NIS key (Wengang Wang).
- init SASL callbacks on every ldap lookup library load.
+- fix incorrect match of map type name when included in map name.
14/01/2008 autofs-5.0.3
-----------------------

View File

@ -1,223 +0,0 @@
autofs-5.0.3 - mount thread create condition handling fix
From: Ian Kent <raven@themaw.net>
Make the mount thread creation condition mutex specific to the
thread being created.
---
CHANGELOG | 1 +
daemon/direct.c | 31 +++++++++++++++++++++++--------
daemon/indirect.c | 31 +++++++++++++++++++++++--------
3 files changed, 47 insertions(+), 16 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 995daea..f7aa839 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -18,6 +18,7 @@
- update nsswitch parser to ignore nsswitch sources that aren't supported.
- check for map key in (possible) alternate map sources when doing lookup.
- eliminate redundant DNS name lookups.
+- additional fix incorrect pthreads condition handling for mount requests.
14/01/2008 autofs-5.0.3
-----------------------
diff --git a/daemon/direct.c b/daemon/direct.c
index 86c817c..768fbf9 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -50,7 +50,6 @@ pthread_key_t key_mnt_direct_params;
pthread_key_t key_mnt_offset_params;
pthread_once_t key_mnt_params_once = PTHREAD_ONCE_INIT;
-static pthread_mutex_t ma_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER;
static void key_mnt_params_destroy(void *arg)
@@ -1218,9 +1217,18 @@ static void mount_send_fail(void *arg)
close(mt->ioctlfd);
}
+static void pending_mutex_destroy(void *arg)
+{
+ struct pending_args *mt = (struct pending_args *) arg;
+ int status = pthread_mutex_destroy(&mt->mutex);
+ if (status)
+ fatal(status);
+}
+
static void mount_mutex_unlock(void *arg)
{
- int status = pthread_mutex_unlock(&ma_mutex);
+ struct pending_args *mt = (struct pending_args *) arg;
+ int status = pthread_mutex_unlock(&mt->mutex);
if (status)
fatal(status);
}
@@ -1243,7 +1251,7 @@ static void *do_mount_direct(void *arg)
args = (struct pending_args *) arg;
- status = pthread_mutex_lock(&ma_mutex);
+ status = pthread_mutex_lock(&args->mutex);
if (status)
fatal(status);
@@ -1256,7 +1264,7 @@ static void *do_mount_direct(void *arg)
if (status)
fatal(status);
- mount_mutex_unlock(NULL);
+ mount_mutex_unlock(args);
pthread_cleanup_push(mount_send_fail, &mt);
@@ -1533,7 +1541,11 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
if (status)
fatal(status);
- status = pthread_mutex_lock(&ma_mutex);
+ status = pthread_mutex_init(&mt->mutex, NULL);
+ if (status)
+ fatal(status);
+
+ status = pthread_mutex_lock(&mt->mutex);
if (status)
fatal(status);
@@ -1553,8 +1565,9 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
send_fail(ap->logopt, ioctlfd, pkt->wait_queue_token);
close(ioctlfd);
cache_unlock(mc);
- mount_mutex_unlock(NULL);
+ mount_mutex_unlock(mt);
pending_cond_destroy(mt);
+ pending_mutex_destroy(mt);
free_pending_args(mt);
pthread_setcancelstate(state, NULL);
return 1;
@@ -1562,13 +1575,14 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
cache_unlock(mc);
pthread_cleanup_push(free_pending_args, mt);
+ pthread_cleanup_push(pending_mutex_destroy, mt);
pthread_cleanup_push(pending_cond_destroy, mt);
- pthread_cleanup_push(mount_mutex_unlock, NULL);
+ pthread_cleanup_push(mount_mutex_unlock, mt);
pthread_setcancelstate(state, NULL);
mt->signaled = 0;
while (!mt->signaled) {
- status = pthread_cond_wait(&mt->cond, &ma_mutex);
+ status = pthread_cond_wait(&mt->cond, &mt->mutex);
if (status)
fatal(status);
}
@@ -1576,6 +1590,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
pthread_cleanup_pop(1);
pthread_cleanup_pop(1);
pthread_cleanup_pop(1);
+ pthread_cleanup_pop(1);
return 0;
}
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 11865b3..9f22ec9 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -40,7 +40,6 @@
extern pthread_attr_t thread_attr;
-static pthread_mutex_t ma_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER;
static int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts)
@@ -651,9 +650,18 @@ static void mount_send_fail(void *arg)
send_fail(mt->ap->logopt, mt->ap->ioctlfd, mt->wait_queue_token);
}
+static void pending_mutex_destroy(void *arg)
+{
+ struct pending_args *mt = (struct pending_args *) arg;
+ int status = pthread_mutex_destroy(&mt->mutex);
+ if (status)
+ fatal(status);
+}
+
static void mount_mutex_unlock(void *arg)
{
- int status = pthread_mutex_unlock(&ma_mutex);
+ struct pending_args *mt = (struct pending_args *) arg;
+ int status = pthread_mutex_unlock(&mt->mutex);
if (status)
fatal(status);
}
@@ -676,7 +684,7 @@ static void *do_mount_indirect(void *arg)
args = (struct pending_args *) arg;
- status = pthread_mutex_lock(&ma_mutex);
+ status = pthread_mutex_lock(&args->mutex);
if (status)
fatal(status);
@@ -689,7 +697,7 @@ static void *do_mount_indirect(void *arg)
if (status)
fatal(status);
- mount_mutex_unlock(NULL);
+ mount_mutex_unlock(args);
pthread_cleanup_push(mount_send_fail, &mt);
@@ -884,7 +892,11 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin
if (status)
fatal(status);
- status = pthread_mutex_lock(&ma_mutex);
+ status = pthread_mutex_init(&mt->mutex, NULL);
+ if (status)
+ fatal(status);
+
+ status = pthread_mutex_lock(&mt->mutex);
if (status)
fatal(status);
@@ -901,21 +913,23 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin
if (status) {
error(ap->logopt, "expire thread create failed");
send_fail(ap->logopt, ap->ioctlfd, pkt->wait_queue_token);
- mount_mutex_unlock(NULL);
+ mount_mutex_unlock(mt);
pending_cond_destroy(mt);
+ pending_mutex_destroy(mt);
free_pending_args(mt);
pthread_setcancelstate(state, NULL);
return 1;
}
pthread_cleanup_push(free_pending_args, mt);
+ pthread_cleanup_push(pending_mutex_destroy, mt);
pthread_cleanup_push(pending_cond_destroy, mt);
- pthread_cleanup_push(mount_mutex_unlock, NULL);
+ pthread_cleanup_push(mount_mutex_unlock, mt);
pthread_setcancelstate(state, NULL);
mt->signaled = 0;
while (!mt->signaled) {
- status = pthread_cond_wait(&mt->cond, &ma_mutex);
+ status = pthread_cond_wait(&mt->cond, &mt->mutex);
if (status)
fatal(status);
}
@@ -923,6 +937,7 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin
pthread_cleanup_pop(1);
pthread_cleanup_pop(1);
pthread_cleanup_pop(1);
+ pthread_cleanup_pop(1);
return 0;
}

View File

@ -1,308 +0,0 @@
--- autofs-5.0.3.orig/daemon/indirect.c
+++ autofs-5.0.3/daemon/indirect.c
@@ -660,7 +660,7 @@ static void mount_mutex_unlock(void *arg
static void *do_mount_indirect(void *arg)
{
- struct pending_args *mt;
+ struct pending_args *args, mt;
struct autofs_point *ap;
char buf[PATH_MAX + 1];
struct stat st;
@@ -674,29 +674,28 @@ static void *do_mount_indirect(void *arg
struct thread_stdenv_vars *tsv;
int len, tmplen, grplen, status, state;
- mt = (struct pending_args *) arg;
+ args = (struct pending_args *) arg;
status = pthread_mutex_lock(&ma_mutex);
if (status)
fatal(status);
- ap = mt->ap;
- mt->status = 0;
+ memcpy(&mt, args, sizeof(struct pending_args));
+
+ ap = mt.ap;
- mt->signaled = 1;
- status = pthread_cond_signal(&mt->cond);
+ args->signaled = 1;
+ status = pthread_cond_signal(&args->cond);
if (status)
fatal(status);
mount_mutex_unlock(NULL);
- pthread_cleanup_push(free_pending_args, mt);
- pthread_cleanup_push(pending_cond_destroy, mt);
- pthread_cleanup_push(mount_send_fail, mt);
+ pthread_cleanup_push(mount_send_fail, &mt);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
- len = ncat_path(buf, sizeof(buf), ap->path, mt->name, mt->len);
+ len = ncat_path(buf, sizeof(buf), ap->path, mt.name, mt.len);
if (!len) {
crit(ap->logopt, "path to be mounted is to long");
pthread_setcancelstate(state, NULL);
@@ -704,7 +703,7 @@ static void *do_mount_indirect(void *arg
}
status = lstat(buf, &st);
- if (status != -1 && !(S_ISDIR(st.st_mode) && st.st_dev == mt->dev)) {
+ if (status != -1 && !(S_ISDIR(st.st_mode) && st.st_dev == mt.dev)) {
error(ap->logopt,
"indirect trigger not valid or already mounted %s", buf);
pthread_setcancelstate(state, NULL);
@@ -725,8 +724,8 @@ static void *do_mount_indirect(void *arg
if (!tsv)
goto cont;
- tsv->uid = mt->uid;
- tsv->gid = mt->gid;
+ tsv->uid = mt.uid;
+ tsv->gid = mt.gid;
/* Try to get passwd info */
@@ -744,7 +743,7 @@ static void *do_mount_indirect(void *arg
goto cont;
}
- status = getpwuid_r(mt->uid, ppw, pw_tmp, tmplen, pppw);
+ status = getpwuid_r(tsv->uid, ppw, pw_tmp, tmplen, pppw);
if (status || !ppw) {
error(ap->logopt, "failed to get passwd info from getpwuid_r");
free(tsv);
@@ -798,7 +797,7 @@ static void *do_mount_indirect(void *arg
gr_tmp = tmp;
pgr = &gr;
ppgr = &pgr;
- status = getgrgid_r(mt->gid, pgr, gr_tmp, tmplen, ppgr);
+ status = getgrgid_r(tsv->gid, pgr, gr_tmp, tmplen, ppgr);
if (status != ERANGE)
break;
tmplen += grplen;
@@ -834,20 +833,18 @@ static void *do_mount_indirect(void *arg
free(tsv);
}
cont:
- status = lookup_nss_mount(ap, NULL, mt->name, mt->len);
+ status = lookup_nss_mount(ap, NULL, mt.name, mt.len);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
if (status) {
- send_ready(ap->logopt, ap->ioctlfd, mt->wait_queue_token);
+ send_ready(ap->logopt, ap->ioctlfd, mt.wait_queue_token);
info(ap->logopt, "mounted %s", buf);
} else {
- send_fail(ap->logopt, ap->ioctlfd, mt->wait_queue_token);
+ send_fail(ap->logopt, ap->ioctlfd, mt.wait_queue_token);
info(ap->logopt, "failed to mount %s", buf);
}
pthread_setcancelstate(state, NULL);
pthread_cleanup_pop(0);
- pthread_cleanup_pop(1);
- pthread_cleanup_pop(1);
return NULL;
}
@@ -911,6 +908,8 @@ int handle_packet_missing_indirect(struc
return 1;
}
+ pthread_cleanup_push(free_pending_args, mt);
+ pthread_cleanup_push(pending_cond_destroy, mt);
pthread_cleanup_push(mount_mutex_unlock, NULL);
pthread_setcancelstate(state, NULL);
@@ -922,6 +921,8 @@ int handle_packet_missing_indirect(struc
}
pthread_cleanup_pop(1);
+ pthread_cleanup_pop(1);
+ pthread_cleanup_pop(1);
return 0;
}
--- autofs-5.0.3.orig/daemon/direct.c
+++ autofs-5.0.3/daemon/direct.c
@@ -1217,7 +1217,7 @@ static void mount_mutex_unlock(void *arg
static void *do_mount_direct(void *arg)
{
- struct pending_args *mt;
+ struct pending_args *args, mt;
struct autofs_point *ap;
struct passwd pw;
struct passwd *ppw = &pw;
@@ -1231,47 +1231,47 @@ static void *do_mount_direct(void *arg)
struct stat st;
int status, state;
- mt = (struct pending_args *) arg;
+ args = (struct pending_args *) arg;
status = pthread_mutex_lock(&ma_mutex);
if (status)
fatal(status);
- ap = mt->ap;
+ memcpy(&mt, args, sizeof(struct pending_args));
+
+ ap = mt.ap;
- mt->signaled = 1;
- status = pthread_cond_signal(&mt->cond);
+ args->signaled = 1;
+ status = pthread_cond_signal(&args->cond);
if (status)
fatal(status);
mount_mutex_unlock(NULL);
- pthread_cleanup_push(free_pending_args, mt);
- pthread_cleanup_push(pending_cond_destroy, mt);
- pthread_cleanup_push(mount_send_fail, mt);
+ pthread_cleanup_push(mount_send_fail, &mt);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
- status = fstat(mt->ioctlfd, &st);
+ status = fstat(mt.ioctlfd, &st);
if (status == -1) {
error(ap->logopt,
- "can't stat direct mount trigger %s", mt->name);
+ "can't stat direct mount trigger %s", mt.name);
pthread_setcancelstate(state, NULL);
pthread_exit(NULL);
}
- status = stat(mt->name, &st);
- if (!S_ISDIR(st.st_mode) || st.st_dev != mt->dev) {
+ status = stat(mt.name, &st);
+ if (!S_ISDIR(st.st_mode) || st.st_dev != mt.dev) {
error(ap->logopt,
"direct trigger not valid or already mounted %s",
- mt->name);
+ mt.name);
pthread_setcancelstate(state, NULL);
pthread_exit(NULL);
}
pthread_setcancelstate(state, NULL);
- info(ap->logopt, "attempting to mount entry %s", mt->name);
+ info(ap->logopt, "attempting to mount entry %s", mt.name);
/*
* Setup thread specific data values for macro
@@ -1283,8 +1283,8 @@ static void *do_mount_direct(void *arg)
if (!tsv)
goto cont;
- tsv->uid = mt->uid;
- tsv->gid = mt->gid;
+ tsv->uid = mt.uid;
+ tsv->gid = mt.gid;
/* Try to get passwd info */
@@ -1302,7 +1302,7 @@ static void *do_mount_direct(void *arg)
goto cont;
}
- status = getpwuid_r(mt->uid, ppw, pw_tmp, tmplen, pppw);
+ status = getpwuid_r(tsv->uid, ppw, pw_tmp, tmplen, pppw);
if (status || !ppw) {
error(ap->logopt, "failed to get passwd info from getpwuid_r");
free(tsv);
@@ -1356,7 +1356,7 @@ static void *do_mount_direct(void *arg)
gr_tmp = tmp;
pgr = &gr;
ppgr = &pgr;
- status = getgrgid_r(mt->gid, pgr, gr_tmp, tmplen, ppgr);
+ status = getgrgid_r(tsv->gid, pgr, gr_tmp, tmplen, ppgr);
if (status != ERANGE)
break;
tmplen += grplen;
@@ -1393,7 +1393,7 @@ static void *do_mount_direct(void *arg)
}
cont:
- status = lookup_nss_mount(ap, NULL, mt->name, strlen(mt->name));
+ status = lookup_nss_mount(ap, NULL, mt.name, strlen(mt.name));
/*
* Direct mounts are always a single mount. If it fails there's
* nothing to undo so just complain
@@ -1402,29 +1402,27 @@ cont:
if (status) {
struct mapent *me;
int real_mount, set_fd;
- cache_readlock(mt->mc);
- me = cache_lookup_distinct(mt->mc, mt->name);
+ cache_readlock(mt.mc);
+ me = cache_lookup_distinct(mt.mc, mt.name);
real_mount = is_mounted(_PATH_MOUNTED, me->key, MNTS_REAL);
set_fd = (real_mount || me->multi == me);
- cache_unlock(mt->mc);
+ cache_unlock(mt.mc);
if (set_fd) {
- me->ioctlfd = mt->ioctlfd;
- send_ready(ap->logopt, mt->ioctlfd, mt->wait_queue_token);
+ me->ioctlfd = mt.ioctlfd;
+ send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token);
} else {
- send_ready(ap->logopt, mt->ioctlfd, mt->wait_queue_token);
- close(mt->ioctlfd);
+ send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token);
+ close(mt.ioctlfd);
}
- info(ap->logopt, "mounted %s", mt->name);
+ info(ap->logopt, "mounted %s", mt.name);
} else {
- send_fail(mt->ap->logopt, mt->ioctlfd, mt->wait_queue_token);
- close(mt->ioctlfd);
- info(ap->logopt, "failed to mount %s", mt->name);
+ send_fail(ap->logopt, mt.ioctlfd, mt.wait_queue_token);
+ close(mt.ioctlfd);
+ info(ap->logopt, "failed to mount %s", mt.name);
}
pthread_setcancelstate(state, NULL);
pthread_cleanup_pop(0);
- pthread_cleanup_pop(1);
- pthread_cleanup_pop(1);
return NULL;
}
@@ -1553,6 +1551,8 @@ int handle_packet_missing_direct(struct
}
cache_unlock(mc);
+ pthread_cleanup_push(free_pending_args, mt);
+ pthread_cleanup_push(pending_cond_destroy, mt);
pthread_cleanup_push(mount_mutex_unlock, NULL);
pthread_setcancelstate(state, NULL);
@@ -1564,6 +1564,8 @@ int handle_packet_missing_direct(struct
}
pthread_cleanup_pop(1);
+ pthread_cleanup_pop(1);
+ pthread_cleanup_pop(1);
return 0;
}
--- autofs-5.0.3.orig/CHANGELOG
+++ autofs-5.0.3/CHANGELOG
@@ -11,6 +11,7 @@
- add missing check for zero length NIS key (Wengang Wang).
- init SASL callbacks on every ldap lookup library load.
- fix incorrect match of map type name when included in map name.
+- fix incorrect pthreads condition handling for mount requests.
14/01/2008 autofs-5.0.3
-----------------------

View File

@ -1,25 +0,0 @@
autofs-5.0.3 - check for mtab pointing to /proc/mounts fix
From: Ian Kent <raven@themaw.net>
Fix incorrect initialization in spawn_bind_mount() which
caused bind mounts to not be added to mtab.
---
daemon/spawn.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/daemon/spawn.c b/daemon/spawn.c
index 85cf9b8..17f92f4 100644
--- a/daemon/spawn.c
+++ b/daemon/spawn.c
@@ -432,7 +432,7 @@ int spawn_bind_mount(unsigned logopt, ...)
char arg_fake[] = "-f";
unsigned int options;
unsigned int retries = MTAB_LOCK_RETRIES;
- int update_mtab = 0, ret, printed = 0;
+ int update_mtab = 1, ret, printed = 0;
char buf[PATH_MAX];
/* If we use mount locking we can't validate the location */

View File

@ -1,170 +0,0 @@
autofs-5.0.3 - check for mtab pointing to /proc/mounts
From: Ian Kent <raven@themaw.net>
autofs has problems if /etc/mtab points to /proc/mounts.
This patchs adds a check to see if this is the case. If it is then
autofs uses the mount(8) "-n" option which disables the normal mtab
update error checking.
---
CHANGELOG | 1 +
daemon/spawn.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 61 insertions(+), 6 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 50c9a27..d2fe0a6 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -33,6 +33,7 @@
- add replicated server selection debug logging.
- update replicated server selection documentation.
- use /dev/urandom instead of /dev/random.
+- check for mtab pointing to /proc/mounts.
14/01/2008 autofs-5.0.3
-----------------------
diff --git a/daemon/spawn.c b/daemon/spawn.c
index 6b26c41..85cf9b8 100644
--- a/daemon/spawn.c
+++ b/daemon/spawn.c
@@ -305,11 +305,13 @@ int spawn_mount(unsigned logopt, ...)
char **argv, **p;
char prog[] = PATH_MOUNT;
char arg0[] = PATH_MOUNT;
+ char argn[] = "-n";
/* In case we need to use the fake option to mount */
char arg_fake[] = "-f";
unsigned int options;
unsigned int retries = MTAB_LOCK_RETRIES;
- int ret, printed = 0;
+ int update_mtab = 1, ret, printed = 0;
+ char buf[PATH_MAX];
/* If we use mount locking we can't validate the location */
#ifdef ENABLE_MOUNT_LOCKING
@@ -322,6 +324,17 @@ int spawn_mount(unsigned logopt, ...)
for (argc = 1; va_arg(arg, char *); argc++);
va_end(arg);
+ ret = readlink(_PATH_MOUNTED, buf, PATH_MAX);
+ if (ret != -1) {
+ buf[ret] = '\0';
+ if (!strcmp(buf, _PROC_MOUNTS)) {
+ debug(logopt,
+ "mtab link detected, passing -n to mount");
+ argc++;
+ update_mtab = 0;
+ }
+ }
+
/* Alloc 1 extra slot in case we need to use the "-f" option */
if (!(argv = alloca(sizeof(char *) * argc + 2)))
return -1;
@@ -329,7 +342,12 @@ int spawn_mount(unsigned logopt, ...)
argv[0] = arg0;
va_start(arg, logopt);
- p = argv + 1;
+ if (update_mtab)
+ p = argv + 1;
+ else {
+ argv[1] = argn;
+ p = argv + 2;
+ }
while ((*p = va_arg(arg, char *))) {
if (options == SPAWN_OPT_NONE && !strcmp(*p, "-o")) {
*(++p) = va_arg(arg, char *);
@@ -409,11 +427,13 @@ int spawn_bind_mount(unsigned logopt, ...)
char prog[] = PATH_MOUNT;
char arg0[] = PATH_MOUNT;
char bind[] = "--bind";
+ char argn[] = "-n";
/* In case we need to use the fake option to mount */
char arg_fake[] = "-f";
unsigned int options;
unsigned int retries = MTAB_LOCK_RETRIES;
- int ret, printed = 0;
+ int update_mtab = 0, ret, printed = 0;
+ char buf[PATH_MAX];
/* If we use mount locking we can't validate the location */
#ifdef ENABLE_MOUNT_LOCKING
@@ -430,6 +450,17 @@ int spawn_bind_mount(unsigned logopt, ...)
for (argc = 2; va_arg(arg, char *); argc++);
va_end(arg);
+ ret = readlink(_PATH_MOUNTED, buf, PATH_MAX);
+ if (ret != -1) {
+ buf[ret] = '\0';
+ if (!strcmp(buf, _PROC_MOUNTS)) {
+ debug(logopt,
+ "mtab link detected, passing -n to mount");
+ argc++;
+ update_mtab = 0;
+ }
+ }
+
if (!(argv = alloca(sizeof(char *) * argc + 2)))
return -1;
@@ -437,7 +468,12 @@ int spawn_bind_mount(unsigned logopt, ...)
argv[1] = bind;
va_start(arg, logopt);
- p = argv + 2;
+ if (update_mtab)
+ p = argv + 2;
+ else {
+ argv[2] = argn;
+ p = argv + 3;
+ }
while ((*p++ = va_arg(arg, char *)));
va_end(arg);
@@ -499,10 +535,12 @@ int spawn_umount(unsigned logopt, ...)
char **argv, **p;
char prog[] = PATH_UMOUNT;
char arg0[] = PATH_UMOUNT;
+ char argn[] = "-n";
unsigned int options;
unsigned int retries = MTAB_LOCK_RETRIES;
- int ret, printed = 0;
+ int update_mtab = 1, ret, printed = 0;
unsigned int wait = defaults_get_umount_wait();
+ char buf[PATH_MAX];
#ifdef ENABLE_MOUNT_LOCKING
options = SPAWN_OPT_LOCK;
@@ -514,13 +552,29 @@ int spawn_umount(unsigned logopt, ...)
for (argc = 1; va_arg(arg, char *); argc++);
va_end(arg);
+ ret = readlink(_PATH_MOUNTED, buf, PATH_MAX);
+ if (ret != -1) {
+ buf[ret] = '\0';
+ if (!strcmp(buf, _PROC_MOUNTS)) {
+ debug(logopt,
+ "mtab link detected, passing -n to mount");
+ argc++;
+ update_mtab = 0;
+ }
+ }
+
if (!(argv = alloca(sizeof(char *) * argc + 1)))
return -1;
argv[0] = arg0;
va_start(arg, logopt);
- p = argv + 1;
+ if (update_mtab)
+ p = argv + 1;
+ else {
+ argv[1] = argn;
+ p = argv + 2;
+ }
while ((*p++ = va_arg(arg, char *)));
va_end(arg);

View File

@ -1,25 +0,0 @@
diff --git a/CHANGELOG b/CHANGELOG
index b172579..5a85a8e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -3,6 +3,7 @@
- correct configure test for ldapr page control functions.
- catch "-xfn" map type and issue "no supported" message.
- correction for handling of LDAP base dns with spaces.
+- avoid using UDP for probing NFSv4 mount requests.
14/01/2008 autofs-5.0.3
-----------------------
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
index 0e7aebe..df01fd6 100644
--- a/modules/mount_nfs.c
+++ b/modules/mount_nfs.c
@@ -129,7 +129,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
}
if (strcmp(fstype, "nfs4") == 0)
- vers = NFS4_VERS_MASK | NFS_PROTO_MASK;
+ vers = NFS4_VERS_MASK | TCP_SUPPORTED;
else
vers = NFS_VERS_MASK | NFS_PROTO_MASK;

View File

@ -1,54 +0,0 @@
autofs-5.0.3 - nisplus partial and free
From: Jeff Bastian <jbastian@redhat.com>
During a nisplus key lookup nis_list() can return NIS_PARTIAL
as well as possibly NIS_NOTFOUND or NIS_S_NOTFOUND when the key
doesn't exist. This patch adds this to the checks and fixes a use
after free of the result struct.
---
modules/lookup_nisplus.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
--- autofs-5.0.3.orig/modules/lookup_nisplus.c
+++ autofs-5.0.3/modules/lookup_nisplus.c
@@ -285,13 +285,15 @@ static int lookup_one(struct autofs_poin
result = nis_list(tablename, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
if (result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) {
+ nis_error rs = result->status;
nis_freeresult(result);
pthread_setcancelstate(cur_state, NULL);
- if (result->status == NIS_NOTFOUND ||
- result->status == NIS_S_NOTFOUND)
+ if (rs == NIS_NOTFOUND ||
+ rs == NIS_S_NOTFOUND ||
+ rs == NIS_PARTIAL)
return CHE_MISSING;
- return -result->status;
+ return -rs;
}
@@ -338,13 +340,15 @@ static int lookup_wild(struct autofs_poi
result = nis_list(tablename, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
if (result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) {
+ nis_error rs = result->status;
nis_freeresult(result);
pthread_setcancelstate(cur_state, NULL);
- if (result->status == NIS_NOTFOUND ||
- result->status == NIS_S_NOTFOUND)
+ if (rs == NIS_NOTFOUND ||
+ rs == NIS_S_NOTFOUND ||
+ rs == NIS_PARTIAL)
return CHE_MISSING;
- return -result->status;
+ return -rs;
}
this = NIS_RES_OBJECT(result);

View File

@ -1,158 +0,0 @@
autofs-5.0.3 - ignore nsswitch sources that aren't supported
From: Ian Kent <raven@themaw.net>
Allow any source name in nsswitch and ignore those we don't support.
This has the side affect of also ignoring any action associated with
a source that isn't supported by autofs.
---
CHANGELOG | 1 +
lib/nss_parse.y | 31 ++++++++++++++++---------------
lib/nss_tok.l | 22 ++++++++++++----------
3 files changed, 29 insertions(+), 25 deletions(-)
--- autofs-5.0.3.orig/CHANGELOG
+++ autofs-5.0.3/CHANGELOG
@@ -13,6 +13,7 @@
- fix incorrect match of map type name when included in map name.
- fix incorrect pthreads condition handling for mount requests.
- add check for exports automatically mounted by NFS kernel client.
+- update nsswitch parser to ignore nsswitch sources that aren't supported.
14/01/2008 autofs-5.0.3
-----------------------
--- autofs-5.0.3.orig/lib/nss_parse.y
+++ autofs-5.0.3/lib/nss_parse.y
@@ -64,7 +64,6 @@ char strval[128];
%token <strval> SOURCE
%token <strval> STATUS
%token <strval> ACTION
-%token <strval> OTHER
%start file
@@ -83,7 +82,9 @@ sources: nss_source
nss_source: SOURCE
{
- if (strcmp($1, "winbind"))
+ if (!strcmp($1, "files") || !strcmp($1, "yp") ||
+ !strcmp($1, "nis") || !strcmp($1, "ldap") ||
+ !strcmp($1, "nisplus") || !strcmp($1, "hesiod"))
src = add_source(nss_list, $1);
else
nss_ignore($1);
@@ -91,7 +92,9 @@ nss_source: SOURCE
{
enum nsswitch_status a;
- if (strcmp($1, "winbind")) {
+ if (!strcmp($1, "files") || !strcmp($1, "yp") ||
+ !strcmp($1, "nis") || !strcmp($1, "ldap") ||
+ !strcmp($1, "nisplus") || !strcmp($1, "hesiod")) {
src = add_source(nss_list, $1);
for (a = 0; a < NSS_STATUS_MAX; a++) {
if (act[a].action != NSS_ACTION_UNKNOWN) {
@@ -101,12 +104,10 @@ nss_source: SOURCE
}
} else
nss_ignore($1);
-} | SOURCE LBRACKET status_exp_list SOURCE { nss_error($4); YYABORT; }
- | SOURCE LBRACKET status_exp_list OTHER { nss_error($4); YYABORT; }
- | SOURCE LBRACKET status_exp_list NL { nss_error("no closing bracket"); YYABORT; }
- | SOURCE LBRACKET OTHER { nss_error($3); YYABORT; }
- | SOURCE OTHER { nss_error("no opening bracket"); YYABORT; }
- | error OTHER { nss_error($2); YYABORT; };
+} | SOURCE LBRACKET status_exp_list SOURCE { nss_error("missing close bracket"); YYABORT; }
+ | SOURCE LBRACKET status_exp_list NL { nss_error("missing close bracket"); YYABORT; }
+ | SOURCE LBRACKET SOURCE { nss_error($3); YYABORT; }
+ | error SOURCE { nss_error($2); YYABORT; };
status_exp_list: status_exp
| status_exp status_exp_list
@@ -117,17 +118,17 @@ status_exp: STATUS EQUAL ACTION
} | BANG STATUS EQUAL ACTION
{
set_action(act, $2, $4, 1);
-} | STATUS EQUAL OTHER {nss_error($3); YYABORT; }
- | STATUS OTHER {nss_error($2); YYABORT; }
- | BANG STATUS EQUAL OTHER {nss_error($4); YYABORT; }
- | BANG STATUS OTHER {nss_error($3); YYABORT; }
- | BANG OTHER {nss_error($2); YYABORT; };
+} | STATUS EQUAL SOURCE {nss_error($3); YYABORT; }
+ | STATUS SOURCE {nss_error($2); YYABORT; }
+ | BANG STATUS EQUAL SOURCE {nss_error($4); YYABORT; }
+ | BANG STATUS SOURCE {nss_error($3); YYABORT; }
+ | BANG SOURCE {nss_error($2); YYABORT; };
%%
static int nss_ignore(const char *s)
{
- logmsg("ignored invalid nsswitch config near [ %s ]", s);
+ logmsg("ignored unsupported autofs nsswitch source \"%s\"", s);
return(0);
}
--- autofs-5.0.3.orig/lib/nss_tok.l
+++ autofs-5.0.3/lib/nss_tok.l
@@ -62,13 +62,13 @@ extern unsigned int nss_automount_found;
%option nounput
-%x AUTOMOUNT
+%x AUTOMOUNT ACTIONSTR
WS [[:blank:]]+
automount ([Aa][Uu][Tt][Oo][Mm][Oo][Uu][Nn][Tt])
-source files|yp|nis|nisplus|ldap|hesiod|winbind
+source [[:alnum:]@$%^&*()-+_":;?,<>./'{}~`]+
success ([Ss][Uu][Cc][Cc][Ee][Ss][Ss])
notfound ([Nn][Oo][Tt][Ff][Oo][Uu][Nn][Dd])
@@ -82,8 +82,6 @@ return ([Rr][Ee][Tt][Uu][Rr][Nn])
action ({continue}|{return})
-other [[:alnum:]@$%^&*()-+_":;?,<>./'{}~`]+
-
%%
^{automount}: {
@@ -101,6 +99,14 @@ other [[:alnum:]@$%^&*()-+_":;?,<>./'{}
return SOURCE;
}
+ "[" { BEGIN(ACTIONSTR); yyless(0); }
+
+ \n { BEGIN(INITIAL); return NL; }
+}
+
+<ACTIONSTR>{
+ {WS} { }
+
{status} {
strcpy(nss_lval.strval, nss_text);
return STATUS;
@@ -112,15 +118,11 @@ other [[:alnum:]@$%^&*()-+_":;?,<>./'{}
}
"[" { return LBRACKET; }
- "]" { return RBRACKET; }
+ "]" { BEGIN(AUTOMOUNT); return RBRACKET; }
"=" { return EQUAL; }
"!" { return BANG; }
- {other} {
- strcpy(nss_lval.strval, nss_text);
- return OTHER;
- }
-
+ . { BEGIN(AUTOMOUNT); yyless(0); }
\n { BEGIN(INITIAL); return NL; }
}

View File

@ -1,121 +0,0 @@
autofs-5.0.3 - add command line option to override is running check
From: Ian Kent <raven@themaw.net>
autofs common usage is to have a single instance of the daemon running
and it checks for this and exits if another instance is found to be
running. But there are situations were people need to run multiple
instances and this patch adds a command line option to overrid the
check. Please note that this doesn't mean that autofs will function
properly and it is the users responsibility to check that the
configuration in use will function properly.
---
CHANGELOG | 1 +
daemon/automount.c | 14 +++++++++++---
man/automount.8 | 10 ++++++++++
3 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 5901c75..f40a941 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -23,6 +23,7 @@
- fix direct mount path length not being checked.
- fix incorrect if check in get user info.
- fix couple of memory leaks.
+- add command line option to override check for daemon already running.
14/01/2008 autofs-5.0.3
-----------------------
diff --git a/daemon/automount.c b/daemon/automount.c
index 7ce9828..48ac30a 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -1694,6 +1694,8 @@ static void usage(void)
" specify global mount options\n"
" -l --set-log-priority priority path [path,...]\n"
" set daemon log verbosity\n"
+ " -C --dont-check-daemon\n"
+ " don't check if daemon is already running\n"
" -V --version print version, build config and exit\n"
, program);
}
@@ -1814,7 +1816,7 @@ int main(int argc, char *argv[])
{
int res, opt, status;
int logpri = -1;
- unsigned ghost, logging;
+ unsigned ghost, logging, daemon_check;
unsigned foreground, have_global_options;
time_t timeout;
time_t age = time(NULL);
@@ -1833,6 +1835,7 @@ int main(int argc, char *argv[])
{"global-options", 1, 0, 'O'},
{"version", 0, 0, 'V'},
{"set-log-priority", 1, 0, 'l'},
+ {"dont-check-daemon", 0, 0, 'C'},
{0, 0, 0, 0}
};
@@ -1851,9 +1854,10 @@ int main(int argc, char *argv[])
global_options = NULL;
have_global_options = 0;
foreground = 0;
+ daemon_check = 1;
opterr = 0;
- while ((opt = getopt_long(argc, argv, "+hp:t:vdD:fVrO:l:n:", long_options, NULL)) != EOF) {
+ while ((opt = getopt_long(argc, argv, "+hp:t:vdD:fVrO:l:n:C", long_options, NULL)) != EOF) {
switch (opt) {
case 'h':
usage();
@@ -1922,6 +1926,10 @@ int main(int argc, char *argv[])
}
break;
+ case 'C':
+ daemon_check = 0;
+ break;
+
case '?':
case ':':
printf("%s: Ambiguous or unknown options\n", program);
@@ -1965,7 +1973,7 @@ int main(int argc, char *argv[])
exit(exit_code);
}
- if (is_automount_running() > 0) {
+ if (daemon_check && is_automount_running() > 0) {
fprintf(stderr, "%s: program is already running.\n",
program);
exit(1);
diff --git a/man/automount.8 b/man/automount.8
index 59ad50e..d9285bf 100644
--- a/man/automount.8
+++ b/man/automount.8
@@ -81,6 +81,9 @@ be disabled, returning the daemon to verbose logging.
.P
The \fIpath\fP argument corresponds to the automounted
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).
.SH ARGUMENTS
\fBautomount\fP takes one optional argument, the name of the master map to
use.
@@ -122,6 +125,13 @@ until they are no longer in use by the processes that held them busy.
If automount managed filesystems are found mounted when autofs is
started they will be recoverd unless they are no longer present in
the map in which case they need to umounted manually.
+.P
+If the option to disable the check to see if the daemon is already
+running is used be aware that autofs currently may not function correctly
+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.
.SH "SEE ALSO"
.BR autofs (5),
.BR autofs (8),

File diff suppressed because it is too large Load Diff

View File

@ -1,239 +0,0 @@
autofs-5.0.3 - eliminate redundant DNS name lookups
From: Ian Kent <raven@themaw.net>
When autofs tries to lookup a DNS host name where one or more DNS
servers aren't available the mount can take a long time. This is
caused by autofs doing the name lookups more often than it needs
to. This patch removes a number of these redundant name lookups.
---
CHANGELOG | 1 +
include/replicated.h | 1 +
include/rpc_subs.h | 4 +++-
lib/rpc_subs.c | 22 ++++++++++++++++++++--
modules/replicated.c | 25 +++++++++++++++++++------
5 files changed, 44 insertions(+), 9 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 3ed84d3..995daea 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -17,6 +17,7 @@
- add check for exports automatically mounted by NFS kernel client.
- update nsswitch parser to ignore nsswitch sources that aren't supported.
- check for map key in (possible) alternate map sources when doing lookup.
+- eliminate redundant DNS name lookups.
14/01/2008 autofs-5.0.3
-----------------------
diff --git a/include/replicated.h b/include/replicated.h
index 672f853..88cd08a 100644
--- a/include/replicated.h
+++ b/include/replicated.h
@@ -52,6 +52,7 @@
struct host {
char *name;
char *addr;
+ size_t addr_len;
char *path;
unsigned int version;
unsigned int proximity;
diff --git a/include/rpc_subs.h b/include/rpc_subs.h
index 3292e01..e20a89d 100644
--- a/include/rpc_subs.h
+++ b/include/rpc_subs.h
@@ -46,6 +46,8 @@
struct conn_info {
const char *host;
+ const char *addr;
+ size_t addr_len;
unsigned short port;
unsigned long program;
unsigned long version;
@@ -61,7 +63,7 @@ int rpc_udp_getclient(struct conn_info *, unsigned int, unsigned int);
void rpc_destroy_udp_client(struct conn_info *);
int rpc_tcp_getclient(struct conn_info *, unsigned int, unsigned int);
void rpc_destroy_tcp_client(struct conn_info *);
-int rpc_portmap_getclient(struct conn_info *, const char *, const char *, unsigned int);
+int rpc_portmap_getclient(struct conn_info *, const char *, const char *, size_t, const char *, unsigned int);
unsigned short rpc_portmap_getport(struct conn_info *, struct pmap *);
int rpc_ping_proto(struct conn_info *);
int rpc_ping(const char *, long, long, unsigned int);
diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c
index 5797639..6be86c6 100644
--- a/lib/rpc_subs.c
+++ b/lib/rpc_subs.c
@@ -86,6 +86,11 @@ static CLIENT *create_udp_client(struct conn_info *info)
memset(&raddr, 0, sizeof(raddr));
raddr.sin_family = AF_INET;
+ if (info->addr) {
+ memcpy(&raddr.sin_addr.s_addr, info->addr, info->addr_len);
+ goto got_addr;
+ }
+
if (inet_aton(info->host, &raddr.sin_addr))
goto got_addr;
@@ -295,6 +300,11 @@ static CLIENT *create_tcp_client(struct conn_info *info)
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
+ if (info->addr) {
+ memcpy(&addr.sin_addr.s_addr, info->addr, info->addr_len);
+ goto got_addr;
+ }
+
if (inet_aton(info->host, &addr.sin_addr))
goto got_addr;
@@ -407,8 +417,8 @@ void rpc_destroy_tcp_client(struct conn_info *info)
}
int rpc_portmap_getclient(struct conn_info *info,
- const char *host, const char *proto,
- unsigned int option)
+ const char *host, const char *addr, size_t addr_len,
+ const char *proto, unsigned int option)
{
struct protoent *pe_proto;
CLIENT *client;
@@ -418,6 +428,8 @@ int rpc_portmap_getclient(struct conn_info *info,
return 0;
info->host = host;
+ info->addr = addr;
+ info->addr_len = addr_len;
info->program = PMAPPROG;
info->port = PMAPPORT;
info->version = PMAPVERS;
@@ -462,6 +474,8 @@ unsigned short rpc_portmap_getport(struct conn_info *info, struct pmap *parms)
client = info->client;
else {
pmap_info.host = info->host;
+ pmap_info.addr = info->addr;
+ pmap_info.addr_len = info->addr_len;
pmap_info.port = PMAPPORT;
pmap_info.program = PMAPPROG;
pmap_info.version = PMAPVERS;
@@ -589,6 +603,8 @@ static unsigned int __rpc_ping(const char *host,
struct pmap parms;
info.host = host;
+ info.addr = NULL;
+ info.addr_len = 0;
info.program = NFS_PROGRAM;
info.version = version;
info.send_sz = 0;
@@ -769,6 +785,8 @@ exports rpc_get_exports(const char *host, long seconds, long micros, unsigned in
int status;
info.host = host;
+ info.addr = NULL;
+ info.addr_len = 0;
info.program = MOUNTPROG;
info.version = MOUNTVERS;
info.send_sz = 0;
diff --git a/modules/replicated.c b/modules/replicated.c
index 90b2925..efbe6b4 100644
--- a/modules/replicated.c
+++ b/modules/replicated.c
@@ -225,7 +225,9 @@ static unsigned int get_proximity(const char *host_addr, int addr_len)
return PROXIMITY_OTHER;
}
-static struct host *new_host(const char *name, const char *addr, unsigned int proximity, unsigned int weight)
+static struct host *new_host(const char *name,
+ const char *addr, size_t addr_len,
+ unsigned int proximity, unsigned int weight)
{
struct host *new;
char *tmp1, *tmp2;
@@ -237,11 +239,12 @@ static struct host *new_host(const char *name, const char *addr, unsigned int pr
if (!tmp1)
return NULL;
- tmp2 = strdup(addr);
+ tmp2 = malloc(addr_len);
if (!tmp2) {
free(tmp1);
return NULL;
}
+ memcpy(tmp2, addr, addr_len);
new = malloc(sizeof(struct host));
if (!new) {
@@ -253,6 +256,7 @@ static struct host *new_host(const char *name, const char *addr, unsigned int pr
memset(new, 0, sizeof(struct host));
new->name = tmp1;
+ new->addr_len = addr_len;
new->addr = tmp2;
new->proximity = proximity;
new->weight = weight;
@@ -437,7 +441,8 @@ static unsigned int get_nfs_info(unsigned logopt, struct host *host,
v3_ver:
if (!have_port_opt) {
status = rpc_portmap_getclient(pm_info,
- host->name, proto, RPC_CLOSE_DEFAULT);
+ host->name, host->addr, host->addr_len,
+ proto, RPC_CLOSE_DEFAULT);
if (!status)
goto done_ver;
}
@@ -551,6 +556,8 @@ static int get_vers_and_cost(unsigned logopt, struct host *host,
timeout = RPC_TIMEOUT * 8;
rpc_info.host = host->name;
+ rpc_info.addr = host->addr;
+ rpc_info.addr_len = host->addr_len;
rpc_info.program = NFS_PROGRAM;
rpc_info.timeout.tv_sec = timeout;
rpc_info.close_option = RPC_CLOSE_DEFAULT;
@@ -606,6 +613,8 @@ static int get_supported_ver_and_cost(unsigned logopt, struct host *host,
timeout = RPC_TIMEOUT * 8;
rpc_info.host = host->name;
+ rpc_info.addr = host->addr;
+ rpc_info.addr_len = host->addr_len;
rpc_info.program = NFS_PROGRAM;
rpc_info.timeout.tv_sec = timeout;
rpc_info.close_option = RPC_CLOSE_DEFAULT;
@@ -652,7 +661,8 @@ static int get_supported_ver_and_cost(unsigned logopt, struct host *host,
return 0;
} else {
int ret = rpc_portmap_getclient(&pm_info,
- host->name, proto, RPC_CLOSE_DEFAULT);
+ host->name, host->addr, host->addr_len,
+ proto, RPC_CLOSE_DEFAULT);
if (!ret)
return 0;
@@ -868,7 +878,7 @@ static int add_host_addrs(struct host **list, const char *host, unsigned int wei
if (prx == PROXIMITY_ERROR)
return 0;
- if (!(new = new_host(host, thost, prx, weight)))
+ if (!(new = new_host(host, thost, sizeof(saddr.sin_addr), prx, weight)))
return 0;
if (!add_host(list, new))
@@ -891,11 +901,14 @@ static int add_host_addrs(struct host **list, const char *host, unsigned int wei
}
for (haddr = phe->h_addr_list; *haddr; haddr++) {
+ struct in_addr tt;
+
prx = get_proximity(*haddr, phe->h_length);
if (prx == PROXIMITY_ERROR)
return 0;
- if (!(new = new_host(host, *haddr, prx, weight)))
+ memcpy(&tt, *haddr, sizeof(struct in_addr));
+ if (!(new = new_host(host, *haddr, phe->h_length, prx, weight)))
return 0;
if (!add_host(list, new)) {

View File

@ -1,32 +0,0 @@
autofs-5.0.3 - submount shutdown recovery fix
From: Ian Kent <raven@themaw.net>
I was sure I fixed this in the final patch but evidently
not.
---
daemon/direct.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/daemon/direct.c b/daemon/direct.c
index 34e882b..afb354e 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -1129,7 +1129,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);
- cache_unlock(mc);
master_source_unlock(ap->entry);
pthread_setcancelstate(state, NULL);
return 1;
@@ -1374,7 +1373,6 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
*/
logerr("can't find map entry for (%lu,%lu)",
(unsigned long) pkt->dev, (unsigned long) pkt->ino);
- cache_unlock(mc);
master_source_unlock(ap->entry);
pthread_setcancelstate(state, NULL);
return 1;

File diff suppressed because it is too large Load Diff

View File

@ -1,52 +0,0 @@
diff --git a/CHANGELOG b/CHANGELOG
index eb4cce1..a0c7fa3 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -7,6 +7,7 @@
- use libldap instead of libldap_r (Guillaume Rousse).
- another fix for don't fail on empty master map.
- fix expire working harder than needed.
+- fix unlink of mount tree incorrectly causing autofs mount fail.
14/01/2008 autofs-5.0.3
-----------------------
diff --git a/daemon/direct.c b/daemon/direct.c
index 760fbd4..8d1e9c6 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -275,7 +275,6 @@ static int unlink_mount_tree(struct autofs_point *ap, struct list_head *list)
else
rv = umount2(mnt->path, MNT_DETACH);
if (rv == -1) {
- ret = 0;
debug(ap->logopt,
"can't unlink %s from mount tree", mnt->path);
@@ -287,6 +286,7 @@ static int unlink_mount_tree(struct autofs_point *ap, struct list_head *list)
case ENOENT:
case EFAULT:
+ ret = 0;
warn(ap->logopt, "bad path for mount");
break;
}
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 39b42da..f0409ac 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -65,7 +65,6 @@ static int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts)
else
rv = umount2(this->path, MNT_DETACH);
if (rv == -1) {
- ret = 0;
debug(ap->logopt,
"can't unlink %s from mount tree", this->path);
@@ -77,6 +76,7 @@ static int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts)
case ENOENT:
case EFAULT:
+ ret = 0;
warn(ap->logopt, "bad path for mount");
break;
}

View File

@ -1,103 +0,0 @@
autofs-5.0.3 - update replicated server selection documentation
From: Ian Kent <raven@themaw.net>
Update the replicated server selection README documentation to
reflect the selection rules now used.
---
CHANGELOG | 1 +
README.replicated-server | 53 ++++++++++++++++++++++------------------------
2 files changed, 26 insertions(+), 28 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index af3318a..be39e33 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -31,6 +31,7 @@
umount during expire.
- make mount of multi-mounts wuth a root offset atomic.
- add replicated server selection debug logging.
+- update replicated server selection documentation.
14/01/2008 autofs-5.0.3
-----------------------
diff --git a/README.replicated-server b/README.replicated-server
index 333dea3..1d771d3 100644
--- a/README.replicated-server
+++ b/README.replicated-server
@@ -3,48 +3,45 @@ Supported forms for mount paths are:
Normal single-host (these are unchanged)
<path> host:/path/path
+Single host entries are not probed for a server response.
+
Multiple replicated hosts, same path:
<path> host1,host2,hostn:/path/path
-This will do an initial RPC call with a .1 second timeout to all hosts to
-find best match. If this fails, it will try a 10 second timeout, if this
-fails it takes the first host.
-
Multiple hosts, some with same path, some with another
<path> host1,host2:/blah host3:/some/other/path
-Works as expected
-
Multiple replicated hosts, different (potentially) paths:
<path> host1:/path/pathA host2:/path/pathB
-Same as above with RPC calls..
-
Mutliple weighted, replicated hosts same path:
-
<path> host1(5),host2(6),host3(1):/path/path
-Will pick lowest weighted host that responds to RPC call.
-RPC time is not counted, only whether the call got a reply
-at all. Initially does a .1 second timeout, if all hosts
-fail this, moves to 10 second timeout. If one of the hosts
-is localhost, the automounter will choose that regardless of
-its weight. (This has been done to remain compatible with
-Sun's automounter)
-
Multiple weighted, replicated hosts different (potentially)
paths:
<path> host1(3):/path/pathA host2(5):/path/pathB
-Same as above with RPC calls/weighting.
-
-Anything else is questionable and unsupported, but these
-variations will also work:
-<path> host1(3),host:/blah
-
-Unsupported and I don't know why you would use this, but will
-work. Weighted host always gets precedence if it responds to RPC
-
-Anything else, I ain't making no promises.
+For these formats a priority ordered list of hosts is created by using
+the following selection rules.
+
+1) Highest priority in selection is proximity.
+ Proximity, in order of precedence is:
+ - PROXIMITY_LOCAL, host corresponds to a local interface.
+ - PROXIMITY_SUBNET, host is located in a subnet reachable
+ through a local interface.
+ - PROXIMITY_NETWORK, host is located in a network reachable
+ through a local interface.
+ - PROXIMITY_OTHER, host is on a network not directlty
+ reachable through a local interface.
+
+2) NFS version and protocol is selected by caclculating the largest
+ number of hosts supporting an NFS version and protocol that
+ have the closest proximity. These hosts are added to the list
+ in response time order. Hosts may have a corresponding weight
+ which essentially increases response time and so influences the
+ host order.
+
+3) Hosts at further proximity that support the selected NFS version
+ and protocol are also added to the list in response time order as
+ in 2 above.
-Jason

View File

@ -1,39 +0,0 @@
autofs-5.0.3 - use /dev/urandom instead of /dev/random
From: Ian Kent <raven@themaw.net>
It has been reported that some headless systems hang when using
/dev/random. It's also been pointed out that /dev/urandom is
sufficient for the needs of autofs.
---
CHANGELOG | 1 +
modules/replicated.c | 2 +-
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index be39e33..50c9a27 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -32,6 +32,7 @@
- make mount of multi-mounts wuth a root offset atomic.
- add replicated server selection debug logging.
- update replicated server selection documentation.
+- use /dev/urandom instead of /dev/random.
14/01/2008 autofs-5.0.3
-----------------------
diff --git a/modules/replicated.c b/modules/replicated.c
index e41713e..362ab1b 100644
--- a/modules/replicated.c
+++ b/modules/replicated.c
@@ -79,7 +79,7 @@ void seed_random(void)
int fd;
unsigned int seed;
- fd = open("/dev/random", O_RDONLY);
+ fd = open("/dev/urandom", O_RDONLY);
if (fd < 0) {
srandom(time(NULL));
return;

View File

@ -1,48 +0,0 @@
autofs-5.0.3 - wait submount expire complete
From: Ian Kent <raven@themaw.net>
When expiring a submount expires away and proceeds to shutdown we
can reach the end of the expire of the parent before the submount
goes away. This can cause an incomplete expire during shutdown in
some cases so, for the case the submount goes to state ST_SHUTDOWN,
we need to wait until the submount either goes away or fails to
shutdown before continuing.
---
lib/master.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
--- autofs-5.0.3.orig/lib/master.c
+++ autofs-5.0.3/lib/master.c
@@ -870,6 +870,29 @@ int master_notify_submount(struct autofs
st_wait_task(this, state, 0);
+ /*
+ * If our submount gets to state ST_SHUTDOWN we need to
+ * wait until it goes away or changes to ST_READY.
+ */
+ mounts_mutex_lock(ap);
+ st_mutex_lock();
+ while ((this = __master_find_submount(ap, path))) {
+ struct timespec t = { 0, 300000000 };
+ struct timespec r;
+
+ if (this->state != ST_SHUTDOWN)
+ break;
+
+ st_mutex_unlock();
+ mounts_mutex_unlock(ap);
+ while (nanosleep(&t, &r) == -1 && errno == EINTR)
+ memcpy(&t, &r, sizeof(struct timespec));
+ mounts_mutex_lock(ap);
+ st_mutex_lock();
+ }
+ st_mutex_unlock();
+ mounts_mutex_unlock(ap);
+
return ret;
}

View File

@ -1,75 +0,0 @@
diff --git a/CHANGELOG b/CHANGELOG
index 98855f5..8d09e93 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
??/??/2008 autofs-5.0.4
-----------------------
- correct configure test for ldapr page control functions.
+- catch "-xfn" map type and issue "no supported" message.
14/01/2008 autofs-5.0.3
-----------------------
diff --git a/lib/master_parse.y b/lib/master_parse.y
index b450122..2184b4f 100644
--- a/lib/master_parse.y
+++ b/lib/master_parse.y
@@ -50,6 +50,7 @@ static int add_multi_mapstr(void);
static int master_error(const char *s);
static int master_notify(const char *s);
+static int master_msg(const char *s);
static char *path;
static char *type;
@@ -119,6 +120,7 @@ static int master_fprintf(FILE *, char *, ...);
%token <strtype> DNNAME
%token <strtype> MAPHOSTS
%token <strtype> MAPNULL
+%token <strtype> MAPXFN
%token <strtype> MAPNAME
%token <inttype> NUMBER
%token <strtype> OPTION
@@ -283,6 +285,12 @@ map: PATH
YYABORT;
}
}
+ | MAPXFN
+ {
+ master_notify($1);
+ master_msg("X/Open Federated Naming service not supported");
+ YYABORT;
+ }
| MAPNULL
{
type = master_strdup($1 + 1);
@@ -598,6 +606,12 @@ static int master_notify(const char *s)
return(0);
}
+static int master_msg(const char *s)
+{
+ logmsg("%s", s);
+ return 0;
+}
+
static void local_init_vars(void)
{
path = NULL;
diff --git a/lib/master_tok.l b/lib/master_tok.l
index d908047..2a6fdf9 100644
--- a/lib/master_tok.l
+++ b/lib/master_tok.l
@@ -215,6 +215,12 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeo
return MAPNULL;
}
+ "-xfn" {
+ BEGIN(OPTSTR);
+ strcpy(master_lval.strtype, master_text);
+ return MAPXFN;
+ }
+
"//" {
BEGIN(DNSTR);
yyless(0);