- add upstream bug fix patches
- add command line option to override is running check. - don't use proc fs for is running check. - fix fail on included browse map not found. - fix incorrect multi source messages. - clear stale flag on map read. - fix proximity other rpc ping timeout. - refactor mount request vars code. - make handle_mounts startup condition distinct. - fix submount shutdown handling. - try not to block on expire. - add configuration paramter UMOUNT_WAIT. - fix multi mount race. - fix nfs4 colon escape handling. - check replicated list after probe. - 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. - fix interface config buffer size. - fix percent hack heap corruption.
This commit is contained in:
parent
4fa4332422
commit
3685ec8873
189
autofs-5.0.3-add-replicated-debug-logging.patch
Normal file
189
autofs-5.0.3-add-replicated-debug-logging.patch
Normal file
@ -0,0 +1,189 @@
|
||||
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;
|
||||
138
autofs-5.0.3-add-umount_wait-parameter.patch
Normal file
138
autofs-5.0.3-add-umount_wait-parameter.patch
Normal file
@ -0,0 +1,138 @@
|
||||
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"
|
||||
33
autofs-5.0.3-check-replicated-list-after-probe.patch
Normal file
33
autofs-5.0.3-check-replicated-list-after-probe.patch
Normal file
@ -0,0 +1,33 @@
|
||||
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 */
|
||||
29
autofs-5.0.3-clear-stale-on-map-read.patch
Normal file
29
autofs-5.0.3-clear-stale-on-map-read.patch
Normal file
@ -0,0 +1,29 @@
|
||||
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
|
||||
495
autofs-5.0.3-dont-block-on-expire.patch
Normal file
495
autofs-5.0.3-dont-block-on-expire.patch
Normal file
@ -0,0 +1,495 @@
|
||||
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);
|
||||
619
autofs-5.0.3-dont-use-proc-for-is-running-check.patch
Normal file
619
autofs-5.0.3-dont-use-proc-for-is-running-check.patch
Normal file
@ -0,0 +1,619 @@
|
||||
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;
|
||||
+}
|
||||
+
|
||||
144
autofs-5.0.3-fix-ifc-buff-size.patch
Normal file
144
autofs-5.0.3-fix-ifc-buff-size.patch
Normal file
@ -0,0 +1,144 @@
|
||||
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 = sizeof(buf);
|
||||
+ 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;
|
||||
}
|
||||
26
autofs-5.0.3-fix-included-browse-map-not-found.patch
Normal file
26
autofs-5.0.3-fix-included-browse-map-not-found.patch
Normal file
@ -0,0 +1,26 @@
|
||||
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);
|
||||
|
||||
1637
autofs-5.0.3-fix-multi-mount-race.patch
Normal file
1637
autofs-5.0.3-fix-multi-mount-race.patch
Normal file
File diff suppressed because it is too large
Load Diff
182
autofs-5.0.3-fix-multi-source-messages.patch
Normal file
182
autofs-5.0.3-fix-multi-source-messages.patch
Normal file
@ -0,0 +1,182 @@
|
||||
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;
|
||||
28
autofs-5.0.3-fix-nfs4-colon-escape.patch
Normal file
28
autofs-5.0.3-fix-nfs4-colon-escape.patch
Normal file
@ -0,0 +1,28 @@
|
||||
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';
|
||||
369
autofs-5.0.3-fix-percent-hack.patch
Normal file
369
autofs-5.0.3-fix-percent-hack.patch
Normal file
@ -0,0 +1,369 @@
|
||||
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)
|
||||
36
autofs-5.0.3-fix-proximity-other-timeout.patch
Normal file
36
autofs-5.0.3-fix-proximity-other-timeout.patch
Normal file
@ -0,0 +1,36 @@
|
||||
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;
|
||||
309
autofs-5.0.3-make-handle_mounts-startup-cond-distinct.patch
Normal file
309
autofs-5.0.3-make-handle_mounts-startup-cond-distinct.patch
Normal file
@ -0,0 +1,309 @@
|
||||
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;
|
||||
}
|
||||
|
||||
170
autofs-5.0.3-mtab-as-proc-mounts.patch
Normal file
170
autofs-5.0.3-mtab-as-proc-mounts.patch
Normal file
@ -0,0 +1,170 @@
|
||||
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);
|
||||
|
||||
121
autofs-5.0.3-override-is-running-check.patch
Normal file
121
autofs-5.0.3-override-is-running-check.patch
Normal file
@ -0,0 +1,121 @@
|
||||
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),
|
||||
1217
autofs-5.0.3-refactor-mount-request-vars.patch
Normal file
1217
autofs-5.0.3-refactor-mount-request-vars.patch
Normal file
File diff suppressed because it is too large
Load Diff
32
autofs-5.0.3-submount-shutdown-recovery-12-fix.patch
Normal file
32
autofs-5.0.3-submount-shutdown-recovery-12-fix.patch
Normal file
@ -0,0 +1,32 @@
|
||||
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;
|
||||
1924
autofs-5.0.3-submount-shutdown-recovery-12.patch
Normal file
1924
autofs-5.0.3-submount-shutdown-recovery-12.patch
Normal file
File diff suppressed because it is too large
Load Diff
103
autofs-5.0.3-update-replicated-doco.patch
Normal file
103
autofs-5.0.3-update-replicated-doco.patch
Normal file
@ -0,0 +1,103 @@
|
||||
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
|
||||
39
autofs-5.0.3-use-dev-urandom.patch
Normal file
39
autofs-5.0.3-use-dev-urandom.patch
Normal file
@ -0,0 +1,39 @@
|
||||
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;
|
||||
46
autofs.spec
46
autofs.spec
@ -4,7 +4,7 @@
|
||||
Summary: A tool for automatically mounting and unmounting filesystems
|
||||
Name: autofs
|
||||
Version: 5.0.3
|
||||
Release: 19
|
||||
Release: 21
|
||||
Epoch: 1
|
||||
License: GPLv2+
|
||||
Group: System Environment/Daemons
|
||||
@ -32,6 +32,27 @@ Patch19: autofs-5.0.3-allow-dir-create-on-nfs-root.patch
|
||||
Patch20: autofs-5.0.3-check-direct-path-len.patch
|
||||
Patch21: autofs-5.0.3-fix-get-user-info-check.patch
|
||||
Patch22: autofs-5.0.3-fix-couple-of-memory-leaks.patch
|
||||
Patch23: autofs-5.0.3-override-is-running-check.patch
|
||||
Patch24: autofs-5.0.3-dont-use-proc-for-is-running-check.patch
|
||||
Patch25: autofs-5.0.3-fix-included-browse-map-not-found.patch
|
||||
Patch26: autofs-5.0.3-fix-multi-source-messages.patch
|
||||
Patch27: autofs-5.0.3-clear-stale-on-map-read.patch
|
||||
Patch28: autofs-5.0.3-fix-proximity-other-timeout.patch
|
||||
Patch29: autofs-5.0.3-refactor-mount-request-vars.patch
|
||||
Patch30: autofs-5.0.3-make-handle_mounts-startup-cond-distinct.patch
|
||||
Patch31: autofs-5.0.3-submount-shutdown-recovery-12.patch
|
||||
Patch32: autofs-5.0.3-dont-block-on-expire.patch
|
||||
Patch33: autofs-5.0.3-add-umount_wait-parameter.patch
|
||||
Patch34: autofs-5.0.3-fix-multi-mount-race.patch
|
||||
Patch35: autofs-5.0.3-submount-shutdown-recovery-12-fix.patch
|
||||
Patch36: autofs-5.0.3-fix-nfs4-colon-escape.patch
|
||||
Patch37: autofs-5.0.3-check-replicated-list-after-probe.patch
|
||||
Patch38: autofs-5.0.3-add-replicated-debug-logging.patch
|
||||
Patch39: autofs-5.0.3-update-replicated-doco.patch
|
||||
Patch40: autofs-5.0.3-use-dev-urandom.patch
|
||||
Patch41: autofs-5.0.3-mtab-as-proc-mounts.patch
|
||||
Patch42: autofs-5.0.3-fix-ifc-buff-size.patch
|
||||
Patch43: autofs-5.0.3-fix-percent-hack.patch
|
||||
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, libxml2-devel, cyrus-sasl-devel, openssl-devel module-init-tools util-linux nfs-utils e2fsprogs
|
||||
Requires: kernel >= 2.6.17
|
||||
@ -147,6 +168,29 @@ fi
|
||||
%{_libdir}/autofs/
|
||||
|
||||
%changelog
|
||||
* Mon Aug 25 2008 Ian Kent <ikent@redhat.com> - 5.0.3-21
|
||||
- add upstream bug fix patches
|
||||
- add command line option to override is running check.
|
||||
- don't use proc fs for is running check.
|
||||
- fix fail on included browse map not found.
|
||||
- fix incorrect multi source messages.
|
||||
- clear stale flag on map read.
|
||||
- fix proximity other rpc ping timeout.
|
||||
- refactor mount request vars code.
|
||||
- make handle_mounts startup condition distinct.
|
||||
- fix submount shutdown handling.
|
||||
- try not to block on expire.
|
||||
- add configuration paramter UMOUNT_WAIT.
|
||||
- fix multi mount race.
|
||||
- fix nfs4 colon escape handling.
|
||||
- check replicated list after probe.
|
||||
- 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.
|
||||
- fix interface config buffer size.
|
||||
- fix percent hack heap corruption.
|
||||
|
||||
* Mon Jul 14 2008 Tom "spot" Callaway <tcallawa@redhat.com> - 5.0.3-19
|
||||
- change conflicts to requires
|
||||
- fix license tag
|
||||
|
||||
Loading…
Reference in New Issue
Block a user