rpms/autofs/FC-6 autofs-5.0.1-rc2-fix-null-map-semantics.patch, NONE, 1.1 autofs-5.0.1-rc2-nfs4-get-port.patch, NONE, 1.1 autofs.spec, 1.157, 1.158
fedora-cvs-commits at redhat.com
fedora-cvs-commits at redhat.com
Wed Dec 6 06:27:08 UTC 2006
- Previous message (by thread): rpms/autofs/devel autofs-5.0.1-rc2-nfs4-get-port.patch, NONE, 1.1 autofs.spec, 1.164, 1.165
- Next message (by thread): rpms/fonts-indic/devel .cvsignore, 1.12, 1.13 fonts-indic.spec, 1.17, 1.18 sources, 1.15, 1.16
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: ikent
Update of /cvs/dist/rpms/autofs/FC-6
In directory cvs.devel.redhat.com:/tmp/cvs-serv600
Modified Files:
autofs.spec
Added Files:
autofs-5.0.1-rc2-fix-null-map-semantics.patch
autofs-5.0.1-rc2-nfs4-get-port.patch
Log Message:
* Wed Dec 6 2006 Ian Kent <ikent at redhat.com> - 5.0.1-0.rc2.28
- alter nfs4 host probing to not use portmap lookup and add options
check for "port=" parameter (bz 208757).
- correct semantics of "-null" map handling (bzs 214800, 208091).
- Resolves: rhbz#214800 rhbz#208757
- Related: rhbz#208091
autofs-5.0.1-rc2-fix-null-map-semantics.patch:
CHANGELOG | 1
daemon/automount.c | 25 ++++++++---
daemon/direct.c | 74 +++++++++++++++++++++++++--------
daemon/lookup.c | 16 +++----
daemon/spawn.c | 1
daemon/state.c | 48 +++++++++++++++++++--
include/automount.h | 3 +
include/master.h | 6 +-
lib/cache.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++
lib/master.c | 67 ++++++++++++++++++++++--------
lib/master_parse.y | 25 ++++++++++-
modules/lookup_file.c | 6 +-
modules/mount_autofs.c | 5 +-
13 files changed, 320 insertions(+), 64 deletions(-)
--- NEW FILE autofs-5.0.1-rc2-fix-null-map-semantics.patch ---
diff --git a/CHANGELOG b/CHANGELOG
index 2ffef53..f5f9efb 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -43,6 +43,7 @@
- eliminate use of pthread_kill to detect task completion.
- alter nfs4 host probing to not use portmap lookup and add options
check for "port=" parameter.
+- correct semantics of "-null" map handling.
1/9/2006 autofs-5.0.1 rc2
-------------------------
diff --git a/daemon/automount.c b/daemon/automount.c
index ae87556..5628425 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -379,7 +379,7 @@ static void update_map_cache(struct auto
pthread_cleanup_push(master_source_lock_cleanup, ap->entry);
master_source_readlock(ap->entry);
- map = ap->entry->first;
+ map = ap->entry->maps;
while (map) {
struct mapent *me = NULL;
@@ -390,11 +390,13 @@ static void update_map_cache(struct auto
}
mc = map->mc;
- cache_writelock(mc);
- me = cache_lookup_distinct(mc, key);
- if (me && me->ioctlfd == -1)
- cache_delete(mc, key);
- cache_unlock(mc);
+ /* If the lock is busy try later */
+ if (cache_try_writelock(mc)) {
+ me = cache_lookup_distinct(mc, key);
+ if (me && me->ioctlfd == -1)
+ cache_delete(mc, key);
+ cache_unlock(mc);
+ }
map = map->next;
}
@@ -487,12 +489,21 @@ static int umount_subtree_mounts(struct
it also tries to umount path itself */
int umount_multi(struct autofs_point *ap, const char *path, int incl)
{
+ struct mapent_cache *nc;
struct statfs fs;
int is_autofs_fs;
int ret, left;
debug(ap->logopt, "path %s incl %d", path, incl);
+ nc = ap->entry->master->nc;
+ cache_readlock(nc);
+ if (cache_lookup_distinct(nc, path)) {
+ cache_unlock(nc);
+ return 0;
+ }
+ cache_unlock(nc);
+
ret = statfs(path, &fs);
if (ret == -1) {
error(ap->logopt, "could not stat fs of %s", path);
@@ -513,7 +524,7 @@ int umount_multi(struct autofs_point *ap
left += umount_subtree_mounts(ap, path, is_autofs_fs);
/* Delete detritus like unwanted mountpoints and symlinks */
- if (left == 0) {
+ if (left == 0 && ap->state != ST_READMAP) {
update_map_cache(ap, path);
check_rm_dirs(ap, path, incl);
}
diff --git a/daemon/direct.c b/daemon/direct.c
index b8dbbc0..8971d99 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -79,6 +79,13 @@ static void key_mnt_params_init(void)
return;
}
+static void mnts_cleanup(void *arg)
+{
+ struct mnt_list *mnts = (struct mnt_list *) arg;
+ tree_free_mnt_tree(mnts);
+ return;
+}
+
static int autofs_init_direct(struct autofs_point *ap)
{
int pipefd[2], cl_flags;
@@ -194,7 +201,7 @@ int do_umount_autofs_direct(struct autof
} else {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
error(ap->logopt,
- "couldn't get ioctl fd for offset %s", me->key);
+ "couldn't get ioctl fd for direct mount %s", me->key);
debug(ap->logopt, "open: %s", estr);
return 1;
}
@@ -252,9 +259,9 @@ force_umount:
int umount_autofs_direct(struct autofs_point *ap)
{
struct map_source *map;
- struct mapent_cache *mc;
+ struct mapent_cache *nc, *mc;
struct mnt_list *mnts;
- struct mapent *me;
+ struct mapent *me, *ne;
close(ap->state_pipe[0]);
close(ap->state_pipe[1]);
@@ -266,24 +273,36 @@ int umount_autofs_direct(struct autofs_p
}
mnts = tree_make_mnt_tree(_PROC_MOUNTS, "/");
+ pthread_cleanup_push(mnts_cleanup, mnts);
pthread_cleanup_push(master_source_lock_cleanup, ap->entry);
master_source_readlock(ap->entry);
- map = ap->entry->first;
+ nc = ap->entry->master->nc;
+ cache_readlock(nc);
+ pthread_cleanup_push(cache_lock_cleanup, nc);
+ map = ap->entry->maps;
while (map) {
mc = map->mc;
pthread_cleanup_push(cache_lock_cleanup, mc);
cache_readlock(mc);
me = cache_enumerate(mc, NULL);
while (me) {
+ ne = cache_lookup_distinct(nc, me->key);
+ if (ne && map->master_line > ne->age) {
+ me = cache_enumerate(mc, me);
+ continue;
+ }
+
/* TODO: check return, locking me */
do_umount_autofs_direct(ap, mnts, me);
+
me = cache_enumerate(mc, me);
}
pthread_cleanup_pop(1);
map = map->next;
}
pthread_cleanup_pop(1);
- tree_free_mnt_tree(mnts);
+ pthread_cleanup_pop(1);
+ pthread_cleanup_pop(1);
return 0;
}
@@ -490,8 +509,8 @@ out_err:
int mount_autofs_direct(struct autofs_point *ap)
{
struct map_source *map;
- struct mapent_cache *mc;
- struct mapent *me;
+ struct mapent_cache *nc, *mc;
+ struct mapent *me, *ne, *nested;
struct mnt_list *mnts;
time_t now = time(NULL);
@@ -512,9 +531,13 @@ int mount_autofs_direct(struct autofs_po
}
mnts = tree_make_mnt_tree(_PROC_MOUNTS, "/");
+ pthread_cleanup_push(mnts_cleanup, mnts);
pthread_cleanup_push(master_source_lock_cleanup, ap->entry);
master_source_readlock(ap->entry);
- map = ap->entry->first;
+ nc = ap->entry->master->nc;
+ cache_readlock(nc);
+ pthread_cleanup_push(cache_lock_cleanup, nc);
+ map = ap->entry->maps;
while (map) {
/*
* Only consider map sources that have been read since
@@ -530,15 +553,37 @@ int mount_autofs_direct(struct autofs_po
cache_readlock(mc);
me = cache_enumerate(mc, NULL);
while (me) {
+ ne = cache_lookup_distinct(nc, me->key);
+ if (ne) {
+ if (map->master_line < ne->age) {
+ /* TODO: check return, locking me */
+ do_mount_autofs_direct(ap, mnts, me);
+ }
+ me = cache_enumerate(mc, me);
+ continue;
+ }
+
+ nested = cache_partial_match(nc, me->key);
+ if (nested) {
+ error(ap->logopt,
+ "removing invalid nested null entry %s",
+ nested->key);
+ nested = cache_partial_match(nc, me->key);
+ if (nested)
+ cache_delete(nc, nested->key);
+ }
+
/* TODO: check return, locking me */
do_mount_autofs_direct(ap, mnts, me);
+
me = cache_enumerate(mc, me);
}
pthread_cleanup_pop(1);
map = map->next;
}
pthread_cleanup_pop(1);
- tree_free_mnt_tree(mnts);
+ pthread_cleanup_pop(1);
+ pthread_cleanup_pop(1);
return 0;
}
@@ -821,13 +866,6 @@ static int expire_direct(int ioctlfd, co
return 1;
}
-static void mnts_cleanup(void *arg)
-{
- struct mnt_list *mnts = (struct mnt_list *) arg;
- tree_free_mnt_tree(mnts);
- return;
-}
-
void *expire_proc_direct(void *arg)
{
struct mnt_list *mnts = NULL, *next;
@@ -1090,7 +1128,7 @@ int handle_packet_expire_direct(struct a
* there is an entry in the cache.
*/
master_source_readlock(ap->entry);
- map = ap->entry->first;
+ map = ap->entry->maps;
while (map) {
mc = map->mc;
cache_readlock(mc);
@@ -1395,7 +1433,7 @@ int handle_packet_missing_direct(struct
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
master_source_readlock(ap->entry);
- map = ap->entry->first;
+ map = ap->entry->maps;
while (map) {
/*
* Only consider map sources that have been read since
diff --git a/daemon/lookup.c b/daemon/lookup.c
index d13886b..db3dac0 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -432,7 +432,7 @@ int lookup_nss_read_map(struct autofs_po
*/
pthread_cleanup_push(master_source_lock_cleanup, entry);
master_source_readlock(entry);
- map = entry->first;
+ map = entry->maps;
while (map) {
/* Is map source up to date or no longer valid */
if (!map->stale || entry->age > map->age) {
@@ -531,7 +531,7 @@ int lookup_ghost(struct autofs_point *ap
pthread_cleanup_push(master_source_lock_cleanup, entry);
master_source_readlock(entry);
- map = entry->first;
+ map = entry->maps;
while (map) {
/*
* Only consider map sources that have been read since
@@ -769,7 +769,7 @@ int lookup_nss_mount(struct autofs_point
*/
pthread_cleanup_push(master_source_lock_cleanup, entry);
master_source_readlock(entry);
- map = entry->first;
+ map = entry->maps;
while (map) {
/*
* Only consider map sources that have been read since
@@ -859,7 +859,7 @@ void lookup_close_lookup(struct autofs_p
{
struct map_source *map;
- map = ap->entry->first;
+ map = ap->entry->maps;
if (!map)
return;
@@ -917,7 +917,7 @@ int lookup_prune_cache(struct autofs_poi
pthread_cleanup_push(master_source_lock_cleanup, entry);
master_source_readlock(entry);
- map = entry->first;
+ map = entry->maps;
while (map) {
if (!map->stale) {
map = map->next;
@@ -1017,7 +1017,7 @@ struct mapent *lookup_source_valid_mapen
struct mapent *me = NULL;
master_source_readlock(entry);
- map = entry->first;
+ map = entry->maps;
while (map) {
/*
* Only consider map sources that have been read since
@@ -1053,7 +1053,7 @@ struct mapent *lookup_source_mapent(stru
struct mapent *me = NULL;
master_source_readlock(entry);
- map = entry->first;
+ map = entry->maps;
while (map) {
mc = map->mc;
cache_readlock(mc);
@@ -1081,7 +1081,7 @@ int lookup_source_close_ioctlfd(struct a
pthread_cleanup_push(master_source_lock_cleanup, entry);
master_source_readlock(entry);
- map = entry->first;
+ map = entry->maps;
while (map) {
mc = map->mc;
cache_readlock(mc);
diff --git a/daemon/spawn.c b/daemon/spawn.c
index 2ede231..7f0a6e0 100644
--- a/daemon/spawn.c
+++ b/daemon/spawn.c
@@ -133,7 +133,6 @@ static int do_spawn(logger *log, unsigne
char **pargv = (char **) argv;
int argc = 0;
pid_t pgrp = getpgrp();
- DIR *dfd;
/* what to mount must always be second last */
while (*pargv++)
diff --git a/daemon/state.c b/daemon/state.c
index 948ba88..d5eca8b 100644
--- a/daemon/state.c
+++ b/daemon/state.c
@@ -331,6 +331,9 @@ static void do_readmap_cleanup(void *arg
st_set_done(ap);
+ if (!ap->submount)
+ alarm_add(ap, ap->exp_runfreq);
+
free(ra);
return;
@@ -347,7 +350,7 @@ static void *do_readmap(void *arg)
{
struct autofs_point *ap;
struct map_source *map;
- struct mapent_cache *mc;
+ struct mapent_cache *nc, *mc;
struct readmap_args *ra;
struct mnt_list *mnts;
int status;
@@ -384,15 +387,18 @@ static void *do_readmap(void *arg)
lookup_prune_cache(ap, now);
status = lookup_ghost(ap);
} else {
- struct mapent *me;
+ struct mapent *me, *ne, *nested;
mnts = tree_make_mnt_tree(_PROC_MOUNTS, "/");
pthread_cleanup_push(tree_mnts_cleanup, mnts);
pthread_cleanup_push(master_source_lock_cleanup, ap->entry);
master_source_readlock(ap->entry);
- map = ap->entry->first;
+ nc = ap->entry->master->nc;
+ cache_readlock(nc);
+ pthread_cleanup_push(cache_lock_cleanup, nc);
+ map = ap->entry->maps;
while (map) {
/* Is map source up to date or no longer valid */
- if (!map->stale || ap->entry->age > map->age) {
+ if (!map->stale) {
map = map->next;
continue;
}
@@ -401,15 +407,29 @@ static void *do_readmap(void *arg)
cache_readlock(mc);
me = cache_enumerate(mc, NULL);
while (me) {
+ ne = cache_lookup_distinct(nc, me->key);
+ if (!ne) {
+ nested = cache_partial_match(nc, me->key);
+ if (nested) {
+ error(ap->logopt,
+ "removing invalid nested null entry %s",
+ nested->key);
+ nested = cache_partial_match(nc, me->key);
+ if (nested)
+ cache_delete(nc, nested->key);
+ }
+ }
+
/* TODO: check return of do_... */
- if (me->age < now) {
+ if (me->age < now || (ne && map->master_line > ne->age)) {
if (!tree_is_mounted(mnts, me->key, MNTS_REAL))
do_umount_autofs_direct(ap, mnts, me);
else
debug(ap->logopt,
- "%s id mounted", me->key);
+ "%s is mounted", me->key);
} else
do_mount_autofs_direct(ap, mnts, me);
+
me = cache_enumerate(mc, me);
}
pthread_cleanup_pop(1);
@@ -417,6 +437,7 @@ static void *do_readmap(void *arg)
}
pthread_cleanup_pop(1);
pthread_cleanup_pop(1);
+ pthread_cleanup_pop(1);
lookup_prune_cache(ap, now);
}
@@ -459,12 +480,21 @@ static unsigned int st_readmap(struct au
assert(ap->state == ST_READY);
assert(ap->readmap_thread == 0);
+ /* Turn off timeouts for this mountpoint */
+ if (!ap->submount)
+ alarm_delete(ap);
+
ap->state = ST_READMAP;
ra = malloc(sizeof(struct readmap_args));
if (!ra) {
error(ap->logopt, "failed to malloc reamap cond struct");
+ state_mutex_lock(ap);
nextstate(ap->state_pipe[1], ST_READY);
+ state_mutex_unlock(ap);
+ /* It didn't work: return to ready */
+ if (!ap->submount)
+ alarm_add(ap, ap->exp_runfreq);
return 0;
}
@@ -488,6 +518,12 @@ static unsigned int st_readmap(struct au
error(ap->logopt, "read map thread create failed");
st_readmap_cleanup(ra);
free(ra);
+ state_mutex_lock(ap);
+ nextstate(ap->state_pipe[1], ST_READY);
+ state_mutex_unlock(ap);
+ /* It didn't work: return to ready */
+ if (!ap->submount)
+ alarm_add(ap, ap->exp_runfreq);
return 0;
}
ap->readmap_thread = thid;
diff --git a/include/automount.h b/include/automount.h
index 92da8f9..6c866dc 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -160,8 +160,10 @@ struct mapent {
void cache_lock_cleanup(void *arg);
void cache_readlock(struct mapent_cache *mc);
void cache_writelock(struct mapent_cache *mc);
+int cache_try_writelock(struct mapent_cache *mc);
void cache_unlock(struct mapent_cache *mc);
struct mapent_cache *cache_init(struct map_source *map);
+struct mapent_cache *cache_init_null_cache(struct master *master);
int cache_set_ino_index(struct mapent_cache *mc, const char *key, dev_t dev, ino_t ino);
/* void cache_set_ino(struct mapent *me, dev_t dev, ino_t ino); */
struct mapent *cache_lookup_ino(struct mapent_cache *mc, dev_t dev, ino_t ino);
@@ -181,6 +183,7 @@ void cache_multi_lock(struct mapent *me)
void cache_multi_unlock(struct mapent *me);
int cache_delete_offset_list(struct mapent_cache *mc, const char *key);
void cache_release(struct map_source *map);
+void cache_release_null_cache(struct master *master);
struct mapent *cache_enumerate(struct mapent_cache *mc, struct mapent *me);
char *cache_get_offset(const char *prefix, char *offset, int start, struct list_head *head, struct list_head **pos);
diff --git a/include/master.h b/include/master.h
index f1f675c..96dfbd2 100644
--- a/include/master.h
+++ b/include/master.h
@@ -28,6 +28,7 @@ struct map_source {
char *type;
char *format;
time_t age;
+ unsigned int master_line;
struct mapent_cache *mc;
unsigned int stale;
unsigned int recurse;
@@ -43,10 +44,10 @@ struct master_mapent {
char *path;
pthread_t thid;
time_t age;
+ struct master *master;
pthread_rwlock_t source_lock;
pthread_mutex_t current_mutex;
pthread_cond_t current_cond;
- struct map_source *first;
struct map_source *current;
struct map_source *maps;
struct autofs_point *ap;
@@ -61,6 +62,7 @@ struct master {
unsigned int default_ghost;
unsigned int default_logging;
unsigned int default_timeout;
+ struct mapent_cache *nc;
struct list_head mounts;
};
@@ -91,7 +93,7 @@ void master_source_lock_cleanup(void *);
void master_source_current_wait(struct master_mapent *);
void master_source_current_signal(struct master_mapent *);
struct master_mapent *master_find_mapent(struct master *, const char *);
-struct master_mapent *master_new_mapent(const char *, time_t);
+struct master_mapent *master_new_mapent(struct master *, const char *, time_t);
void master_add_mapent(struct master *, struct master_mapent *);
void master_remove_mapent(struct master_mapent *);
void master_free_mapent_sources(struct master_mapent *, unsigned int);
diff --git a/lib/cache.c b/lib/cache.c
index fde050d..9bb692e 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -79,6 +79,18 @@ void cache_writelock(struct mapent_cache
return;
}
+int cache_try_writelock(struct mapent_cache *mc)
+{
+ int status;
+
+ status = pthread_rwlock_trywrlock(&mc->rwlock);
+ if (status) {
+ debug(LOGOPT_ANY, "mapent cache rwlock busy");
+ return 0;
+ }
+ return 1;
+}
+
void cache_unlock(struct mapent_cache *mc)
{
int status;
@@ -200,6 +212,54 @@ struct mapent_cache *cache_init(struct m
return mc;
}
+struct mapent_cache *cache_init_null_cache(struct master *master)
+{
+ struct mapent_cache *mc;
+ unsigned int i;
+ int status;
+
+ if (master->nc)
+ cache_release_null_cache(master);
+
+ mc = malloc(sizeof(struct mapent_cache));
+ if (!mc)
+ return NULL;
+
+ mc->size = HASHSIZE;
+
+ mc->hash = malloc(mc->size * sizeof(struct entry *));
+ if (!mc->hash) {
+ free(mc);
+ return NULL;
+ }
+
+ mc->ino_index = malloc(mc->size * sizeof(struct list_head));
+ if (!mc->ino_index) {
+ free(mc->hash);
+ free(mc);
+ return NULL;
+ }
+
+ status = pthread_mutex_init(&mc->ino_index_mutex, NULL);
+ if (status)
+ fatal(status);
+
+ status = pthread_rwlock_init(&mc->rwlock, NULL);
+ if (status)
+ fatal(status);
+
+ cache_writelock(mc);
+
+ for (i = 0; i < mc->size; i++) {
+ mc->hash[i] = NULL;
+ INIT_LIST_HEAD(&mc->ino_index[i]);
+ }
+
+ cache_unlock(mc);
+
+ return mc;
+}
+
static unsigned int hash(const char *key)
{
unsigned long hashval;
@@ -834,6 +894,53 @@ void cache_release(struct map_source *ma
free(mc);
}
+void cache_release_null_cache(struct master *master)
+{
+ struct mapent_cache *mc;
+ struct mapent *me, *next;
+ int status;
+ unsigned int i;
+
+ mc = master->nc;
+
+ cache_writelock(mc);
+
+ for (i = 0; i < mc->size; i++) {
+ me = mc->hash[i];
+ if (me == NULL)
+ continue;
+ next = me->next;
+ free(me->key);
+ if (me->mapent)
+ free(me->mapent);
+ free(me);
+
+ while (next != NULL) {
+ me = next;
+ next = me->next;
+ free(me->key);
+ free(me);
+ }
+ }
+
+ master->nc = NULL;
+
+ cache_unlock(mc);
+
+ status = pthread_mutex_destroy(&mc->ino_index_mutex);
+ if (status)
+ fatal(status);
+
+ status = pthread_rwlock_destroy(&mc->rwlock);
+ if (status)
+ fatal(status);
+
+ free(mc->hash);
+ free(mc->ino_index);
+ free(mc);
+}
+
+
/* cache must be read locked by caller */
struct mapent *cache_enumerate(struct mapent_cache *mc, struct mapent *me)
diff --git a/lib/master.c b/lib/master.c
index 1c499d6..0066f8b 100644
--- a/lib/master.c
+++ b/lib/master.c
@@ -190,10 +190,9 @@ master_add_map_source(struct master_mape
master_source_writelock(entry);
- if (!entry->maps) {
+ if (!entry->maps)
entry->maps = source;
- entry->first = source;
- } else {
+ else {
struct map_source *this, *last, *next;
/* Typically there only a few map sources */
@@ -259,7 +258,7 @@ __master_find_map_source(struct master_m
struct map_source *source = NULL;
int res;
- map = entry->first;
+ map = entry->maps;
while (map) {
res = compare_source_type_and_format(map, type, format);
if (!res)
@@ -417,6 +416,7 @@ master_add_source_instance(struct map_so
}
new->age = age;
+ new->master_line = 0;
new->mc = source->mc;
tmpargv = copy_argv(source->argc, source->argv);
@@ -565,7 +565,7 @@ struct master_mapent *master_find_mapent
return NULL;
}
-struct master_mapent *master_new_mapent(const char *path, time_t age)
+struct master_mapent *master_new_mapent(struct master *master, const char *path, time_t age)
{
struct master_mapent *entry;
int status;
@@ -586,7 +586,7 @@ struct master_mapent *master_new_mapent(
entry->thid = 0;
entry->age = age;
- entry->first = NULL;
+ entry->master = master;
entry->current = NULL;
entry->maps = NULL;
entry->ap = NULL;
@@ -642,7 +642,6 @@ void master_free_mapent_sources(struct m
m = n;
}
entry->maps = NULL;
- entry->first = NULL;
}
master_source_unlock(entry);
@@ -690,10 +689,13 @@ struct master *master_new(const char *na
else
tmp = strdup(name);
- if (!tmp)
+ if (!tmp) {
+ free(master);
return NULL;
+ }
master->name = tmp;
+ master->nc = NULL;
master->recurse = 0;
master->depth = 0;
@@ -709,6 +711,18 @@ struct master *master_new(const char *na
int master_read_master(struct master *master, time_t age, int readall)
{
+ struct mapent_cache *nc;
+
+ nc = cache_init_null_cache(master);
+ if (!nc) {
+ error(LOGOPT_ANY,
+ "failed to init null map cache for %s", master->name);
+ return 0;
+ }
+ master->nc = nc;
+
+ master_init_scan();
+
if (!lookup_nss_read_master(master, age)) {
error(LOGOPT_ANY,
"can't read master map %s", master->name);
@@ -1013,30 +1027,28 @@ static void check_update_map_sources(str
struct mapent *me;
cache_readlock(source->mc);
me = cache_lookup_first(source->mc);
- cache_unlock(source->mc);
if (!me) {
struct map_source *next = source->next;
+ cache_unlock(source->mc);
+
if (!last)
entry->maps = next;
else
last->next = next;
- if (entry->first == source)
- entry->first = next;
+ if (entry->maps == source)
+ entry->maps = next;
master_free_map_source(source, 1);
source = next;
continue;
- }
- } else if (source->type) {
- if (!strcmp(source->type, "null")) {
-/* entry->ap->mc = cache_init(entry->ap); */
- entry->first = source->next;
- readall = 1;
+ } else {
+ source->stale = 1;
map_stale = 1;
}
+ cache_unlock(source->mc);
}
last = source;
source = source->next;
@@ -1062,6 +1074,7 @@ static void check_update_map_sources(str
int master_mount_mounts(struct master *master, time_t age, int readall)
{
+ struct mapent_cache *nc = master->nc;
struct list_head *p, *head;
int cur_state;
@@ -1073,6 +1086,7 @@ int master_mount_mounts(struct master *m
while (p != head) {
struct master_mapent *this;
struct autofs_point *ap;
+ struct mapent *ne, *nested;
struct stat st;
int state_pipe, save_errno;
int ret;
@@ -1088,6 +1102,24 @@ int master_mount_mounts(struct master *m
continue;
}
+ cache_readlock(nc);
+ ne = cache_lookup_distinct(nc, this->path);
+ if (ne && this->age > ne->age) {
+ cache_unlock(nc);
+ shutdown_entry(this);
+ continue;
+ }
+ nested = cache_partial_match(nc, this->path);
+ if (nested) {
+ error(ap->logopt,
+ "removing invalid nested null entry %s",
+ nested->key);
+ nested = cache_partial_match(nc, this->path);
+ if (nested)
+ cache_delete(nc, nested->key);
+ }
+ cache_unlock(nc);
+
check_update_map_sources(this, readall);
state_mutex_lock(ap);
@@ -1134,6 +1166,7 @@ int master_kill(struct master *master)
if (master->name)
free(master->name);
+ cache_release_null_cache(master);
free(master);
return 1;
diff --git a/lib/master_parse.y b/lib/master_parse.y
index 3250d39..e0af295 100644
--- a/lib/master_parse.y
+++ b/lib/master_parse.y
@@ -510,6 +510,7 @@ void master_init_scan(void)
int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigned int logging, time_t age)
{
struct master *master = master_list;
+ struct mapent_cache *nc;
struct master_mapent *entry, *new;
struct map_source *source;
unsigned int logopt = logging;
@@ -527,6 +528,26 @@ int master_parse_entry(const char *buffe
return 0;
}
+ nc = master->nc;
+
+ /* Add null map entries to the null map cache */
+ if (type && !strcmp(type, "null")) {
+ cache_writelock(nc);
+ cache_update(nc, path, NULL, lineno);
+ cache_unlock(nc);
+ local_free_vars();
+ return 1;
+ }
+
+ /* Ignore all subsequent matching nulled entries */
+ cache_readlock(nc);
+ if (cache_lookup_distinct(nc, path)) {
+ cache_unlock(nc);
+ local_free_vars();
+ return 1;
+ }
+ cache_unlock(nc);
+
if (debug || verbose) {
logopt = (debug ? LOGOPT_DEBUG : 0);
logopt |= (verbose ? LOGOPT_VERBOSE : 0);
@@ -538,7 +559,7 @@ int master_parse_entry(const char *buffe
new = NULL;
entry = master_find_mapent(master, path);
if (!entry) {
- new = master_new_mapent(path, age);
+ new = master_new_mapent(master, path, age);
if (!new) {
local_free_vars();
return 0;
@@ -604,9 +625,9 @@ int master_parse_entry(const char *buffe
return 0;
}
}
+ source->master_line = lineno;
entry->age = age;
- entry->first = entry->maps;
entry->current = NULL;
if (new)
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index a0e22d2..051e5b5 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -402,7 +402,6 @@ int lookup_read_master(struct master *ma
fcntl(fd, F_SETFD, cl_flags);
}
- master_init_scan();
while(1) {
entry = read_one(f, path, &path_len, ent, &ent_len);
if (!entry) {
@@ -516,6 +515,7 @@ static int check_self_include(const char
static struct autofs_point *
prepare_plus_include(struct autofs_point *ap, time_t age, char *key, unsigned int inc)
{
+ struct master *master;
struct master_mapent *entry;
struct map_source *current;
struct map_source *source;
@@ -532,7 +532,9 @@ prepare_plus_include(struct autofs_point
ap->entry->current = NULL;
master_source_current_signal(ap->entry);
- entry = master_new_mapent(ap->path, ap->entry->age);
+ master = ap->entry->master;
+
+ entry = master_new_mapent(master, ap->path, ap->entry->age);
if (!entry) {
error(ap->logopt, MODPREFIX "malloc failed for entry");
return NULL;
diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c
index e901f20..f8d8ed2 100644
--- a/modules/mount_autofs.c
+++ b/modules/mount_autofs.c
@@ -53,6 +53,7 @@ int mount_mount(struct autofs_point *ap,
time_t timeout = ap->exp_timeout;
unsigned logopt = ap->logopt;
char *type, *format, *tmp, *tmp2;
+ struct master *master;
struct master_mapent *entry;
struct map_source *source;
struct autofs_point *nap;
@@ -137,7 +138,9 @@ int mount_mount(struct autofs_point *ap,
MODPREFIX "fullpath=%s what=%s options=%s",
fullpath, what, options);
- entry = master_new_mapent(fullpath, ap->entry->age);
+ master = ap->entry->master;
+
+ entry = master_new_mapent(master, fullpath, ap->entry->age);
if (!entry) {
error(ap->logopt,
MODPREFIX "failed to malloc master_mapent struct");
autofs-5.0.1-rc2-nfs4-get-port.patch:
CHANGELOG | 2
include/replicated.h | 2
modules/mount_nfs.c | 2
modules/replicated.c | 120 +++++++++++++++++++++++++++++++++++----------------
4 files changed, 88 insertions(+), 38 deletions(-)
--- NEW FILE autofs-5.0.1-rc2-nfs4-get-port.patch ---
diff --git a/CHANGELOG b/CHANGELOG
index 01822f0..2ffef53 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -41,6 +41,8 @@
- fix parsing of bad mount mount point in master map.
- fix use after free memory access in cache.c and lookup_yp.c.
- eliminate use of pthread_kill to detect task completion.
+- alter nfs4 host probing to not use portmap lookup and add options
+ check for "port=" parameter.
1/9/2006 autofs-5.0.1 rc2
-------------------------
diff --git a/include/replicated.h b/include/replicated.h
index 00cf641..970cd31 100644
--- a/include/replicated.h
+++ b/include/replicated.h
@@ -62,7 +62,7 @@ struct host {
void free_host_list(struct host **);
int parse_location(struct host **, const char *);
-int prune_host_list(struct host **, unsigned int);
+int prune_host_list(struct host **, unsigned int, const char *);
void dump_host_list(struct host *);
#endif
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
index 94c8e8b..e859284 100644
--- a/modules/mount_nfs.c
+++ b/modules/mount_nfs.c
@@ -134,7 +134,7 @@ int mount_mount(struct autofs_point *ap,
warn(ap->logopt, MODPREFIX "no hosts available");
return 1;
}
- prune_host_list(&hosts, vers);
+ prune_host_list(&hosts, vers, nfsoptions);
if (!hosts) {
warn(ap->logopt, MODPREFIX "no hosts available");
diff --git a/modules/replicated.c b/modules/replicated.c
index 9b9a44b..5aaaba1 100644
--- a/modules/replicated.c
+++ b/modules/replicated.c
@@ -329,10 +329,42 @@ void free_host_list(struct host **list)
*list = NULL;
}
+static unsigned short get_port_option(const char *options)
+{
+ const char *start;
+ long port = 0;
+
+ if (!options)
+ return NFS_PORT;
+
+ start = strstr(options, "port=");
+ if (!start)
+ port = NFS_PORT;
+ else {
+ char optport[30], *opteq, *end;
+ int len;
+
+ end = strchr(start, ',');
+ len = end ? end - start : strlen(start);
+ strncpy(optport, start, len);
+ optport[len] = '\0';
+ opteq = strchr(optport, '=');
+ if (opteq)
+ port = atoi(opteq + 1);
+ }
+
+ if (port < 0)
+ port = 0;
+
+ return (unsigned short) port;
+}
+
static unsigned int get_nfs_info(struct host *host,
struct conn_info *pm_info, struct conn_info *rpc_info,
- const char *proto, unsigned int version)
+ const char *proto, unsigned int version,
+ const char *options)
{
+ char *have_port_opt = options ? strstr(options, "port=") : NULL;
struct pmap parms;
struct timeval start, end;
struct timezone tz;
@@ -349,19 +381,10 @@ static unsigned int get_nfs_info(struct
if (!rpc_info->proto)
return 0;
- status = rpc_portmap_getclient(pm_info,
- host->name, proto, RPC_CLOSE_DEFAULT);
- if (!status)
- return 0;
-
- parms.pm_prot = rpc_info->proto->p_proto;
-
if (!(version & NFS4_REQUESTED))
goto v3_ver;
- parms.pm_vers = NFS4_VERSION;
- rpc_info->port = rpc_portmap_getport(pm_info, &parms);
- if (!rpc_info->port)
+ if (!(rpc_info->port = get_port_option(options)))
goto v3_ver;
if (rpc_info->proto->p_proto == IPPROTO_UDP)
@@ -380,13 +403,26 @@ static unsigned int get_nfs_info(struct
}
v3_ver:
+ if (!have_port_opt) {
+ status = rpc_portmap_getclient(pm_info,
+ host->name, proto, RPC_CLOSE_DEFAULT);
+ if (!status)
+ goto done_ver;
+ }
+
if (!(version & NFS3_REQUESTED))
goto v2_ver;
- parms.pm_vers = NFS3_VERSION;
- rpc_info->port = rpc_portmap_getport(pm_info, &parms);
- if (!rpc_info->port)
- goto v2_ver;
+ if (have_port_opt) {
+ if (!(rpc_info->port = get_port_option(options)))
+ goto done_ver;
+ } else {
+ parms.pm_prot = rpc_info->proto->p_proto;
+ parms.pm_vers = NFS3_VERSION;
+ rpc_info->port = rpc_portmap_getport(pm_info, &parms);
+ if (!rpc_info->port)
+ goto v2_ver;
+ }
if (rpc_info->proto->p_proto == IPPROTO_UDP)
status = rpc_udp_getclient(rpc_info, NFS_PROGRAM, NFS3_VERSION);
@@ -407,10 +443,16 @@ v2_ver:
if (!(version & NFS2_REQUESTED))
goto done_ver;
- parms.pm_vers = NFS2_VERSION;
- rpc_info->port = rpc_portmap_getport(pm_info, &parms);
- if (!rpc_info->port)
- goto done_ver;
+ if (have_port_opt) {
+ if (!(rpc_info->port = get_port_option(options)))
+ goto done_ver;
+ } else {
+ parms.pm_prot = rpc_info->proto->p_proto;
+ parms.pm_vers = NFS2_VERSION;
+ rpc_info->port = rpc_portmap_getport(pm_info, &parms);
+ if (!rpc_info->port)
+ goto done_ver;
+ }
if (rpc_info->proto->p_proto == IPPROTO_UDP)
status = rpc_udp_getclient(rpc_info, NFS_PROGRAM, NFS2_VERSION);
@@ -451,7 +493,7 @@ done_ver:
return supported;
}
-static int get_vers_and_cost(struct host *host, unsigned int version)
+static int get_vers_and_cost(struct host *host, unsigned int version, const char *options)
{
struct conn_info pm_info, rpc_info;
time_t timeout = RPC_TIMEOUT;
@@ -475,7 +517,7 @@ static int get_vers_and_cost(struct host
vers &= version;
if (version & UDP_REQUESTED) {
- supported = get_nfs_info(host, &pm_info, &rpc_info, "udp", vers);
+ supported = get_nfs_info(host, &pm_info, &rpc_info, "udp", vers, options);
if (supported) {
ret = 1;
host->version |= (supported << 8);
@@ -483,7 +525,7 @@ static int get_vers_and_cost(struct host
}
if (version & TCP_REQUESTED) {
- supported = get_nfs_info(host, &pm_info, &rpc_info, "tcp", vers);
+ supported = get_nfs_info(host, &pm_info, &rpc_info, "tcp", vers, options);
if (supported) {
ret = 1;
host->version |= supported;
@@ -493,8 +535,9 @@ static int get_vers_and_cost(struct host
return ret;
}
-static int get_supported_ver_and_cost(struct host *host, unsigned int version)
+static int get_supported_ver_and_cost(struct host *host, unsigned int version, const char *options)
{
+ char *have_port_opt = options ? strstr(options, "port=") : NULL;
struct conn_info pm_info, rpc_info;
struct pmap parms;
const char *proto;
@@ -534,18 +577,23 @@ static int get_supported_ver_and_cost(st
if (!rpc_info.proto)
return 0;
- status = rpc_portmap_getclient(&pm_info,
- host->name, proto, RPC_CLOSE_DEFAULT);
- if (!status)
- return 0;
-
- parms.pm_prot = rpc_info.proto->p_proto;
-
status = 0;
+
parms.pm_vers = vers;
- rpc_info.port = rpc_portmap_getport(&pm_info, &parms);
- if (!rpc_info.port)
- goto done;
+ if (have_port_opt || (vers & NFS4_VERSION)) {
+ if (!(rpc_info.port = get_port_option(options)))
+ return 0;
+ } else {
+ int ret = rpc_portmap_getclient(&pm_info,
+ host->name, proto, RPC_CLOSE_DEFAULT);
+ if (!ret)
+ return 0;
+
+ parms.pm_prot = rpc_info.proto->p_proto;
+ rpc_info.port = rpc_portmap_getport(&pm_info, &parms);
+ if (!rpc_info.port)
+ goto done;
+ }
if (rpc_info.proto->p_proto == IPPROTO_UDP)
status = rpc_udp_getclient(&rpc_info, NFS_PROGRAM, parms.pm_vers);
@@ -581,7 +629,7 @@ done:
return 0;
}
-int prune_host_list(struct host **list, unsigned int vers)
+int prune_host_list(struct host **list, unsigned int vers, const char *options)
{
struct host *this, *last, *first;
struct host *new = NULL;
@@ -604,7 +652,7 @@ int prune_host_list(struct host **list,
struct host *next = this->next;
if (this->name) {
- status = get_vers_and_cost(this, vers);
+ status = get_vers_and_cost(this, vers, options);
if (!status) {
if (this == first) {
first = next;
@@ -695,7 +743,7 @@ int prune_host_list(struct host **list,
if (!this->name)
add_host(&new, this);
else {
- status = get_supported_ver_and_cost(this, selected_version);
+ status = get_supported_ver_and_cost(this, selected_version, options);
if (status) {
this->version = selected_version;
remove_host(list, this);
Index: autofs.spec
===================================================================
RCS file: /cvs/dist/rpms/autofs/FC-6/autofs.spec,v
retrieving revision 1.157
retrieving revision 1.158
diff -u -r1.157 -r1.158
--- autofs.spec 25 Nov 2006 08:52:53 -0000 1.157
+++ autofs.spec 6 Dec 2006 06:27:05 -0000 1.158
@@ -4,7 +4,7 @@
Summary: A tool for automatically mounting and unmounting filesystems.
Name: autofs
%define version 5.0.1
-%define release 0.rc2.25
+%define release 0.rc2.28
Version: %{version}
Release: %{release}
Epoch: 1
@@ -50,6 +50,8 @@
Patch36: autofs-5.0.1-rc2-parse-bad-master-map-mountpoint.patch
Patch37: autofs-5.0.1-rc2-fix-use-after-free.patch
Patch38: autofs-5.0.1-rc2-use-task-done.patch
+Patch39: autofs-5.0.1-rc2-nfs4-get-port.patch
+Patch40: autofs-5.0.1-rc2-fix-null-map-semantics.patch
Buildroot: /var/tmp/autofs-tmp
BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, libxml2-devel, cyrus-sasl-devel, openssl-devel
Prereq: chkconfig
@@ -128,6 +130,8 @@
%patch36 -p1
%patch37 -p1
%patch38 -p1
+%patch39 -p1
+%patch40 -p1
%build
#CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir}
@@ -184,6 +188,11 @@
%{_libdir}/autofs/*
%changelog
+* Wed Dec 6 2006 Ian Kent <ikent at redhat.com> - 5.0.1-0.rc2.28
+- alter nfs4 host probing to not use portmap lookup and add options
+ check for "port=" parameter (bz 208757).
+- correct semantics of "-null" map handling (bzs 214800, 208091).
+
* Sat Nov 25 2006 Ian Kent <ikent at redhat.com> - 5.0.1-0.rc2.25
- fix parsing of bad mount mount point in master map (bz 215620).
- fix use after free memory access in cache.c and lookup_yp.c (bz 208091).
- Previous message (by thread): rpms/autofs/devel autofs-5.0.1-rc2-nfs4-get-port.patch, NONE, 1.1 autofs.spec, 1.164, 1.165
- Next message (by thread): rpms/fonts-indic/devel .cvsignore, 1.12, 1.13 fonts-indic.spec, 1.17, 1.18 sources, 1.15, 1.16
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the fedora-cvs-commits
mailing list