- add current released upstream patches plus fix incorrect committer changelog entries.

This commit is contained in:
Ian Kent 2016-01-20 12:50:32 +08:00
parent 4ab0285116
commit 1cd346b242
51 changed files with 7811 additions and 4 deletions

View File

@ -0,0 +1,243 @@
autofs-5.1.1 - Add a mode option for master map entries
From: Cyril B <cbay@excellency.fr>
Add a --mode map option to change the mode for the base location mount
point. If this option is given, autofs will chmod the mount point right
after mounting it (as the kernel autofs filesystem doesn't support a
'mode' option).
Changing the mode of the base location mount point is normally not needed,
but if one wants to do that, it's much better to do it inside autofs rather
than outside to avoid race conditions and making sure the correct permissions
are always set.
Signed-off-by: Cyril B <cbay@excellency.fr>
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 4 ++++
daemon/indirect.c | 4 ++++
include/automount.h | 1 +
lib/master.c | 1 +
lib/master_parse.y | 9 ++++++++-
lib/master_tok.l | 19 ++++++++++++++++++-
man/auto.master.5.in | 5 +++++
8 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 8d27e55..f954018 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -22,6 +22,7 @@
- add configuration option to use fqdn in mounts.
- fix out of order call in program map lookup.
- fix error handling of is_mounted().
+- Add a mode option for master map entries.
21/04/2015 autofs-5.1.1
=======================
diff --git a/daemon/direct.c b/daemon/direct.c
index 5569299..1962a58 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -339,6 +339,7 @@ int do_mount_autofs_direct(struct autofs_point *ap,
int status, ret, ioctlfd;
const char *map_name;
time_t runfreq;
+ int err;
if (timeout) {
/* Calculate the expire run frequency */
@@ -433,6 +434,9 @@ int do_mount_autofs_direct(struct autofs_point *ap,
goto out_umount;
}
+ if (ap->mode && (err = chmod(me->key, ap->mode)))
+ warn(ap->logopt, "failed to change mode of %s", me->key);
+
ops->open(ap->logopt, &ioctlfd, st.st_dev, me->key);
if (ioctlfd < 0) {
crit(ap->logopt, "failed to create ioctl fd for %s", me->key);
diff --git a/daemon/indirect.c b/daemon/indirect.c
index a04a624..bfd181d 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -95,6 +95,7 @@ static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root)
struct stat st;
struct mnt_list *mnts;
int ret;
+ int err;
ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
@@ -163,6 +164,9 @@ static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root)
goto out_umount;
}
+ if (ap->mode && (err = chmod(root, ap->mode)))
+ warn(ap->logopt, "failed to change mode of %s", ap->path);
+
if (ops->open(ap->logopt, &ap->ioctlfd, st.st_dev, root)) {
crit(ap->logopt,
"failed to create ioctl fd for autofs path %s", ap->path);
diff --git a/include/automount.h b/include/automount.h
index 3ea2381..c56e265 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -508,6 +508,7 @@ struct kernel_mod_version {
struct autofs_point {
pthread_t thid;
char *path; /* Mount point name */
+ mode_t mode; /* Mount point mode */
char *pref; /* amd prefix */
int pipefd; /* File descriptor for pipe */
int kpipefd; /* Kernel end descriptor for pipe */
diff --git a/lib/master.c b/lib/master.c
index 6c38b1c..4588fa7 100644
--- a/lib/master.c
+++ b/lib/master.c
@@ -129,6 +129,7 @@ int master_add_autofs_point(struct master_mapent *entry, unsigned logopt,
free(ap);
return 0;
}
+ ap->mode = 0;
entry->ap = ap;
diff --git a/lib/master_parse.y b/lib/master_parse.y
index 9da78fc..0011429 100644
--- a/lib/master_parse.y
+++ b/lib/master_parse.y
@@ -63,6 +63,7 @@ static unsigned ghost;
extern unsigned global_selection_options;
static unsigned random_selection;
static unsigned use_weight;
+static unsigned long mode;
static char **tmp_argv;
static int tmp_argc;
static char **local_argv;
@@ -101,7 +102,7 @@ static int master_fprintf(FILE *, char *, ...);
%token COMMENT
%token MAP
%token OPT_TIMEOUT OPT_NTIMEOUT OPT_NOBIND OPT_NOGHOST OPT_GHOST OPT_VERBOSE
-%token OPT_DEBUG OPT_RANDOM OPT_USE_WEIGHT OPT_SYMLINK
+%token OPT_DEBUG OPT_RANDOM OPT_USE_WEIGHT OPT_SYMLINK OPT_MODE
%token COLON COMMA NL DDASH
%type <strtype> map
%type <strtype> options
@@ -126,6 +127,7 @@ static int master_fprintf(FILE *, char *, ...);
%token <strtype> MAPXFN
%token <strtype> MAPNAME
%token <longtype> NUMBER
+%token <longtype> OCTALNUMBER
%token <strtype> OPTION
%start file
@@ -192,6 +194,7 @@ line:
| PATH OPT_GHOST { master_notify($1); YYABORT; }
| PATH OPT_NOGHOST { master_notify($1); YYABORT; }
| PATH OPT_VERBOSE { master_notify($1); YYABORT; }
+ | PATH OPT_MODE { master_notify($1); YYABORT; }
| PATH { master_notify($1); YYABORT; }
| QUOTE { master_notify($1); YYABORT; }
| OPTION { master_notify($1); YYABORT; }
@@ -576,6 +579,7 @@ daemon_option: OPT_TIMEOUT NUMBER { timeout = $2; }
| OPT_DEBUG { debug = 1; }
| OPT_RANDOM { random_selection = 1; }
| OPT_USE_WEIGHT { use_weight = 1; }
+ | OPT_MODE OCTALNUMBER { mode = $2; }
;
mount_option: OPTION
@@ -644,6 +648,7 @@ static void local_init_vars(void)
ghost = defaults_get_browse_mode();
random_selection = global_selection_options & MOUNT_FLAG_RANDOM_SELECT;
use_weight = 0;
+ mode = 0;
tmp_argv = NULL;
tmp_argc = 0;
local_argv = NULL;
@@ -847,6 +852,8 @@ int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigne
entry->ap->flags |= MOUNT_FLAG_SYMLINK;
if (negative_timeout)
entry->ap->negative_timeout = negative_timeout;
+ if (mode && mode < LONG_MAX)
+ entry->ap->mode = mode;
/*
source = master_find_map_source(entry, type, format,
diff --git a/lib/master_tok.l b/lib/master_tok.l
index c692e14..b32918d 100644
--- a/lib/master_tok.l
+++ b/lib/master_tok.l
@@ -84,7 +84,7 @@ unsigned int tlen;
%option nounput
-%x PATHSTR MAPSTR DNSTR OPTSTR
+%x PATHSTR MAPSTR DNSTR OPTSTR OCTAL
WS [[:blank:]]+
OPTWS [[:blank:]]*
@@ -95,6 +95,7 @@ OPTIONSTR ([\-]?([[:alpha:]_]([[:alnum:]_\-])*(=(\"?([[:alnum:]_\-\:])+\"?))?)+)
MACROSTR (-D{OPTWS}([[:alpha:]_]([[:alnum:]_\-\.])*)=([[:alnum:]_\-\.])+)
SLASHIFYSTR (--(no-)?slashify-colons)
NUMBER [0-9]+
+OCTALNUMBER [0-7]+
DNSERVSTR1 ([[:alpha:]][[:alnum:]\-.]*(:[0-9]+)?:)
DNSERVSTR2 (\[([[:xdigit:]]:.)+\](:[0-9]+)?:)
@@ -125,6 +126,8 @@ MTYPE ((file|program|exec|sss|yp|nis|nisplus|ldap|ldaps|hesiod|userdir)(,(sun|h
OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS})
OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeout{OPTWS}={OPTWS})
+MODE (--mode{OPTWS}|--mode{OPTWS}={OPTWS})
+
%%
<INITIAL>{
@@ -392,6 +395,11 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeo
-w|--use-weight-only { return(OPT_USE_WEIGHT); }
-r|--random-multimount-selection { return(OPT_RANDOM); }
+ {MODE}/{OCTALNUMBER} {
+ BEGIN(OCTAL);
+ return(OPT_MODE);
+ }
+
{OPTWS}","{OPTWS} { return(COMMA); }
{OPTWS} {}
@@ -423,6 +431,15 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeo
<<EOF>> { BEGIN(INITIAL); }
}
+<OCTAL>{
+ {OCTALNUMBER} {
+ master_lval.longtype = strtoul(master_text, NULL, 8);
+ return(OCTALNUMBER);
+ }
+
+ . { BEGIN(OPTSTR); yyless(0); }
+}
+
%%
#include "automount.h"
diff --git a/man/auto.master.5.in b/man/auto.master.5.in
index 2e475dc..ba28494 100644
--- a/man/auto.master.5.in
+++ b/man/auto.master.5.in
@@ -211,6 +211,11 @@ or in the configuration.
Set the timeout for caching failed key lookups. This option can be
used to override the global default given either on the command line
or in the configuration.
+.TP
+.I "\-\-mode <octal_mode>"
+Set the directory mode for the base location of the \fBautofs\fP mount point.
+If this option is given, \fBautofs\fP will chmod that directory with this
+mode.
.SH BUILTIN MAP \-hosts
If "\-hosts" is given as the map then accessing a key under the mount point
which corresponds to a hostname will allow access to the exports of that

View File

@ -0,0 +1,198 @@
autofs-5.1.1 - add configuration option to use fqdn in mounts
From: Ian Kent <raven@themaw.net>
When a server name returns multiple IP addresses autofs uses the IP
address when performing the mount to ensure that the the host proximity
order is respected, and that servers that aren't responding aren't
tried.
But sometimes people need to use the server name for the mount so
add a configuration option to enable that.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
include/defaults.h | 3 +++
lib/defaults.c | 18 ++++++++++++++++++
man/autofs.conf.5.in | 18 ++++++++++++++++++
modules/mount_nfs.c | 3 ++-
modules/replicated.c | 6 ++++++
redhat/autofs.conf.default.in | 8 ++++++++
samples/autofs.conf.default.in | 8 ++++++++
8 files changed, 64 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index 2b8d224..2c516e4 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -19,6 +19,7 @@
- fix update_hosts_mounts() return.
- change lookup to use reinit instead of reopen.
- update map_hash_table_size description.
+- add configuration option to use fqdn in mounts.
21/04/2015 autofs-5.1.1
=======================
diff --git a/include/defaults.h b/include/defaults.h
index 4f32e12..3788078 100644
--- a/include/defaults.h
+++ b/include/defaults.h
@@ -47,6 +47,8 @@
#define DEFAULT_MAP_HASH_TABLE_SIZE "1024"
+#define DEFAULT_USE_HOSTNAME_FOR_MOUNTS "0"
+
/* Config entry flags */
#define CONF_NONE 0x00000000
#define CONF_ENV 0x00000001
@@ -162,6 +164,7 @@ unsigned int defaults_get_mount_wait(void);
unsigned int defaults_get_umount_wait(void);
const char *defaults_get_auth_conf_file(void);
unsigned int defaults_get_map_hash_table_size(void);
+unsigned int defaults_use_hostname_for_mounts(void);
unsigned int conf_amd_mount_section_exists(const char *);
char *conf_amd_get_arch(void);
diff --git a/lib/defaults.c b/lib/defaults.c
index 74fafc5..7159536 100644
--- a/lib/defaults.c
+++ b/lib/defaults.c
@@ -73,6 +73,8 @@
#define NAME_MAP_HASH_TABLE_SIZE "map_hash_table_size"
+#define NAME_USE_HOSTNAME_FOR_MOUNTS "use_hostname_for_mounts"
+
#define NAME_AMD_ARCH "arch"
#define NAME_AMD_AUTO_ATTRCACHE "auto_attrcache"
#define NAME_AMD_AUTO_DIR "auto_dir"
@@ -335,6 +337,11 @@ static int conf_load_autofs_defaults(void)
if (ret == CFG_FAIL)
goto error;
+ ret = conf_update(sec, NAME_USE_HOSTNAME_FOR_MOUNTS,
+ DEFAULT_USE_HOSTNAME_FOR_MOUNTS, CONF_ENV);
+ if (ret == CFG_FAIL)
+ goto error;
+
/* LDAP_URI and SEARCH_BASE can occur multiple times */
while ((co = conf_lookup(sec, NAME_LDAP_URI)))
conf_delete(co->section, co->name);
@@ -1701,6 +1708,17 @@ unsigned int defaults_get_map_hash_table_size(void)
return (unsigned int) size;
}
+unsigned int defaults_use_hostname_for_mounts(void)
+{
+ int res;
+
+ res = conf_get_yesno(autofs_gbl_sec, NAME_USE_HOSTNAME_FOR_MOUNTS);
+ if (res < 0)
+ res = atoi(DEFAULT_USE_HOSTNAME_FOR_MOUNTS);
+
+ return res;
+}
+
unsigned int conf_amd_mount_section_exists(const char *section)
{
return conf_section_exists(section);
diff --git a/man/autofs.conf.5.in b/man/autofs.conf.5.in
index 4434eb8..6eb5d02 100644
--- a/man/autofs.conf.5.in
+++ b/man/autofs.conf.5.in
@@ -111,6 +111,24 @@ entries, in this case, is usually much less than the number of entries
in the map. In this last case it would be unusual for the map entry
cache to grow large enough to warrant increasing the default before
an event that cleans stale entries, a map re-read for example.
+.TP
+.B use_hostname_for_mounts
+.br
+NFS mounts where the host name resolves to more than one IP address
+are probed for availability and to establish the order in which mounts
+to them should be tried. To ensure that mount attempts are made only
+to hosts that are responding and are tried in the order of hosts with
+the quickest response the IP address of the host needs to be used for
+the mount.
+
+If it is necessary to use the hostname given in the map entry for the
+mount regardless, then set this option to "yes".
+
+Be aware that if this is done there is no defense against the host
+name resolving to one that isn't responding and while the number
+of attempts at a successful mount will correspond to the number of
+addresses the host name resolves to the order will also not correspond
+to fastest responding hosts.
.SS LDAP Configuration
.P
Configuration settings available are:
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
index 15e1043..aa786f3 100644
--- a/modules/mount_nfs.c
+++ b/modules/mount_nfs.c
@@ -316,7 +316,8 @@ dont_probe:
/* Not a local host - do an NFS mount */
- if (this->rr && this->addr) {
+ if (this->rr && this->addr &&
+ !defaults_use_hostname_for_mounts()) {
socklen_t len = INET6_ADDRSTRLEN;
char n_buf[len + 1];
const char *n_addr;
diff --git a/modules/replicated.c b/modules/replicated.c
index 32860d5..8437f5f 100644
--- a/modules/replicated.c
+++ b/modules/replicated.c
@@ -667,6 +667,12 @@ int prune_host_list(unsigned logopt, struct host **list,
if (!*list)
return 0;
+ /* If we're using the host name then there's no point probing
+ * avialability and respose time.
+ */
+ if (defaults_use_hostname_for_mounts())
+ return 1;
+
/* Use closest hosts to choose NFS version */
first = *list;
diff --git a/redhat/autofs.conf.default.in b/redhat/autofs.conf.default.in
index da0882f..b751043 100644
--- a/redhat/autofs.conf.default.in
+++ b/redhat/autofs.conf.default.in
@@ -142,6 +142,14 @@ mount_nfs_default_protocol = 4
#
#map_hash_table_size = 1024
#
+# use_hostname_for_mounts - nfs mounts where the host name resolves
+# to more than one IP address normally need
+# to use the IP address to esure a mount to
+# a host that isn't responding isn't done.
+# If that behaviour is not wanted then set
+# ths to "yes", default is "no".
+#
+#use_hostname_for_mounts = "no"
#
# Otions for the amd parser within autofs.
#
diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in
index 80abb43..4b48c63 100644
--- a/samples/autofs.conf.default.in
+++ b/samples/autofs.conf.default.in
@@ -141,6 +141,14 @@ browse_mode = no
#
#map_hash_table_size = 1024
#
+# use_hostname_for_mounts - nfs mounts where the host name resolves
+# to more than one IP address normally need
+# to use the IP address to esure a mount to
+# a host that isn't responding isn't done.
+# If that behaviour is not wanted then set
+# ths to "yes", default is "no".
+#
+#use_hostname_for_mounts = "no"
#
# Otions for the amd parser within autofs.
#

View File

@ -0,0 +1,666 @@
autofs-5.1.1 - add reinit entry point to modules
From: Ian Kent <raven@themaw.net>
In order to avoid closing and then re-opening lookup modules
on HUP signal (since there init entry point needs to be called
for initialization) add a reinit entry point to lookup, parse
and mount modules.
Signed-off-by: Ian Kent <raven@themaw.net>
---
daemon/module.c | 39 +++++++++++++++++++++++++++++++++++++++
include/automount.h | 15 +++++++++++++++
modules/lookup_dir.c | 9 ++++++++-
modules/lookup_file.c | 9 ++++++++-
modules/lookup_hesiod.c | 9 ++++++++-
modules/lookup_hosts.c | 9 ++++++++-
modules/lookup_ldap.c | 9 ++++++++-
modules/lookup_multi.c | 9 ++++++++-
modules/lookup_nisplus.c | 9 ++++++++-
modules/lookup_program.c | 9 ++++++++-
modules/lookup_sss.c | 9 ++++++++-
modules/lookup_userhome.c | 9 ++++++++-
modules/lookup_yp.c | 9 ++++++++-
modules/mount_afs.c | 5 +++++
modules/mount_autofs.c | 5 +++++
modules/mount_bind.c | 5 +++++
modules/mount_changer.c | 5 +++++
modules/mount_ext2.c | 5 +++++
modules/mount_generic.c | 5 +++++
modules/mount_nfs.c | 5 +++++
modules/parse_amd.c | 5 +++++
modules/parse_hesiod.c | 5 +++++
modules/parse_sun.c | 5 +++++
23 files changed, 192 insertions(+), 11 deletions(-)
diff --git a/daemon/module.c b/daemon/module.c
index 9028aaa..3bd7a0c 100644
--- a/daemon/module.c
+++ b/daemon/module.c
@@ -105,6 +105,7 @@ int open_lookup(const char *name, const char *err_prefix, const char *mapfmt,
}
if (!(mod->lookup_init = (lookup_init_t) dlsym(dh, "lookup_init")) ||
+ !(mod->lookup_reinit = (lookup_reinit_t) dlsym(dh, "lookup_reinit")) ||
!(mod->lookup_read_master = (lookup_read_master_t) dlsym(dh, "lookup_read_master")) ||
!(mod->lookup_read_map = (lookup_read_map_t) dlsym(dh, "lookup_read_map")) ||
!(mod->lookup_mount = (lookup_mount_t) dlsym(dh, "lookup_mount")) ||
@@ -127,6 +128,19 @@ int open_lookup(const char *name, const char *err_prefix, const char *mapfmt,
return NSS_STATUS_SUCCESS;
}
+int reinit_lookup(struct lookup_mod *mod, const char *name,
+ const char *err_prefix, const char *mapfmt,
+ int argc, const char *const *argv)
+{
+ if (mod->lookup_reinit(mapfmt, argc, argv, &mod->context)) {
+ if (err_prefix)
+ logerr("%scould not reinit lookup module %s",
+ err_prefix, name);
+ return 1;
+ }
+ return 0;
+}
+
int close_lookup(struct lookup_mod *mod)
{
int rv = mod->lookup_done(mod->context);
@@ -185,6 +199,7 @@ struct parse_mod *open_parse(const char *name, const char *err_prefix,
}
if (!(mod->parse_init = (parse_init_t) dlsym(dh, "parse_init")) ||
+ !(mod->parse_reinit = (parse_reinit_t) dlsym(dh, "parse_reinit")) ||
!(mod->parse_mount = (parse_mount_t) dlsym(dh, "parse_mount")) ||
!(mod->parse_done = (parse_done_t) dlsym(dh, "parse_done"))) {
if (err_prefix)
@@ -204,6 +219,18 @@ struct parse_mod *open_parse(const char *name, const char *err_prefix,
return mod;
}
+int reinit_parse(struct parse_mod *mod, const char *name,
+ const char *err_prefix, int argc, const char *const *argv)
+{
+ if (mod->parse_reinit(argc, argv, &mod->context)) {
+ if (err_prefix)
+ logerr("%scould not reinit parse module %s",
+ err_prefix, name);
+ return 1;
+ }
+ return 0;
+}
+
int close_parse(struct parse_mod *mod)
{
int rv = mod->parse_done(mod->context);
@@ -261,6 +288,7 @@ struct mount_mod *open_mount(const char *name, const char *err_prefix)
}
if (!(mod->mount_init = (mount_init_t) dlsym(dh, "mount_init")) ||
+ !(mod->mount_reinit = (mount_reinit_t) dlsym(dh, "mount_reinit")) ||
!(mod->mount_mount = (mount_mount_t) dlsym(dh, "mount_mount")) ||
!(mod->mount_done = (mount_done_t) dlsym(dh, "mount_done"))) {
if (err_prefix)
@@ -280,6 +308,17 @@ struct mount_mod *open_mount(const char *name, const char *err_prefix)
return mod;
}
+int reinit_mount(struct mount_mod *mod, const char *name, const char *err_prefix)
+{
+ if (mod->mount_reinit(&mod->context)) {
+ if (err_prefix)
+ logerr("%scould not reinit mount module %s",
+ err_prefix, name);
+ return 1;
+ }
+ return 0;
+}
+
int close_mount(struct mount_mod *mod)
{
int rv = mod->mount_done(mod->context);
diff --git a/include/automount.h b/include/automount.h
index d614c10..ab3e360 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -281,12 +281,14 @@ int lookup_source_close_ioctlfd(struct autofs_point *ap, const char *key);
#ifdef MODULE_LOOKUP
int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context);
+int lookup_reinit(const char *mapfmt, int argc, const char *const *argv, void **context);
int lookup_read_master(struct master *master, time_t age, void *context);
int lookup_read_map(struct autofs_point *, time_t, void *context);
int lookup_mount(struct autofs_point *, const char *, int, void *);
int lookup_done(void *);
#endif
typedef int (*lookup_init_t) (const char *, int, const char *const *, void **);
+typedef int (*lookup_reinit_t) (const char *, int, const char *const *, void **);
typedef int (*lookup_read_master_t) (struct master *master, time_t, void *);
typedef int (*lookup_read_map_t) (struct autofs_point *, time_t, void *);
typedef int (*lookup_mount_t) (struct autofs_point *, const char *, int, void *);
@@ -294,6 +296,7 @@ typedef int (*lookup_done_t) (void *);
struct lookup_mod {
lookup_init_t lookup_init;
+ lookup_reinit_t lookup_reinit;
lookup_read_master_t lookup_read_master;
lookup_read_map_t lookup_read_map;
lookup_mount_t lookup_mount;
@@ -304,6 +307,9 @@ struct lookup_mod {
int open_lookup(const char *name, const char *err_prefix, const char *mapfmt,
int argc, const char *const *argv, struct lookup_mod **lookup);
+int reinit_lookup(struct lookup_mod *mod, const char *name,
+ const char *err_prefix, const char *mapfmt,
+ int argc, const char *const *argv);
int close_lookup(struct lookup_mod *);
/* parse module */
@@ -312,16 +318,19 @@ int close_lookup(struct lookup_mod *);
#ifdef MODULE_PARSE
int parse_init(int argc, const char *const *argv, void **context);
+int parse_reinit(int argc, const char *const *argv, void **context);
int parse_mount(struct autofs_point *ap, const char *name,
int name_len, const char *mapent, void *context);
int parse_done(void *);
#endif
typedef int (*parse_init_t) (int, const char *const *, void **);
+typedef int (*parse_reinit_t) (int, const char *const *, void **);
typedef int (*parse_mount_t) (struct autofs_point *, const char *, int, const char *, void *);
typedef int (*parse_done_t) (void *);
struct parse_mod {
parse_init_t parse_init;
+ parse_reinit_t parse_reinit;
parse_mount_t parse_mount;
parse_done_t parse_done;
void *dlhandle;
@@ -330,6 +339,8 @@ struct parse_mod {
struct parse_mod *open_parse(const char *name, const char *err_prefix,
int argc, const char *const *argv);
+int reinit_parse(struct parse_mod *, const char *name,
+ const char *err_prefix, int argc, const char *const *argv);
int close_parse(struct parse_mod *);
/* mount module */
@@ -338,17 +349,20 @@ int close_parse(struct parse_mod *);
#ifdef MODULE_MOUNT
int mount_init(void **context);
+int mount_reinit(void **context);
int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len,
const char *what, const char *fstype, const char *options, void *context);
int mount_done(void *context);
#endif
typedef int (*mount_init_t) (void **);
+typedef int (*mount_reinit_t) (void **);
typedef int (*mount_mount_t) (struct autofs_point *, const char *, const char *, int,
const char *, const char *, const char *, void *);
typedef int (*mount_done_t) (void *);
struct mount_mod {
mount_init_t mount_init;
+ mount_reinit_t mount_reinit;
mount_mount_t mount_mount;
mount_done_t mount_done;
void *dlhandle;
@@ -356,6 +370,7 @@ struct mount_mod {
};
struct mount_mod *open_mount(const char *name, const char *err_prefix);
+int reinit_mount(struct mount_mod *mod, const char *name, const char *err_prefix);
int close_mount(struct mount_mod *);
/* buffer management */
diff --git a/modules/lookup_dir.c b/modules/lookup_dir.c
index cbeda1f..7a95e24 100644
--- a/modules/lookup_dir.c
+++ b/modules/lookup_dir.c
@@ -51,7 +51,8 @@ struct lookup_context {
int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context)
+int lookup_init(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
{
struct lookup_context *ctxt;
char buf[MAX_ERR_BUF];
@@ -105,6 +106,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
return 0;
}
+int lookup_reinit(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
+{
+ return 0;
+}
+
static int acceptable_dirent_p(const struct dirent *e)
{
size_t namesz;
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index 7c982c6..c32a4cd 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -50,7 +50,8 @@ struct lookup_context {
int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context)
+int lookup_init(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
{
struct lookup_context *ctxt;
char buf[MAX_ERR_BUF];
@@ -112,6 +113,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
return 0;
}
+int lookup_reinit(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
+{
+ return 0;
+}
+
static int read_one(unsigned logopt, FILE *f, char *key, unsigned int *k_len, char *mapent, unsigned int *m_len)
{
char *kptr, *p;
diff --git a/modules/lookup_hesiod.c b/modules/lookup_hesiod.c
index 526f294..de5ec08 100644
--- a/modules/lookup_hesiod.c
+++ b/modules/lookup_hesiod.c
@@ -39,7 +39,8 @@ int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
/* This initializes a context (persistent non-global data) for queries to
this module. */
-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context)
+int lookup_init(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
{
struct lookup_context *ctxt = NULL;
char buf[MAX_ERR_BUF];
@@ -96,6 +97,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
return 0;
}
+int lookup_reinit(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
+{
+ return 0;
+}
+
int lookup_read_master(struct master *master, time_t age, void *context)
{
return NSS_STATUS_UNKNOWN;
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
index 53aa9d6..8ba0a4a 100644
--- a/modules/lookup_hosts.c
+++ b/modules/lookup_hosts.c
@@ -46,7 +46,8 @@ int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
exports rpc_get_exports(const char *host, long seconds, long micros, unsigned int option);
void rpc_exports_free(exports list);
-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context)
+int lookup_init(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
{
struct lookup_context *ctxt;
char buf[MAX_ERR_BUF];
@@ -73,6 +74,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
return 0;
}
+int lookup_reinit(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
+{
+ return 0;
+}
+
int lookup_read_master(struct master *master, time_t age, void *context)
{
return NSS_STATUS_UNKNOWN;
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index d846d8e..0f5bc48 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -1687,7 +1687,8 @@ static void validate_uris(struct list_head *list)
* This initializes a context (persistent non-global data) for queries to
* this module. Return zero if we succeed.
*/
-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context)
+int lookup_init(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
{
unsigned int is_amd_format;
struct lookup_context *ctxt;
@@ -1835,6 +1836,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
return 0;
}
+int lookup_reinit(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
+{
+ return 0;
+}
+
int lookup_read_master(struct master *master, time_t age, void *context)
{
struct lookup_context *ctxt = (struct lookup_context *) context;
diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c
index ba8d4f0..0ee20f5 100644
--- a/modules/lookup_multi.c
+++ b/modules/lookup_multi.c
@@ -150,7 +150,8 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch
return NULL;
}
-int lookup_init(const char *my_mapfmt, int argc, const char *const *argv, void **context)
+int lookup_init(const char *my_mapfmt,
+ int argc, const char *const *argv, void **context)
{
struct lookup_context *ctxt;
char buf[MAX_ERR_BUF];
@@ -244,6 +245,12 @@ error_out:
return 1;
}
+int lookup_reinit(const char *my_mapfmt,
+ int argc, const char *const *argv, void **context)
+{
+ return 0;
+}
+
int lookup_read_master(struct master *master, time_t age, void *context)
{
return NSS_STATUS_UNKNOWN;
diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
index d5eba47..0c66152 100644
--- a/modules/lookup_nisplus.c
+++ b/modules/lookup_nisplus.c
@@ -30,7 +30,8 @@ struct lookup_context {
int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context)
+int lookup_init(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
{
struct lookup_context *ctxt;
char buf[MAX_ERR_BUF];
@@ -76,6 +77,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
return 0;
}
+int lookup_reinit(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
+{
+ return 0;
+}
+
int lookup_read_master(struct master *master, time_t age, void *context)
{
struct lookup_context *ctxt = (struct lookup_context *) context;
diff --git a/modules/lookup_program.c b/modules/lookup_program.c
index a3a7e98..fa4f54d 100644
--- a/modules/lookup_program.c
+++ b/modules/lookup_program.c
@@ -49,7 +49,8 @@ struct parse_context {
int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context)
+int lookup_init(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
{
struct lookup_context *ctxt;
char buf[MAX_ERR_BUF];
@@ -100,6 +101,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
return 0;
}
+int lookup_reinit(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
+{
+ return 0;
+}
+
int lookup_read_master(struct master *master, time_t age, void *context)
{
return NSS_STATUS_UNKNOWN;
diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c
index 720b5e3..c58a272 100644
--- a/modules/lookup_sss.c
+++ b/modules/lookup_sss.c
@@ -56,7 +56,8 @@ struct lookup_context {
int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context)
+int lookup_init(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
{
struct lookup_context *ctxt;
char buf[MAX_ERR_BUF];
@@ -137,6 +138,12 @@ lib_names_fail:
return 1;
}
+int lookup_reinit(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
+{
+ return 0;
+}
+
static int setautomntent(unsigned int logopt,
struct lookup_context *ctxt, const char *mapname,
void **sss_ctxt)
diff --git a/modules/lookup_userhome.c b/modules/lookup_userhome.c
index fb3caaa..c21dee9 100644
--- a/modules/lookup_userhome.c
+++ b/modules/lookup_userhome.c
@@ -29,7 +29,14 @@
int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context)
+int lookup_init(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
+{
+ return 0; /* Nothing to do */
+}
+
+int lookup_reinit(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
{
return 0; /* Nothing to do */
}
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
index fcf470a..1e5a7ed 100644
--- a/modules/lookup_yp.c
+++ b/modules/lookup_yp.c
@@ -103,7 +103,8 @@ static unsigned int get_map_order(const char *domain, const char *map)
return (unsigned int) last_changed;
}
-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context)
+int lookup_init(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
{
struct lookup_context *ctxt;
char buf[MAX_ERR_BUF];
@@ -165,6 +166,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
return 0;
}
+int lookup_reinit(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
+{
+ return 0;
+}
+
int yp_all_master_callback(int status, char *ypkey, int ypkeylen,
char *val, int vallen, char *ypcb_data)
{
diff --git a/modules/mount_afs.c b/modules/mount_afs.c
index 50628ce..2a776bd 100644
--- a/modules/mount_afs.c
+++ b/modules/mount_afs.c
@@ -25,6 +25,11 @@ int mount_init(void **context)
return 0;
}
+int mount_reinit(void **context)
+{
+ return 0;
+}
+
int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len,
const char *what, const char *fstype, const char *options, void *context)
{
diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c
index 4846e7f..39948e6 100644
--- a/modules/mount_autofs.c
+++ b/modules/mount_autofs.c
@@ -39,6 +39,11 @@ int mount_init(void **context)
return 0;
}
+int mount_reinit(void **context)
+{
+ return 0;
+}
+
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)
diff --git a/modules/mount_bind.c b/modules/mount_bind.c
index ac954e3..4864ea5 100644
--- a/modules/mount_bind.c
+++ b/modules/mount_bind.c
@@ -67,6 +67,11 @@ out:
return 0;
}
+int mount_reinit(void **context)
+{
+ return 0;
+}
+
int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len,
const char *what, const char *fstype, const char *options, void *context)
{
diff --git a/modules/mount_changer.c b/modules/mount_changer.c
index 5e2b47c..798f23b 100644
--- a/modules/mount_changer.c
+++ b/modules/mount_changer.c
@@ -41,6 +41,11 @@ int mount_init(void **context)
return 0;
}
+int mount_reinit(void **context)
+{
+ return 0;
+}
+
int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len,
const char *what, const char *fstype, const char *options, void *context)
{
diff --git a/modules/mount_ext2.c b/modules/mount_ext2.c
index 3c87512..c00e3d5 100644
--- a/modules/mount_ext2.c
+++ b/modules/mount_ext2.c
@@ -33,6 +33,11 @@ int mount_init(void **context)
return 0;
}
+int mount_reinit(void **context)
+{
+ return 0;
+}
+
int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len,
const char *what, const char *fstype, const char *options, void *context)
{
diff --git a/modules/mount_generic.c b/modules/mount_generic.c
index c4108e6..ae63787 100644
--- a/modules/mount_generic.c
+++ b/modules/mount_generic.c
@@ -33,6 +33,11 @@ int mount_init(void **context)
return 0;
}
+int mount_reinit(void **context)
+{
+ return 0;
+}
+
int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len,
const char *what, const char *fstype, const char *options,
void *context)
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
index 315fc99..15e1043 100644
--- a/modules/mount_nfs.c
+++ b/modules/mount_nfs.c
@@ -54,6 +54,11 @@ int mount_init(void **context)
return !mount_bind;
}
+int mount_reinit(void **context)
+{
+ return 0;
+}
+
int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len,
const char *what, const char *fstype, const char *options,
void *context)
diff --git a/modules/parse_amd.c b/modules/parse_amd.c
index 2e3d21f..0626bf4 100644
--- a/modules/parse_amd.c
+++ b/modules/parse_amd.c
@@ -130,6 +130,11 @@ int parse_init(int argc, const char *const *argv, void **context)
return 0;
}
+int parse_reinit(int argc, const char *const *argv, void **context)
+{
+ return 0;
+}
+
static struct substvar *add_lookup_vars(struct autofs_point *ap,
const char *key, int key_len,
struct map_source *source,
diff --git a/modules/parse_hesiod.c b/modules/parse_hesiod.c
index 237fd50..0b2b57f 100644
--- a/modules/parse_hesiod.c
+++ b/modules/parse_hesiod.c
@@ -261,6 +261,11 @@ int parse_init(int argc, const char *const *argv, void **context)
return 0;
}
+int parse_reinit(int argc, const char *const *argv, void **context)
+{
+ return 0;
+}
+
int parse_done(void *context)
{
return 0;
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 10dbd0c..35d6da5 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -413,6 +413,11 @@ options_done:
return 0;
}
+int parse_reinit(int argc, const char *const *argv, void **context)
+{
+ return 0;
+}
+
static const char *parse_options(const char *str, char **ret, unsigned int logopt)
{
const char *cp = str;

View File

@ -0,0 +1,101 @@
autofs-5.1.1 - add type to struct lookup_mod
From: Ian Kent <raven@themaw.net>
Add opened map type field to struct lookup_mod for module comparison
during reinit.
Signed-off-by: Ian Kent <raven@themaw.net>
---
daemon/module.c | 18 ++++++++++++++++++
include/automount.h | 1 +
2 files changed, 19 insertions(+)
diff --git a/daemon/module.c b/daemon/module.c
index 3bd7a0c..d9921f4 100644
--- a/daemon/module.c
+++ b/daemon/module.c
@@ -61,6 +61,7 @@ int open_lookup(const char *name, const char *err_prefix, const char *mapfmt,
char buf[MAX_ERR_BUF];
char fnbuf[PATH_MAX];
size_t size;
+ char *type;
void *dh;
int *ver;
@@ -75,10 +76,20 @@ int open_lookup(const char *name, const char *err_prefix, const char *mapfmt,
return NSS_STATUS_UNAVAIL;
}
+ type = strdup(name);
+ if (!type) {
+ free(mod);
+ if (err_prefix) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ logerr("%s%s", err_prefix, estr);
+ }
+ }
+
size = snprintf(fnbuf, sizeof(fnbuf),
"%s/lookup_%s.so", AUTOFS_LIB_DIR, name);
if (size >= sizeof(fnbuf)) {
free(mod);
+ free(type);
if (err_prefix) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
logerr("%s%s", err_prefix, estr);
@@ -91,6 +102,7 @@ int open_lookup(const char *name, const char *err_prefix, const char *mapfmt,
logerr("%scannot open lookup module %s (%s)",
err_prefix, name, dlerror());
free(mod);
+ free(type);
return NSS_STATUS_UNAVAIL;
}
@@ -101,6 +113,7 @@ int open_lookup(const char *name, const char *err_prefix, const char *mapfmt,
err_prefix, name);
dlclose(dh);
free(mod);
+ free(type);
return NSS_STATUS_UNAVAIL;
}
@@ -114,14 +127,18 @@ int open_lookup(const char *name, const char *err_prefix, const char *mapfmt,
logerr("%slookup module %s corrupt", err_prefix, name);
dlclose(dh);
free(mod);
+ free(type);
return NSS_STATUS_UNAVAIL;
}
if (mod->lookup_init(mapfmt, argc, argv, &mod->context)) {
dlclose(dh);
free(mod);
+ free(type);
return NSS_STATUS_NOTFOUND;
}
+
+ mod->type = type;
mod->dlhandle = dh;
*lookup = mod;
@@ -145,6 +162,7 @@ int close_lookup(struct lookup_mod *mod)
{
int rv = mod->lookup_done(mod->context);
dlclose(mod->dlhandle);
+ free(mod->type);
free(mod);
return rv;
}
diff --git a/include/automount.h b/include/automount.h
index ab3e360..3ea2381 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -301,6 +301,7 @@ struct lookup_mod {
lookup_read_map_t lookup_read_map;
lookup_mount_t lookup_mount;
lookup_done_t lookup_done;
+ char *type;
void *dlhandle;
void *context;
};

View File

@ -0,0 +1,77 @@
autofs-5.1.1 - change lookup to use reinit instead of reopen
From: Ian Kent <raven@themaw.net>
When a HUP signal is received lookup module are cloed and then re-opened.
This can occassionally cause a problem with library data segemets and
lead to a SEGV.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/lookup.c | 32 +++++++++++++++++++++-----------
2 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 77aad99..16e5344 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -17,6 +17,7 @@
- fix direct map expire not set for initail empty map.
- fix missing source sss in multi map lookup.
- fix update_hosts_mounts() return.
+- change lookup to use reinit instead of reopen.
21/04/2015 autofs-5.1.1
=======================
diff --git a/daemon/lookup.c b/daemon/lookup.c
index 0579f98..afd14ab 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -300,17 +300,27 @@ static int do_read_map(struct autofs_point *ap, struct map_source *map, time_t a
struct lookup_mod *lookup;
int status;
- status = open_lookup(map->type, "", map->format,
- map->argc, map->argv, &lookup);
- if (status != NSS_STATUS_SUCCESS) {
- debug(ap->logopt, "lookup module %s failed", map->type);
- return status;
- }
-
+ lookup = NULL;
master_source_writelock(ap->entry);
- if (map->lookup)
- close_lookup(map->lookup);
- map->lookup = lookup;
+ if (!map->lookup) {
+ status = open_lookup(map->type, "", map->format,
+ map->argc, map->argv, &lookup);
+ if (status != NSS_STATUS_SUCCESS) {
+ master_source_unlock(ap->entry);
+ debug(ap->logopt,
+ "lookup module %s open failed", map->type);
+ return status;
+ }
+ map->lookup = lookup;
+ } else {
+ lookup = map->lookup;
+ status = lookup->lookup_reinit(map->format,
+ map->argc, map->argv,
+ &lookup->context);
+ if (status)
+ warn(ap->logopt,
+ "lookup module %s reinit failed", map->type);
+ }
master_source_unlock(ap->entry);
if (!map->stale)
@@ -742,7 +752,7 @@ int do_lookup_mount(struct autofs_point *ap, struct map_source *map, const char
map->format, map->argc, map->argv, &lookup);
if (status != NSS_STATUS_SUCCESS) {
debug(ap->logopt,
- "lookup module %s failed", map->type);
+ "lookup module %s open failed", map->type);
return status;
}
map->lookup = lookup;

View File

@ -0,0 +1,170 @@
autofs-5.1.1 - change remaining gettimeofday() to use clock_gettime()
From: Yu Ning <ning.yu@ubuntu.com>
The time returned by gettimeofday() is affected by discontinuous jumps
in the system time, so it causes an issue that autofs may not auto
unmount a mount point if system time is manually changed by the system
administrator.
To fix the issue we need to convert to using a monotonic clock source
instead of the clock source used by gettimeofday().
Change the reamining gettimeofday() function calls to clock_gettime()
calls.
Signed-off-by: Yu Ning <ning.yu@ubuntu.com>
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/rpc_subs.c | 9 ++++-----
modules/replicated.c | 30 ++++++++++++++----------------
3 files changed, 19 insertions(+), 21 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index c243a8a..49520d3 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -28,6 +28,7 @@
- define pending condition init helper function.
- use monotonic clock for direct mount condition.
- use monotonic clock for indirect mount condition.
+- change remaining gettimeofday() to use clock_gettime().
21/04/2015 autofs-5.1.1
=======================
diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c
index e0e1979..4a84c16 100644
--- a/lib/rpc_subs.c
+++ b/lib/rpc_subs.c
@@ -1092,19 +1092,18 @@ int rpc_time(const char *host,
{
int status;
double taken;
- struct timeval start, end;
- struct timezone tz;
+ struct timespec start, end;
int proto = (ping_proto & RPC_PING_UDP) ? IPPROTO_UDP : IPPROTO_TCP;
unsigned long vers = ping_vers;
- gettimeofday(&start, &tz);
+ clock_gettime(CLOCK_MONOTONIC, &start);
status = __rpc_ping(host, vers, proto, seconds, micros, option);
- gettimeofday(&end, &tz);
+ clock_gettime(CLOCK_MONOTONIC, &end);
if (status == RPC_PING_FAIL || status < 0)
return status;
- taken = elapsed(start, end);
+ taken = monotonic_elapsed(start, end);
if (result != NULL)
*result = taken;
diff --git a/modules/replicated.c b/modules/replicated.c
index 8437f5f..f4cae3e 100644
--- a/modules/replicated.c
+++ b/modules/replicated.c
@@ -231,8 +231,7 @@ static unsigned int get_nfs_info(unsigned logopt, struct host *host,
socklen_t len = INET6_ADDRSTRLEN;
char buf[len + 1];
struct pmap parms;
- struct timeval start, end;
- struct timezone tz;
+ struct timespec start, end;
unsigned int supported = 0;
double taken = 0;
int status, count = 0;
@@ -292,9 +291,9 @@ static unsigned int get_nfs_info(unsigned logopt, struct host *host,
supported = status;
goto done_ver;
} else if (!status) {
- gettimeofday(&start, &tz);
+ clock_gettime(CLOCK_MONOTONIC, &start);
status = rpc_ping_proto(rpc_info);
- gettimeofday(&end, &tz);
+ clock_gettime(CLOCK_MONOTONIC, &end);
if (status == -ETIMEDOUT) {
supported = status;
goto done_ver;
@@ -306,7 +305,7 @@ static unsigned int get_nfs_info(unsigned logopt, struct host *host,
debug(logopt,
"nfs v4 random selection time: %f", reply);
} else {
- reply = elapsed(start, end);
+ reply = monotonic_elapsed(start, end);
debug(logopt, "nfs v4 rpc ping time: %f", reply);
}
taken += reply;
@@ -351,9 +350,9 @@ v3_ver:
supported = status;
goto done_ver;
} else if (!status) {
- gettimeofday(&start, &tz);
+ clock_gettime(CLOCK_MONOTONIC, &start);
status = rpc_ping_proto(rpc_info);
- gettimeofday(&end, &tz);
+ clock_gettime(CLOCK_MONOTONIC, &end);
if (status == -ETIMEDOUT) {
supported = status;
goto done_ver;
@@ -365,7 +364,7 @@ v3_ver:
debug(logopt,
"nfs v3 random selection time: %f", reply);
} else {
- reply = elapsed(start, end);
+ reply = monotonic_elapsed(start, end);
debug(logopt, "nfs v3 rpc ping time: %f", reply);
}
taken += reply;
@@ -407,9 +406,9 @@ v2_ver:
supported = status;
goto done_ver;
} else if (!status) {
- gettimeofday(&start, &tz);
+ clock_gettime(CLOCK_MONOTONIC, &start);
status = rpc_ping_proto(rpc_info);
- gettimeofday(&end, &tz);
+ clock_gettime(CLOCK_MONOTONIC, &end);
if (status == -ETIMEDOUT)
supported = status;
else if (status > 0) {
@@ -420,7 +419,7 @@ v2_ver:
debug(logopt,
"nfs v2 random selection time: %f", reply);
} else {
- reply = elapsed(start, end);;
+ reply = monotonic_elapsed(start, end);;
debug(logopt, "nfs v2 rpc ping time: %f", reply);
}
taken += reply;
@@ -523,8 +522,7 @@ static int get_supported_ver_and_cost(unsigned logopt, struct host *host,
struct conn_info pm_info, rpc_info;
int proto;
unsigned int vers;
- struct timeval start, end;
- struct timezone tz;
+ struct timespec start, end;
double taken = 0;
time_t timeout = RPC_TIMEOUT;
int status = 0;
@@ -610,16 +608,16 @@ static int get_supported_ver_and_cost(unsigned logopt, struct host *host,
if (status == -EHOSTUNREACH)
goto done;
else if (!status) {
- gettimeofday(&start, &tz);
+ clock_gettime(CLOCK_MONOTONIC, &start);
status = rpc_ping_proto(&rpc_info);
- gettimeofday(&end, &tz);
+ clock_gettime(CLOCK_MONOTONIC, &end);
if (status > 0) {
if (random_selection) {
/* Random value between 0 and 1 */
taken = ((float) random())/((float) RAND_MAX+1);
debug(logopt, "random selection time %f", taken);
} else {
- taken = elapsed(start, end);
+ taken = monotonic_elapsed(start, end);
debug(logopt, "rpc ping time %f", taken);
}
}

View File

@ -0,0 +1,581 @@
autofs-5.1.1 - change time() to use monotonic_clock()
From: Yu Ning <ning.yu@ubuntu.com>
The time returned by gettimeofday() is affected by discontinuous jumps
in the system time, so it causes an issue that autofs may not auto
unmount a mount point if system time is manually changed by the system
administrator.
To fix the issue we need to convert to using a monotonic clock source
instead of the clock source used by gettimeofday().
Finally hange the time() function calls to monotonic_clock() calls.
Signed-off-by: Yu Ning <ning.yu@ubuntu.com>
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 4 ++--
daemon/direct.c | 4 ++--
daemon/indirect.c | 4 ++--
daemon/lookup.c | 6 +++---
daemon/state.c | 2 +-
lib/cache.c | 2 +-
lib/master.c | 4 ++--
modules/dclist.c | 2 +-
modules/lookup_file.c | 8 ++++----
modules/lookup_hesiod.c | 6 +++---
modules/lookup_hosts.c | 4 ++--
modules/lookup_ldap.c | 10 +++++-----
modules/lookup_nisplus.c | 10 +++++-----
modules/lookup_program.c | 10 +++++-----
modules/lookup_sss.c | 6 +++---
modules/lookup_userhome.c | 2 +-
modules/lookup_yp.c | 8 ++++----
modules/mount_autofs.c | 2 +-
modules/parse_amd.c | 2 +-
modules/replicated.c | 4 ++--
21 files changed, 51 insertions(+), 50 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 49520d3..4f589db 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -29,6 +29,7 @@
- use monotonic clock for direct mount condition.
- use monotonic clock for indirect mount condition.
- change remaining gettimeofday() to use clock_gettime().
+- change time() to use monotonic_clock().
21/04/2015 autofs-5.1.1
=======================
diff --git a/daemon/automount.c b/daemon/automount.c
index 6cba3db..74e62a1 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -1454,7 +1454,7 @@ static void *statemachine(void *arg)
break;
case SIGHUP:
- do_hup_signal(master_list, time(NULL));
+ do_hup_signal(master_list, monotonic_time(NULL));
break;
default:
@@ -2005,7 +2005,7 @@ int main(int argc, char *argv[])
unsigned ghost, logging, daemon_check;
unsigned dumpmaps, foreground, have_global_options;
time_t timeout;
- time_t age = time(NULL);
+ time_t age = monotonic_time(NULL);
struct rlimit rlim;
const char *options = "+hp:t:vmdD:fVrO:l:n:CF";
static const struct option long_options[] = {
diff --git a/daemon/direct.c b/daemon/direct.c
index 9b7fd76..d427580 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -468,7 +468,7 @@ int mount_autofs_direct(struct autofs_point *ap)
struct mapent_cache *nc, *mc;
struct mapent *me, *ne, *nested;
struct mnt_list *mnts;
- time_t now = time(NULL);
+ time_t now = monotonic_time(NULL);
if (strcmp(ap->path, "/-")) {
error(ap->logopt, "expected direct map, exiting");
@@ -1387,7 +1387,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
}
/* Check if we recorded a mount fail for this key */
- if (me->status >= time(NULL)) {
+ if (me->status >= monotonic_time(NULL)) {
ops->send_fail(ap->logopt,
ioctlfd, pkt->wait_queue_token, -ENOENT);
ops->close(ap->logopt, ioctlfd);
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 263fff1..4c32bdb 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -201,7 +201,7 @@ out_err:
int mount_autofs_indirect(struct autofs_point *ap, const char *root)
{
- time_t now = time(NULL);
+ time_t now = monotonic_time(NULL);
int status;
int map;
@@ -817,7 +817,7 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin
/* Check if we recorded a mount fail for this key anywhere */
me = lookup_source_mapent(ap, pkt->name, LKP_DISTINCT);
if (me) {
- if (me->status >= time(NULL)) {
+ if (me->status >= monotonic_time(NULL)) {
ops->send_fail(ap->logopt, ap->ioctlfd,
pkt->wait_queue_token, -ENOENT);
cache_unlock(me->mc);
diff --git a/daemon/lookup.c b/daemon/lookup.c
index afd14ab..0129f75 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -841,7 +841,7 @@ static int lookup_name_file_source_instance(struct autofs_point *ap, struct map_
struct map_source *instance;
char src_file[] = "file";
char src_prog[] = "program";
- time_t age = time(NULL);
+ time_t age = monotonic_time(NULL);
struct stat st;
char *type, *format;
@@ -881,7 +881,7 @@ static int lookup_name_source_instance(struct autofs_point *ap, struct map_sourc
{
struct map_source *instance;
const char *format;
- time_t age = time(NULL);
+ time_t age = monotonic_time(NULL);
if (*name == '/' && map->flags & MAP_FLAG_FORMAT_AMD)
return lookup_amd_instance(ap, map, name, name_len);
@@ -1045,7 +1045,7 @@ static void update_negative_cache(struct autofs_point *ap, struct map_source *so
else
map = entry->maps;
if (map) {
- time_t now = time(NULL);
+ time_t now = monotonic_time(NULL);
int rv = CHE_FAIL;
cache_writelock(map->mc);
diff --git a/daemon/state.c b/daemon/state.c
index 6c8c4f6..3ef8d95 100644
--- a/daemon/state.c
+++ b/daemon/state.c
@@ -564,7 +564,7 @@ static unsigned int st_readmap(struct autofs_point *ap)
pthread_t thid;
struct readmap_args *ra;
int status;
- int now = time(NULL);
+ int now = monotonic_time(NULL);
debug(ap->logopt, "state %d path %s", ap->state, ap->path);
diff --git a/lib/cache.c b/lib/cache.c
index 631d275..44e323d 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -775,7 +775,7 @@ void cache_update_negative(struct mapent_cache *mc,
struct map_source *ms, const char *key,
time_t timeout)
{
- time_t now = time(NULL);
+ time_t now = monotonic_time(NULL);
struct mapent *me;
int rv = CHE_OK;
diff --git a/lib/master.c b/lib/master.c
index 4588fa7..9ffdd1a 100644
--- a/lib/master.c
+++ b/lib/master.c
@@ -1484,7 +1484,7 @@ int dump_map(struct master *master, const char *type, const char *name)
struct map_source *source;
struct master_mapent *this;
struct autofs_point *ap;
- time_t now = time(NULL);
+ time_t now = monotonic_time(NULL);
this = list_entry(p, struct master_mapent, list);
p = p->next;
@@ -1602,7 +1602,7 @@ int master_show_mounts(struct master *master)
struct map_source *source;
struct master_mapent *this;
struct autofs_point *ap;
- time_t now = time(NULL);
+ time_t now = monotonic_time(NULL);
unsigned int count = 0;
this = list_entry(p, struct master_mapent, list);
diff --git a/modules/dclist.c b/modules/dclist.c
index af21ce0..4daa199 100644
--- a/modules/dclist.c
+++ b/modules/dclist.c
@@ -568,7 +568,7 @@ struct dclist *get_dc_list(unsigned int logopt, const char *uri)
if (!list)
goto out_error;
- dclist->expire = time(NULL) + min_ttl;
+ dclist->expire = monotonic_time(NULL) + min_ttl;
dclist->uri = list;
return dclist;
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index aed3cba..72444fe 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -795,7 +795,7 @@ static int match_key(struct autofs_point *ap,
{
char buf[MAX_ERR_BUF];
struct mapent_cache *mc;
- time_t age = time(NULL);
+ time_t age = monotonic_time(NULL);
char *lkp_key;
char *prefix;
size_t map_key_len;
@@ -860,7 +860,7 @@ static int lookup_one(struct autofs_point *ap,
struct mapent_cache *mc = source->mc;
char mkey[KEY_MAX_LEN + 1];
char mapent[MAPENT_MAX_LEN + 1];
- time_t age = time(NULL);
+ time_t age = monotonic_time(NULL);
FILE *f;
unsigned int k_len, m_len;
int entry, ret;
@@ -966,7 +966,7 @@ static int lookup_wild(struct autofs_point *ap,
struct mapent_cache *mc;
char mkey[KEY_MAX_LEN + 1];
char mapent[MAPENT_MAX_LEN + 1];
- time_t age = time(NULL);
+ time_t age = monotonic_time(NULL);
FILE *f;
unsigned int k_len, m_len;
int entry, ret;
@@ -1170,7 +1170,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
/* Check if we recorded a mount fail for this key anywhere */
me = lookup_source_mapent(ap, key, LKP_DISTINCT);
if (me) {
- if (me->status >= time(NULL)) {
+ if (me->status >= monotonic_time(NULL)) {
cache_unlock(me->mc);
return NSS_STATUS_NOTFOUND;
} else {
diff --git a/modules/lookup_hesiod.c b/modules/lookup_hesiod.c
index c0f7f51..12ccf41 100644
--- a/modules/lookup_hesiod.c
+++ b/modules/lookup_hesiod.c
@@ -222,7 +222,7 @@ static int lookup_one(struct autofs_point *ap,
}
cache_writelock(mc);
- ret = cache_update(mc, source, key, best_record, time(NULL));
+ ret = cache_update(mc, source, key, best_record, monotonic_time(NULL));
cache_unlock(mc);
if (ret == CHE_FAIL) {
hesiod_free_list(ctxt->hesiod_context, hes_result);
@@ -287,7 +287,7 @@ static int lookup_one_amd(struct autofs_point *ap,
}
cache_writelock(mc);
- ret = cache_update(mc, source, lkp_key, *hes_result, time(NULL));
+ ret = cache_update(mc, source, lkp_key, *hes_result, monotonic_time(NULL));
cache_unlock(mc);
if (hes_result)
@@ -398,7 +398,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
/* Check if we recorded a mount fail for this key anywhere */
me = lookup_source_mapent(ap, name, LKP_DISTINCT);
if (me) {
- if (me->status >= time(NULL)) {
+ if (me->status >= monotonic_time(NULL)) {
cache_unlock(me->mc);
return NSS_STATUS_NOTFOUND;
} else {
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
index 0a64655..163b02d 100644
--- a/modules/lookup_hosts.c
+++ b/modules/lookup_hosts.c
@@ -302,7 +302,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
struct mapent *me;
char *mapent = NULL;
int mapent_len;
- time_t now = time(NULL);
+ time_t now = monotonic_time(NULL);
int ret;
source = ap->entry->current;
@@ -314,7 +314,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
/* Check if we recorded a mount fail for this key anywhere */
me = lookup_source_mapent(ap, name, LKP_DISTINCT);
if (me) {
- if (me->status >= time(NULL)) {
+ if (me->status >= monotonic_time(NULL)) {
cache_unlock(me->mc);
return NSS_STATUS_NOTFOUND;
} else {
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 578d6c6..afc89c1 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -995,7 +995,7 @@ static int do_reconnect(unsigned logopt,
uris_mutex_lock(ctxt);
if (ctxt->dclist) {
- if (!ldap || ctxt->dclist->expire < time(NULL)) {
+ if (!ldap || ctxt->dclist->expire < monotonic_time(NULL)) {
free_dclist(ctxt->dclist);
ctxt->dclist = NULL;
}
@@ -2961,7 +2961,7 @@ static int lookup_one(struct autofs_point *ap, struct map_source *source,
struct mapent_cache *mc;
int rv, i, l, ql, count;
char buf[MAX_ERR_BUF];
- time_t age = time(NULL);
+ time_t age = monotonic_time(NULL);
char *query;
LDAPMessage *result = NULL, *e;
char *class, *info, *entry;
@@ -3326,7 +3326,7 @@ static int lookup_one_amd(struct autofs_point *ap,
struct berval **bvKey;
struct berval **bvValues;
char buf[MAX_ERR_BUF];
- time_t age = time(NULL);
+ time_t age = monotonic_time(NULL);
int rv, l, ql, count;
int ret = CHE_MISSING;
@@ -3531,7 +3531,7 @@ static int check_map_indirect(struct autofs_point *ap,
unsigned int is_amd_format = source->flags & MAP_FLAG_FORMAT_AMD;
struct mapent_cache *mc;
struct mapent *me;
- time_t now = time(NULL);
+ time_t now = monotonic_time(NULL);
time_t t_last_read;
int ret, cur_state;
int status;
@@ -3669,7 +3669,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
/* Check if we recorded a mount fail for this key anywhere */
me = lookup_source_mapent(ap, key, LKP_DISTINCT);
if (me) {
- if (me->status >= time(NULL)) {
+ if (me->status >= monotonic_time(NULL)) {
cache_unlock(me->mc);
return NSS_STATUS_NOTFOUND;
} else {
diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
index 5fd1d89..27f9856 100644
--- a/modules/lookup_nisplus.c
+++ b/modules/lookup_nisplus.c
@@ -338,7 +338,7 @@ static int lookup_one(struct autofs_point *ap,
nis_result *result;
nis_object *this;
char *mapent;
- time_t age = time(NULL);
+ time_t age = monotonic_time(NULL);
int ret, cur_state;
char buf[MAX_ERR_BUF];
@@ -450,7 +450,7 @@ static int lookup_wild(struct autofs_point *ap,
nis_result *result;
nis_object *this;
char *mapent;
- time_t age = time(NULL);
+ time_t age = monotonic_time(NULL);
int ret, cur_state;
char buf[MAX_ERR_BUF];
@@ -537,7 +537,7 @@ static int lookup_amd_defaults(struct autofs_point *ap,
mapent = ENTRY_VAL(this, 1);
cache_writelock(mc);
- ret = cache_update(mc, source, "/defaults", mapent, time(NULL));
+ ret = cache_update(mc, source, "/defaults", mapent, monotonic_time(NULL));
cache_unlock(mc);
nis_freeresult(result);
@@ -555,7 +555,7 @@ static int check_map_indirect(struct autofs_point *ap,
unsigned int is_amd_format = source->flags & MAP_FLAG_FORMAT_AMD;
struct mapent_cache *mc;
struct mapent *me, *exists;
- time_t now = time(NULL);
+ time_t now = monotonic_time(NULL);
time_t t_last_read;
int ret = 0;
@@ -700,7 +700,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
/* Check if we recorded a mount fail for this key anywhere */
me = lookup_source_mapent(ap, key, LKP_DISTINCT);
if (me) {
- if (me->status >= time(NULL)) {
+ if (me->status >= monotonic_time(NULL)) {
cache_unlock(me->mc);
return NSS_STATUS_NOTFOUND;
} else {
diff --git a/modules/lookup_program.c b/modules/lookup_program.c
index a46ff0e..b3f1c1f 100644
--- a/modules/lookup_program.c
+++ b/modules/lookup_program.c
@@ -430,7 +430,7 @@ static int lookup_amd_defaults(struct autofs_point *ap,
while (isblank(*start))
start++;
cache_writelock(mc);
- ret = cache_update(mc, source, "/defaults", start, time(NULL));
+ ret = cache_update(mc, source, "/defaults", start, monotonic_time(NULL));
cache_unlock(mc);
if (ret == CHE_FAIL) {
free(ment);
@@ -499,7 +499,7 @@ static int match_key(struct autofs_point *ap,
start++;
}
cache_writelock(mc);
- ret = cache_update(mc, source, lkp_key, start, time(NULL));
+ ret = cache_update(mc, source, lkp_key, start, monotonic_time(NULL));
cache_unlock(mc);
if (ret == CHE_FAIL) {
free(ment);
@@ -552,7 +552,7 @@ static int match_key(struct autofs_point *ap,
while (isblank(*start))
start++;
cache_writelock(mc);
- ret = cache_update(mc, source, match, start, time(NULL));
+ ret = cache_update(mc, source, match, start, monotonic_time(NULL));
cache_unlock(mc);
if (ret == CHE_FAIL) {
free(match);
@@ -598,7 +598,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
/* Check if we recorded a mount fail for this key anywhere */
me = lookup_source_mapent(ap, name, LKP_DISTINCT);
if (me) {
- if (me->status >= time(NULL)) {
+ if (me->status >= monotonic_time(NULL)) {
cache_unlock(me->mc);
return NSS_STATUS_NOTFOUND;
} else {
@@ -647,7 +647,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
* proceed with the program map lookup.
*/
if (strchr(name, '/') ||
- me->age + ap->negative_timeout > time(NULL)) {
+ me->age + ap->negative_timeout > monotonic_time(NULL)) {
char *ent = NULL;
if (me->mapent) {
diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c
index 2f32e94..e01dd28 100644
--- a/modules/lookup_sss.c
+++ b/modules/lookup_sss.c
@@ -447,7 +447,7 @@ static int lookup_one(struct autofs_point *ap,
struct mapent_cache *mc;
struct mapent *we;
void *sss_ctxt = NULL;
- time_t age = time(NULL);
+ time_t age = monotonic_time(NULL);
char buf[MAX_ERR_BUF];
char *value = NULL;
char *s_key;
@@ -568,7 +568,7 @@ static int check_map_indirect(struct autofs_point *ap,
struct map_source *source;
struct mapent_cache *mc;
struct mapent *me;
- time_t now = time(NULL);
+ time_t now = monotonic_time(NULL);
time_t t_last_read;
int ret, cur_state;
@@ -662,7 +662,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
/* Check if we recorded a mount fail for this key anywhere */
me = lookup_source_mapent(ap, key, LKP_DISTINCT);
if (me) {
- if (me->status >= time(NULL)) {
+ if (me->status >= monotonic_time(NULL)) {
cache_unlock(me->mc);
return NSS_STATUS_NOTFOUND;
} else {
diff --git a/modules/lookup_userhome.c b/modules/lookup_userhome.c
index c21dee9..8117640 100644
--- a/modules/lookup_userhome.c
+++ b/modules/lookup_userhome.c
@@ -84,7 +84,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
}
cache_writelock(mc);
- ret = cache_update(mc, source, name, NULL, time(NULL));
+ ret = cache_update(mc, source, name, NULL, monotonic_time(NULL));
cache_unlock(mc);
if (ret == CHE_FAIL) {
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
index e31c2cf..eda2aba 100644
--- a/modules/lookup_yp.c
+++ b/modules/lookup_yp.c
@@ -461,7 +461,7 @@ static int lookup_one(struct autofs_point *ap,
char *mapname;
char *mapent;
int mapent_len;
- time_t age = time(NULL);
+ time_t age = monotonic_time(NULL);
int ret;
mc = source->mc;
@@ -573,7 +573,7 @@ static int lookup_wild(struct autofs_point *ap,
char *mapname;
char *mapent;
int mapent_len;
- time_t age = time(NULL);
+ time_t age = monotonic_time(NULL);
int ret;
mc = source->mc;
@@ -654,7 +654,7 @@ static int lookup_amd_defaults(struct autofs_point *ap,
return CHE_FAIL;
cache_writelock(mc);
- ret = cache_update(mc, source, "/defaults", mapent, time(NULL));
+ ret = cache_update(mc, source, "/defaults", mapent, monotonic_time(NULL));
cache_unlock(mc);
return ret;
@@ -809,7 +809,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
/* Check if we recorded a mount fail for this key anywhere */
me = lookup_source_mapent(ap, key, LKP_DISTINCT);
if (me) {
- if (me->status >= time(NULL)) {
+ if (me->status >= monotonic_time(NULL)) {
cache_unlock(me->mc);
return NSS_STATUS_NOTFOUND;
} else {
diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c
index 39948e6..c6a3199 100644
--- a/modules/mount_autofs.c
+++ b/modules/mount_autofs.c
@@ -247,7 +247,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
source = master_add_map_source(entry,
info->type, info->format,
- time(NULL), argc, argv);
+ monotonic_time(NULL), argc, argv);
if (!source) {
error(ap->logopt,
MODPREFIX "failed to add map source to entry");
diff --git a/modules/parse_amd.c b/modules/parse_amd.c
index 0626bf4..b8e0078 100644
--- a/modules/parse_amd.c
+++ b/modules/parse_amd.c
@@ -1188,7 +1188,7 @@ static int do_host_mount(struct autofs_point *ap, const char *name,
"hosts", "sun", argc, pargv);
if (!instance) {
instance = master_add_source_instance(source,
- "hosts", "sun", time(NULL), argc, pargv);
+ "hosts", "sun", monotonic_time(NULL), argc, pargv);
if (!instance) {
error(ap->logopt, MODPREFIX
"failed to create source instance for hosts map");
diff --git a/modules/replicated.c b/modules/replicated.c
index f4cae3e..315e300 100644
--- a/modules/replicated.c
+++ b/modules/replicated.c
@@ -69,14 +69,14 @@ void seed_random(void)
fd = open_fd("/dev/urandom", O_RDONLY);
if (fd < 0) {
- srandom(time(NULL));
+ srandom(monotonic_time(NULL));
return;
}
if (read(fd, &seed, sizeof(seed)) != -1)
srandom(seed);
else
- srandom(time(NULL));
+ srandom(monotonic_time(NULL));
close(fd);

View File

@ -0,0 +1,91 @@
autofs-5.1.1 - define monotonic clock helper functions
From: Yu Ning <ning.yu@ubuntu.com>
The time returned by gettimeofday() is affected by discontinuous jumps
in the system time, so it causes an issue that autofs may not auto
unmount a mount point if system time is manually changed by the system
administrator.
To fix the issue we need to convert to using a monotonic clock source
instead of the clock source used by gettimeofday().
Start by defining two helper functions that will be used by later
patches.
Signed-off-by: Yu Ning <ning.yu@ubuntu.com>
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
include/automount.h | 10 ++++++++++
include/rpc_subs.h | 1 +
lib/rpc_subs.c | 11 +++++++++++
4 files changed, 23 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index f954018..566a6c6 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -23,6 +23,7 @@
- fix out of order call in program map lookup.
- fix error handling of is_mounted().
- Add a mode option for master map entries.
+- define monotonic clock helper functions.
21/04/2015 autofs-5.1.1
=======================
diff --git a/include/automount.h b/include/automount.h
index c56e265..9e82048 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -582,6 +582,16 @@ do { \
fatal(_m_unlock); \
} while(0)
+static inline time_t monotonic_time(time_t *t)
+{
+ struct timespec ts;
+
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ if (t)
+ *t = (time_t) ts.tv_sec;
+ return (time_t) ts.tv_sec;
+}
+
/* Expire alarm handling routines */
int alarm_start_handler(void);
int alarm_add(struct autofs_point *ap, time_t seconds);
diff --git a/include/rpc_subs.h b/include/rpc_subs.h
index b6d59f9..e329224 100644
--- a/include/rpc_subs.h
+++ b/include/rpc_subs.h
@@ -71,6 +71,7 @@ int rpc_portmap_getport(struct conn_info *, struct pmap *, unsigned short *);
int rpc_ping_proto(struct conn_info *);
int rpc_ping(const char *, long, long, unsigned int);
double elapsed(struct timeval, struct timeval);
+double monotonic_elapsed(struct timespec, struct timespec);
int rpc_time(const char *, unsigned int, unsigned int, long, long, unsigned int, double *);
const char *get_addr_string(struct sockaddr *, char *, socklen_t);
diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c
index 68d68f4..e0e1979 100644
--- a/lib/rpc_subs.c
+++ b/lib/rpc_subs.c
@@ -1075,6 +1075,17 @@ double elapsed(struct timeval start, struct timeval end)
return t2-t1;
}
+double monotonic_elapsed(struct timespec start, struct timespec end)
+{
+ double t1, t2;
+
+ t1 = (double) start.tv_sec +
+ (double) (start.tv_nsec/(1000*1000*1000));
+ t2 = (double) end.tv_sec +
+ (double) (end.tv_nsec/(1000*1000*1000));
+ return t2 - t1;
+}
+
int rpc_time(const char *host,
unsigned int ping_vers, unsigned int ping_proto,
long seconds, long micros, unsigned int option, double *result)

View File

@ -0,0 +1,68 @@
autofs-5.1.1 - define pending condition init helper function
From: Yu Ning <ning.yu@ubuntu.com>
The time returned by gettimeofday() is affected by discontinuous jumps
in the system time, so it causes an issue that autofs may not auto
unmount a mount point if system time is manually changed by the system
administrator.
To fix the issue we need to convert to using a monotonic clock source
instead of the clock source used by gettimeofday().
We also want to use a monotonic clock source for the condition wait
of both the direct and indirect mount thread creation as well the
expire thread creation of each. So create a common helper function
to initialize a condition variable to use a monotonic clock source.
Signed-off-by: Yu Ning <ning.yu@ubuntu.com>
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
include/automount.h | 21 +++++++++++++++++++++
2 files changed, 22 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index c443f49..20a64a7 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -25,6 +25,7 @@
- Add a mode option for master map entries.
- define monotonic clock helper functions.
- use monotonic clock for alarm thread condition wait.
+- define pending condition init helper function.
21/04/2015 autofs-5.1.1
=======================
diff --git a/include/automount.h b/include/automount.h
index 9e82048..2cf0611 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -429,6 +429,27 @@ struct pending_args {
};
#ifdef INCLUDE_PENDING_FUNCTIONS
+static void pending_cond_init(void *arg)
+{
+ struct pending_args *mt = (struct pending_args *) arg;
+ pthread_condattr_t condattrs;
+ int status;
+
+ status = pthread_condattr_init(&condattrs);
+ if (status)
+ fatal(status);
+
+ status = pthread_condattr_setclock(&condattrs, CLOCK_MONOTONIC);
+ if (status)
+ fatal(status);
+
+ status = pthread_cond_init(&mt->cond, &condattrs);
+ if (status)
+ fatal(status);
+
+ pthread_condattr_destroy(&condattrs);
+}
+
static void pending_cond_destroy(void *arg)
{
struct pending_args *mt = (struct pending_args *) arg;

View File

@ -0,0 +1,203 @@
autofs-5.1.1 - factor out alloc multi map context
From: Ian Kent <raven@themaw.net>
Seperate out the context allocation function for the multi map module.
Signed-off-by: Ian Kent <raven@themaw.net>
---
modules/lookup_multi.c | 161 +++++++++++++++++++++++++-----------------------
1 file changed, 85 insertions(+), 76 deletions(-)
diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c
index 36ace11..433b424 100644
--- a/modules/lookup_multi.c
+++ b/modules/lookup_multi.c
@@ -40,6 +40,84 @@ struct lookup_context {
int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
+static int free_multi_context(struct lookup_context *);
+
+static struct lookup_context *alloc_context(const char *format,
+ int argc, const char *const *argv)
+{
+ struct lookup_context *ctxt;
+ char buf[MAX_ERR_BUF];
+ char **args;
+ int i, an;
+ char *estr;
+
+ ctxt = malloc(sizeof(struct lookup_context));
+ if (!ctxt)
+ goto nomem;
+
+ memset(ctxt, 0, sizeof(struct lookup_context));
+
+ if (argc < 1) {
+ logerr(MODPREFIX "No map list");
+ goto error_out;
+ }
+
+ ctxt->n = 1; /* Always at least one map */
+ for (i = 0; i < argc; i++) {
+ if (!strcmp(argv[i], "--")) /* -- separates maps */
+ ctxt->n++;
+ }
+
+ if (!(ctxt->m = malloc(ctxt->n * sizeof(struct module_info))) ||
+ !(ctxt->argl = malloc((argc + 1) * sizeof(const char *))))
+ goto nomem;
+
+ memset(ctxt->m, 0, ctxt->n * sizeof(struct module_info));
+
+ memcpy(ctxt->argl, argv, (argc + 1) * sizeof(const char *));
+
+ args = NULL;
+ for (i = an = 0; ctxt->argl[an]; an++) {
+ if (ctxt->m[i].argc == 0)
+ args = (char **) &ctxt->argl[an];
+
+ if (strcmp(ctxt->argl[an], "--"))
+ ctxt->m[i].argc++;
+ else {
+ ctxt->argl[an] = NULL;
+ if (!args) {
+ logerr(MODPREFIX "error assigning map args");
+ goto error_out;
+ }
+ ctxt->m[i].argv = copy_argv(ctxt->m[i].argc,
+ (const char **) args);
+ if (!ctxt->m[i].argv)
+ goto nomem;
+ args = NULL;
+ i++;
+ }
+ }
+
+ /* catch the last one */
+ if (args) {
+ ctxt->m[i].argv = copy_argv(ctxt->m[i].argc, (const char **) args);
+ if (!ctxt->m[i].argv)
+ goto nomem;
+ }
+
+ return ctxt;
+
+nomem:
+ estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ logerr(MODPREFIX "error: %s", estr);
+
+error_out:
+ free_multi_context(ctxt);
+ free(ctxt);
+
+ return NULL;
+}
+
static int free_multi_context(struct lookup_context *ctxt)
{
int rv;
@@ -180,95 +258,26 @@ int lookup_init(const char *my_mapfmt,
int argc, const char *const *argv, void **context)
{
struct lookup_context *ctxt;
- char buf[MAX_ERR_BUF];
- char **args;
- int i, an;
- char *estr;
+ int i;
- ctxt = malloc(sizeof(struct lookup_context));
+ ctxt = alloc_context(my_mapfmt, argc, argv);
if (!ctxt)
- goto nomem;
-
- memset(ctxt, 0, sizeof(struct lookup_context));
-
- if (argc < 1) {
- logerr(MODPREFIX "No map list");
- goto error_out;
- }
-
- ctxt->n = 1; /* Always at least one map */
- for (i = 0; i < argc; i++) {
- if (!strcmp(argv[i], "--")) /* -- separates maps */
- ctxt->n++;
- }
-
- if (!(ctxt->m = malloc(ctxt->n * sizeof(struct module_info))) ||
- !(ctxt->argl = malloc((argc + 1) * sizeof(const char *))))
- goto nomem;
-
- memset(ctxt->m, 0, ctxt->n * sizeof(struct module_info));
-
- memcpy(ctxt->argl, argv, (argc + 1) * sizeof(const char *));
-
- args = NULL;
- for (i = an = 0; ctxt->argl[an]; an++) {
- if (ctxt->m[i].argc == 0) {
- args = (char **) &ctxt->argl[an];
- }
- if (!strcmp(ctxt->argl[an], "--")) {
- ctxt->argl[an] = NULL;
- if (!args) {
- logerr(MODPREFIX "error assigning map args");
- goto error_out;
- }
- ctxt->m[i].argv = copy_argv(ctxt->m[i].argc, (const char **) args);
- if (!ctxt->m[i].argv)
- goto nomem;
- args = NULL;
- i++;
- } else {
- ctxt->m[i].argc++;
- }
- }
-
- /* catch the last one */
- if (args) {
- ctxt->m[i].argv = copy_argv(ctxt->m[i].argc, (const char **) args);
- if (!ctxt->m[i].argv)
- goto nomem;
- }
+ return 1;
for (i = 0; i < ctxt->n; i++) {
ctxt->m[i].mod = nss_open_lookup(my_mapfmt,
ctxt->m[i].argc, ctxt->m[i].argv);
if (!ctxt->m[i].mod) {
logerr(MODPREFIX "error opening module");
- goto error_out;
+ free_multi_context(ctxt);
+ free(ctxt);
+ return 1;
}
}
*context = ctxt;
- return 0;
-nomem:
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
- logerr(MODPREFIX "error: %s", estr);
-error_out:
- if (ctxt) {
- if (ctxt->m) {
- for (i = 0; i < ctxt->n; i++) {
- if (ctxt->m[i].mod)
- close_lookup(ctxt->m[i].mod);
- if (ctxt->m[i].argv)
- free_argv(ctxt->m[i].argc, ctxt->m[i].argv);
- }
- free(ctxt->m);
- }
- if (ctxt->argl)
- free(ctxt->argl);
- free(ctxt);
- }
- return 1;
+ return 0;
}
int lookup_reinit(const char *my_mapfmt,

View File

@ -0,0 +1,68 @@
autofs-5.1.1 - factor out free multi map context
From: Ian Kent <raven@themaw.net>
Seperate out the free context function for the multi map module.
Signed-off-by: Ian Kent <raven@themaw.net>
---
modules/lookup_multi.c | 38 +++++++++++++++++++++++++++++---------
1 file changed, 29 insertions(+), 9 deletions(-)
diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c
index 0ee20f5..36ace11 100644
--- a/modules/lookup_multi.c
+++ b/modules/lookup_multi.c
@@ -40,6 +40,32 @@ struct lookup_context {
int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
+static int free_multi_context(struct lookup_context *ctxt)
+{
+ int rv;
+
+ if (!ctxt)
+ return 0;
+
+ rv = 0;
+ if (ctxt->m) {
+ int i;
+
+ for (i = 0; i < ctxt->n; i++) {
+ if (ctxt->m[i].mod)
+ rv = rv || close_lookup(ctxt->m[i].mod);
+ if (ctxt->m[i].argv)
+ free_argv(ctxt->m[i].argc, ctxt->m[i].argv);
+ }
+ free(ctxt->m);
+ }
+
+ if (ctxt->argl)
+ free(ctxt->argl);
+
+ return rv;
+}
+
static struct lookup_mod *nss_open_lookup(const char *format, int argc, const char **argv)
{
struct list_head nsslist;
@@ -306,16 +332,10 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
int lookup_done(void *context)
{
struct lookup_context *ctxt = (struct lookup_context *) context;
- int i, rv = 0;
+ int rv;
- for (i = 0; i < ctxt->n; i++) {
- if (ctxt->m[i].mod)
- rv = rv || close_lookup(ctxt->m[i].mod);
- if (ctxt->m[i].argv)
- free_argv(ctxt->m[i].argc, ctxt->m[i].argv);
- }
- free(ctxt->argl);
- free(ctxt->m);
+ rv = free_multi_context(ctxt);
free(ctxt);
+
return rv;
}

View File

@ -0,0 +1,58 @@
autofs-5.1.1 - fix config old name lookup
From: Ian Kent <raven@themaw.net>
There are three cases needed to handle configuration name lookup.
First there's the configuration key name, the name match is case
insensitive so the recent case change isn't a seperate case.
But the much older configuration key names that began with "DEFAULT_"
need special handling.
There are two cases that need to be covered:
1) an old name is given but a new name needs to be located.
2) a new name is given but an old name needs to be located.
Only 1) is currently covered, so fix that in conf_lookup().
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/defaults.c | 11 +++++++++++
2 files changed, 12 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index 3bd7145..ebd66d8 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -11,6 +11,7 @@
- make find_server() return a status.
- fix return handling of do_reconnect() in ldap module.
- fix rwlock unlock crash.
+- fix config old name lookup.
21/04/2015 autofs-5.1.1
=======================
diff --git a/lib/defaults.c b/lib/defaults.c
index 5711e65..74fafc5 100644
--- a/lib/defaults.c
+++ b/lib/defaults.c
@@ -728,6 +728,17 @@ static struct conf_option *conf_lookup(const char *section, const char *key)
*/
if (strlen(key) > 8 && !strncasecmp("DEFAULT_", key, 8))
co = conf_lookup_key(section, key + 8);
+ else {
+ /* A new key name has been given but the value
+ * we seek is stored under an old key name (which
+ * includes the "DEFAULT_" prefix or doesn't exist.
+ */
+ char old_key[PATH_MAX + 1];
+
+ strcpy(old_key, "DEFAULT_");
+ strcat(old_key, key);
+ co = conf_lookup_key(section, old_key);
+ }
}
return co;

View File

@ -0,0 +1,56 @@
autofs-5.1.1 - fix direct map expire not set for initial empty map
From: Ian Kent <raven@themaw.net>
If an empty direct map is present at startup the expire alarm can't be
set because the expire run frequency isn't known. But if the map is
re-read and is no longer empty the expire alarm wasn't being set.
Fix suggested by xuw at redhat dot com, thanks.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/state.c | 10 ++++++++++
2 files changed, 11 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index 7bd261a..52b166d 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -14,6 +14,7 @@
- fix config old name lookup.
- fix error handling on ldap bind fail.
- fix direct mount stale instance flag reset.
+- fix direct map expire not set for initail empty map.
21/04/2015 autofs-5.1.1
=======================
diff --git a/daemon/state.c b/daemon/state.c
index 3bea4af..6c8c4f6 100644
--- a/daemon/state.c
+++ b/daemon/state.c
@@ -488,6 +488,7 @@ static void *do_readmap(void *arg)
status = lookup_ghost(ap, ap->path);
} else {
struct mapent *me;
+ unsigned int append_alarm = !ap->exp_runfreq;
mnts = tree_make_mnt_tree(_PROC_MOUNTS, "/");
pthread_cleanup_push(tree_mnts_cleanup, mnts);
@@ -517,6 +518,15 @@ static void *do_readmap(void *arg)
map->stale = 0;
map = map->next;
}
+
+ /* If the direct mount map was empty at startup no expire
+ * alarm will have been added. So add it here if there are
+ * now map entries.
+ */
+ if (append_alarm && ap->exp_runfreq)
+ alarm_add(ap, ap->exp_runfreq +
+ rand() % ap->exp_runfreq);
+
pthread_cleanup_pop(1);
pthread_cleanup_pop(1);
pthread_cleanup_pop(1);

View File

@ -0,0 +1,38 @@
autofs-5.1.1 - fix direct mount stale instance flag reset
From: Ian Kent <raven@themaw.net>
When re-reading a direct map the stale map instance flag was not being
reset. This caused the map to be seen as stale on subsequent lookups
thereby triggering a map re-read.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/state.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index cbe039c..7bd261a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -13,6 +13,7 @@
- fix rwlock unlock crash.
- fix config old name lookup.
- fix error handling on ldap bind fail.
+- fix direct mount stale instance flag reset.
21/04/2015 autofs-5.1.1
=======================
diff --git a/daemon/state.c b/daemon/state.c
index 3174a9c..3bea4af 100644
--- a/daemon/state.c
+++ b/daemon/state.c
@@ -513,6 +513,7 @@ static void *do_readmap(void *arg)
}
lookup_prune_one_cache(ap, map->mc, now);
pthread_cleanup_pop(1);
+ clear_stale_instances(map);
map->stale = 0;
map = map->next;
}

View File

@ -0,0 +1,71 @@
autofs-5.1.1 - fix error handling of is_mounted()
From: Ian Kent <raven@themaw.net>
If the ops->ismountpoint() ioctl call fails for some reason is_mounted()
would return 0 indicating the path isn't mounted even if it is.
In this case fall back to the resource intensive mount table lookup.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 15 +++++++++++----
2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 3dd28cc..8d27e55 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -21,6 +21,7 @@
- update map_hash_table_size description.
- add configuration option to use fqdn in mounts.
- fix out of order call in program map lookup.
+- fix error handling of is_mounted().
21/04/2015 autofs-5.1.1
=======================
diff --git a/lib/mounts.c b/lib/mounts.c
index f665721..455bdca 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1032,12 +1032,19 @@ static int table_is_mounted(const char *table, const char *path, unsigned int ty
return ret;
}
-static int ioctl_is_mounted(const char *path, unsigned int type)
+static int ioctl_is_mounted(const char *table, const char *path, unsigned int type)
{
struct ioctl_ops *ops = get_ioctl_ops();
unsigned int mounted;
+ int ret;
+
+ /* If the ioctl fails fall back to the potentially resource
+ * intensive mount table check.
+ */
+ ret = ops->ismountpoint(LOGOPT_NONE, -1, path, &mounted);
+ if (ret == -1)
+ return table_is_mounted(table, path, type);
- ops->ismountpoint(LOGOPT_NONE, -1, path, &mounted);
if (mounted) {
switch (type) {
case MNTS_ALL:
@@ -1056,7 +1063,7 @@ int is_mounted(const char *table, const char *path, unsigned int type)
struct ioctl_ops *ops = get_ioctl_ops();
if (ops->ismountpoint)
- return ioctl_is_mounted(path, type);
+ return ioctl_is_mounted(table, path, type);
else
return table_is_mounted(table, path, type);
}
@@ -1439,7 +1446,7 @@ int tree_is_mounted(struct mnt_list *mnts, const char *path, unsigned int type)
int mounted = 0;
if (ops->ismountpoint)
- return ioctl_is_mounted(path, type);
+ return ioctl_is_mounted(_PROC_MOUNTS, path, type);
INIT_LIST_HEAD(&list);

View File

@ -0,0 +1,91 @@
autofs-5.1.1 - fix error handling on ldap bind fail
From: Ian Kent <raven@themaw.net>
When calling unbind_ldap_connection() if a sasl connection is
being used then autofs_sasl_unbind() should be called and not
ldap_unbind_ext(), otherwise the ldap connection release code
could be called twice.
So, in unbind_ldap_connection() check if a sasl connection is in
use and unbind it if it is otherwise call ldap_unbind_ext() to
release the ldap connection.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_ldap.c | 17 ++++++++++-------
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index ebd66d8..cbe039c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -12,6 +12,7 @@
- fix return handling of do_reconnect() in ldap module.
- fix rwlock unlock crash.
- fix config old name lookup.
+- fix error handling on ldap bind fail.
21/04/2015 autofs-5.1.1
=======================
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 7e23869..d846d8e 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -216,15 +216,18 @@ int bind_ldap_simple(unsigned logopt, LDAP *ldap, const char *uri, struct lookup
int __unbind_ldap_connection(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
{
- int rv;
+ int rv = LDAP_SUCCESS;
if (ctxt->use_tls == LDAP_TLS_RELEASE)
ctxt->use_tls = LDAP_TLS_INIT;
#ifdef WITH_SASL
- autofs_sasl_unbind(ctxt);
-#endif
-
+ if (ctxt->auth_required & LDAP_NEED_AUTH)
+ autofs_sasl_unbind(ctxt);
+ else
+ rv = ldap_unbind_ext(ldap, NULL, NULL);
+#else
rv = ldap_unbind_ext(ldap, NULL, NULL);
+#endif
if (rv != LDAP_SUCCESS)
error(logopt, "unbind failed: %s", ldap_err2string(rv));
@@ -302,7 +305,7 @@ LDAP *__init_ldap_connection(unsigned logopt, const char *uri, struct lookup_con
rv = ldap_start_tls_s(ldap, NULL, NULL);
if (rv != LDAP_SUCCESS) {
- __unbind_ldap_connection(logopt, ldap, ctxt);
+ ldap_unbind_ext(ldap, NULL, NULL);
if (ctxt->tls_required) {
error(logopt, MODPREFIX
"TLS required but START_TLS failed: %s",
@@ -576,14 +579,13 @@ static int do_bind(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_c
char *host = NULL, *nhost;
int rv;
+ ldapinit_mutex_lock();
#ifdef WITH_SASL
debug(logopt, MODPREFIX "auth_required: %d, sasl_mech %s",
ctxt->auth_required, ctxt->sasl_mech);
if (ctxt->auth_required & LDAP_NEED_AUTH) {
- ldapinit_mutex_lock();
rv = autofs_sasl_bind(logopt, ldap, ctxt);
- ldapinit_mutex_unlock();
debug(logopt, MODPREFIX "autofs_sasl_bind returned %d", rv);
} else {
rv = bind_ldap_simple(logopt, ldap, uri, ctxt);
@@ -593,6 +595,7 @@ static int do_bind(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_c
rv = bind_ldap_simple(logopt, ldap, uri, ctxt);
debug(logopt, MODPREFIX "ldap simple bind returned %d", rv);
#endif
+ ldapinit_mutex_unlock();
if (rv != 0)
return 0;

View File

@ -0,0 +1,41 @@
autofs-5.1.1 - fix left mount count return from umount_multi_triggers()
From: Xu Wang <xuw@redhat.com>
If a umount of an NFS mount at the root of a multi-mount fails
umount_multi_triggers() will return an zero (success) when it should
return 1 (a fail). In this case do_expire_direct() will close the
me->ioctlfd fd used for expires stopping further expires of the
direct mount.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index 3a9266d..bd7b981 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,7 @@
=======================
- update libtirpc workaround for new soname.
- revert fix libtirpc name clash.
+- fix left mount count return from umount_multi_triggers().
21/04/2015 autofs-5.1.1
=======================
diff --git a/lib/mounts.c b/lib/mounts.c
index 84af6be..f665721 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2131,7 +2131,7 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
if (mount_multi_triggers(ap, me, root, strlen(root), "/") < 0)
warn(ap->logopt,
"failed to remount offset triggers");
- return left++;
+ return ++left;
}
}

View File

@ -0,0 +1,47 @@
autofs-5.1.1 - fix map format check in nss_open_lookup() multi map module
From: Ian Kent <raven@themaw.net>
The nss_open_lookup() function doesn't properly allow for map format when
it's given with the map type.
Signed-off-by: Ian Kent <raven@themaw.net>
---
modules/lookup_multi.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c
index 433b424..f8ebf94 100644
--- a/modules/lookup_multi.c
+++ b/modules/lookup_multi.c
@@ -24,6 +24,8 @@
#include "automount.h"
#include "nsswitch.h"
+#define MAX_MAP_TYPE_STRING 20
+
#define MODPREFIX "lookup(multi): "
struct module_info {
@@ -166,11 +168,17 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch
!strncmp(argv[0], "ldaps", 5) ||
!strncmp(argv[0], "ldap", 4) ||
!strncmp(argv[0], "sss", 3)) {
- const char *fmt = strchr(argv[0], ',');
- if (fmt)
+ char type[MAX_MAP_TYPE_STRING];
+ char *fmt;
+
+ strcpy(type, argv[0]);
+ fmt = strchr(type, ',');
+ if (!fmt)
+ fmt = (char *) format;
+ else {
+ *fmt = '\0';
fmt++;
- else
- fmt = format;
+ }
open_lookup(argv[0], MODPREFIX, fmt, argc - 1, argv + 1, &mod);
return mod;
}

View File

@ -0,0 +1,38 @@
autofs-5.1.1 - fix missing source sss in multi map lookup
From: Ian Kent <raven@themaw.net>
The sss source isn't accounted for in the multi map lookup module.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_multi.c | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index 52b166d..e22877e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -15,6 +15,7 @@
- fix error handling on ldap bind fail.
- fix direct mount stale instance flag reset.
- fix direct map expire not set for initail empty map.
+- fix missing source sss in multi map lookup.
21/04/2015 autofs-5.1.1
=======================
diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c
index 6ec8434..ffb236c 100644
--- a/modules/lookup_multi.c
+++ b/modules/lookup_multi.c
@@ -58,7 +58,8 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch
!strncmp(argv[0], "nisplus", 7) ||
!strncmp(argv[0], "nis", 3) ||
!strncmp(argv[0], "ldaps", 5) ||
- !strncmp(argv[0], "ldap", 4)) {
+ !strncmp(argv[0], "ldap", 4) ||
+ !strncmp(argv[0], "sss", 3)) {
const char *fmt = strchr(argv[0], ',');
if (fmt)
fmt++;

View File

@ -0,0 +1,48 @@
autofs-5.1.1 - fix nsswitch handling when opening multi map
From: Ian Kent <raven@themaw.net>
When initializing the lookup module for multi-map entries nsswitch
actions should be honoured to the extent they can be. In particular
the case of a map not found should use an nsswitch action (if present)
to work out whether to continue looking or return a failure.
Signed-off-by: Ian Kent <raven@themaw.net>
---
modules/lookup_multi.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c
index 55035e4..ba8d4f0 100644
--- a/modules/lookup_multi.c
+++ b/modules/lookup_multi.c
@@ -84,6 +84,7 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch
list_for_each(p, head) {
struct nss_source *this;
int status;
+ int ret;
this = list_entry(p, struct nss_source, list);
@@ -127,6 +128,10 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch
argv[0] = save_argv0;
free(path);
+
+ ret = check_nss_result(this, status);
+ if (ret >= 0)
+ break;
}
status = open_lookup(this->source, MODPREFIX,
@@ -135,6 +140,10 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch
free_sources(&nsslist);
return mod;
}
+
+ ret = check_nss_result(this, status);
+ if (ret >= 0)
+ break;
}
free_sources(&nsslist);

View File

@ -0,0 +1,69 @@
autofs-5.1.1 - fix out of order call in program map lookup
From: Ian Kent <raven@themaw.net>
Commit 91e42e58b4 fixed a problem with program map environment variable
naming and commit 743deb0e4e added a configuration option to force use
of the old environment names for those who need it and are sure it is
safe to continue to use them.
But the call to get the configuration entry was placed after a fork()
so the state of the mutex used when querying the configuration is
undefined and can lead to a deadlock.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_program.c | 20 ++++++++++----------
2 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 2c516e4..3dd28cc 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -20,6 +20,7 @@
- change lookup to use reinit instead of reopen.
- update map_hash_table_size description.
- add configuration option to use fqdn in mounts.
+- fix out of order call in program map lookup.
21/04/2015 autofs-5.1.1
=======================
diff --git a/modules/lookup_program.c b/modules/lookup_program.c
index 3e9c448..a46ff0e 100644
--- a/modules/lookup_program.c
+++ b/modules/lookup_program.c
@@ -200,6 +200,16 @@ static char *lookup_one(struct autofs_point *ap,
}
/*
+ * By default use a prefix with standard environment
+ * variables to prevent system subversion by interpreted
+ * languages.
+ */
+ if (defaults_force_std_prog_map_env())
+ prefix = NULL;
+ else
+ prefix = "AUTOFS_";
+
+ /*
* We don't use popen because we don't want to run /bin/sh plus we
* want to send stderr to the syslog, and we don't use spawnl()
* because we need the pipe hooks
@@ -238,16 +248,6 @@ static char *lookup_one(struct autofs_point *ap,
ap->path, ctxt->mapname);
/*
- * By default use a prefix with standard environment
- * variables to prevent system subversion by interpreted
- * languages.
- */
- if (defaults_force_std_prog_map_env())
- prefix = NULL;
- else
- prefix = "AUTOFS_";
-
- /*
* MAPFMT_DEFAULT must be "sun" for ->parse_init() to have setup
* the macro table.
*/

View File

@ -0,0 +1,98 @@
autofs-5.1.1 - fix return handling in sss lookup module
From: Ian Kent <raven@themaw.net>
In the sss lookup module some of the calls don't distinguish between
no entry found and service unavailable.
If service unavailable gets returned from a master map read it results
in autofs not updating the mounts. A notfound return doesn't because it
indicates the map doesn't exist so updating the mounts isn't a problem
as it can be when the source is unavailable.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_sss.c | 24 +++++++++++++++++-------
2 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index bd7b981..ee078bb 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -3,6 +3,7 @@
- update libtirpc workaround for new soname.
- revert fix libtirpc name clash.
- fix left mount count return from umount_multi_triggers().
+- fix return handling in sss lookup module.
21/04/2015 autofs-5.1.1
=======================
diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c
index 528ab41..720b5e3 100644
--- a/modules/lookup_sss.c
+++ b/modules/lookup_sss.c
@@ -148,9 +148,8 @@ static int setautomntent(unsigned int logopt,
error(logopt, MODPREFIX "setautomntent: %s", estr);
if (*sss_ctxt)
free(*sss_ctxt);
- return 0;
}
- return 1;
+ return ret;
}
static int endautomntent(unsigned int logopt,
@@ -161,9 +160,8 @@ static int endautomntent(unsigned int logopt,
char buf[MAX_ERR_BUF];
char *estr = strerror_r(ret, buf, MAX_ERR_BUF);
error(logopt, MODPREFIX "endautomntent: %s", estr);
- return 0;
}
- return 1;
+ return ret;
}
int lookup_read_master(struct master *master, time_t age, void *context)
@@ -180,8 +178,12 @@ int lookup_read_master(struct master *master, time_t age, void *context)
char *value = NULL;
int count, ret;
- if (!setautomntent(logopt, ctxt, ctxt->mapname, &sss_ctxt))
+ ret = setautomntent(logopt, ctxt, ctxt->mapname, &sss_ctxt);
+ if (ret) {
+ if (ret == ENOENT)
+ return NSS_STATUS_NOTFOUND;
return NSS_STATUS_UNAVAIL;
+ }
count = 0;
while (1) {
@@ -280,8 +282,12 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
return NSS_STATUS_SUCCESS;
}
- if (!setautomntent(ap->logopt, ctxt, ctxt->mapname, &sss_ctxt))
+ ret = setautomntent(ap->logopt, ctxt, ctxt->mapname, &sss_ctxt);
+ if (ret) {
+ if (ret == ENOENT)
+ return NSS_STATUS_NOTFOUND;
return NSS_STATUS_UNAVAIL;
+ }
count = 0;
while (1) {
@@ -386,8 +392,12 @@ static int lookup_one(struct autofs_point *ap,
mc = source->mc;
- if (!setautomntent(ap->logopt, ctxt, ctxt->mapname, &sss_ctxt))
+ ret = setautomntent(ap->logopt, ctxt, ctxt->mapname, &sss_ctxt);
+ if (ret) {
+ if (ret == ENOENT)
+ return NSS_STATUS_NOTFOUND;
return NSS_STATUS_UNAVAIL;
+ }
ret = ctxt->getautomntbyname_r(qKey, &value, sss_ctxt);
if (ret && ret != ENOENT) {

View File

@ -0,0 +1,208 @@
autofs-5.1.1 - fix return handling of do_reconnect() in ldap module
From: Ian Kent <raven@themaw.net>
In the ldap lookup module the do_reconnect() call doesn't distinguish
between no entry found and service unavailable.
If service unavailable gets returned from a master map read it results
in autofs not updating the mounts. A notfound return doesn't because it
indicates the map doesn't exist so updating the mounts isn't a problem
as it can be when the source is unavailable.
Finally make do_reconnect() return a status instead of an LDAP handle
and pass back the LDAP handle via a function parameter.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_ldap.c | 78 ++++++++++++++++++++++++++++---------------------
2 files changed, 46 insertions(+), 33 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index bc79bc0..fa8231c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -9,6 +9,7 @@
- make connect_to_server() return a status.
- make find_dc_server() return a status.
- make find_server() return a status.
+- fix return handling of do_reconnect() in ldap module.
21/04/2015 autofs-5.1.1
=======================
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 783239d..7e23869 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -961,31 +961,33 @@ static int find_server(unsigned logopt,
return ret;
}
-static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt)
+static int do_reconnect(unsigned logopt,
+ LDAP **ldap, struct lookup_context *ctxt)
{
- LDAP *ldap = NULL;
- int ret;
+ int ret = NSS_STATUS_UNAVAIL;
+ int dcrv = NSS_STATUS_SUCCESS;
+ int rv = NSS_STATUS_SUCCESS;
if (ctxt->server || !ctxt->uris) {
- ret = do_connect(logopt, &ldap, ctxt->server, ctxt);
+ ret = do_connect(logopt, ldap, ctxt->server, ctxt);
#ifdef WITH_SASL
/* Dispose of the sasl authentication connection and try again. */
- if (ret != NSS_STATUS_SUCCESS &&
- ctxt->auth_required & LDAP_NEED_AUTH) {
+ if (ctxt->auth_required & LDAP_NEED_AUTH &&
+ ret != NSS_STATUS_SUCCESS && ret != NSS_STATUS_NOTFOUND) {
ldapinit_mutex_lock();
autofs_sasl_dispose(ctxt);
ldapinit_mutex_unlock();
- ret = connect_to_server(logopt, &ldap,
+ ret = connect_to_server(logopt, ldap,
ctxt->server, ctxt);
}
#endif
- return ldap;
+ return ret;
}
if (ctxt->dclist) {
- ret = find_dc_server(logopt, &ldap, ctxt->dclist->uri, ctxt);
- if (ret == NSS_STATUS_SUCCESS)
- return ldap;
+ dcrv = find_dc_server(logopt, ldap, ctxt->dclist->uri, ctxt);
+ if (dcrv == NSS_STATUS_SUCCESS)
+ return dcrv;
}
uris_mutex_lock(ctxt);
@@ -1004,22 +1006,22 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt)
if (!ctxt->uri)
goto find_server;
- ret = do_connect(logopt, &ldap, ctxt->uri->uri, ctxt);
+ rv = do_connect(logopt, ldap, ctxt->uri->uri, ctxt);
#ifdef WITH_SASL
/*
* Dispose of the sasl authentication connection and try the
* current server again before trying other servers in the list.
*/
- if (ret != NSS_STATUS_SUCCESS &&
- ctxt->auth_required & LDAP_NEED_AUTH) {
+ if (ctxt->auth_required & LDAP_NEED_AUTH &&
+ rv != NSS_STATUS_SUCCESS && rv != NSS_STATUS_NOTFOUND) {
ldapinit_mutex_lock();
autofs_sasl_dispose(ctxt);
ldapinit_mutex_unlock();
- ret = connect_to_server(logopt, &ldap, ctxt->uri->uri, ctxt);
+ rv = connect_to_server(logopt, ldap, ctxt->uri->uri, ctxt);
}
#endif
- if (ldap)
- return ldap;
+ if (rv == NSS_STATUS_SUCCESS)
+ return rv;
/* Failed to connect, try to find a new server */
@@ -1031,11 +1033,16 @@ find_server:
#endif
/* Current server failed, try the rest or dc connection */
- ret = find_server(logopt, &ldap, ctxt);
- if (ret != NSS_STATUS_SUCCESS)
+ ret = find_server(logopt, ldap, ctxt);
+ if (ret != NSS_STATUS_SUCCESS) {
+ if (ret == NSS_STATUS_NOTFOUND ||
+ dcrv == NSS_STATUS_NOTFOUND ||
+ rv == NSS_STATUS_NOTFOUND)
+ ret = NSS_STATUS_NOTFOUND;
error(logopt, MODPREFIX "failed to find available server");
+ }
- return ldap;
+ return ret;
}
int get_property(unsigned logopt, xmlNodePtr node, const char *prop, char **value)
@@ -1841,12 +1848,12 @@ int lookup_read_master(struct master *master, time_t age, void *context)
char **values = NULL;
char *attrs[3];
int scope = LDAP_SCOPE_SUBTREE;
- LDAP *ldap;
+ LDAP *ldap = NULL;
/* Initialize the LDAP context. */
- ldap = do_reconnect(logopt, ctxt);
- if (!ldap)
- return NSS_STATUS_UNAVAIL;
+ rv = do_reconnect(logopt, &ldap, ctxt);
+ if (rv)
+ return rv;
class = ctxt->schema->entry_class;
entry = ctxt->schema->entry_attr;
@@ -2754,9 +2761,10 @@ static int read_one_map(struct autofs_point *ap,
sp.age = age;
/* Initialize the LDAP context. */
- sp.ldap = do_reconnect(ap->logopt, ctxt);
- if (!sp.ldap)
- return NSS_STATUS_UNAVAIL;
+ sp.ldap = NULL;
+ rv = do_reconnect(ap->logopt, &sp.ldap, ctxt);
+ if (rv)
+ return rv;
class = ctxt->schema->entry_class;
entry = ctxt->schema->entry_attr;
@@ -2908,7 +2916,7 @@ static int lookup_one(struct autofs_point *ap, struct map_source *source,
struct berval **bvValues;
char *attrs[3];
int scope = LDAP_SCOPE_SUBTREE;
- LDAP *ldap;
+ LDAP *ldap = NULL;
struct mapent *we;
unsigned int wild = 0;
int ret = CHE_MISSING;
@@ -2921,9 +2929,11 @@ static int lookup_one(struct autofs_point *ap, struct map_source *source,
}
/* Initialize the LDAP context. */
- ldap = do_reconnect(ap->logopt, ctxt);
- if (!ldap)
+ rv = do_reconnect(ap->logopt, &ldap, ctxt);
+ if (rv == NSS_STATUS_UNAVAIL)
return CHE_UNAVAIL;
+ if (rv == NSS_STATUS_NOTFOUND)
+ return ret;
class = ctxt->schema->entry_class;
entry = ctxt->schema->entry_attr;
@@ -3252,7 +3262,7 @@ static int lookup_one_amd(struct autofs_point *ap,
struct lookup_context *ctxt)
{
struct mapent_cache *mc = source->mc;
- LDAP *ldap;
+ LDAP *ldap = NULL;
LDAPMessage *result = NULL, *e;
char *query;
int scope = LDAP_SCOPE_SUBTREE;
@@ -3271,9 +3281,11 @@ static int lookup_one_amd(struct autofs_point *ap,
}
/* Initialize the LDAP context. */
- ldap = do_reconnect(ap->logopt, ctxt);
- if (!ldap)
+ rv = do_reconnect(ap->logopt, &ldap, ctxt);
+ if (rv == NSS_STATUS_UNAVAIL)
return CHE_UNAVAIL;
+ if (rv == NSS_STATUS_NOTFOUND)
+ return ret;
map = ctxt->schema->map_attr;
class = ctxt->schema->entry_class;

View File

@ -0,0 +1,67 @@
autofs-5.1.1 - fix rwlock unlock crash
From: Ian Kent <raven@themaw.net>
It should be the case that the only way that automount can exit
the kernel communication read loop is after reading a packet and
performing shutdown operations.
However there are reports of pthread_rwlock_unlock() being called
from the exit cleanup function when the lock it is trying to unlock
is not held.
But the call to the cleanup function is outside the communication
loop so call it from each of the loop break points instead so that
the expected locks must be held.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 7 ++++---
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index fa8231c..3bd7145 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -10,6 +10,7 @@
- make find_dc_server() return a status.
- make find_server() return a status.
- fix return handling of do_reconnect() in ldap module.
+- fix rwlock unlock crash.
21/04/2015 autofs-5.1.1
=======================
diff --git a/daemon/automount.c b/daemon/automount.c
index c81b4af..6cba3db 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -1757,6 +1757,7 @@ void *handle_mounts(void *arg)
*/
if (ap->type == LKP_DIRECT) {
umount_autofs(ap, NULL, 1);
+ handle_mounts_cleanup(ap);
break;
}
@@ -1767,8 +1768,10 @@ void *handle_mounts(void *arg)
* occurs while we're trying to umount.
*/
ret = umount_autofs(ap, NULL, 1);
- if (!ret)
+ if (!ret) {
+ handle_mounts_cleanup(ap);
break;
+ }
/* Failed shutdown returns to ready */
warn(ap->logopt,
@@ -1789,8 +1792,6 @@ void *handle_mounts(void *arg)
}
}
- handle_mounts_cleanup(ap);
-
return NULL;
}

View File

@ -0,0 +1,836 @@
autofs-5.1.1 - fix sasl connection concurrancy problem
From: Ian Kent <raven@themaw.net>
After using the contributed Cyrus SASL code in autofs for years I've
finally looked at the Cyrus SASL C API RFC only to find that the
library isn't thread safe unless a connection context per thread is
used, similar to the LDAP library.
To be fair this code originated prior to the threaded version of
autofs so it's my bad I didn't check.
But having seen this I have no choice but to make the sasl context
per thread not per autofs lookup context.
Also extend the mutual exclusion even further.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
include/lookup_ldap.h | 16 +++-
modules/cyrus-sasl.c | 46 ++++++-----
modules/lookup_ldap.c | 198 +++++++++++++++++++++++++------------------------
4 files changed, 136 insertions(+), 125 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 83412a3..663b867 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -32,6 +32,7 @@
- change time() to use monotonic_clock().
- remove unused function elapsed().
- fix unbind sasl external mech.
+- fix sasl connection concurrancy problem.
21/04/2015 autofs-5.1.1
=======================
diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h
index be4bc1e..3a7aba7 100644
--- a/include/lookup_ldap.h
+++ b/include/lookup_ldap.h
@@ -34,6 +34,13 @@ struct ldap_searchdn {
struct ldap_searchdn *next;
};
+struct ldap_conn {
+ LDAP *ldap;
+#ifdef WITH_SASL
+ sasl_conn_t *sasl_conn;
+#endif
+};
+
struct lookup_context {
char *mapname;
unsigned int format;
@@ -86,7 +93,6 @@ struct lookup_context {
/* Kerberos */
krb5_context krb5ctxt;
krb5_ccache krb5_ccache;
- sasl_conn_t *sasl_conn;
/* SASL external */
char *extern_cert;
char *extern_key;
@@ -113,16 +119,16 @@ struct lookup_context {
/* lookup_ldap.c */
LDAP *init_ldap_connection(unsigned logopt, const char *uri, struct lookup_context *ctxt);
-int unbind_ldap_connection(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt);
+int unbind_ldap_connection(unsigned logopt, struct ldap_conn *conn, struct lookup_context *ctxt);
int authtype_requires_creds(const char *authtype);
#ifdef WITH_SASL
/* cyrus-sasl.c */
int autofs_sasl_client_init(unsigned logopt);
int autofs_sasl_init(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt);
-int autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt);
-void autofs_sasl_unbind(LDAP *ldap, struct lookup_context *ctxt);
-void autofs_sasl_dispose(LDAP *ldap, struct lookup_context *ctxt);
+int autofs_sasl_bind(unsigned logopt, struct ldap_conn *conn, struct lookup_context *ctxt);
+void autofs_sasl_unbind(struct ldap_conn *conn, struct lookup_context *ctxt);
+void autofs_sasl_dispose(struct ldap_conn *conn, struct lookup_context *ctxt);
void autofs_sasl_done(void);
/* cyrus-sasl-extern */
int do_sasl_extern(LDAP *ldap, struct lookup_context *ctxt);
diff --git a/modules/cyrus-sasl.c b/modules/cyrus-sasl.c
index c5e72f7..11a1178 100644
--- a/modules/cyrus-sasl.c
+++ b/modules/cyrus-sasl.c
@@ -885,16 +885,19 @@ sasl_choose_mech(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
* Routine called when unbinding an ldap connection.
*/
void
-autofs_sasl_unbind(LDAP *ldap, struct lookup_context *ctxt)
+autofs_sasl_unbind(struct ldap_conn *conn, struct lookup_context *ctxt)
{
if (ctxt->sasl_mech && !strncmp(ctxt->sasl_mech, "EXTERNAL", 8)) {
- ldap_unbind_s(ldap);
+ if (conn->ldap) {
+ ldap_unbind_s(conn->ldap);
+ conn->ldap = NULL;
+ }
return;
}
- if (ctxt->sasl_conn) {
- sasl_dispose(&ctxt->sasl_conn);
- ctxt->sasl_conn = NULL;
+ if (conn->sasl_conn) {
+ sasl_dispose(&conn->sasl_conn);
+ conn->sasl_conn = NULL;
}
}
@@ -908,13 +911,10 @@ autofs_sasl_unbind(LDAP *ldap, struct lookup_context *ctxt)
* -1 - Failure
*/
int
-autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
+autofs_sasl_bind(unsigned logopt,
+ struct ldap_conn *conn, struct lookup_context *ctxt)
{
- sasl_conn_t *conn = NULL;
-
- /* If we already have a connection use it */
- if (ctxt->sasl_conn)
- return 0;
+ sasl_conn_t *sasl_conn = NULL;
if (ctxt->sasl_mech && !strncmp(ctxt->sasl_mech, "EXTERNAL", 8)) {
int result;
@@ -923,7 +923,7 @@ autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
"Attempting sasl bind with mechanism %s",
ctxt->sasl_mech);
- result = do_sasl_extern(ldap, ctxt);
+ result = do_sasl_extern(conn->ldap, ctxt);
if (result)
debug(logopt,
"Failed to authenticate with mech %s",
@@ -953,14 +953,16 @@ autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
* auth mechanism.
*/
if (ctxt->sasl_mech)
- conn = sasl_bind_mech(logopt, ldap, ctxt, ctxt->sasl_mech);
+ sasl_conn = sasl_bind_mech(logopt,
+ conn->ldap, ctxt, ctxt->sasl_mech);
else
- conn = sasl_choose_mech(logopt, ldap, ctxt);
+ sasl_conn = sasl_choose_mech(logopt, conn->ldap, ctxt);
if (!conn)
return -1;
- ctxt->sasl_conn = conn;
+ conn->sasl_conn = sasl_conn;
+
return 0;
}
@@ -968,19 +970,21 @@ autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
* Destructor routine. This should be called when finished with an ldap
* session.
*/
-void autofs_sasl_dispose(LDAP *ldap, struct lookup_context *ctxt)
+void autofs_sasl_dispose(struct ldap_conn *conn, struct lookup_context *ctxt)
{
int status, ret;
if (ctxt->sasl_mech && !strncmp(ctxt->sasl_mech, "EXTERNAL", 8)) {
- if (ldap)
- ldap_unbind_s(ldap);
+ if (conn && conn->ldap) {
+ ldap_unbind_s(conn->ldap);
+ conn->ldap = NULL;
+ }
return;
}
- if (ctxt->sasl_conn) {
- sasl_dispose(&ctxt->sasl_conn);
- ctxt->sasl_conn = NULL;
+ if (conn && conn->sasl_conn) {
+ sasl_dispose(&conn->sasl_conn);
+ conn->sasl_conn = NULL;
}
if (ctxt->kinit_successful) {
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 7f50c34..959890a 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -214,7 +214,9 @@ int bind_ldap_simple(unsigned logopt, LDAP *ldap, const char *uri, struct lookup
return 0;
}
-int __unbind_ldap_connection(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
+int __unbind_ldap_connection(unsigned logopt,
+ struct ldap_conn *conn,
+ struct lookup_context *ctxt)
{
int rv = LDAP_SUCCESS;
@@ -222,30 +224,35 @@ int __unbind_ldap_connection(unsigned logopt, LDAP *ldap, struct lookup_context
ctxt->use_tls = LDAP_TLS_INIT;
#ifdef WITH_SASL
if (ctxt->auth_required & LDAP_NEED_AUTH)
- autofs_sasl_unbind(ldap, ctxt);
- else
- rv = ldap_unbind_ext(ldap, NULL, NULL);
-#else
- rv = ldap_unbind_ext(ldap, NULL, NULL);
+ autofs_sasl_unbind(conn, ctxt);
+ /* No, sasl_dispose does not release the ldap connection
+ * unless it's using sasl EXTERNAL
+ */
#endif
+ if (conn->ldap) {
+ rv = ldap_unbind_ext(conn->ldap, NULL, NULL);
+ conn->ldap = NULL;
+ }
if (rv != LDAP_SUCCESS)
error(logopt, "unbind failed: %s", ldap_err2string(rv));
return rv;
}
-int unbind_ldap_connection(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
+int unbind_ldap_connection(unsigned logopt,
+ struct ldap_conn *conn,
+ struct lookup_context *ctxt)
{
int rv;
ldapinit_mutex_lock();
- rv = __unbind_ldap_connection(logopt, ldap, ctxt);
+ rv = __unbind_ldap_connection(logopt, conn, ctxt);
ldapinit_mutex_unlock();
return rv;
}
-LDAP *__init_ldap_connection(unsigned logopt, const char *uri, struct lookup_context *ctxt)
+LDAP *init_ldap_connection(unsigned logopt, const char *uri, struct lookup_context *ctxt)
{
LDAP *ldap = NULL;
struct timeval timeout = { ctxt->timeout, 0 };
@@ -313,7 +320,7 @@ LDAP *__init_ldap_connection(unsigned logopt, const char *uri, struct lookup_con
return NULL;
}
ctxt->use_tls = LDAP_TLS_DONT_USE;
- ldap = __init_ldap_connection(logopt, uri, ctxt);
+ ldap = init_ldap_connection(logopt, uri, ctxt);
if (ldap)
ctxt->use_tls = LDAP_TLS_INIT;
return ldap;
@@ -324,17 +331,6 @@ LDAP *__init_ldap_connection(unsigned logopt, const char *uri, struct lookup_con
return ldap;
}
-LDAP *init_ldap_connection(unsigned logopt, const char *uri, struct lookup_context *ctxt)
-{
- LDAP *ldap;
-
- ldapinit_mutex_lock();
- ldap = __init_ldap_connection(logopt, uri, ctxt);
- ldapinit_mutex_unlock();
-
- return ldap;
-}
-
static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt, const char *class, const char *key)
{
char buf[MAX_ERR_BUF];
@@ -574,33 +570,32 @@ static int find_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctx
return 0;
}
-static int do_bind(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_context *ctxt)
+static int do_bind(unsigned logopt, struct ldap_conn *conn,
+ const char *uri, struct lookup_context *ctxt)
{
char *host = NULL, *nhost;
int rv;
- ldapinit_mutex_lock();
#ifdef WITH_SASL
debug(logopt, MODPREFIX "auth_required: %d, sasl_mech %s",
ctxt->auth_required, ctxt->sasl_mech);
if (ctxt->auth_required & LDAP_NEED_AUTH) {
- rv = autofs_sasl_bind(logopt, ldap, ctxt);
+ rv = autofs_sasl_bind(logopt, conn, ctxt);
debug(logopt, MODPREFIX "autofs_sasl_bind returned %d", rv);
} else {
- rv = bind_ldap_simple(logopt, ldap, uri, ctxt);
+ rv = bind_ldap_simple(logopt, conn->ldap, uri, ctxt);
debug(logopt, MODPREFIX "ldap simple bind returned %d", rv);
}
#else
- rv = bind_ldap_simple(logopt, ldap, uri, ctxt);
+ rv = bind_ldap_simple(logopt, conn->ldap, uri, ctxt);
debug(logopt, MODPREFIX "ldap simple bind returned %d", rv);
#endif
- ldapinit_mutex_unlock();
if (rv != 0)
return 0;
- rv = ldap_get_option(ldap, LDAP_OPT_HOST_NAME, &host);
+ rv = ldap_get_option(conn->ldap, LDAP_OPT_HOST_NAME, &host);
if (rv != LDAP_SUCCESS || !host) {
debug(logopt, "failed to get hostname for connection");
return 0;
@@ -634,15 +629,12 @@ static int do_bind(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_c
return 1;
}
-static int do_connect(unsigned logopt, LDAP **ldap,
+static int do_connect(unsigned logopt, struct ldap_conn *conn,
const char *uri, struct lookup_context *ctxt)
{
char *cur_host = NULL;
- LDAP *handle;
int ret = NSS_STATUS_SUCCESS;
- *ldap = NULL;
-
#ifdef WITH_SASL
if (ctxt->extern_cert && ctxt->extern_key) {
set_env(logopt, ENV_LDAPTLS_CERT, ctxt->extern_cert);
@@ -650,8 +642,8 @@ static int do_connect(unsigned logopt, LDAP **ldap,
}
#endif
- handle = init_ldap_connection(logopt, uri, ctxt);
- if (!handle) {
+ conn->ldap = init_ldap_connection(logopt, uri, ctxt);
+ if (!conn->ldap) {
ret = NSS_STATUS_UNAVAIL;
goto out;
}
@@ -661,8 +653,8 @@ static int do_connect(unsigned logopt, LDAP **ldap,
cur_host = ctxt->cur_host;
uris_mutex_unlock(ctxt);
- if (!do_bind(logopt, handle, uri, ctxt)) {
- unbind_ldap_connection(logopt, handle, ctxt);
+ if (!do_bind(logopt, conn, uri, ctxt)) {
+ __unbind_ldap_connection(logopt, conn, ctxt);
ret = NSS_STATUS_UNAVAIL;
goto out;
}
@@ -673,7 +665,6 @@ static int do_connect(unsigned logopt, LDAP **ldap,
uris_mutex_lock(ctxt);
if (ctxt->schema && ctxt->qdn && (cur_host == ctxt->cur_host)) {
uris_mutex_unlock(ctxt);
- *ldap = handle;
goto out;
}
uris_mutex_unlock(ctxt);
@@ -684,8 +675,8 @@ static int do_connect(unsigned logopt, LDAP **ldap,
* base dn for searches.
*/
if (!ctxt->schema) {
- if (!find_query_dn(logopt, handle, ctxt)) {
- unbind_ldap_connection(logopt, handle, ctxt);
+ if (!find_query_dn(logopt, conn->ldap, ctxt)) {
+ __unbind_ldap_connection(logopt, conn, ctxt);
ret = NSS_STATUS_NOTFOUND;
warn(logopt,
MODPREFIX "failed to find valid query dn");
@@ -694,21 +685,21 @@ static int do_connect(unsigned logopt, LDAP **ldap,
} else if (!(ctxt->format & MAP_FLAG_FORMAT_AMD)) {
const char *class = ctxt->schema->map_class;
const char *key = ctxt->schema->map_attr;
- if (!get_query_dn(logopt, handle, ctxt, class, key)) {
- unbind_ldap_connection(logopt, handle, ctxt);
+ if (!get_query_dn(logopt, conn->ldap, ctxt, class, key)) {
+ __unbind_ldap_connection(logopt, conn, ctxt);
ret = NSS_STATUS_NOTFOUND;
error(logopt, MODPREFIX "failed to get query dn");
goto out;
}
}
- *ldap = handle;
out:
return ret;
}
static unsigned long get_amd_timestamp(struct lookup_context *ctxt)
{
+ struct ldap_conn conn;
LDAP *ldap;
LDAPMessage *result = NULL, *e;
char *query;
@@ -719,9 +710,11 @@ static unsigned long get_amd_timestamp(struct lookup_context *ctxt)
unsigned long timestamp = 0;
int rv, l, ql;
- rv = do_connect(LOGOPT_ANY, &ldap, ctxt->server, ctxt);
+ memset(&conn, 0, sizeof(struct ldap_conn));
+ rv = do_connect(LOGOPT_ANY, &conn, ctxt->server, ctxt);
if (rv != NSS_STATUS_SUCCESS)
return 0;
+ ldap = conn.ldap;
map = amd_timestamp.map_attr;
class = amd_timestamp.entry_class;
@@ -758,7 +751,7 @@ static unsigned long get_amd_timestamp(struct lookup_context *ctxt)
rv = ldap_search_s(ldap, ctxt->base, scope, query, attrs, 0, &result);
if ((rv != LDAP_SUCCESS) || !result) {
crit(LOGOPT_ANY, MODPREFIX "timestamp query failed %s", query);
- unbind_ldap_connection(LOGOPT_ANY, ldap, ctxt);
+ unbind_ldap_connection(LOGOPT_ANY, &conn, ctxt);
if (result)
ldap_msgfree(result);
free(query);
@@ -770,7 +763,7 @@ static unsigned long get_amd_timestamp(struct lookup_context *ctxt)
debug(LOGOPT_ANY,
MODPREFIX "got answer, but no entry for timestamp");
ldap_msgfree(result);
- unbind_ldap_connection(LOGOPT_ANY, ldap, ctxt);
+ unbind_ldap_connection(LOGOPT_ANY, &conn, ctxt);
free(query);
return CHE_MISSING;
}
@@ -821,18 +814,18 @@ next:
}
ldap_msgfree(result);
- unbind_ldap_connection(LOGOPT_ANY, ldap, ctxt);
+ unbind_ldap_connection(LOGOPT_ANY, &conn, ctxt);
free(query);
return timestamp;
}
-static int connect_to_server(unsigned logopt, LDAP **ldap,
+static int connect_to_server(unsigned logopt, struct ldap_conn *conn,
const char *uri, struct lookup_context *ctxt)
{
int ret;
- ret = do_connect(logopt, ldap, uri, ctxt);
+ ret = do_connect(logopt, conn, uri, ctxt);
if (ret != NSS_STATUS_SUCCESS) {
warn(logopt,
MODPREFIX "couldn't connect to server %s",
@@ -842,7 +835,7 @@ static int connect_to_server(unsigned logopt, LDAP **ldap,
return ret;
}
-static int find_dc_server(unsigned logopt, LDAP **ldap,
+static int find_dc_server(unsigned logopt, struct ldap_conn *conn,
const char *uri, struct lookup_context *ctxt)
{
char *str, *tok, *ptr = NULL;
@@ -858,7 +851,7 @@ static int find_dc_server(unsigned logopt, LDAP **ldap,
int rv;
debug(logopt, "trying server uri %s", this);
- rv = connect_to_server(logopt, ldap, this, ctxt);
+ rv = connect_to_server(logopt, conn, this, ctxt);
if (rv == NSS_STATUS_SUCCESS) {
info(logopt, "connected to uri %s", this);
free(str);
@@ -875,7 +868,7 @@ static int find_dc_server(unsigned logopt, LDAP **ldap,
}
static int find_server(unsigned logopt,
- LDAP **ldap, struct lookup_context *ctxt)
+ struct ldap_conn *conn, struct lookup_context *ctxt)
{
struct ldap_uri *this = NULL;
struct list_head *p, *first;
@@ -906,7 +899,7 @@ static int find_server(unsigned logopt,
if (!strstr(this->uri, ":///")) {
uri = strdup(this->uri);
debug(logopt, "trying server uri %s", uri);
- rv = connect_to_server(logopt, ldap, uri, ctxt);
+ rv = connect_to_server(logopt, conn, uri, ctxt);
if (rv == NSS_STATUS_SUCCESS) {
ret = NSS_STATUS_SUCCESS;
info(logopt, "connected to uri %s", uri);
@@ -928,7 +921,7 @@ static int find_server(unsigned logopt,
dclist = tmp;
uri = strdup(dclist->uri);
}
- rv = find_dc_server(logopt, ldap, uri, ctxt);
+ rv = find_dc_server(logopt, conn, uri, ctxt);
if (rv == NSS_STATUS_SUCCESS) {
ret = NSS_STATUS_SUCCESS;
free(uri);
@@ -947,7 +940,7 @@ static int find_server(unsigned logopt,
}
uris_mutex_lock(ctxt);
- if (ldap)
+ if (conn->ldap)
ctxt->uri = this;
if (dclist) {
if (!ctxt->dclist)
@@ -965,37 +958,39 @@ static int find_server(unsigned logopt,
}
static int do_reconnect(unsigned logopt,
- LDAP **ldap, struct lookup_context *ctxt)
+ struct ldap_conn *conn, struct lookup_context *ctxt)
{
int ret = NSS_STATUS_UNAVAIL;
int dcrv = NSS_STATUS_SUCCESS;
int rv = NSS_STATUS_SUCCESS;
+ ldapinit_mutex_lock();
if (ctxt->server || !ctxt->uris) {
- ret = do_connect(logopt, ldap, ctxt->server, ctxt);
+ ret = do_connect(logopt, conn, ctxt->server, ctxt);
#ifdef WITH_SASL
/* Dispose of the sasl authentication connection and try again. */
if (ctxt->auth_required & LDAP_NEED_AUTH &&
ret != NSS_STATUS_SUCCESS && ret != NSS_STATUS_NOTFOUND) {
- ldapinit_mutex_lock();
- autofs_sasl_dispose(*ldap, ctxt);
- ldapinit_mutex_unlock();
- ret = connect_to_server(logopt, ldap,
+ autofs_sasl_dispose(conn, ctxt);
+ ret = connect_to_server(logopt, conn,
ctxt->server, ctxt);
}
#endif
+ ldapinit_mutex_unlock();
return ret;
}
if (ctxt->dclist) {
- dcrv = find_dc_server(logopt, ldap, ctxt->dclist->uri, ctxt);
- if (dcrv == NSS_STATUS_SUCCESS)
+ dcrv = find_dc_server(logopt, conn, ctxt->dclist->uri, ctxt);
+ if (dcrv == NSS_STATUS_SUCCESS) {
+ ldapinit_mutex_unlock();
return dcrv;
+ }
}
uris_mutex_lock(ctxt);
if (ctxt->dclist) {
- if (!ldap || ctxt->dclist->expire < monotonic_time(NULL)) {
+ if (!conn->ldap || ctxt->dclist->expire < monotonic_time(NULL)) {
free_dclist(ctxt->dclist);
ctxt->dclist = NULL;
}
@@ -1009,7 +1004,7 @@ static int do_reconnect(unsigned logopt,
if (!ctxt->uri)
goto find_server;
- rv = do_connect(logopt, ldap, ctxt->uri->uri, ctxt);
+ rv = do_connect(logopt, conn, ctxt->uri->uri, ctxt);
#ifdef WITH_SASL
/*
* Dispose of the sasl authentication connection and try the
@@ -1017,26 +1012,24 @@ static int do_reconnect(unsigned logopt,
*/
if (ctxt->auth_required & LDAP_NEED_AUTH &&
rv != NSS_STATUS_SUCCESS && rv != NSS_STATUS_NOTFOUND) {
- ldapinit_mutex_lock();
- autofs_sasl_dispose(*ldap, ctxt);
- ldapinit_mutex_unlock();
- rv = connect_to_server(logopt, ldap, ctxt->uri->uri, ctxt);
+ autofs_sasl_dispose(conn, ctxt);
+ rv = connect_to_server(logopt, conn, ctxt->uri->uri, ctxt);
}
#endif
- if (rv == NSS_STATUS_SUCCESS)
+ if (rv == NSS_STATUS_SUCCESS) {
+ ldapinit_mutex_unlock();
return rv;
+ }
/* Failed to connect, try to find a new server */
find_server:
#ifdef WITH_SASL
- ldapinit_mutex_lock();
- autofs_sasl_dispose(*ldap, ctxt);
- ldapinit_mutex_unlock();
+ autofs_sasl_dispose(conn, ctxt);
#endif
/* Current server failed, try the rest or dc connection */
- ret = find_server(logopt, ldap, ctxt);
+ ret = find_server(logopt, conn, ctxt);
if (ret != NSS_STATUS_SUCCESS) {
if (ret == NSS_STATUS_NOTFOUND ||
dcrv == NSS_STATUS_NOTFOUND ||
@@ -1044,6 +1037,7 @@ find_server:
ret = NSS_STATUS_NOTFOUND;
error(logopt, MODPREFIX "failed to find available server");
}
+ ldapinit_mutex_unlock();
return ret;
}
@@ -1877,11 +1871,6 @@ int lookup_reinit(const char *mapfmt,
*context = new;
-#ifdef WITH_SASL
- ldapinit_mutex_lock();
- autofs_sasl_dispose(NULL, ctxt);
- ldapinit_mutex_unlock();
-#endif
free_context(ctxt);
return 0;
@@ -1893,6 +1882,8 @@ int lookup_read_master(struct master *master, time_t age, void *context)
unsigned int timeout = master->default_timeout;
unsigned int logging = master->default_logging;
unsigned int logopt = master->logopt;
+ struct ldap_conn conn;
+ LDAP *ldap;
int rv, l, count;
char buf[MAX_ERR_BUF];
char parse_buf[PARSE_MAX_BUF];
@@ -1903,12 +1894,13 @@ int lookup_read_master(struct master *master, time_t age, void *context)
char **values = NULL;
char *attrs[3];
int scope = LDAP_SCOPE_SUBTREE;
- LDAP *ldap = NULL;
/* Initialize the LDAP context. */
- rv = do_reconnect(logopt, &ldap, ctxt);
+ memset(&conn, 0, sizeof(struct ldap_conn));
+ rv = do_reconnect(logopt, &conn, ctxt);
if (rv)
return rv;
+ ldap = conn.ldap;
class = ctxt->schema->entry_class;
entry = ctxt->schema->entry_attr;
@@ -1942,7 +1934,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
if ((rv != LDAP_SUCCESS) || !result) {
error(logopt, MODPREFIX "query failed for %s: %s",
query, ldap_err2string(rv));
- unbind_ldap_connection(logging, ldap, ctxt);
+ unbind_ldap_connection(logging, &conn, ctxt);
if (result)
ldap_msgfree(result);
free(query);
@@ -1955,7 +1947,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
MODPREFIX "query succeeded, no matches for %s",
query);
ldap_msgfree(result);
- unbind_ldap_connection(logging, ldap, ctxt);
+ unbind_ldap_connection(logging, &conn, ctxt);
free(query);
return NSS_STATUS_NOTFOUND;
} else
@@ -2076,7 +2068,7 @@ next:
/* Clean up. */
ldap_msgfree(result);
- unbind_ldap_connection(logopt, ldap, ctxt);
+ unbind_ldap_connection(logopt, &conn, ctxt);
free(query);
return NSS_STATUS_SUCCESS;
@@ -2796,6 +2788,7 @@ static int read_one_map(struct autofs_point *ap,
struct lookup_context *ctxt,
time_t age, int *result_ldap)
{
+ struct ldap_conn conn;
struct ldap_search_params sp;
char buf[MAX_ERR_BUF];
char *class, *info, *entry;
@@ -2816,10 +2809,11 @@ static int read_one_map(struct autofs_point *ap,
sp.age = age;
/* Initialize the LDAP context. */
- sp.ldap = NULL;
- rv = do_reconnect(ap->logopt, &sp.ldap, ctxt);
+ memset(&conn, 0, sizeof(struct ldap_conn));
+ rv = do_reconnect(ap->logopt, &conn, ctxt);
if (rv)
return rv;
+ sp.ldap = conn.ldap;
class = ctxt->schema->entry_class;
entry = ctxt->schema->entry_attr;
@@ -2878,7 +2872,7 @@ static int read_one_map(struct autofs_point *ap,
if (sp.pageSize < 5) {
debug(ap->logopt, MODPREFIX
"result size too small");
- unbind_ldap_connection(ap->logopt, sp.ldap, ctxt);
+ unbind_ldap_connection(ap->logopt, &conn, ctxt);
*result_ldap = rv;
free(sp.query);
return NSS_STATUS_UNAVAIL;
@@ -2887,7 +2881,7 @@ static int read_one_map(struct autofs_point *ap,
}
if (rv != LDAP_SUCCESS || !sp.result) {
- unbind_ldap_connection(ap->logopt, sp.ldap, ctxt);
+ unbind_ldap_connection(ap->logopt, &conn, ctxt);
*result_ldap = rv;
if (sp.result)
ldap_msgfree(sp.result);
@@ -2903,7 +2897,7 @@ static int read_one_map(struct autofs_point *ap,
rv = do_get_entries(&sp, source, ctxt);
if (rv != LDAP_SUCCESS) {
ldap_msgfree(sp.result);
- unbind_ldap_connection(ap->logopt, sp.ldap, ctxt);
+ unbind_ldap_connection(ap->logopt, &conn, ctxt);
*result_ldap = rv;
if (sp.cookie)
ber_bvfree(sp.cookie);
@@ -2916,7 +2910,7 @@ static int read_one_map(struct autofs_point *ap,
debug(ap->logopt, MODPREFIX "done updating map");
- unbind_ldap_connection(ap->logopt, sp.ldap, ctxt);
+ unbind_ldap_connection(ap->logopt, &conn, ctxt);
source->age = age;
if (sp.cookie)
@@ -2959,6 +2953,8 @@ static int lookup_one(struct autofs_point *ap, struct map_source *source,
char *qKey, int qKey_len, struct lookup_context *ctxt)
{
struct mapent_cache *mc;
+ struct ldap_conn conn;
+ LDAP *ldap;
int rv, i, l, ql, count;
char buf[MAX_ERR_BUF];
time_t age = monotonic_time(NULL);
@@ -2971,7 +2967,6 @@ static int lookup_one(struct autofs_point *ap, struct map_source *source,
struct berval **bvValues;
char *attrs[3];
int scope = LDAP_SCOPE_SUBTREE;
- LDAP *ldap = NULL;
struct mapent *we;
unsigned int wild = 0;
int ret = CHE_MISSING;
@@ -2984,11 +2979,13 @@ static int lookup_one(struct autofs_point *ap, struct map_source *source,
}
/* Initialize the LDAP context. */
- rv = do_reconnect(ap->logopt, &ldap, ctxt);
+ memset(&conn, 0, sizeof(struct ldap_conn));
+ rv = do_reconnect(ap->logopt, &conn, ctxt);
if (rv == NSS_STATUS_UNAVAIL)
return CHE_UNAVAIL;
if (rv == NSS_STATUS_NOTFOUND)
return ret;
+ ldap = conn.ldap;
class = ctxt->schema->entry_class;
entry = ctxt->schema->entry_attr;
@@ -3076,7 +3073,7 @@ static int lookup_one(struct autofs_point *ap, struct map_source *source,
if ((rv != LDAP_SUCCESS) || !result) {
crit(ap->logopt, MODPREFIX "query failed for %s", query);
- unbind_ldap_connection(ap->logopt, ldap, ctxt);
+ unbind_ldap_connection(ap->logopt, &conn, ctxt);
if (result)
ldap_msgfree(result);
free(query);
@@ -3091,7 +3088,7 @@ static int lookup_one(struct autofs_point *ap, struct map_source *source,
debug(ap->logopt,
MODPREFIX "got answer, but no entry for %s", query);
ldap_msgfree(result);
- unbind_ldap_connection(ap->logopt, ldap, ctxt);
+ unbind_ldap_connection(ap->logopt, &conn, ctxt);
free(query);
return CHE_MISSING;
}
@@ -3277,7 +3274,7 @@ next:
}
ldap_msgfree(result);
- unbind_ldap_connection(ap->logopt, ldap, ctxt);
+ unbind_ldap_connection(ap->logopt, &conn, ctxt);
/* Failed to find wild entry, update cache if needed */
cache_writelock(mc);
@@ -3317,7 +3314,8 @@ static int lookup_one_amd(struct autofs_point *ap,
struct lookup_context *ctxt)
{
struct mapent_cache *mc = source->mc;
- LDAP *ldap = NULL;
+ struct ldap_conn conn;
+ LDAP *ldap;
LDAPMessage *result = NULL, *e;
char *query;
int scope = LDAP_SCOPE_SUBTREE;
@@ -3336,11 +3334,13 @@ static int lookup_one_amd(struct autofs_point *ap,
}
/* Initialize the LDAP context. */
- rv = do_reconnect(ap->logopt, &ldap, ctxt);
+ memset(&conn, 0, sizeof(struct ldap_conn));
+ rv = do_reconnect(ap->logopt, &conn, ctxt);
if (rv == NSS_STATUS_UNAVAIL)
return CHE_UNAVAIL;
if (rv == NSS_STATUS_NOTFOUND)
return ret;
+ ldap = conn.ldap;
map = ctxt->schema->map_attr;
class = ctxt->schema->entry_class;
@@ -3382,7 +3382,7 @@ static int lookup_one_amd(struct autofs_point *ap,
rv = ldap_search_s(ldap, ctxt->base, scope, query, attrs, 0, &result);
if ((rv != LDAP_SUCCESS) || !result) {
crit(ap->logopt, MODPREFIX "query failed for %s", query);
- unbind_ldap_connection(ap->logopt, ldap, ctxt);
+ unbind_ldap_connection(ap->logopt, &conn, ctxt);
if (result)
ldap_msgfree(result);
free(query);
@@ -3397,7 +3397,7 @@ static int lookup_one_amd(struct autofs_point *ap,
debug(ap->logopt,
MODPREFIX "got answer, but no entry for %s", query);
ldap_msgfree(result);
- unbind_ldap_connection(ap->logopt, ldap, ctxt);
+ unbind_ldap_connection(ap->logopt, &conn, ctxt);
free(query);
return CHE_MISSING;
}
@@ -3459,7 +3459,7 @@ next:
}
ldap_msgfree(result);
- unbind_ldap_connection(ap->logopt, ldap, ctxt);
+ unbind_ldap_connection(ap->logopt, &conn, ctxt);
free(query);
return ret;

View File

@ -0,0 +1,140 @@
autofs-5.1.1 - fix unbind sasl external mech
From: Ian Kent <raven@themaw.net>
If the sasl EXTERNAL mechanism is being used autofs leaks ldap
connection resources.
In this case the current ldap connection needs to be unbound
when calling autofs_sasl_unbind() or autofs_sasl_dispose().
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
include/lookup_ldap.h | 4 ++--
modules/cyrus-sasl.c | 15 +++++++++++++--
modules/lookup_ldap.c | 12 ++++++------
4 files changed, 22 insertions(+), 10 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 4acb332..83412a3 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -31,6 +31,7 @@
- change remaining gettimeofday() to use clock_gettime().
- change time() to use monotonic_clock().
- remove unused function elapsed().
+- fix unbind sasl external mech.
21/04/2015 autofs-5.1.1
=======================
diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h
index ba817aa..be4bc1e 100644
--- a/include/lookup_ldap.h
+++ b/include/lookup_ldap.h
@@ -121,8 +121,8 @@ int authtype_requires_creds(const char *authtype);
int autofs_sasl_client_init(unsigned logopt);
int autofs_sasl_init(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt);
int autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt);
-void autofs_sasl_unbind(struct lookup_context *ctxt);
-void autofs_sasl_dispose(struct lookup_context *ctxt);
+void autofs_sasl_unbind(LDAP *ldap, struct lookup_context *ctxt);
+void autofs_sasl_dispose(LDAP *ldap, struct lookup_context *ctxt);
void autofs_sasl_done(void);
/* cyrus-sasl-extern */
int do_sasl_extern(LDAP *ldap, struct lookup_context *ctxt);
diff --git a/modules/cyrus-sasl.c b/modules/cyrus-sasl.c
index 21bc00c..c5e72f7 100644
--- a/modules/cyrus-sasl.c
+++ b/modules/cyrus-sasl.c
@@ -885,8 +885,13 @@ sasl_choose_mech(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
* Routine called when unbinding an ldap connection.
*/
void
-autofs_sasl_unbind(struct lookup_context *ctxt)
+autofs_sasl_unbind(LDAP *ldap, struct lookup_context *ctxt)
{
+ if (ctxt->sasl_mech && !strncmp(ctxt->sasl_mech, "EXTERNAL", 8)) {
+ ldap_unbind_s(ldap);
+ return;
+ }
+
if (ctxt->sasl_conn) {
sasl_dispose(&ctxt->sasl_conn);
ctxt->sasl_conn = NULL;
@@ -963,10 +968,16 @@ autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
* Destructor routine. This should be called when finished with an ldap
* session.
*/
-void autofs_sasl_dispose(struct lookup_context *ctxt)
+void autofs_sasl_dispose(LDAP *ldap, struct lookup_context *ctxt)
{
int status, ret;
+ if (ctxt->sasl_mech && !strncmp(ctxt->sasl_mech, "EXTERNAL", 8)) {
+ if (ldap)
+ ldap_unbind_s(ldap);
+ return;
+ }
+
if (ctxt->sasl_conn) {
sasl_dispose(&ctxt->sasl_conn);
ctxt->sasl_conn = NULL;
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index afc89c1..7f50c34 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -222,7 +222,7 @@ int __unbind_ldap_connection(unsigned logopt, LDAP *ldap, struct lookup_context
ctxt->use_tls = LDAP_TLS_INIT;
#ifdef WITH_SASL
if (ctxt->auth_required & LDAP_NEED_AUTH)
- autofs_sasl_unbind(ctxt);
+ autofs_sasl_unbind(ldap, ctxt);
else
rv = ldap_unbind_ext(ldap, NULL, NULL);
#else
@@ -978,7 +978,7 @@ static int do_reconnect(unsigned logopt,
if (ctxt->auth_required & LDAP_NEED_AUTH &&
ret != NSS_STATUS_SUCCESS && ret != NSS_STATUS_NOTFOUND) {
ldapinit_mutex_lock();
- autofs_sasl_dispose(ctxt);
+ autofs_sasl_dispose(*ldap, ctxt);
ldapinit_mutex_unlock();
ret = connect_to_server(logopt, ldap,
ctxt->server, ctxt);
@@ -1018,7 +1018,7 @@ static int do_reconnect(unsigned logopt,
if (ctxt->auth_required & LDAP_NEED_AUTH &&
rv != NSS_STATUS_SUCCESS && rv != NSS_STATUS_NOTFOUND) {
ldapinit_mutex_lock();
- autofs_sasl_dispose(ctxt);
+ autofs_sasl_dispose(*ldap, ctxt);
ldapinit_mutex_unlock();
rv = connect_to_server(logopt, ldap, ctxt->uri->uri, ctxt);
}
@@ -1031,7 +1031,7 @@ static int do_reconnect(unsigned logopt,
find_server:
#ifdef WITH_SASL
ldapinit_mutex_lock();
- autofs_sasl_dispose(ctxt);
+ autofs_sasl_dispose(*ldap, ctxt);
ldapinit_mutex_unlock();
#endif
@@ -1879,7 +1879,7 @@ int lookup_reinit(const char *mapfmt,
#ifdef WITH_SASL
ldapinit_mutex_lock();
- autofs_sasl_dispose(ctxt);
+ autofs_sasl_dispose(NULL, ctxt);
ldapinit_mutex_unlock();
#endif
free_context(ctxt);
@@ -3816,7 +3816,7 @@ int lookup_done(void *context)
int rv = close_parse(ctxt->parse);
#ifdef WITH_SASL
ldapinit_mutex_lock();
- autofs_sasl_dispose(ctxt);
+ autofs_sasl_dispose(NULL, ctxt);
autofs_sasl_done();
ldapinit_mutex_unlock();
#endif

View File

@ -0,0 +1,59 @@
autofs-5.1.1 - fix update_hosts_mounts() return
From: Ian Kent <raven@themaw.net>
The return of update_hosts_mounts() isn't used so set it to void type
and log a warning if the map entry fails the parse.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_hosts.c | 11 ++++++-----
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index e22877e..77aad99 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -16,6 +16,7 @@
- fix direct mount stale instance flag reset.
- fix direct map expire not set for initail empty map.
- fix missing source sss in multi map lookup.
+- fix update_hosts_mounts() return.
21/04/2015 autofs-5.1.1
=======================
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
index 0d48356..53aa9d6 100644
--- a/modules/lookup_hosts.c
+++ b/modules/lookup_hosts.c
@@ -162,9 +162,9 @@ static int do_parse_mount(struct autofs_point *ap, struct map_source *source,
return NSS_STATUS_SUCCESS;
}
-static int update_hosts_mounts(struct autofs_point *ap,
- struct map_source *source, time_t age,
- struct lookup_context *ctxt)
+static void update_hosts_mounts(struct autofs_point *ap,
+ struct map_source *source, time_t age,
+ struct lookup_context *ctxt)
{
struct mapent_cache *mc;
struct mapent *me;
@@ -212,13 +212,14 @@ next:
ap->flags |= MOUNT_FLAG_REMOUNT;
ret = ctxt->parse->parse_mount(ap, me->key, strlen(me->key),
me->mapent, ctxt->parse->context);
+ if (ret)
+ warn(ap->logopt, MODPREFIX
+ "failed to parse mount %s", me->mapent);
ap->flags &= ~MOUNT_FLAG_REMOUNT;
cont:
me = cache_lookup_next(mc, me);
}
pthread_cleanup_pop(1);
-
- return NSS_STATUS_SUCCESS;
}
int lookup_read_map(struct autofs_point *ap, time_t age, void *context)

View File

@ -0,0 +1,121 @@
autofs-5.1.1 - implement reinit in dir lookup module
From: Ian Kent <raven@themaw.net>
Refactor the dir lookup module to add an implementation for the newly
added reinit entry point.
Signed-off-by: Ian Kent <raven@themaw.net>
---
modules/lookup_dir.c | 58 ++++++++++++++++++++++++++++++++++----------------
1 file changed, 39 insertions(+), 19 deletions(-)
diff --git a/modules/lookup_dir.c b/modules/lookup_dir.c
index 7a95e24..2880447 100644
--- a/modules/lookup_dir.c
+++ b/modules/lookup_dir.c
@@ -50,24 +50,13 @@ struct lookup_context {
int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
-
-int lookup_init(const char *mapfmt,
- int argc, const char *const *argv, void **context)
+static int do_init(const char *mapfmt,
+ int argc, const char *const *argv,
+ struct lookup_context *ctxt)
{
- struct lookup_context *ctxt;
- char buf[MAX_ERR_BUF];
struct stat st;
- *context = NULL;
- ctxt = malloc(sizeof(struct lookup_context));
- if (!ctxt) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- logerr(MODPREFIX "malloc: %s", estr);
- return 1;
- }
-
if (argc < 1) {
- free(ctxt);
logerr(MODPREFIX "No map name");
return 1;
}
@@ -75,40 +64,71 @@ int lookup_init(const char *mapfmt,
ctxt->mapname = argv[0];
if (ctxt->mapname[0] != '/') {
- free(ctxt);
logmsg(MODPREFIX
"dir map %s is not an absolute pathname", argv[0]);
return 1;
}
if (access(ctxt->mapname, R_OK)) {
- free(ctxt);
warn(LOGOPT_NONE, MODPREFIX
"dir map %s missing or not readable", argv[0]);
return 1;
}
if (stat(ctxt->mapname, &st)) {
- free(ctxt);
warn(LOGOPT_NONE, MODPREFIX
"dir map %s, could not stat", argv[0]);
return 1;
}
- if ( (!S_ISDIR(st.st_mode)) && (!S_ISLNK(st.st_mode)) ) {
- free(ctxt);
+ if ((!S_ISDIR(st.st_mode)) && (!S_ISLNK(st.st_mode))) {
warn(LOGOPT_NONE, MODPREFIX
"dir map %s, is not a directory", argv[0]);
return 1;
}
+ return 0;
+}
+
+int lookup_init(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
+{
+ struct lookup_context *ctxt;
+ char buf[MAX_ERR_BUF];
+
+ *context = NULL;
+
+ ctxt = malloc(sizeof(struct lookup_context));
+ if (!ctxt) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ logerr(MODPREFIX "malloc: %s", estr);
+ return 1;
+ }
+ memset(ctxt, 0, sizeof(struct lookup_context));
+
+ if (do_init(mapfmt, argc, argv, ctxt)) {
+ free(ctxt);
+ return 1;
+ }
+
*context = ctxt;
+
return 0;
}
int lookup_reinit(const char *mapfmt,
int argc, const char *const *argv, void **context)
{
+ struct lookup_context *ctxt = (struct lookup_context *) *context;
+ struct lookup_context new;
+ int ret;
+
+ ret = do_init(mapfmt, argc, argv, &new);
+ if (ret)
+ return 1;
+
+ ctxt->mapname = new.mapname;
+
return 0;
}

View File

@ -0,0 +1,147 @@
autofs-5.1.1 - implement reinit in file lookup module
From: Ian Kent <raven@themaw.net>
Refactor the file lookup module to add an implementation for the newly
added reinit entry point.
Signed-off-by: Ian Kent <raven@themaw.net>
---
modules/lookup_file.c | 85 +++++++++++++++++++++++++++++++++++++------------
1 file changed, 65 insertions(+), 20 deletions(-)
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index c32a4cd..aed3cba 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -50,23 +50,13 @@ struct lookup_context {
int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
-int lookup_init(const char *mapfmt,
- int argc, const char *const *argv, void **context)
+static int do_init(const char *mapfmt,
+ int argc, const char *const *argv,
+ struct lookup_context *ctxt, unsigned int reinit)
{
- struct lookup_context *ctxt;
- char buf[MAX_ERR_BUF];
-
- *context = NULL;
-
- ctxt = malloc(sizeof(struct lookup_context));
- if (!ctxt) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- logerr(MODPREFIX "malloc: %s", estr);
- return 1;
- }
+ int ret = 0;
if (argc < 1) {
- free(ctxt);
logerr(MODPREFIX "No map name");
return 1;
}
@@ -74,14 +64,12 @@ int lookup_init(const char *mapfmt,
ctxt->mapname = argv[0];
if (ctxt->mapname[0] != '/') {
- free(ctxt);
logmsg(MODPREFIX
"file map %s is not an absolute pathname", argv[0]);
return 1;
}
if (access(ctxt->mapname, R_OK)) {
- free(ctxt);
warn(LOGOPT_NONE, MODPREFIX
"file map %s missing or not readable", argv[0]);
return 1;
@@ -95,19 +83,51 @@ int lookup_init(const char *mapfmt,
ctxt->opts_argv = copy_argv(argc, (const char **) argv);
if (ctxt->opts_argv == NULL) {
- free(ctxt);
warn(LOGOPT_NONE, MODPREFIX "failed to duplicate options");
return 1;
}
ctxt->opts_argc = argc;
- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc, argv);
- if (!ctxt->parse) {
+ if (reinit) {
+ ret = reinit_parse(ctxt->parse, mapfmt, MODPREFIX, argc, argv);
+ if (ret)
+ logmsg(MODPREFIX "failed to reinit parse context");
+ } else {
+ ctxt->parse = open_parse(mapfmt, MODPREFIX, argc, argv);
+ if (!ctxt->parse) {
+ logmsg(MODPREFIX "failed to open parse context");
+ ret = 1;
+ }
+ }
+
+ if (ret)
free_argv(ctxt->opts_argc, ctxt->opts_argv);
+
+ return ret;
+}
+
+int lookup_init(const char *mapfmt,
+ int argc, const char *const *argv,
+ void **context)
+{
+ struct lookup_context *ctxt;
+ char buf[MAX_ERR_BUF];
+
+ *context = NULL;
+
+ ctxt = malloc(sizeof(struct lookup_context));
+ if (!ctxt) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ logerr(MODPREFIX "malloc: %s", estr);
+ return 1;
+ }
+ memset(ctxt, 0, sizeof(struct lookup_context));
+
+ if (do_init(mapfmt, argc, argv, ctxt, 0)) {
free(ctxt);
- logmsg(MODPREFIX "failed to open parse context");
return 1;
}
+
*context = ctxt;
return 0;
@@ -116,6 +136,31 @@ int lookup_init(const char *mapfmt,
int lookup_reinit(const char *mapfmt,
int argc, const char *const *argv, void **context)
{
+ struct lookup_context *ctxt = (struct lookup_context *) *context;
+ struct lookup_context *new;
+ char buf[MAX_ERR_BUF];
+ int ret;
+
+ new = malloc(sizeof(struct lookup_context));
+ if (!new) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ logerr(MODPREFIX "malloc: %s", estr);
+ return 1;
+ }
+ memset(new, 0, sizeof(struct lookup_context));
+
+ new->parse = ctxt->parse;
+ ret = do_init(mapfmt, argc, argv, new, 1);
+ if (ret) {
+ free(new);
+ return 1;
+ }
+
+ *context = new;
+
+ free_argv(ctxt->opts_argc, ctxt->opts_argv);
+ free(ctxt);
+
return 0;
}

View File

@ -0,0 +1,154 @@
autofs-5.1.1 - implement reinit in hesiod lookup module
From: Ian Kent <raven@themaw.net>
Refactor the hesiod lookup module to add an implementation for the newly
added reinit entry point.
Signed-off-by: Ian Kent <raven@themaw.net>
---
modules/lookup_hesiod.c | 96 ++++++++++++++++++++++++++++++++++++-----------
1 file changed, 74 insertions(+), 22 deletions(-)
diff --git a/modules/lookup_hesiod.c b/modules/lookup_hesiod.c
index de5ec08..c0f7f51 100644
--- a/modules/lookup_hesiod.c
+++ b/modules/lookup_hesiod.c
@@ -37,24 +37,12 @@ static pthread_mutex_t hesiod_mutex = PTHREAD_MUTEX_INITIALIZER;
int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
-/* This initializes a context (persistent non-global data) for queries to
- this module. */
-int lookup_init(const char *mapfmt,
- int argc, const char *const *argv, void **context)
+static int do_init(const char *mapfmt,
+ int argc, const char *const *argv,
+ struct lookup_context *ctxt, unsigned int reinit)
{
- struct lookup_context *ctxt = NULL;
char buf[MAX_ERR_BUF];
-
- *context = NULL;
-
- /* If we can't build a context, bail. */
- ctxt = malloc(sizeof(struct lookup_context));
- if (!ctxt) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- logerr(MODPREFIX "malloc: %s", estr);
- return 1;
- }
- memset(ctxt, 0, sizeof(struct lookup_context));
+ int ret = 0;
/* Initialize the resolver. */
res_init();
@@ -63,7 +51,6 @@ int lookup_init(const char *mapfmt,
if (hesiod_init(&(ctxt->hesiod_context)) != 0) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
logerr(MODPREFIX "hesiod_init(): %s", estr);
- free(ctxt);
return 1;
}
@@ -75,9 +62,9 @@ int lookup_init(const char *mapfmt,
/* amd formated hesiod maps have a map name */
const char *mapname = argv[0];
if (strncmp(mapname, AMD_MAP_PREFIX, AMD_MAP_PREFIX_LEN)) {
+ hesiod_end(ctxt->hesiod_context);
logerr(MODPREFIX
"incorrect prefix for hesiod map %s", mapname);
- free(ctxt);
return 1;
}
ctxt->mapname = mapname;
@@ -85,13 +72,52 @@ int lookup_init(const char *mapfmt,
argv++;
}
- /* Open the parser, if we can. */
- ctxt->parser = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
- if (!ctxt->parser) {
- logerr(MODPREFIX "failed to open parse context");
+ if (reinit) {
+ ret = reinit_parse(ctxt->parser, mapfmt,
+ MODPREFIX, argc - 1, argv - 1);
+ if (ret)
+ logerr(MODPREFIX "failed to reinit parse context");
+ } else {
+ ctxt->parser = open_parse(mapfmt,
+ MODPREFIX, argc - 1, argv + 1);
+ if (!ctxt->parser) {
+ logerr(MODPREFIX "failed to open parse context");
+ ret = 1;
+ }
+ }
+
+ if (ret)
+ hesiod_end(ctxt->hesiod_context);
+
+ return ret;
+}
+
+/* This initializes a context (persistent non-global data) for queries to
+ this module. */
+int lookup_init(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
+{
+ struct lookup_context *ctxt;
+ char buf[MAX_ERR_BUF];
+ int ret;
+
+ *context = NULL;
+
+ /* If we can't build a context, bail. */
+ ctxt = malloc(sizeof(struct lookup_context));
+ if (!ctxt) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ logerr(MODPREFIX "malloc: %s", estr);
+ return 1;
+ }
+ memset(ctxt, 0, sizeof(struct lookup_context));
+
+ ret = do_init(mapfmt, argc, argv, ctxt, 0);
+ if (ret) {
free(ctxt);
return 1;
}
+
*context = ctxt;
return 0;
@@ -100,6 +126,32 @@ int lookup_init(const char *mapfmt,
int lookup_reinit(const char *mapfmt,
int argc, const char *const *argv, void **context)
{
+ struct lookup_context *ctxt = (struct lookup_context *) *context;
+ struct lookup_context *new;
+ char buf[MAX_ERR_BUF];
+ int ret;
+
+ /* If we can't build a context, bail. */
+ new = malloc(sizeof(struct lookup_context));
+ if (!new) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ logerr(MODPREFIX "malloc: %s", estr);
+ return 1;
+ }
+ memset(new, 0, sizeof(struct lookup_context));
+
+ new->parser = ctxt->parser;
+ ret = do_init(mapfmt, argc, argv, new, 1);
+ if (ret) {
+ free(new);
+ return 1;
+ }
+
+ *context = new;
+
+ hesiod_end(ctxt->hesiod_context);
+ free(ctxt);
+
return 0;
}

View File

@ -0,0 +1,40 @@
autofs-5.1.1 - implement reinit in hosts lookup module
From: Ian Kent <raven@themaw.net>
Refactor the hosts lookup module to add an implementation for the newly
added reinit entry point.
Signed-off-by: Ian Kent <raven@themaw.net>
---
modules/lookup_hosts.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
index 8ba0a4a..0a64655 100644
--- a/modules/lookup_hosts.c
+++ b/modules/lookup_hosts.c
@@ -69,6 +69,7 @@ int lookup_init(const char *mapfmt,
free(ctxt);
return 1;
}
+
*context = ctxt;
return 0;
@@ -77,6 +78,15 @@ int lookup_init(const char *mapfmt,
int lookup_reinit(const char *mapfmt,
int argc, const char *const *argv, void **context)
{
+ struct lookup_context *ctxt = (struct lookup_context *) *context;
+ int ret;
+
+ mapfmt = MAPFMT_DEFAULT;
+
+ ret = reinit_parse(ctxt->parse, mapfmt, MODPREFIX, argc, argv);
+ if (ret)
+ return 1;
+
return 0;
}

View File

@ -0,0 +1,216 @@
autofs-5.1.1 - implement reinit in ldap lookup module
From: Ian Kent <raven@themaw.net>
Refactor the ldap lookup module to add an implementation for the newly
added reinit entry point.
Signed-off-by: Ian Kent <raven@themaw.net>
---
modules/lookup_ldap.c | 109 +++++++++++++++++++++++++++++++++++--------------
1 file changed, 77 insertions(+), 32 deletions(-)
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 0f5bc48..578d6c6 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -1683,39 +1683,23 @@ static void validate_uris(struct list_head *list)
return;
}
-/*
- * This initializes a context (persistent non-global data) for queries to
- * this module. Return zero if we succeed.
- */
-int lookup_init(const char *mapfmt,
- int argc, const char *const *argv, void **context)
+static int do_init(const char *mapfmt,
+ int argc, const char *const *argv,
+ struct lookup_context *ctxt, unsigned int reinit)
{
unsigned int is_amd_format;
- struct lookup_context *ctxt;
- char buf[MAX_ERR_BUF];
int ret;
- *context = NULL;
-
- /* If we can't build a context, bail. */
- ctxt = malloc(sizeof(struct lookup_context));
- if (!ctxt) {
- char *estr = strerror_r(errno, buf, sizeof(buf));
- logerr(MODPREFIX "malloc: %s", estr);
- return 1;
- }
- memset(ctxt, 0, sizeof(struct lookup_context));
-
ret = pthread_mutex_init(&ctxt->uris_mutex, NULL);
if (ret) {
error(LOGOPT_ANY, MODPREFIX "failed to init uris mutex");
- free(ctxt);
return 1;
}
/* If a map type isn't explicitly given, parse it like sun entries. */
if (mapfmt == NULL)
mapfmt = MAPFMT_DEFAULT;
+
is_amd_format = 0;
if (!strcmp(mapfmt, "amd")) {
is_amd_format = 1;
@@ -1733,7 +1717,6 @@ int lookup_init(const char *mapfmt,
*/
if (!parse_server_string(LOGOPT_NONE, argv[0], ctxt)) {
error(LOGOPT_ANY, MODPREFIX "cannot parse server string");
- free_context(ctxt);
return 1;
}
@@ -1758,7 +1741,6 @@ int lookup_init(const char *mapfmt,
char *tmp = conf_amd_get_ldap_base();
if (!tmp) {
error(LOGOPT_ANY, MODPREFIX "failed to get base dn");
- free_context(ctxt);
return 1;
}
ctxt->base = tmp;
@@ -1767,7 +1749,6 @@ int lookup_init(const char *mapfmt,
if (!tmp) {
error(LOGOPT_ANY,
MODPREFIX "failed to get ldap_hostports");
- free_context(ctxt);
return 1;
}
@@ -1777,21 +1758,18 @@ int lookup_init(const char *mapfmt,
*/
if (!parse_server_string(LOGOPT_NONE, tmp, ctxt)) {
error(LOGOPT_ANY, MODPREFIX "cannot parse server string");
- free_context(ctxt);
return 1;
}
free(tmp);
if (!ctxt->server) {
error(LOGOPT_ANY, MODPREFIX "ldap_hostports not valid");
- free_context(ctxt);
return 1;
}
tmp = strdup(argv[0]);
if (!tmp) {
error(LOGOPT_ANY, MODPREFIX "failed to set mapname");
- free_context(ctxt);
return 1;
}
ctxt->mapname = tmp;
@@ -1805,7 +1783,7 @@ int lookup_init(const char *mapfmt,
*/
ret = parse_ldap_config(LOGOPT_NONE, ctxt);
if (ret) {
- free_context(ctxt);
+ error(LOGOPT_ANY, MODPREFIX "failed to parse ldap config");
return 1;
}
@@ -1815,7 +1793,6 @@ int lookup_init(const char *mapfmt,
if (!autofs_sasl_client_init(LOGOPT_NONE)) {
error(LOGOPT_ANY, "failed to init sasl client");
ldapinit_mutex_unlock();
- free_context(ctxt);
return 1;
}
ldapinit_mutex_unlock();
@@ -1824,13 +1801,51 @@ int lookup_init(const char *mapfmt,
if (is_amd_format)
ctxt->timestamp = get_amd_timestamp(ctxt);
- /* Open the parser, if we can. */
- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
- if (!ctxt->parse) {
+ if (reinit) {
+ ret = reinit_parse(ctxt->parse,
+ mapfmt, MODPREFIX, argc - 1, argv + 1);
+ if (ret)
+ logmsg(MODPREFIX "failed to reinit parse context");
+ } else {
+ /* Open the parser, if we can. */
+ ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
+ if (!ctxt->parse) {
+ logerr(MODPREFIX "failed to open parse context");
+ ret = 1;
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * This initializes a context (persistent non-global data) for queries to
+ * this module. Return zero if we succeed.
+ */
+int lookup_init(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
+{
+ struct lookup_context *ctxt;
+ char buf[MAX_ERR_BUF];
+ int ret;
+
+ *context = NULL;
+
+ /* If we can't build a context, bail. */
+ ctxt = malloc(sizeof(struct lookup_context));
+ if (!ctxt) {
+ char *estr = strerror_r(errno, buf, sizeof(buf));
+ logerr(MODPREFIX "malloc: %s", estr);
+ return 1;
+ }
+ memset(ctxt, 0, sizeof(struct lookup_context));
+
+ ret = do_init(mapfmt, argc, argv, ctxt, 0);
+ if (ret) {
free_context(ctxt);
- logerr(MODPREFIX "failed to open parse context");
return 1;
}
+
*context = ctxt;
return 0;
@@ -1839,6 +1854,36 @@ int lookup_init(const char *mapfmt,
int lookup_reinit(const char *mapfmt,
int argc, const char *const *argv, void **context)
{
+ struct lookup_context *ctxt = (struct lookup_context *) *context;
+ struct lookup_context *new;
+ char buf[MAX_ERR_BUF];
+ int ret;
+
+ /* If we can't build a context, bail. */
+ new = malloc(sizeof(struct lookup_context));
+ if (!new) {
+ char *estr = strerror_r(errno, buf, sizeof(buf));
+ logerr(MODPREFIX "malloc: %s", estr);
+ return 1;
+ }
+ memset(new, 0, sizeof(struct lookup_context));
+
+ new->parse = ctxt->parse;
+ ret = do_init(mapfmt, argc, argv, new, 1);
+ if (ret) {
+ free_context(new);
+ return 1;
+ }
+
+ *context = new;
+
+#ifdef WITH_SASL
+ ldapinit_mutex_lock();
+ autofs_sasl_dispose(ctxt);
+ ldapinit_mutex_unlock();
+#endif
+ free_context(ctxt);
+
return 0;
}

View File

@ -0,0 +1,265 @@
autofs-5.1.1 - implement reinit in multi lookup module
From: Ian Kent <raven@themaw.net>
Update the multi lookup module to add an implementation for the newly
added reinit entry point.
Signed-off-by: Ian Kent <raven@themaw.net>
---
modules/lookup_multi.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 227 insertions(+), 1 deletion(-)
diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c
index f8ebf94..fadd2ea 100644
--- a/modules/lookup_multi.c
+++ b/modules/lookup_multi.c
@@ -146,6 +146,31 @@ static int free_multi_context(struct lookup_context *ctxt)
return rv;
}
+static struct lookup_context *update_multi_context(struct lookup_context *ctxt,
+ struct lookup_context *new)
+{
+ int i;
+
+ for (i = 0; i < new->n && i < ctxt->n; i++) {
+ if (new->m[i].mod)
+ continue;
+
+ if (!ctxt->m[i].mod)
+ continue;
+
+ /* reinit or open failed, use old one, questionable but
+ * we need to do something.
+ */
+ new->m[i].mod = ctxt->m[i].mod;
+ ctxt->m[i].mod = NULL;
+ new->m[i].argc = ctxt->m[i].argc;
+ new->m[i].argv = ctxt->m[i].argv;
+ ctxt->m[i].argv = NULL;
+ }
+
+ return new;
+}
+
static struct lookup_mod *nss_open_lookup(const char *format, int argc, const char **argv)
{
struct list_head nsslist;
@@ -268,6 +293,8 @@ int lookup_init(const char *my_mapfmt,
struct lookup_context *ctxt;
int i;
+ *context = NULL;
+
ctxt = alloc_context(my_mapfmt, argc, argv);
if (!ctxt)
return 1;
@@ -291,7 +318,206 @@ int lookup_init(const char *my_mapfmt,
int lookup_reinit(const char *my_mapfmt,
int argc, const char *const *argv, void **context)
{
- return 0;
+ struct lookup_context *ctxt = (struct lookup_context *) *context;
+ struct list_head nsslist;
+ struct list_head *head, *p;
+ struct lookup_context *new;
+ char buf[MAX_ERR_BUF], *estr;
+ int i, ret = 0;
+ int status;
+
+ new = alloc_context(my_mapfmt, argc, argv);
+ if (!new)
+ return 1;
+
+ for (i = 0; i < new->n; i++) {
+ if (i >= ctxt->n) {
+ new->m[i].mod = nss_open_lookup(my_mapfmt,
+ new->m[i].argc,
+ new->m[i].argv);
+ if (!new->m[i].mod) {
+ logerr(MODPREFIX "error opening module");
+ /* TODO: check */
+ ret = 1;
+ goto out;
+ }
+ continue;
+ }
+
+ if (*new->m[i].argv[0] == '/') {
+ if (strcmp(new->m[i].argv[0], ctxt->m[i].argv[0]))
+ open_lookup("file", MODPREFIX,
+ my_mapfmt,
+ new->m[i].argc,
+ new->m[i].argv,
+ &new->m[i].mod);
+ else {
+ new->m[i].mod = ctxt->m[i].mod;
+ if (reinit_lookup(new->m[i].mod, "file",
+ MODPREFIX, my_mapfmt,
+ new->m[i].argc, new->m[i].argv))
+ new->m[i].mod = NULL;
+ else
+ ctxt->m[i].mod = NULL;
+ }
+ continue;
+ }
+
+ if (!strncmp(new->m[i].argv[0], "file", 4) ||
+ !strncmp(new->m[i].argv[0], "yp", 2) ||
+ !strncmp(new->m[i].argv[0], "nisplus", 7) ||
+ !strncmp(new->m[i].argv[0], "nis", 3) ||
+ !strncmp(new->m[i].argv[0], "ldaps", 5) ||
+ !strncmp(new->m[i].argv[0], "ldap", 4) ||
+ !strncmp(new->m[i].argv[0], "sss", 3)) {
+ char type[MAX_MAP_TYPE_STRING];
+ char *fmt;
+
+ strcpy(type, new->m[i].argv[0]);
+ fmt = strchr(type, ',');
+ if (!fmt)
+ fmt = (char *) my_mapfmt;
+ else {
+ *fmt = '\0';
+ fmt++;
+ }
+
+ if (!strcmp(new->m[i].argv[0], ctxt->m[i].argv[0]) &&
+ !strcmp(new->m[i].argv[1], ctxt->m[i].argv[1])) {
+ new->m[i].mod = ctxt->m[i].mod;
+ if (reinit_lookup(new->m[i].mod, new->m[i].argv[0],
+ MODPREFIX, fmt,
+ new->m[i].argc - 1, new->m[i].argv + 1))
+ new->m[i].mod = NULL;
+ else
+ ctxt->m[i].mod = NULL;
+ } else {
+ open_lookup(type, MODPREFIX, fmt,
+ new->m[i].argc - 1,
+ new->m[i].argv + 1,
+ &new->m[i].mod);
+ }
+ continue;
+ }
+
+ INIT_LIST_HEAD(&nsslist);
+
+ if (nsswitch_parse(&nsslist)) {
+ if (!list_empty(&nsslist))
+ free_sources(&nsslist);
+ logerr("can't to read name service switch config.");
+ /* TODO: check */
+ ret = 1;
+ goto out;
+ }
+
+ head = &nsslist;
+ list_for_each(p, head) {
+ struct nss_source *this;
+
+ this = list_entry(p, struct nss_source, list);
+
+ if (!strcmp(this->source, ctxt->m[i].mod->type)) {
+ new->m[i].mod = ctxt->m[i].mod;
+ if (reinit_lookup(new->m[i].mod, this->source,
+ MODPREFIX, my_mapfmt,
+ new->m[i].argc, new->m[i].argv))
+ new->m[i].mod = NULL;
+ else
+ ctxt->m[i].mod = NULL;
+ continue;
+ }
+
+ if (!strcmp(this->source, "files")) {
+ char src_file[] = "file";
+ char src_prog[] = "program";
+ struct stat st;
+ char *type, *path, *save_argv0;
+
+ path = malloc(strlen(AUTOFS_MAP_DIR) +
+ strlen(new->m[i].argv[0]) + 2);
+ if (!path) {
+ estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ logerr(MODPREFIX "error: %s", estr);
+ free_sources(&nsslist);
+ ret = 1;
+ goto out;
+ }
+ strcpy(path, AUTOFS_MAP_DIR);
+ strcat(path, "/");
+ strcat(path, new->m[i].argv[0]);
+
+ if (stat(path, &st) == -1 || !S_ISREG(st.st_mode)) {
+ free(path);
+ continue;
+ }
+
+ if (st.st_mode & __S_IEXEC)
+ type = src_prog;
+ else
+ type = src_file;
+
+ save_argv0 = (char *) new->m[i].argv[0];
+ new->m[i].argv[0] = path;
+
+ if (strcmp(type, ctxt->m[i].mod->type)) {
+ status = open_lookup(type,
+ MODPREFIX,
+ my_mapfmt,
+ new->m[i].argc,
+ new->m[i].argv,
+ &new->m[i].mod);
+ if (status == NSS_STATUS_SUCCESS) {
+ free(save_argv0);
+ break;
+ }
+ } else {
+ new->m[i].mod = ctxt->m[i].mod;
+ if (reinit_lookup(new->m[i].mod, type,
+ MODPREFIX, my_mapfmt,
+ new->m[i].argc, new->m[i].argv))
+ new->m[i].mod = NULL;
+ else {
+ ctxt->m[i].mod = NULL;
+ free(save_argv0);
+ break;
+ }
+ }
+
+ new->m[i].argv[0] = save_argv0;
+ free(path);
+ continue;
+ }
+
+ if (strcmp(this->source, ctxt->m[i].mod->type)) {
+ status = open_lookup(this->source, MODPREFIX,
+ my_mapfmt,
+ new->m[i].argc,
+ new->m[i].argv,
+ &new->m[i].mod);
+ if (status == NSS_STATUS_SUCCESS)
+ break;
+ } else {
+ new->m[i].mod = ctxt->m[i].mod;
+ if (reinit_lookup(new->m[i].mod, this->source,
+ MODPREFIX, my_mapfmt,
+ new->m[i].argc, new->m[i].argv))
+ new->m[i].mod = NULL;
+ else {
+ ctxt->m[i].mod = NULL;
+ break;
+ }
+ }
+ }
+ free_sources(&nsslist);
+ }
+out:
+ /* Update new context with any needed old context */
+ *context = update_multi_context(ctxt, new);
+ free_multi_context(ctxt);
+ free(ctxt);
+
+ return ret;
}
int lookup_read_master(struct master *master, time_t age, void *context)

View File

@ -0,0 +1,133 @@
autofs-5.1.1 - implement reinit in nisplus lookup module
From: Ian Kent <raven@themaw.net>
Refactor the nisplus lookup module to add an implementation for the newly
added reinit entry point.
Signed-off-by: Ian Kent <raven@themaw.net>
---
modules/lookup_nisplus.c | 83 +++++++++++++++++++++++++++++++++++-----------
1 file changed, 63 insertions(+), 20 deletions(-)
diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
index 0c66152..5fd1d89 100644
--- a/modules/lookup_nisplus.c
+++ b/modules/lookup_nisplus.c
@@ -30,25 +30,16 @@ struct lookup_context {
int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
-int lookup_init(const char *mapfmt,
- int argc, const char *const *argv, void **context)
+static int do_init(const char *mapfmt,
+ int argc, const char *const *argv,
+ struct lookup_context *ctxt, unsigned int reinit)
{
- struct lookup_context *ctxt;
- char buf[MAX_ERR_BUF];
-
- *context = NULL;
-
- ctxt = malloc(sizeof(struct lookup_context));
- if (!ctxt) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- logerr(MODPREFIX "%s", estr);
- return 1;
- }
+ int ret = 0;
if (argc < 1) {
- free(ctxt);
logmsg(MODPREFIX "No map name");
- return 1;
+ ret = 1;
+ goto out;
}
ctxt->mapname = argv[0];
@@ -58,20 +49,50 @@ int lookup_init(const char *mapfmt,
*/
ctxt->domainname = nis_local_directory();
if (!ctxt->domainname) {
- free(ctxt);
logmsg(MODPREFIX "NIS+ domain not set");
- return 1;
+ ret = 1;
+ goto out;
}
if (!mapfmt)
mapfmt = MAPFMT_DEFAULT;
- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
- if (!ctxt->parse) {
+ if (reinit) {
+ ret = reinit_parse(ctxt->parse, mapfmt, MODPREFIX, argc, argv);
+ if (ret)
+ logmsg(MODPREFIX "failed to reinit parse context");
+ } else {
+ ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
+ if (!ctxt->parse) {
+ logerr(MODPREFIX "failed to open parse context");
+ ret = 1;
+ }
+ }
+out:
+ return ret;
+}
+
+int lookup_init(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
+{
+ struct lookup_context *ctxt;
+ char buf[MAX_ERR_BUF];
+
+ *context = NULL;
+
+ ctxt = malloc(sizeof(struct lookup_context));
+ if (!ctxt) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ logerr(MODPREFIX "%s", estr);
+ return 1;
+ }
+ memset(ctxt, 0, sizeof(struct lookup_context));
+
+ if (do_init(mapfmt, argc, argv, ctxt, 0)) {
free(ctxt);
- logerr(MODPREFIX "failed to open parse context");
return 1;
}
+
*context = ctxt;
return 0;
@@ -80,6 +101,28 @@ int lookup_init(const char *mapfmt,
int lookup_reinit(const char *mapfmt,
int argc, const char *const *argv, void **context)
{
+ struct lookup_context *ctxt = (struct lookup_context *) *context;
+ struct lookup_context *new;
+ char buf[MAX_ERR_BUF];
+ int ret;
+
+ new = malloc(sizeof(struct lookup_context));
+ if (!new) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ logerr(MODPREFIX "%s", estr);
+ return 1;
+ }
+ memset(new, 0, sizeof(struct lookup_context));
+
+ new->parse = ctxt->parse;
+ ret = do_init(mapfmt, argc, argv, new, 1);
+ if (ret)
+ return 1;
+
+ *context = new;
+
+ free(ctxt);
+
return 0;
}

View File

@ -0,0 +1,146 @@
autofs-5.1.1 - implement reinit in parse modules
From: Ian Kent <raven@themaw.net>
Refactor the parse modules to add an implementation for the newly added
reinit entry point.
Signed-off-by: Ian Kent <raven@themaw.net>
---
modules/parse_hesiod.c | 1 +
modules/parse_sun.c | 70 ++++++++++++++++++++++++++++++++++++------------
2 files changed, 54 insertions(+), 17 deletions(-)
diff --git a/modules/parse_hesiod.c b/modules/parse_hesiod.c
index 0b2b57f..a02da82 100644
--- a/modules/parse_hesiod.c
+++ b/modules/parse_hesiod.c
@@ -258,6 +258,7 @@ static int parse_generic(struct autofs_point *ap,
int parse_init(int argc, const char *const *argv, void **context)
{
+ *context = NULL;
return 0;
}
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 35d6da5..a164fba 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -232,27 +232,15 @@ int expandsunent(const char *src, char *dst, const char *key,
return len;
}
-int parse_init(int argc, const char *const *argv, void **context)
+static int do_init(int argc, const char *const *argv, struct parse_context *ctxt)
{
- struct parse_context *ctxt;
- char buf[MAX_ERR_BUF];
char *noptstr, *def, *val, *macros, *gbl_options;
- const char *xopt;
+ char buf[MAX_ERR_BUF];
int optlen, len, offset;
+ const char *xopt;
int i, bval;
unsigned int append_options;
- /* Set up context and escape chain */
-
- if (!(ctxt = (struct parse_context *) malloc(sizeof(struct parse_context)))) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- logerr(MODPREFIX "malloc: %s", estr);
- *context = NULL;
- return 1;
- }
- *context = (void *) ctxt;
-
- *ctxt = default_context;
optlen = 0;
/* Look for options and capture, and create new defines if we need to */
@@ -359,7 +347,6 @@ int parse_init(int argc, const char *const *argv, void **context)
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
kill_context(ctxt);
logerr(MODPREFIX "%s", estr);
- *context = NULL;
return 1;
}
ctxt->optstr = noptstr;
@@ -391,9 +378,36 @@ int parse_init(int argc, const char *const *argv, void **context)
}
}
options_done:
+
debug(LOGOPT_NONE,
MODPREFIX "init gathered global options: %s", ctxt->optstr);
+ return 0;
+}
+
+int parse_init(int argc, const char *const *argv, void **context)
+{
+ struct parse_context *ctxt;
+ char buf[MAX_ERR_BUF];
+
+ *context = NULL;
+
+ /* Set up context and escape chain */
+
+ ctxt = (struct parse_context *) malloc(sizeof(struct parse_context));
+ if (!ctxt) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ logerr(MODPREFIX "malloc: %s", estr);
+ return 1;
+ }
+
+ *ctxt = default_context;
+
+ if (do_init(argc, argv, ctxt)) {
+ free(ctxt);
+ return 1;
+ }
+
/* We only need this once. NFS mounts are so common that we cache
this module. */
instance_mutex_lock();
@@ -404,17 +418,39 @@ options_done:
init_ctr++;
} else {
kill_context(ctxt);
- *context = NULL;
instance_mutex_unlock();
return 1;
}
}
instance_mutex_unlock();
+
+ *context = (void *) ctxt;
+
return 0;
}
int parse_reinit(int argc, const char *const *argv, void **context)
{
+ struct parse_context *ctxt = (struct parse_context *) *context;
+ struct parse_context *new;
+ char buf[MAX_ERR_BUF];
+
+ new = (struct parse_context *) malloc(sizeof(struct parse_context));
+ if (!new) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ logerr(MODPREFIX "malloc: %s", estr);
+ return 1;
+ }
+
+ *new = default_context;
+
+ if (do_init(argc, argv, new))
+ return 1;
+
+ kill_context(ctxt);
+
+ *context = (void *) new;
+
return 0;
}

View File

@ -0,0 +1,153 @@
autofs-5.1.1 - implement reinit in program lookup module
From: Ian Kent <raven@themaw.net>
Refactor the program lookup module to add an implementation for the newly
added reinit entry point.
Signed-off-by: Ian Kent <raven@themaw.net>
---
modules/lookup_program.c | 98 ++++++++++++++++++++++++++++++++++++----------
1 file changed, 76 insertions(+), 22 deletions(-)
diff --git a/modules/lookup_program.c b/modules/lookup_program.c
index fa4f54d..3e9c448 100644
--- a/modules/lookup_program.c
+++ b/modules/lookup_program.c
@@ -49,53 +49,82 @@ struct parse_context {
int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
-int lookup_init(const char *mapfmt,
- int argc, const char *const *argv, void **context)
+static int do_init(const char *mapfmt,
+ int argc, const char *const *argv,
+ struct lookup_context *ctxt, unsigned int reinit)
{
- struct lookup_context *ctxt;
- char buf[MAX_ERR_BUF];
-
- *context = NULL;
-
- ctxt = malloc(sizeof(struct lookup_context));
- if (!ctxt) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- logerr(MODPREFIX "malloc: %s", estr);
- return 1;
- }
+ int ret = 0;
if (argc < 1) {
logmsg(MODPREFIX "No map name");
- free(ctxt);
- return 1;
+ ret = 1;
+ goto out;
}
ctxt->mapname = argv[0];
if (ctxt->mapname[0] != '/') {
logmsg(MODPREFIX "program map %s is not an absolute pathname",
ctxt->mapname);
- free(ctxt);
- return 1;
+ ret = 1;
+ goto out;
}
if (access(ctxt->mapname, X_OK)) {
logmsg(MODPREFIX "program map %s missing or not executable",
ctxt->mapname);
- free(ctxt);
- return 1;
+ ret = 1;
+ goto out;
}
if (!mapfmt)
mapfmt = MAPFMT_DEFAULT;
ctxt->mapfmt = strdup(mapfmt);
+ if (!ctxt->mapfmt) {
+ logmsg(MODPREFIX "failed to allocate storage for map format");
+ ret = 1;
+ goto out;
+ }
- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
- if (!ctxt->parse) {
- logmsg(MODPREFIX "failed to open parse context");
+ if (reinit) {
+ ret = reinit_parse(ctxt->parse, mapfmt, MODPREFIX, argc - 1, argv + 1);
+ if (ret)
+ logmsg(MODPREFIX "failed to reinit parse context");
+ } else {
+ ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
+ if (!ctxt->parse) {
+ logmsg(MODPREFIX "failed to open parse context");
+ ret = 1;
+ }
+ }
+out:
+ if (ret && ctxt->mapfmt)
+ free(ctxt->mapfmt);
+
+ return ret;
+}
+
+int lookup_init(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
+{
+ struct lookup_context *ctxt;
+ char buf[MAX_ERR_BUF];
+
+ *context = NULL;
+
+ ctxt = malloc(sizeof(struct lookup_context));
+ if (!ctxt) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ logerr(MODPREFIX "malloc: %s", estr);
+ return 1;
+ }
+ memset(ctxt, 0, sizeof(struct lookup_context));
+
+ if (do_init(mapfmt, argc, argv, ctxt, 0)) {
free(ctxt);
return 1;
}
+
*context = ctxt;
return 0;
@@ -104,6 +133,31 @@ int lookup_init(const char *mapfmt,
int lookup_reinit(const char *mapfmt,
int argc, const char *const *argv, void **context)
{
+ struct lookup_context *ctxt = (struct lookup_context *) *context;
+ struct lookup_context *new;
+ char buf[MAX_ERR_BUF];
+ int ret;
+
+ new = malloc(sizeof(struct lookup_context));
+ if (!new) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ logerr(MODPREFIX "malloc: %s", estr);
+ return 1;
+ }
+ memset(new, 0, sizeof(struct lookup_context));
+
+ new->parse = ctxt->parse;
+ ret = do_init(mapfmt, argc, argv, new, 1);
+ if (ret) {
+ free(new);
+ return 1;
+ }
+
+ *context = new;
+
+ free(ctxt->mapfmt);
+ free(ctxt);
+
return 0;
}

View File

@ -0,0 +1,189 @@
autofs-5.1.1 - implement reinit in sss lookup module
From: Ian Kent <raven@themaw.net>
Refactor the sss lookup module to add an implementation for the newly
added reinit entry point.
Signed-off-by: Ian Kent <raven@themaw.net>
---
modules/lookup_sss.c | 130 +++++++++++++++++++++++++++++++++++++-------------
1 file changed, 95 insertions(+), 35 deletions(-)
diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c
index c58a272..2f32e94 100644
--- a/modules/lookup_sss.c
+++ b/modules/lookup_sss.c
@@ -56,39 +56,16 @@ struct lookup_context {
int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
-int lookup_init(const char *mapfmt,
- int argc, const char *const *argv, void **context)
+static int open_sss_lib(struct lookup_context *ctxt)
{
- struct lookup_context *ctxt;
- char buf[MAX_ERR_BUF];
char dlbuf[PATH_MAX];
char *estr;
void *dh;
size_t size;
- *context = NULL;
-
- ctxt = malloc(sizeof(struct lookup_context));
- if (!ctxt) {
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
- logerr(MODPREFIX "malloc: %s", estr);
- return 1;
- }
-
- if (argc < 1) {
- free(ctxt);
- logerr(MODPREFIX "No map name");
- return 1;
- }
- ctxt->mapname = argv[0];
-
- if (!mapfmt)
- mapfmt = MAPFMT_DEFAULT;
-
size = snprintf(dlbuf, sizeof(dlbuf),
"%s/%s.so", SSS_LIB_DIR, SSS_SO_NAME);
if (size >= sizeof(dlbuf)) {
- free(ctxt);
logmsg(MODPREFIX "sss library path too long");
return 1;
}
@@ -96,7 +73,6 @@ int lookup_init(const char *mapfmt,
dh = dlopen(dlbuf, RTLD_LAZY);
if (!dh) {
logerr(MODPREFIX "failed to open %s: %s", dlbuf, dlerror());
- free(ctxt);
return 1;
}
ctxt->dlhandle = dh;
@@ -117,15 +93,6 @@ int lookup_init(const char *mapfmt,
if (!ctxt->setautomntent)
goto lib_names_fail;
- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
- if (!ctxt->parse) {
- logmsg(MODPREFIX "failed to open parse context");
- dlclose(dh);
- free(ctxt);
- return 1;
- }
- *context = ctxt;
-
return 0;
lib_names_fail:
@@ -134,13 +101,106 @@ lib_names_fail:
else
logerr(MODPREFIX "dlsym: %s", estr);
dlclose(dh);
- free(ctxt);
+
return 1;
}
+static int do_init(const char *mapfmt,
+ int argc, const char *const *argv,
+ struct lookup_context *ctxt, unsigned int reinit)
+{
+ int ret = 0;
+
+ if (argc < 1) {
+ logerr(MODPREFIX "No map name");
+ ret = 1;
+ goto out;
+ }
+ ctxt->mapname = argv[0];
+
+ if (!mapfmt)
+ mapfmt = MAPFMT_DEFAULT;
+
+ if (!reinit) {
+ ret = open_sss_lib(ctxt);
+ if (ret)
+ goto out;
+ }
+
+ if (reinit) {
+ ret = reinit_parse(ctxt->parse, mapfmt, MODPREFIX, argc - 1, argv + 1);
+ if (ret)
+ logmsg(MODPREFIX "failed to reinit parse context");
+ } else {
+ ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
+ if (!ctxt->parse) {
+ logmsg(MODPREFIX "failed to open parse context");
+ dlclose(ctxt->dlhandle);
+ ret = 1;
+ }
+ }
+out:
+ return ret;
+}
+
+int lookup_init(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
+{
+ struct lookup_context *ctxt;
+ char buf[MAX_ERR_BUF];
+ char *estr;
+
+ *context = NULL;
+
+ ctxt = malloc(sizeof(struct lookup_context));
+ if (!ctxt) {
+ estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ logerr(MODPREFIX "malloc: %s", estr);
+ return 1;
+ }
+
+ if (do_init(mapfmt, argc, argv, ctxt, 0)) {
+ free(ctxt);
+ return 1;
+ }
+
+ *context = ctxt;
+
+ return 0;
+}
+
int lookup_reinit(const char *mapfmt,
int argc, const char *const *argv, void **context)
{
+ struct lookup_context *ctxt = (struct lookup_context *) *context;
+ struct lookup_context *new;
+ char buf[MAX_ERR_BUF];
+ int ret;
+
+ new = malloc(sizeof(struct lookup_context));
+ if (!new) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ logerr(MODPREFIX "malloc: %s", estr);
+ return 1;
+ }
+
+ new->parse = ctxt->parse;
+ ret = do_init(mapfmt, argc, argv, new, 1);
+ if (ret) {
+ free(new);
+ return 1;
+ }
+
+ new->dlhandle = ctxt->dlhandle;
+ new->setautomntent = ctxt->setautomntent;
+ new->getautomntent_r = ctxt->getautomntent_r;
+ new->getautomntbyname_r = ctxt->getautomntbyname_r;
+ new->endautomntent = ctxt->endautomntent;
+
+ *context = new;
+
+ free(ctxt);
+
return 0;
}

View File

@ -0,0 +1,151 @@
autofs-5.1.1 - implement reinit in yp lookup module
From: Ian Kent <raven@themaw.net>
Refactor the yp lookup module to add an implementation for the newly
added reinit entry point.
Signed-off-by: Ian Kent <raven@themaw.net>
---
modules/lookup_yp.c | 93 +++++++++++++++++++++++++++++++++++++++------------
1 file changed, 71 insertions(+), 22 deletions(-)
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
index 1e5a7ed..e31c2cf 100644
--- a/modules/lookup_yp.c
+++ b/modules/lookup_yp.c
@@ -103,27 +103,18 @@ static unsigned int get_map_order(const char *domain, const char *map)
return (unsigned int) last_changed;
}
-int lookup_init(const char *mapfmt,
- int argc, const char *const *argv, void **context)
+static int do_init(const char *mapfmt,
+ int argc, const char *const *argv,
+ struct lookup_context *ctxt, unsigned int reinit)
{
- struct lookup_context *ctxt;
char buf[MAX_ERR_BUF];
int err;
-
- *context = NULL;
-
- ctxt = malloc(sizeof(struct lookup_context));
- if (!ctxt) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- logerr(MODPREFIX "malloc: %s", estr);
- return 1;
- }
- memset(ctxt, 0, sizeof(struct lookup_context));
+ int ret = 0;
if (argc < 1) {
- free(ctxt);
logerr(MODPREFIX "no map name");
- return 1;
+ ret = 1;
+ goto out;
}
ctxt->mapname = argv[0];
ctxt->check_defaults = 1;
@@ -138,15 +129,15 @@ int lookup_init(const char *mapfmt,
if (err) {
logerr(MODPREFIX
"map %s: %s", ctxt->mapname, yperr_string(err));
- free(ctxt);
- return 1;
+ ret = 1;
+ goto out;
}
ctxt->domainname = strdup(domainname);
if (!ctxt->domainname) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
logerr(MODPREFIX "strdup: %s", estr);
- free(ctxt);
- return 1;
+ ret = 1;
+ goto out;
}
}
@@ -155,12 +146,45 @@ int lookup_init(const char *mapfmt,
if (!mapfmt)
mapfmt = MAPFMT_DEFAULT;
- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
- if (!ctxt->parse) {
+ if (reinit) {
+ ret = reinit_parse(ctxt->parse, mapfmt, MODPREFIX, argc - 1, argv + 1);
+ if (ret)
+ logmsg(MODPREFIX "failed to reinit parse context");
+ } else {
+ ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
+ if (!ctxt->parse) {
+ logmsg(MODPREFIX "failed to open parse context");
+ ret = 1;
+ }
+ }
+out:
+ if (ret && ctxt->domainname)
+ free(ctxt->domainname);
+
+ return ret;
+}
+
+int lookup_init(const char *mapfmt,
+ int argc, const char *const *argv, void **context)
+{
+ struct lookup_context *ctxt;
+ char buf[MAX_ERR_BUF];
+
+ *context = NULL;
+
+ ctxt = malloc(sizeof(struct lookup_context));
+ if (!ctxt) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ logerr(MODPREFIX "malloc: %s", estr);
+ return 1;
+ }
+ memset(ctxt, 0, sizeof(struct lookup_context));
+
+ if (do_init(mapfmt, argc, argv, ctxt, 0)) {
free(ctxt);
- logmsg(MODPREFIX "failed to open parse context");
return 1;
}
+
*context = ctxt;
return 0;
@@ -169,6 +193,31 @@ int lookup_init(const char *mapfmt,
int lookup_reinit(const char *mapfmt,
int argc, const char *const *argv, void **context)
{
+ struct lookup_context *ctxt = (struct lookup_context *) *context;
+ struct lookup_context *new;
+ char buf[MAX_ERR_BUF];
+ int ret;
+
+ new = malloc(sizeof(struct lookup_context));
+ if (!new) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ logerr(MODPREFIX "malloc: %s", estr);
+ return 1;
+ }
+ memset(new, 0, sizeof(struct lookup_context));
+
+ new->parse = ctxt->parse;
+ ret = do_init(mapfmt, argc, argv, new, 1);
+ if (ret) {
+ free(new);
+ return 1;
+ }
+
+ *context = new;
+
+ free(ctxt->domainname);
+ free(ctxt);
+
return 0;
}

View File

@ -0,0 +1,115 @@
autofs-5.1.1 - make connect_to_server() return a status
From: Ian Kent <raven@themaw.net>
In the ldap lookup module the do_reconnect() call doesn't distinguish
between no entry found and service unavailable.
If service unavailable gets returned from a master map read it results
in autofs not updating the mounts. A notfound return doesn't because it
indicates the map doesn't exist so updating the mounts isn't a problem
as it can be when the source is unavailable.
Next step in the update of do_reconnect() is to make connect_to_server()
return a status instead of an LDAP handle and pass back the LDAP handle
via a function parameter.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_ldap.c | 25 ++++++++++++++-----------
2 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 2f1e380..6d57581 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -6,6 +6,7 @@
- fix return handling in sss lookup module.
- move query dn calculation from do_bind() to do_connect().
- make do_connect() return a status.
+- make connect_to_server() return a status.
21/04/2015 autofs-5.1.1
=======================
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 268c812..776c174 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -824,20 +824,19 @@ next:
return timestamp;
}
-static LDAP *connect_to_server(unsigned logopt, const char *uri, struct lookup_context *ctxt)
+static int connect_to_server(unsigned logopt, LDAP **ldap,
+ const char *uri, struct lookup_context *ctxt)
{
- LDAP *ldap;
int ret;
- ret = do_connect(logopt, &ldap, uri, ctxt);
+ ret = do_connect(logopt, ldap, uri, ctxt);
if (ret != NSS_STATUS_SUCCESS) {
warn(logopt,
MODPREFIX "couldn't connect to server %s",
uri ? uri : "default");
- return NULL;
}
- return ldap;
+ return ret;
}
static LDAP *find_dc_server(unsigned logopt, const char *uri, struct lookup_context *ctxt)
@@ -852,9 +851,11 @@ static LDAP *find_dc_server(unsigned logopt, const char *uri, struct lookup_cont
tok = strtok_r(str, " ", &ptr);
while (tok) {
const char *this = (const char *) tok;
+ int ret;
+
debug(logopt, "trying server uri %s", this);
- ldap = connect_to_server(logopt, this, ctxt);
- if (ldap) {
+ ret = connect_to_server(logopt, &ldap, this, ctxt);
+ if (ret == NSS_STATUS_SUCCESS) {
info(logopt, "connected to uri %s", this);
free(str);
return ldap;
@@ -874,6 +875,7 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
struct list_head *p, *first;
struct dclist *dclist;
char *uri = NULL;
+ int ret;
uris_mutex_lock(ctxt);
dclist = ctxt->dclist;
@@ -896,8 +898,8 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
if (!strstr(this->uri, ":///")) {
uri = strdup(this->uri);
debug(logopt, "trying server uri %s", uri);
- ldap = connect_to_server(logopt, uri, ctxt);
- if (ldap) {
+ ret = connect_to_server(logopt, &ldap, uri, ctxt);
+ if (ret == NSS_STATUS_SUCCESS) {
info(logopt, "connected to uri %s", uri);
free(uri);
break;
@@ -962,7 +964,8 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt)
ldapinit_mutex_lock();
autofs_sasl_dispose(ctxt);
ldapinit_mutex_unlock();
- ldap = connect_to_server(logopt, ctxt->server, ctxt);
+ ret = connect_to_server(logopt, &ldap,
+ ctxt->server, ctxt);
}
#endif
return ldap;
@@ -1001,7 +1004,7 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt)
ldapinit_mutex_lock();
autofs_sasl_dispose(ctxt);
ldapinit_mutex_unlock();
- ldap = connect_to_server(logopt, ctxt->uri->uri, ctxt);
+ ret = connect_to_server(logopt, &ldap, ctxt->uri->uri, ctxt);
}
#endif
if (ldap)

View File

@ -0,0 +1,184 @@
autofs-5.1.1 - make do_connect() return a status
From: Ian Kent <raven@themaw.net>
In the ldap lookup module the do_reconnect() call doesn't distinguish
between no entry found and service unavailable.
If service unavailable gets returned from a master map read it results
in autofs not updating the mounts. A notfound return doesn't because it
indicates the map doesn't exist so updating the mounts isn't a problem
as it can be when the source is unavailable.
The next step in the update of do_reconnect() is to make do_connect()
return a status instead of an LDAP handle and pass back the LDAP handle
via a function parameter.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_ldap.c | 60 ++++++++++++++++++++++++++++++-------------------
2 files changed, 38 insertions(+), 23 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 0be1bf2..2f1e380 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -5,6 +5,7 @@
- fix left mount count return from umount_multi_triggers().
- fix return handling in sss lookup module.
- move query dn calculation from do_bind() to do_connect().
+- make do_connect() return a status.
21/04/2015 autofs-5.1.1
=======================
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index ea63736..268c812 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -631,10 +631,14 @@ static int do_bind(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_c
return 1;
}
-static LDAP *do_connect(unsigned logopt, const char *uri, struct lookup_context *ctxt)
+static int do_connect(unsigned logopt, LDAP **ldap,
+ const char *uri, struct lookup_context *ctxt)
{
char *cur_host = NULL;
- LDAP *ldap;
+ LDAP *handle;
+ int ret = NSS_STATUS_SUCCESS;
+
+ *ldap = NULL;
#ifdef WITH_SASL
if (ctxt->extern_cert && ctxt->extern_key) {
@@ -643,18 +647,20 @@ static LDAP *do_connect(unsigned logopt, const char *uri, struct lookup_context
}
#endif
- ldap = init_ldap_connection(logopt, uri, ctxt);
- if (!ldap)
+ handle = init_ldap_connection(logopt, uri, ctxt);
+ if (!handle) {
+ ret = NSS_STATUS_UNAVAIL;
goto out;
+ }
uris_mutex_lock(ctxt);
if (ctxt->cur_host)
cur_host = ctxt->cur_host;
uris_mutex_unlock(ctxt);
- if (!do_bind(logopt, ldap, uri, ctxt)) {
- unbind_ldap_connection(logopt, ldap, ctxt);
- ldap = NULL;
+ if (!do_bind(logopt, handle, uri, ctxt)) {
+ unbind_ldap_connection(logopt, handle, ctxt);
+ ret = NSS_STATUS_UNAVAIL;
goto out;
}
@@ -664,7 +670,8 @@ static LDAP *do_connect(unsigned logopt, const char *uri, struct lookup_context
uris_mutex_lock(ctxt);
if (ctxt->schema && ctxt->qdn && (cur_host == ctxt->cur_host)) {
uris_mutex_unlock(ctxt);
- return ldap;
+ *ldap = handle;
+ goto out;
}
uris_mutex_unlock(ctxt);
@@ -674,9 +681,9 @@ static LDAP *do_connect(unsigned logopt, const char *uri, struct lookup_context
* base dn for searches.
*/
if (!ctxt->schema) {
- if (!find_query_dn(logopt, ldap, ctxt)) {
- unbind_ldap_connection(logopt, ldap, ctxt);
- ldap = NULL;
+ if (!find_query_dn(logopt, handle, ctxt)) {
+ unbind_ldap_connection(logopt, handle, ctxt);
+ ret = NSS_STATUS_NOTFOUND;
warn(logopt,
MODPREFIX "failed to find valid query dn");
goto out;
@@ -684,14 +691,17 @@ static LDAP *do_connect(unsigned logopt, const char *uri, struct lookup_context
} else if (!(ctxt->format & MAP_FLAG_FORMAT_AMD)) {
const char *class = ctxt->schema->map_class;
const char *key = ctxt->schema->map_attr;
- if (!get_query_dn(logopt, ldap, ctxt, class, key)) {
- unbind_ldap_connection(logopt, ldap, ctxt);
- ldap = NULL;
+ if (!get_query_dn(logopt, handle, ctxt, class, key)) {
+ unbind_ldap_connection(logopt, handle, ctxt);
+ ret = NSS_STATUS_NOTFOUND;
error(logopt, MODPREFIX "failed to get query dn");
+ goto out;
}
}
+
+ *ldap = handle;
out:
- return ldap;
+ return ret;
}
static unsigned long get_amd_timestamp(struct lookup_context *ctxt)
@@ -706,8 +716,8 @@ static unsigned long get_amd_timestamp(struct lookup_context *ctxt)
unsigned long timestamp = 0;
int rv, l, ql;
- ldap = do_connect(LOGOPT_ANY, ctxt->server, ctxt);
- if (!ldap)
+ rv = do_connect(LOGOPT_ANY, &ldap, ctxt->server, ctxt);
+ if (rv != NSS_STATUS_SUCCESS)
return 0;
map = amd_timestamp.map_attr;
@@ -817,9 +827,10 @@ next:
static LDAP *connect_to_server(unsigned logopt, const char *uri, struct lookup_context *ctxt)
{
LDAP *ldap;
+ int ret;
- ldap = do_connect(logopt, uri, ctxt);
- if (!ldap) {
+ ret = do_connect(logopt, &ldap, uri, ctxt);
+ if (ret != NSS_STATUS_SUCCESS) {
warn(logopt,
MODPREFIX "couldn't connect to server %s",
uri ? uri : "default");
@@ -940,12 +951,14 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt)
{
LDAP *ldap = NULL;
+ int ret;
if (ctxt->server || !ctxt->uris) {
- ldap = do_connect(logopt, ctxt->server, ctxt);
+ ret = do_connect(logopt, &ldap, ctxt->server, ctxt);
#ifdef WITH_SASL
/* Dispose of the sasl authentication connection and try again. */
- if (!ldap && ctxt->auth_required & LDAP_NEED_AUTH) {
+ if (ret != NSS_STATUS_SUCCESS &&
+ ctxt->auth_required & LDAP_NEED_AUTH) {
ldapinit_mutex_lock();
autofs_sasl_dispose(ctxt);
ldapinit_mutex_unlock();
@@ -977,13 +990,14 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt)
if (!ctxt->uri)
goto find_server;
- ldap = do_connect(logopt, ctxt->uri->uri, ctxt);
+ ret = do_connect(logopt, &ldap, ctxt->uri->uri, ctxt);
#ifdef WITH_SASL
/*
* Dispose of the sasl authentication connection and try the
* current server again before trying other servers in the list.
*/
- if (!ldap && ctxt->auth_required & LDAP_NEED_AUTH) {
+ if (ret != NSS_STATUS_SUCCESS &&
+ ctxt->auth_required & LDAP_NEED_AUTH) {
ldapinit_mutex_lock();
autofs_sasl_dispose(ctxt);
ldapinit_mutex_unlock();

View File

@ -0,0 +1,105 @@
autofs-5.1.1 - make find_dc_server() return a status
From: Ian Kent <raven@themaw.net>
In the ldap lookup module the do_reconnect() call doesn't distinguish
between no entry found and service unavailable.
If service unavailable gets returned from a master map read it results
in autofs not updating the mounts. A notfound return doesn't because it
indicates the map doesn't exist so updating the mounts isn't a problem
as it can be when the source is unavailable.
Next step in the update of do_reconnect() is to make find_dc_server()
return a status instead of an LDAP handle and pass back the LDAP handle
via a function parameter.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_ldap.c | 27 +++++++++++++++------------
2 files changed, 16 insertions(+), 12 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 6d57581..99f465a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -7,6 +7,7 @@
- move query dn calculation from do_bind() to do_connect().
- make do_connect() return a status.
- make connect_to_server() return a status.
+- make find_dc_server() return a status.
21/04/2015 autofs-5.1.1
=======================
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 776c174..02d9ca9 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -839,33 +839,36 @@ static int connect_to_server(unsigned logopt, LDAP **ldap,
return ret;
}
-static LDAP *find_dc_server(unsigned logopt, const char *uri, struct lookup_context *ctxt)
+static int find_dc_server(unsigned logopt, LDAP **ldap,
+ const char *uri, struct lookup_context *ctxt)
{
char *str, *tok, *ptr = NULL;
- LDAP *ldap = NULL;
+ int ret = NSS_STATUS_UNAVAIL;
str = strdup(uri);
if (!str)
- return NULL;
+ return ret;
tok = strtok_r(str, " ", &ptr);
while (tok) {
const char *this = (const char *) tok;
- int ret;
+ int rv;
debug(logopt, "trying server uri %s", this);
- ret = connect_to_server(logopt, &ldap, this, ctxt);
- if (ret == NSS_STATUS_SUCCESS) {
+ rv = connect_to_server(logopt, ldap, this, ctxt);
+ if (rv == NSS_STATUS_SUCCESS) {
info(logopt, "connected to uri %s", this);
free(str);
- return ldap;
+ return rv;
}
+ if (rv == NSS_STATUS_NOTFOUND)
+ ret = NSS_STATUS_NOTFOUND;
tok = strtok_r(NULL, " ", &ptr);
}
free(str);
- return NULL;
+ return ret;
}
static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
@@ -917,8 +920,8 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
dclist = tmp;
uri = strdup(dclist->uri);
}
- ldap = find_dc_server(logopt, uri, ctxt);
- if (ldap) {
+ ret = find_dc_server(logopt, &ldap, uri, ctxt);
+ if (ret == NSS_STATUS_SUCCESS) {
free(uri);
break;
}
@@ -972,8 +975,8 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt)
}
if (ctxt->dclist) {
- ldap = find_dc_server(logopt, ctxt->dclist->uri, ctxt);
- if (ldap)
+ ret = find_dc_server(logopt, &ldap, ctxt->dclist->uri, ctxt);
+ if (ret == NSS_STATUS_SUCCESS)
return ldap;
}

View File

@ -0,0 +1,121 @@
autofs-5.1.1 - make find_server() return a status
From: Ian Kent <raven@themaw.net>
In the ldap lookup module the do_reconnect() call doesn't distinguish
between no entry found and service unavailable.
If service unavailable gets returned from a master map read it results
in autofs not updating the mounts. A notfound return doesn't because it
indicates the map doesn't exist so updating the mounts isn't a problem
as it can be when the source is unavailable.
Next step in the update of do_reconnect() is to make find_server()
return a status instead of an LDAP handle and pass back the LDAP handle
via a function parameter.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_ldap.c | 30 +++++++++++++++++++-----------
2 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 99f465a..bc79bc0 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -8,6 +8,7 @@
- make do_connect() return a status.
- make connect_to_server() return a status.
- make find_dc_server() return a status.
+- make find_server() return a status.
21/04/2015 autofs-5.1.1
=======================
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 02d9ca9..783239d 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -871,14 +871,14 @@ static int find_dc_server(unsigned logopt, LDAP **ldap,
return ret;
}
-static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
+static int find_server(unsigned logopt,
+ LDAP **ldap, struct lookup_context *ctxt)
{
- LDAP *ldap = NULL;
- struct ldap_uri *this;
+ struct ldap_uri *this = NULL;
struct list_head *p, *first;
struct dclist *dclist;
char *uri = NULL;
- int ret;
+ int ret = NSS_STATUS_UNAVAIL;
uris_mutex_lock(ctxt);
dclist = ctxt->dclist;
@@ -892,6 +892,8 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
/* Try each uri, save point in server list upon success */
p = first->next;
while(p != first) {
+ int rv;
+
/* Skip list head */
if (p == ctxt->uris) {
p = p->next;
@@ -901,12 +903,15 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
if (!strstr(this->uri, ":///")) {
uri = strdup(this->uri);
debug(logopt, "trying server uri %s", uri);
- ret = connect_to_server(logopt, &ldap, uri, ctxt);
- if (ret == NSS_STATUS_SUCCESS) {
+ rv = connect_to_server(logopt, ldap, uri, ctxt);
+ if (rv == NSS_STATUS_SUCCESS) {
+ ret = NSS_STATUS_SUCCESS;
info(logopt, "connected to uri %s", uri);
free(uri);
break;
}
+ if (rv == NSS_STATUS_NOTFOUND)
+ ret = NSS_STATUS_NOTFOUND;
} else {
if (dclist)
uri = strdup(dclist->uri);
@@ -920,11 +925,14 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
dclist = tmp;
uri = strdup(dclist->uri);
}
- ret = find_dc_server(logopt, &ldap, uri, ctxt);
- if (ret == NSS_STATUS_SUCCESS) {
+ rv = find_dc_server(logopt, ldap, uri, ctxt);
+ if (rv == NSS_STATUS_SUCCESS) {
+ ret = NSS_STATUS_SUCCESS;
free(uri);
break;
}
+ if (rv == NSS_STATUS_NOTFOUND)
+ ret = NSS_STATUS_NOTFOUND;
}
free(uri);
uri = NULL;
@@ -950,7 +958,7 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
}
uris_mutex_unlock(ctxt);
- return ldap;
+ return ret;
}
static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt)
@@ -1023,8 +1031,8 @@ find_server:
#endif
/* Current server failed, try the rest or dc connection */
- ldap = find_server(logopt, ctxt);
- if (!ldap)
+ ret = find_server(logopt, &ldap, ctxt);
+ if (ret != NSS_STATUS_SUCCESS)
error(logopt, MODPREFIX "failed to find available server");
return ldap;

View File

@ -0,0 +1,260 @@
autofs-5.1.1 - make open_lookup() return nss status
From: Ian Kent <raven@themaw.net>
In order to distinguish between source unavailable and map not found
when opening nsswitch sources that have non-default actions open_lookup()
needs to return distinct results for these two cases.
Signed-off-by: Ian Kent <raven@themaw.net>
---
daemon/lookup.c | 21 +++++++++++----------
daemon/module.c | 22 +++++++++++++---------
include/automount.h | 4 ++--
modules/lookup_multi.c | 20 +++++++++++++-------
modules/parse_amd.c | 6 ++++--
5 files changed, 43 insertions(+), 30 deletions(-)
diff --git a/daemon/lookup.c b/daemon/lookup.c
index 53455a1..0579f98 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -44,9 +44,9 @@ static int do_read_master(struct master *master, char *type, time_t age)
argv[0] = master->name;
argv[1] = NULL;
- lookup = open_lookup(type, "", NULL, argc, argv);
- if (!lookup)
- return NSS_STATUS_UNAVAIL;
+ status = open_lookup(type, "", NULL, argc, argv, &lookup);
+ if (status != NSS_STATUS_SUCCESS)
+ return status;
status = lookup->lookup_read_master(master, age, lookup->context);
@@ -300,10 +300,11 @@ static int do_read_map(struct autofs_point *ap, struct map_source *map, time_t a
struct lookup_mod *lookup;
int status;
- lookup = open_lookup(map->type, "", map->format, map->argc, map->argv);
- if (!lookup) {
+ status = open_lookup(map->type, "", map->format,
+ map->argc, map->argv, &lookup);
+ if (status != NSS_STATUS_SUCCESS) {
debug(ap->logopt, "lookup module %s failed", map->type);
- return NSS_STATUS_UNAVAIL;
+ return status;
}
master_source_writelock(ap->entry);
@@ -737,12 +738,12 @@ int do_lookup_mount(struct autofs_point *ap, struct map_source *map, const char
int status;
if (!map->lookup) {
- lookup = open_lookup(map->type, "",
- map->format, map->argc, map->argv);
- if (!lookup) {
+ status = open_lookup(map->type, "",
+ map->format, map->argc, map->argv, &lookup);
+ if (status != NSS_STATUS_SUCCESS) {
debug(ap->logopt,
"lookup module %s failed", map->type);
- return NSS_STATUS_UNAVAIL;
+ return status;
}
map->lookup = lookup;
}
diff --git a/daemon/module.c b/daemon/module.c
index 466d8d7..9028aaa 100644
--- a/daemon/module.c
+++ b/daemon/module.c
@@ -17,6 +17,7 @@
#include <string.h>
#include <stdlib.h>
#include "automount.h"
+#include "nsswitch.h"
int load_autofs4_module(void)
{
@@ -53,8 +54,8 @@ int load_autofs4_module(void)
return 1;
}
-struct lookup_mod *open_lookup(const char *name, const char *err_prefix,
- const char *mapfmt, int argc, const char *const *argv)
+int open_lookup(const char *name, const char *err_prefix, const char *mapfmt,
+ int argc, const char *const *argv, struct lookup_mod **lookup)
{
struct lookup_mod *mod;
char buf[MAX_ERR_BUF];
@@ -63,6 +64,7 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix,
void *dh;
int *ver;
+ *lookup = NULL;
mod = malloc(sizeof(struct lookup_mod));
if (!mod) {
@@ -70,7 +72,7 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix,
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
logerr("%s%s", err_prefix, estr);
}
- return NULL;
+ return NSS_STATUS_UNAVAIL;
}
size = snprintf(fnbuf, sizeof(fnbuf),
@@ -81,7 +83,7 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix,
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
logerr("%s%s", err_prefix, estr);
}
- return NULL;
+ return NSS_STATUS_UNAVAIL;
}
if (!(dh = dlopen(fnbuf, RTLD_NOW))) {
@@ -89,7 +91,7 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix,
logerr("%scannot open lookup module %s (%s)",
err_prefix, name, dlerror());
free(mod);
- return NULL;
+ return NSS_STATUS_UNAVAIL;
}
if (!(ver = (int *) dlsym(dh, "lookup_version"))
@@ -99,7 +101,7 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix,
err_prefix, name);
dlclose(dh);
free(mod);
- return NULL;
+ return NSS_STATUS_UNAVAIL;
}
if (!(mod->lookup_init = (lookup_init_t) dlsym(dh, "lookup_init")) ||
@@ -111,16 +113,18 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix,
logerr("%slookup module %s corrupt", err_prefix, name);
dlclose(dh);
free(mod);
- return NULL;
+ return NSS_STATUS_UNAVAIL;
}
if (mod->lookup_init(mapfmt, argc, argv, &mod->context)) {
dlclose(dh);
free(mod);
- return NULL;
+ return NSS_STATUS_NOTFOUND;
}
mod->dlhandle = dh;
- return mod;
+ *lookup = mod;
+
+ return NSS_STATUS_SUCCESS;
}
int close_lookup(struct lookup_mod *mod)
diff --git a/include/automount.h b/include/automount.h
index 447aba1..d614c10 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -302,8 +302,8 @@ struct lookup_mod {
void *context;
};
-struct lookup_mod *open_lookup(const char *name, const char *err_prefix,
- const char *mapfmt, int argc, const char *const *argv);
+int open_lookup(const char *name, const char *err_prefix, const char *mapfmt,
+ int argc, const char *const *argv, struct lookup_mod **lookup);
int close_lookup(struct lookup_mod *);
/* parse module */
diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c
index ffb236c..55035e4 100644
--- a/modules/lookup_multi.c
+++ b/modules/lookup_multi.c
@@ -50,8 +50,10 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch
if (!argv || !argv[0])
return NULL;
- if (*argv[0] == '/')
- return open_lookup("file", MODPREFIX, format, argc, argv);
+ if (*argv[0] == '/') {
+ open_lookup("file", MODPREFIX, format, argc, argv, &mod);
+ return mod;
+ }
if (!strncmp(argv[0], "file", 4) ||
!strncmp(argv[0], "yp", 2) ||
@@ -65,7 +67,8 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch
fmt++;
else
fmt = format;
- return open_lookup(argv[0], MODPREFIX, fmt, argc -1, argv + 1);
+ open_lookup(argv[0], MODPREFIX, fmt, argc - 1, argv + 1, &mod);
+ return mod;
}
INIT_LIST_HEAD(&nsslist);
@@ -80,6 +83,7 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch
head = &nsslist;
list_for_each(p, head) {
struct nss_source *this;
+ int status;
this = list_entry(p, struct nss_source, list);
@@ -113,8 +117,9 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch
save_argv0 = (char *) argv[0];
argv[0] = path;
- mod = open_lookup(type, MODPREFIX, format, argc, argv);
- if (mod) {
+ status = open_lookup(type, MODPREFIX,
+ format, argc, argv, &mod);
+ if (status == NSS_STATUS_SUCCESS) {
free_sources(&nsslist);
free(save_argv0);
return mod;
@@ -124,8 +129,9 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch
free(path);
}
- mod = open_lookup(this->source, MODPREFIX, format, argc, argv);
- if (mod) {
+ status = open_lookup(this->source, MODPREFIX,
+ format, argc, argv, &mod);
+ if (status == NSS_STATUS_SUCCESS) {
free_sources(&nsslist);
return mod;
}
diff --git a/modules/parse_amd.c b/modules/parse_amd.c
index 899be40..2e3d21f 100644
--- a/modules/parse_amd.c
+++ b/modules/parse_amd.c
@@ -31,6 +31,7 @@
#define MODULE_PARSE
#include "automount.h"
+#include "nsswitch.h"
#define MODPREFIX "parse(amd): "
@@ -1129,6 +1130,7 @@ static int do_host_mount(struct autofs_point *ap, const char *name,
struct mapent *me;
const char *argv[2];
const char **pargv = NULL;
+ int status;
int argc = 0;
int ret = 1;
@@ -1170,8 +1172,8 @@ static int do_host_mount(struct autofs_point *ap, const char *name,
}
instance_mutex_lock();
- lookup = open_lookup("hosts", MODPREFIX, NULL, argc, pargv);
- if (!lookup) {
+ status = open_lookup("hosts", MODPREFIX, NULL, argc, pargv, &lookup);
+ if (status != NSS_STATUS_SUCCESS) {
debug(ap->logopt, "open lookup module hosts failed");
instance_mutex_unlock();
goto out;

View File

@ -0,0 +1,138 @@
autofs-5.1.1 - move check_nss_result() to nsswitchr.c
From: Ian Kent <raven@themaw.net>
The check_nss_result() function will be needed by the multi-map lookup
module so move it to the nss library module.
Signed-off-by: Ian Kent <raven@themaw.net>
---
daemon/lookup.c | 45 ---------------------------------------------
include/nsswitch.h | 1 +
lib/nsswitch.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 46 insertions(+), 45 deletions(-)
diff --git a/daemon/lookup.c b/daemon/lookup.c
index 62071df..53455a1 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -25,51 +25,6 @@
#include "automount.h"
#include "nsswitch.h"
-static int check_nss_result(struct nss_source *this, enum nsswitch_status result)
-{
- enum nsswitch_status status;
- struct nss_action a;
-
- /* Check if we have negated actions */
- for (status = 0; status < NSS_STATUS_MAX; status++) {
- a = this->action[status];
- if (a.action == NSS_ACTION_UNKNOWN)
- continue;
-
- if (a.negated && result != status) {
- if (a.action == NSS_ACTION_RETURN) {
- if (result == NSS_STATUS_SUCCESS)
- return 1;
- else
- return 0;
- }
- }
- }
-
- a = this->action[result];
-
- /* Check if we have other actions for this status */
- switch (result) {
- case NSS_STATUS_SUCCESS:
- if (a.action == NSS_ACTION_CONTINUE)
- break;
- return 1;
-
- case NSS_STATUS_NOTFOUND:
- case NSS_STATUS_UNAVAIL:
- case NSS_STATUS_TRYAGAIN:
- if (a.action == NSS_ACTION_RETURN) {
- return 0;
- }
- break;
-
- default:
- break;
- }
-
- return -1;
-}
-
static void nsslist_cleanup(void *arg)
{
struct list_head *nsslist = (struct list_head *) arg;
diff --git a/include/nsswitch.h b/include/nsswitch.h
index 2b445a9..d3e4027 100644
--- a/include/nsswitch.h
+++ b/include/nsswitch.h
@@ -56,6 +56,7 @@ struct nss_source {
};
int set_action(struct nss_action *a, char *status, char *action, int negated);
+int check_nss_result(struct nss_source *this, enum nsswitch_status result);
struct nss_source *add_source(struct list_head *head, char *source);
int free_sources(struct list_head *list);
diff --git a/lib/nsswitch.c b/lib/nsswitch.c
index c6163a7..74c7525 100644
--- a/lib/nsswitch.c
+++ b/lib/nsswitch.c
@@ -55,6 +55,51 @@ int set_action(struct nss_action *act, char *status, char *action, int negated)
return 1;
}
+int check_nss_result(struct nss_source *this, enum nsswitch_status result)
+{
+ enum nsswitch_status status;
+ struct nss_action a;
+
+ /* Check if we have negated actions */
+ for (status = 0; status < NSS_STATUS_MAX; status++) {
+ a = this->action[status];
+ if (a.action == NSS_ACTION_UNKNOWN)
+ continue;
+
+ if (a.negated && result != status) {
+ if (a.action == NSS_ACTION_RETURN) {
+ if (result == NSS_STATUS_SUCCESS)
+ return 1;
+ else
+ return 0;
+ }
+ }
+ }
+
+ a = this->action[result];
+
+ /* Check if we have other actions for this status */
+ switch (result) {
+ case NSS_STATUS_SUCCESS:
+ if (a.action == NSS_ACTION_CONTINUE)
+ break;
+ return 1;
+
+ case NSS_STATUS_NOTFOUND:
+ case NSS_STATUS_UNAVAIL:
+ case NSS_STATUS_TRYAGAIN:
+ if (a.action == NSS_ACTION_RETURN) {
+ return 0;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return -1;
+}
+
struct nss_source *add_source(struct list_head *head, char *source)
{
struct nss_source *s;

View File

@ -0,0 +1,160 @@
autofs-5.1.1 - move query dn calculation from do_bind() to do_connect()
From: Ian Kent <raven@themaw.net>
In the ldap lookup module the do_reconnect() call doesn't distinguish
between no entry found and service unavailable.
If service unavailable gets returned from a master map read it results
in autofs not updating the mounts. A notfound return doesn't because it
indicates the map doesn't exist so updating the mounts isn't a problem
as it can be when the source is unavailable.
Start the update of do_reconnect() by moving the query dn calculation
from do_bind() to do_connect().
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_ldap.c | 81 ++++++++++++++++++++++++++++++-------------------
2 files changed, 51 insertions(+), 31 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index ee078bb..0be1bf2 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -4,6 +4,7 @@
- revert fix libtirpc name clash.
- fix left mount count return from umount_multi_triggers().
- fix return handling in sss lookup module.
+- move query dn calculation from do_bind() to do_connect().
21/04/2015 autofs-5.1.1
=======================
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 5da613e..ea63736 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -574,7 +574,7 @@ static int find_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctx
static int do_bind(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_context *ctxt)
{
char *host = NULL, *nhost;
- int rv, need_base = 1;
+ int rv;
#ifdef WITH_SASL
debug(logopt, MODPREFIX "auth_required: %d, sasl_mech %s",
@@ -610,6 +610,7 @@ static int do_bind(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_c
}
ldap_memfree(host);
+ uris_mutex_lock(ctxt);
if (!ctxt->cur_host) {
ctxt->cur_host = nhost;
if (!(ctxt->format & MAP_FLAG_FORMAT_AMD)) {
@@ -618,43 +619,21 @@ static int do_bind(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_c
}
} else {
/* If connection host has changed update */
- if (strcmp(ctxt->cur_host, nhost)) {
+ if (!strcmp(ctxt->cur_host, nhost))
+ free(nhost);
+ else {
free(ctxt->cur_host);
ctxt->cur_host = nhost;
- } else {
- free(nhost);
- need_base = 0;
- }
- }
-
- if (ctxt->schema && ctxt->qdn && !need_base)
- return 1;
-
- /*
- * If the schema isn't defined in the configuration then check for
- * presence of a map dn with a the common schema. Then calculate the
- * base dn for searches.
- */
- if (!ctxt->schema) {
- if (!find_query_dn(logopt, ldap, ctxt)) {
- warn(logopt,
- MODPREFIX "failed to find valid query dn");
- return 0;
- }
- } else if (!(ctxt->format & MAP_FLAG_FORMAT_AMD)) {
- const char *class = ctxt->schema->map_class;
- const char *key = ctxt->schema->map_attr;
- if (!get_query_dn(logopt, ldap, ctxt, class, key)) {
- error(logopt, MODPREFIX "failed to get query dn");
- return 0;
}
}
+ uris_mutex_unlock(ctxt);
return 1;
}
static LDAP *do_connect(unsigned logopt, const char *uri, struct lookup_context *ctxt)
{
+ char *cur_host = NULL;
LDAP *ldap;
#ifdef WITH_SASL
@@ -665,13 +644,53 @@ static LDAP *do_connect(unsigned logopt, const char *uri, struct lookup_context
#endif
ldap = init_ldap_connection(logopt, uri, ctxt);
- if (ldap) {
- if (!do_bind(logopt, ldap, uri, ctxt)) {
+ if (!ldap)
+ goto out;
+
+ uris_mutex_lock(ctxt);
+ if (ctxt->cur_host)
+ cur_host = ctxt->cur_host;
+ uris_mutex_unlock(ctxt);
+
+ if (!do_bind(logopt, ldap, uri, ctxt)) {
+ unbind_ldap_connection(logopt, ldap, ctxt);
+ ldap = NULL;
+ goto out;
+ }
+
+ /* If the lookup schema and the query dn are set and the
+ * ldap host hasn't changed return.
+ */
+ uris_mutex_lock(ctxt);
+ if (ctxt->schema && ctxt->qdn && (cur_host == ctxt->cur_host)) {
+ uris_mutex_unlock(ctxt);
+ return ldap;
+ }
+ uris_mutex_unlock(ctxt);
+
+ /*
+ * If the schema isn't defined in the configuration then check for
+ * presence of a map dn with a the common schema. Then calculate the
+ * base dn for searches.
+ */
+ if (!ctxt->schema) {
+ if (!find_query_dn(logopt, ldap, ctxt)) {
+ unbind_ldap_connection(logopt, ldap, ctxt);
+ ldap = NULL;
+ warn(logopt,
+ MODPREFIX "failed to find valid query dn");
+ goto out;
+ }
+ } else if (!(ctxt->format & MAP_FLAG_FORMAT_AMD)) {
+ const char *class = ctxt->schema->map_class;
+ const char *key = ctxt->schema->map_attr;
+ if (!get_query_dn(logopt, ldap, ctxt, class, key)) {
unbind_ldap_connection(logopt, ldap, ctxt);
ldap = NULL;
+ error(logopt, MODPREFIX "failed to get query dn");
}
}
-
+out:
return ldap;
}

View File

@ -0,0 +1,57 @@
autofs-5.1.1 - remove unused function elapsed()
From: Ian Kent <raven@themaw.net>
Now that the monotonic clock source is used the elapsed() function
is no longer used, remove it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
include/rpc_subs.h | 1 -
lib/rpc_subs.c | 8 --------
3 files changed, 1 insertion(+), 9 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 4f589db..4acb332 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -30,6 +30,7 @@
- use monotonic clock for indirect mount condition.
- change remaining gettimeofday() to use clock_gettime().
- change time() to use monotonic_clock().
+- remove unused function elapsed().
21/04/2015 autofs-5.1.1
=======================
diff --git a/include/rpc_subs.h b/include/rpc_subs.h
index e329224..e744e89 100644
--- a/include/rpc_subs.h
+++ b/include/rpc_subs.h
@@ -70,7 +70,6 @@ int rpc_portmap_getclient(struct conn_info *, const char *, struct sockaddr *, s
int rpc_portmap_getport(struct conn_info *, struct pmap *, unsigned short *);
int rpc_ping_proto(struct conn_info *);
int rpc_ping(const char *, long, long, unsigned int);
-double elapsed(struct timeval, struct timeval);
double monotonic_elapsed(struct timespec, struct timespec);
int rpc_time(const char *, unsigned int, unsigned int, long, long, unsigned int, double *);
const char *get_addr_string(struct sockaddr *, char *, socklen_t);
diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c
index 4a84c16..8995996 100644
--- a/lib/rpc_subs.c
+++ b/lib/rpc_subs.c
@@ -1067,14 +1067,6 @@ int rpc_ping(const char *host, long seconds, long micros, unsigned int option)
return status;
}
-double elapsed(struct timeval start, struct timeval end)
-{
- double t1, t2;
- t1 = (double)start.tv_sec + (double)start.tv_usec/(1000*1000);
- t2 = (double)end.tv_sec + (double)end.tv_usec/(1000*1000);
- return t2-t1;
-}
-
double monotonic_elapsed(struct timespec start, struct timespec end)
{
double t1, t2;

View File

@ -0,0 +1,108 @@
autofs-5.1.1 - update map_hash_table_size description
From: Ian Kent <raven@themaw.net>
The configuration parameter map_hash_table_size has been ommitted
from the autofs.conf(5) man page and it's description in the
configuration file comments is poor.
Add a description of the parameter to autofs.conf(5) and update
the configuration file comments to direct people to the map page
for more information.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
man/autofs.conf.5.in | 31 +++++++++++++++++++++++++++++++
redhat/autofs.conf.default.in | 6 ++++--
samples/autofs.conf.default.in | 6 ++++--
4 files changed, 40 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 16e5344..2b8d224 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -18,6 +18,7 @@
- fix missing source sss in multi map lookup.
- fix update_hosts_mounts() return.
- change lookup to use reinit instead of reopen.
+- update map_hash_table_size description.
21/04/2015 autofs-5.1.1
=======================
diff --git a/man/autofs.conf.5.in b/man/autofs.conf.5.in
index 7d66878..4434eb8 100644
--- a/man/autofs.conf.5.in
+++ b/man/autofs.conf.5.in
@@ -80,6 +80,37 @@ user setting these standard environment variables opens automount(8) to
potential user privilege escalation when the program map is written in a
language that can load components from, for example, a user home directory
(program default "no").
+.TP
+.B map_hash_table_size
+.br
+This configuration option may be used to change the number of hash
+table slots (default 1024).
+
+This configuration option affects the overhead of searching the map
+entry cache for map entries when there are a large number of entries.
+It affects the number of entries that must be looked at to locate a
+map entry in the map entry cache. For example, the default of 1024
+and a direct map with 8000 entries would result in each slot
+containing an average of 8 entries, which should be acceptable.
+
+However, if excessive CPU usage is observed during automount lookups
+increasing this option can reduce the CPU overhead considerably becuase
+it reduces the length of the search chains.
+
+Note that the number of entries in a map doesn't necessarily relate
+to the number of entries used in the map entry cache.
+
+There are three distinct cases, direct maps and indirect maps that
+use the "browse" option must be read in their entirity at program
+start so, in these two cases the map size does retate directly to
+the map entry cache size.
+
+For indirect maps that do not use the "browse" option entries are
+added to the map entry cache at lookup so the number of active cache
+entries, in this case, is usually much less than the number of entries
+in the map. In this last case it would be unusual for the map entry
+cache to grow large enough to warrant increasing the default before
+an event that cleans stale entries, a map re-read for example.
.SS LDAP Configuration
.P
Configuration settings available are:
diff --git a/redhat/autofs.conf.default.in b/redhat/autofs.conf.default.in
index 13bbb7e..da0882f 100644
--- a/redhat/autofs.conf.default.in
+++ b/redhat/autofs.conf.default.in
@@ -135,8 +135,10 @@ mount_nfs_default_protocol = 4
#auth_conf_file = @@autofsmapdir@@/autofs_ldap_auth.conf
#
# map_hash_table_size - set the map cache hash table size.
-# Should be a power of 2 with a ratio roughly
-# between 1:10 and 1:20 for each map.
+# Should be a power of 2 with a ratio of
+# close to 1:8 for acceptable performance
+# with maps up to around 8000 entries.
+# See autofs.conf(5) for more details.
#
#map_hash_table_size = 1024
#
diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in
index 441b68e..80abb43 100644
--- a/samples/autofs.conf.default.in
+++ b/samples/autofs.conf.default.in
@@ -134,8 +134,10 @@ browse_mode = no
#auth_conf_file = @@autofsmapdir@@/autofs_ldap_auth.conf
#
# map_hash_table_size - set the map cache hash table size.
-# Should be a power of 2 with a ratio roughly
-# between 1:10 and 1:20 for each map.
+# Should be a power of 2 with a ratio of
+# close to 1:8 for acceptable performance
+# with maps up to around 8000 entries.
+# See autofs.conf(5) for more details.
#
#map_hash_table_size = 1024
#

View File

@ -0,0 +1,109 @@
autofs-5.1.1 - use monotonic clock for alarm thread condition wait
From: Yu Ning <ning.yu@ubuntu.com>
The time returned by gettimeofday() is affected by discontinuous jumps
in the system time, so it causes an issue that autofs may not auto
unmount a mount point if system time is manually changed by the system
administrator.
To fix the issue we need to convert to using a monotonic clock source
instead of the clock source used by gettimeofday().
Convert the alarm_handler() to use a monotonic clock source.
Signed-off-by: Yu Ning <ning.yu@ubuntu.com>
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/alarm.c | 28 ++++++++++++++++++++++------
2 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 566a6c6..c443f49 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -24,6 +24,7 @@
- fix error handling of is_mounted().
- Add a mode option for master map entries.
- define monotonic clock helper functions.
+- use monotonic clock for alarm thread condition wait.
21/04/2015 autofs-5.1.1
=======================
diff --git a/lib/alarm.c b/lib/alarm.c
index 0f04ef8..e6a880b 100755
--- a/lib/alarm.c
+++ b/lib/alarm.c
@@ -23,7 +23,7 @@ struct alarm {
};
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+static pthread_cond_t cond;
static LIST_HEAD(alarms);
#define alarm_lock() \
@@ -46,7 +46,7 @@ int alarm_add(struct autofs_point *ap, time_t seconds)
struct list_head *head;
struct list_head *p;
struct alarm *new;
- time_t now = time(NULL);
+ time_t now = monotonic_time(NULL);
time_t next_alarm = 0;
unsigned int empty = 1;
int status;
@@ -175,17 +175,18 @@ static void *alarm_handler(void *arg)
first = list_entry(head->next, struct alarm, list);
- now = time(NULL);
+ now = monotonic_time(NULL);
if (first->time > now) {
- struct timeval usecs;
+ struct timespec nsecs;
+
/*
* Wait for alarm to trigger or a new alarm
* to be added.
*/
- gettimeofday(&usecs, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &nsecs);
expire.tv_sec = first->time;
- expire.tv_nsec = usecs.tv_usec * 1000;
+ expire.tv_nsec = nsecs.tv_nsec;
status = pthread_cond_timedwait(&cond, &mutex, &expire);
if (status && status != ETIMEDOUT)
@@ -212,6 +213,7 @@ int alarm_start_handler(void)
pthread_t thid;
pthread_attr_t attrs;
pthread_attr_t *pattrs = &attrs;
+ pthread_condattr_t condattrs;
int status;
status = pthread_attr_init(pattrs);
@@ -224,8 +226,22 @@ int alarm_start_handler(void)
#endif
}
+ status = pthread_condattr_init(&condattrs);
+ if (status)
+ fatal(status);
+
+ status = pthread_condattr_setclock(&condattrs, CLOCK_MONOTONIC);
+ if (status)
+ fatal(status);
+
+ status = pthread_cond_init(&cond, &condattrs);
+ if (status)
+ fatal(status);
+
status = pthread_create(&thid, pattrs, alarm_handler, NULL);
+ pthread_condattr_destroy(&condattrs);
+
if (pattrs)
pthread_attr_destroy(pattrs);

View File

@ -0,0 +1,100 @@
autofs-5.1.1 - use monotonic clock for direct mount condition
From: Yu Ning <ning.yu@ubuntu.com>
The time returned by gettimeofday() is affected by discontinuous jumps
in the system time, so it causes an issue that autofs may not auto
unmount a mount point if system time is manually changed by the system
administrator.
To fix the issue we need to convert to using a monotonic clock source
instead of the clock source used by gettimeofday().
Change the direct mount and expire thread creation to use a monotonic
clock source.
Signed-off-by: Yu Ning <ning.yu@ubuntu.com>
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 20 ++++++--------------
2 files changed, 7 insertions(+), 14 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 20a64a7..e3b1f04 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -26,6 +26,7 @@
- define monotonic clock helper functions.
- use monotonic clock for alarm thread condition wait.
- define pending condition init helper function.
+- use monotonic clock for direct mount condition.
21/04/2015 autofs-5.1.1
=======================
diff --git a/daemon/direct.c b/daemon/direct.c
index 1962a58..9b7fd76 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -1045,7 +1045,6 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
char buf[MAX_ERR_BUF];
pthread_t thid;
struct timespec wait;
- struct timeval now;
int status, state;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
@@ -1115,9 +1114,7 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
return 1;
}
- status = pthread_cond_init(&mt->cond, NULL);
- if (status)
- fatal(status);
+ pending_cond_init(mt);
status = pthread_mutex_init(&mt->mutex, NULL);
if (status)
@@ -1163,9 +1160,8 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
mt->signaled = 0;
while (!mt->signaled) {
- gettimeofday(&now, NULL);
- wait.tv_sec = now.tv_sec + 2;
- wait.tv_nsec = now.tv_usec * 1000;
+ clock_gettime(CLOCK_MONOTONIC, &wait);
+ wait.tv_sec += 2;
status = pthread_cond_timedwait(&mt->cond, &mt->mutex, &wait);
if (status && status != ETIMEDOUT)
fatal(status);
@@ -1300,7 +1296,6 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
char buf[MAX_ERR_BUF];
int status = 0;
struct timespec wait;
- struct timeval now;
int ioctlfd, len, state;
unsigned int kver_major = get_kver_major();
unsigned int kver_minor = get_kver_minor();
@@ -1431,9 +1426,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
}
memset(mt, 0, sizeof(struct pending_args));
- status = pthread_cond_init(&mt->cond, NULL);
- if (status)
- fatal(status);
+ pending_cond_init(mt);
status = pthread_mutex_init(&mt->mutex, NULL);
if (status)
@@ -1482,9 +1475,8 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
mt->signaled = 0;
while (!mt->signaled) {
- gettimeofday(&now, NULL);
- wait.tv_sec = now.tv_sec + 2;
- wait.tv_nsec = now.tv_usec * 1000;
+ clock_gettime(CLOCK_MONOTONIC, &wait);
+ wait.tv_sec += 2;
status = pthread_cond_timedwait(&mt->cond, &mt->mutex, &wait);
if (status && status != ETIMEDOUT)
fatal(status);

View File

@ -0,0 +1,100 @@
autofs-5.1.1 - use monotonic clock for indirect mount condition
From: Yu Ning <ning.yu@ubuntu.com>
The time returned by gettimeofday() is affected by discontinuous jumps
in the system time, so it causes an issue that autofs may not auto
unmount a mount point if system time is manually changed by the system
administrator.
To fix the issue we need to convert to using a monotonic clock source
instead of the clock source used by gettimeofday().
Change the indirect mount and expire thread creation to use a monotonic
clock source.
Signed-off-by: Yu Ning <ning.yu@ubuntu.com>
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/indirect.c | 20 ++++++--------------
2 files changed, 7 insertions(+), 14 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index e3b1f04..c243a8a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -27,6 +27,7 @@
- use monotonic clock for alarm thread condition wait.
- define pending condition init helper function.
- use monotonic clock for direct mount condition.
+- use monotonic clock for indirect mount condition.
21/04/2015 autofs-5.1.1
=======================
diff --git a/daemon/indirect.c b/daemon/indirect.c
index bfd181d..263fff1 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -640,7 +640,6 @@ int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_
char buf[MAX_ERR_BUF];
pthread_t thid;
struct timespec wait;
- struct timeval now;
int status, state;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
@@ -658,9 +657,7 @@ int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_
return 1;
}
- status = pthread_cond_init(&mt->cond, NULL);
- if (status)
- fatal(status);
+ pending_cond_init(mt);
status = pthread_mutex_init(&mt->mutex, NULL);
if (status)
@@ -695,9 +692,8 @@ int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_
mt->signaled = 0;
while (!mt->signaled) {
- gettimeofday(&now, NULL);
- wait.tv_sec = now.tv_sec + 2;
- wait.tv_nsec = now.tv_usec * 1000;
+ clock_gettime(CLOCK_MONOTONIC, &wait);
+ wait.tv_sec += 2;
status = pthread_cond_timedwait(&mt->cond, &mt->mutex, &wait);
if (status && status != ETIMEDOUT)
fatal(status);
@@ -799,7 +795,6 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin
char buf[MAX_ERR_BUF];
struct pending_args *mt;
struct timespec wait;
- struct timeval now;
struct mapent *me;
int status, state;
@@ -845,9 +840,7 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin
}
memset(mt, 0, sizeof(struct pending_args));
- status = pthread_cond_init(&mt->cond, NULL);
- if (status)
- fatal(status);
+ pending_cond_init(mt);
status = pthread_mutex_init(&mt->mutex, NULL);
if (status)
@@ -888,9 +881,8 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin
mt->signaled = 0;
while (!mt->signaled) {
- gettimeofday(&now, NULL);
- wait.tv_sec = now.tv_sec + 2;
- wait.tv_nsec = now.tv_usec * 1000;
+ clock_gettime(CLOCK_MONOTONIC, &wait);
+ wait.tv_sec += 2;
status = pthread_cond_timedwait(&mt->cond, &mt->mutex, &wait);
if (status && status != ETIMEDOUT)
fatal(status);

View File

@ -8,7 +8,7 @@
Summary: A tool for automatically mounting and unmounting filesystems
Name: autofs
Version: 5.1.1
Release: 7%{?dist}
Release: 20%{?dist}
Epoch: 1
License: GPLv2+
Group: System Environment/Daemons
@ -18,6 +18,56 @@ Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
Patch1: autofs-5.1.1-fix-fix-gcc5-complaints.patch
Patch2: autofs-5.1.1-update-libtirpc-workaround-for-new-soname.patch
Patch3: autofs-5.1.1-revert-fix-libtirpc-name-clash.patch
Patch4: autofs-5.1.1-fix-left-mount-count-return.patch
Patch5: autofs-5.1.1-fix-return-handling-in-sss-lookup-module.patch
Patch6: autofs-5.1.1-move-query-dn-calculation-from-do_bind-to-do_connect.patch
Patch7: autofs-5.1.1-make-do_connect-return-a-status.patch
Patch8: autofs-5.1.1-make-connect_to_server-return-a-status.patch
Patch9: autofs-5.1.1-make-find_dc_server-return-a-status.patch
Patch10: autofs-5.1.1-make-find_server-return-a-status.patch
Patch11: autofs-5.1.1-fix-return-handling-of-do_reconnect-in-ldap-module.patch
Patch12: autofs-5.1.1-fix-rwlock-unlock-crash.patch
Patch13: autofs-5.1.1-fix-config-old-name-lookup.patch
Patch14: autofs-5.1.1-fix-error-handling-on-ldap-bind-fail.patch
Patch15: autofs-5.1.1-fix-direct-mount-stale-instance-flag-reset.patch
Patch16: autofs-5.1.1-fix-direct-map-expire-not-set-for-initial-empty-map.patch
Patch17: autofs-5.1.1-fix-missing-source-sss-in-multi-map-lookup.patch
Patch18: autofs-5.1.1-fix-update_hosts_mounts-return.patch
Patch19: autofs-5.1.1-move-check_nss_result-to-nsswitch_c.patch
Patch20: autofs-5.1.1-make-open_lookup-return-nss-status.patch
Patch21: autofs-5.1.1-fix-nsswitch-handling-when-opening-multi-map.patch
Patch22: autofs-5.1.1-add-reinit-entry-point-to-modules.patch
Patch23: autofs-5.1.1-implement-reinit-in-parse-modules.patch
Patch24: autofs-5.1.1-implement-reinit-in-dir-lookup-module.patch
Patch25: autofs-5.1.1-implement-reinit-in-file-lookup-module.patch
Patch26: autofs-5.1.1-implement-reinit-in-hesiod-lookup-module.patch
Patch27: autofs-5.1.1-implement-reinit-in-hosts-lookup-module.patch
Patch28: autofs-5.1.1-implement-reinit-in-ldap-lookup-module.patch
Patch29: autofs-5.1.1-implement-reinit-in-nisplus-lookup-module.patch
Patch30: autofs-5.1.1-implement-reinit-in-program-lookup-module.patch
Patch31: autofs-5.1.1-implement-reinit-in-sss-lookup-module.patch
Patch32: autofs-5.1.1-implement-reinit-in-yp-lookup-module.patch
Patch33: autofs-5.1.1-add-type-to-struct-lookup_mod.patch
Patch34: autofs-5.1.1-factor-out-free-multi-map-context.patch
Patch35: autofs-5.1.1-factor-out-alloc-multi-map-context.patch
Patch36: autofs-5.1.1-fix-map-format-check-in-nss_open_lookup-multi-map-module.patch
Patch37: autofs-5.1.1-implement-reinit-in-multi-lookup-module.patch
Patch38: autofs-5.1.1-change-lookup-to-use-reinit-instead-of-reopen.patch
Patch39: autofs-5.1.1-update-map_hash_table_size-description.patch
Patch40: autofs-5.1.1-add-configuration-option-to-use-hostname-in-mounts.patch
Patch41: autofs-5.1.1-fix-out-of-order-call-in-program-map-lookup.patch
Patch42: autofs-5.1.1-fix-error-handling-of-is_mounted.patch
Patch43: autofs-5.1.1-Add-a-mode-option-for-master-map-entries.patch
Patch44: autofs-5.1.1-define-monotonic-clock-helper-functions.patch
Patch45: autofs-5.1.1-use-monotonic-clock-for-alarm-thread-condition-wait.patch
Patch46: autofs-5.1.1-define-pending-condition-init-helper-function.patch
Patch47: autofs-5.1.1-use-monotonic-clock-for-direct-mount-condition.patch
Patch48: autofs-5.1.1-use-monotonic-clock-for-indirect-mount-condition.patch
Patch49: autofs-5.1.1-change-remaining-gettimeofday-to-use-clock_gettime.patch
Patch50: autofs-5.1.1-change-time-to-use-monotonic_clock.patch
Patch51: autofs-5.1.1-remove-unused-function-elapsed.patch
Patch52: autofs-5.1.1-fix-unbind-external-mech.patch
Patch53: autofs-5.1.1-fix-sasl-connection-concurrancy-problem.patch
%if %{with_systemd}
BuildRequires: systemd-units
@ -80,6 +130,56 @@ echo %{version}-%{release} > .version
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
%patch22 -p1
%patch23 -p1
%patch24 -p1
%patch25 -p1
%patch26 -p1
%patch27 -p1
%patch28 -p1
%patch29 -p1
%patch30 -p1
%patch31 -p1
%patch32 -p1
%patch33 -p1
%patch34 -p1
%patch35 -p1
%patch36 -p1
%patch37 -p1
%patch38 -p1
%patch39 -p1
%patch40 -p1
%patch41 -p1
%patch42 -p1
%patch43 -p1
%patch44 -p1
%patch45 -p1
%patch46 -p1
%patch47 -p1
%patch48 -p1
%patch49 -p1
%patch50 -p1
%patch51 -p1
%patch52 -p1
%patch53 -p1
%build
LDFLAGS=-Wl,-z,now
@ -173,13 +273,17 @@ fi
%dir /etc/auto.master.d
%changelog
* Wed Nov 04 2015 Kalev Lember <klember@redhat.com> - 1:5.1.1-7
* Wed Jan 20 2016 Ian Kent <ikent@redhat.com> - 1:5.1.1-20
- fix incorrect committer changelog entries.
- add current released upstream patches.
* Wed Nov 04 2015 Ian Kent <ikent@redhat.com> - 1:5.1.1-7
- revert fix libtirpc name clash patch (an old 5.0.6 patch).
* Wed Nov 04 2015 Kalev Lember <klember@redhat.com> - 1:5.1.1-6
* Wed Nov 04 2015 Ian Kent <ikent@redhat.com> - 1:5.1.1-6
- remove unnecessary nfs-utils BuildRequires (bz1277669).
* Mon Nov 02 2015 Kalev Lember <klember@redhat.com> - 1:5.1.1-5
* Mon Nov 02 2015 Ian Kent <ikent@redhat.com> - 1:5.1.1-5
- fix fix gcc5 complaints.
- update libtirpc workaround for new soname.