rpms/autofs/devel autofs-5.0.1-rc1-cthon-expire-nested.patch, NONE, 1.1 autofs.spec, 1.132, 1.133
fedora-cvs-commits at redhat.com
fedora-cvs-commits at redhat.com
Thu Jul 27 08:41:46 UTC 2006
Author: ikent
Update of /cvs/dist/rpms/autofs/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv22178
Modified Files:
autofs.spec
Added Files:
autofs-5.0.1-rc1-cthon-expire-nested.patch
Log Message:
* Thu Jul 27 2006 Ian Kent <ikent at redhat.com> - 5.0.1-0.rc1.7
- cthon fix expire of various forms of nested mounts.
autofs-5.0.1-rc1-cthon-expire-nested.patch:
CHANGELOG | 1
daemon/automount.c | 75 ++++++++++++++++++-------------------------------
daemon/direct.c | 46 +++++++++++++++++++-----------
daemon/indirect.c | 69 ++++++++++++++++++++++-----------------------
daemon/lookup.c | 68 ++++++++++++++++++++++++++++++++++++++++----
daemon/state.c | 21 +++----------
include/automount.h | 10 +++---
include/master.h | 6 +++
include/state.h | 28 ++++++++++++++++++
lib/master.c | 28 ++++++++++++++----
lib/mounts.c | 26 +++++++++++++---
modules/mount_autofs.c | 2 -
modules/parse_sun.c | 38 +++++++++++++++---------
13 files changed, 268 insertions(+), 150 deletions(-)
--- NEW FILE autofs-5.0.1-rc1-cthon-expire-nested.patch ---
diff --git a/CHANGELOG b/CHANGELOG
index 111c6af..f68e16e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -12,6 +12,7 @@
- cthon fix submount operation broken by above.
- cthon more parser corrections and attempt to fix multi-mounts
with various combinations of submounts (still broken).
+- cthon fix expire of various forms of nested mounts.
13/7/2006 autofs-5.0.1 rc1
--------------------------
diff --git a/daemon/automount.c b/daemon/automount.c
index 8fcf19a..91f4d15 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -550,21 +550,35 @@ int umount_multi(struct autofs_point *ap
left = 0;
list_for_each(p, &list) {
+ struct autofs_point *oap = ap;
+ char *has_opt_direct;
+ int is_autofs;
+
mptr = list_entry(p, struct mnt_list, list);
- /* We only want real mounts */
- if (!strcmp(mptr->fs_type, "autofs"))
+ is_autofs = !strcmp(mptr->fs_type, "autofs");
+ has_opt_direct = strstr(mptr->opts, "direct");
+
+ /* We only want real mounts and top level direct mounts */
+ if (is_autofs && !has_opt_direct)
continue;
+ if (ap->submount)
+ oap = ap->parent;
+
sched_yield();
- if (umount_offsets(ap, mnts, mptr->path))
- warn(ap->logopt, "could not umount some offsets under %s",
- mptr->path);
+ if (umount_offsets(oap, mnts, mptr->path))
+ warn(ap->logopt,
+ "could not umount some offsets under %s",
+ mptr->path);
+
+ if (is_autofs)
+ continue;
sched_yield();
- debug(ap->logopt, "unmounting dir = %s", mptr->path);
+ warn(ap->logopt, "unmounting dir = %s", mptr->path);
if (umount_ent(ap, mptr->path, mptr->fs_type)) {
warn(ap->logopt, "could not umount dir %s",
@@ -573,49 +587,16 @@ int umount_multi(struct autofs_point *ap
}
}
- /* Lastly check for offsets with no root mount */
- n = scandir(path, &de, 0, alphasort);
- if (n && n != -1) {
- char buf[PATH_MAX + 1];
-
- while (n--) {
- size_t size;
- int ret;
+ /* Catch any offsets of indirect mounts with no root mount */
+ if (!left && !tree_is_mounted(mnts, path, MNTS_ALL)) {
+ struct autofs_point *rap = ap;
- sched_yield();
+ if (ap->submount)
+ rap = ap->parent;
- if (strcmp(de[n]->d_name, ".") == 0 ||
- strcmp(de[n]->d_name, "..") == 0) {
- free(de[n]);
- continue;
- }
-
- size = sizeof(buf);
- ret = cat_path(buf, size, path, de[n]->d_name);
- if (!ret) {
- do {
- free(de[n]);
- } while (n--);
- left++;
- break;
- }
-
- if (umount_offsets(ap, mnts, buf)) {
- warn(ap->logopt,
- "could not umount some offsets under %s",
- buf);
- left++;
- }
- free(de[n]);
- }
- free(de);
- }
-
- if (!left && !tree_is_mounted(mnts, path)) {
- sched_yield();
- if (umount_offsets(ap, mnts, path)) {
+ if (umount_offsets(rap, mnts, path)) {
warn(ap->logopt,
- "could not umount some offsets under %s", path);
+ "could not umount some offsets under %s", path);
left++;
}
}
@@ -1229,7 +1210,7 @@ static void handle_mounts_cleanup(void *
umount_autofs(ap, 1);
if (submount)
- master_signal_submount(ap);
+ master_signal_submount(ap, MASTER_SUBMNT_JOIN);
else
master_remove_mapent(ap->entry);
master_free_mapent_sources(ap->entry, 1);
diff --git a/daemon/direct.c b/daemon/direct.c
index 89c8db2..f4f60f3 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -125,6 +125,24 @@ int do_umount_autofs_direct(struct autof
me->ioctlfd = open(me->key, O_RDONLY);
if (me->ioctlfd >= 0) {
+ int status = 1;
+
+ rv = ioctl(me->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &status);
+ if (rv) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ error(ap->logopt, "ioctl failed: %s", estr);
+ return 1;
+ } else if (!status) {
+ if (ap->state != ST_SHUTDOWN_FORCE) {
+ debug(ap->logopt, "ask umount returned busy");
+ return 1;
+ } else {
+ ioctl(me->ioctlfd, AUTOFS_IOC_CATATONIC, 0);
+ close(me->ioctlfd);
+ me->ioctlfd = -1;
+ goto force_umount;
+ }
+ }
ioctl(me->ioctlfd, AUTOFS_IOC_CATATONIC, 0);
close(me->ioctlfd);
me->ioctlfd = -1;
@@ -136,7 +154,7 @@ int do_umount_autofs_direct(struct autof
}
rv = umount(me->key);
- if (rv != 0) {
+ if (rv == -1) {
switch (errno) {
case ENOENT:
case EINVAL:
@@ -468,8 +486,12 @@ int umount_autofs_offset(struct autofs_p
if (me->ioctlfd >= 0) {
int status = 1;
- ioctl(me->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &status);
- if (!status) {
+ rv = ioctl(me->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &status);
+ if (rv) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ error(ap->logopt, "ioctl failed: %s", estr);
+ return 1;
+ } else if (!status) {
if (ap->state != ST_SHUTDOWN_FORCE) {
debug(ap->logopt, "ask umount returned busy");
return 1;
@@ -517,15 +539,7 @@ force_umount:
rv = umount2(me->key, MNT_DETACH);
} else
msg("umounted offset %s", me->key);
-/*
- if (!rv && me->dir_created) {
- if (rmdir(me->key) == -1) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- warn(ap->logopt,
- "failed to remove dir %s: %s", me->key, estr);
- }
- }
-*/
+
return rv;
}
@@ -800,25 +814,25 @@ static void kernel_callback_cleanup(void
mc = mt->mc;
if (mt->status) {
+ cache_writelock(mc);
send_ready(mt->ioctlfd, mt->wait_queue_token);
if (mt->type == NFY_EXPIRE) {
close(mt->ioctlfd);
- cache_writelock(mc);
me = cache_lookup_distinct(mc, mt->name);
if (me)
me->ioctlfd = -1;
- cache_unlock(mc);
}
+ cache_unlock(mc);
} else {
+ cache_writelock(mc);
send_fail(mt->ioctlfd, mt->wait_queue_token);
if (mt->type == NFY_MOUNT) {
close(mt->ioctlfd);
- cache_writelock(mc);
me = cache_lookup_distinct(mc, mt->name);
if (me)
me->ioctlfd = -1;
- cache_unlock(mc);
}
+ cache_unlock(mc);
}
free(mt);
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 7bde7ec..737d965 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -289,40 +289,24 @@ int umount_autofs_indirect(struct autofs
* to do it here. If the cache entry isn't found then there aren't
* any offset mounts.
*/
- if (ap->submount) {
- struct master_mapent *entry = ap->parent->entry;
- struct map_source *map;
- struct mapent_cache *mc;
- struct mapent *me;
-
- pthread_cleanup_push(master_source_lock_cleanup, entry);
- master_source_readlock(entry);
- map = entry->first;
- while (map) {
- mc = map->mc;
- cache_readlock(mc);
- me = cache_lookup_distinct(mc, ap->path);
- if (me) {
- close(me->ioctlfd);
- me->ioctlfd = -1;
- cache_unlock(mc);
- break;
- }
- cache_unlock(mc);
- map = map->next;
- }
- pthread_cleanup_pop(1);
- }
+ if (ap->submount)
+ lookup_source_close_ioctlfd(ap->parent, ap->path);
/* If we are trying to shutdown make sure we can umount */
- if (!ioctl(ap->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &ret)) {
- if (!ret)
- warn(ap->logopt, "mount still busy %s", ap->path);
+ rv = ioctl(ap->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &ret);
+ if (rv) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ error(ap->logopt, "ioctl failed: %s", estr);
+ return 1;
+ } else if (!ret) {
+ error(ap->logopt, "ask umount returned busy %s", ap->path);
+ busy = 1;
}
if (ap->ioctlfd >= 0) {
ioctl(ap->ioctlfd, AUTOFS_IOC_CATATONIC, 0);
close(ap->ioctlfd);
+ ap->ioctlfd = -1;
close(ap->state_pipe[0]);
close(ap->state_pipe[1]);
ap->state_pipe[0] = -1;
@@ -340,12 +324,12 @@ int umount_autofs_indirect(struct autofs
switch (errno) {
case ENOENT:
case EINVAL:
- warn(ap->logopt,
+ error(ap->logopt,
"mount point %s does not exist", ap->path);
return 0;
break;
case EBUSY:
- warn(ap->logopt,
+ error(ap->logopt,
"mount point %s is in use", ap->path);
if (ap->state == ST_SHUTDOWN_FORCE)
goto force_umount;
@@ -385,6 +369,7 @@ void *expire_proc_indirect(void *arg)
int offsets, submnts, count;
int ioctlfd;
int status, ret;
+ char buf[MAX_ERR_BUF];
ea = (struct expire_args *) arg;
@@ -470,8 +455,9 @@ void *expire_proc_indirect(void *arg)
ret = ioctl(ioctlfd, AUTOFS_IOC_EXPIRE_MULTI, &now);
if (ret < 0 && errno != EAGAIN) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
warn(ap->logopt,
- "failed to expire mount %s", next->path);
+ "failed to expire mount %s:", next->path, estr);
ea->status = 1;
break;
}
@@ -479,7 +465,7 @@ void *expire_proc_indirect(void *arg)
free_mnt_list(mnts);
count = offsets = submnts = 0;
- mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 0);
+ mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 1);
/* Are there any real mounts left */
for (next = mnts; next; next = next->next) {
if (strcmp(next->fs_type, "autofs"))
@@ -497,10 +483,10 @@ void *expire_proc_indirect(void *arg)
* have some offset mounts with no '/' offset so we need to
* umount them here.
*/
- if (mnts && !ea->status && !count) {
- int ret;
+ if (mnts) {
+ int ret, tries = (count + submnts + offsets + 2) * 2;
- while (offsets--) {
+ while (tries--) {
ret = ioctl(ap->ioctlfd, AUTOFS_IOC_EXPIRE_MULTI, &now);
if (ret < 0 && errno != EAGAIN) {
warn(ap->logopt,
@@ -513,6 +499,21 @@ void *expire_proc_indirect(void *arg)
}
free_mnt_list(mnts);
+ count = offsets = submnts = 0;
+ mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 0);
+ /* Are there any real mounts left */
+ for (next = mnts; next; next = next->next) {
+ if (strcmp(next->fs_type, "autofs"))
+ count++;
+ else {
+ if (strstr(next->opts, "indirect"))
+ submnts++;
+ else
+ offsets++;
+ }
+ }
+ free_mnt_list(mnts);
+
if (submnts) {
debug(ap->logopt,
"%d submounts remaining in %s", submnts, ap->path);
diff --git a/daemon/lookup.c b/daemon/lookup.c
index f0f9718..a8ef518 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -395,6 +395,7 @@ int lookup_nss_read_map(struct autofs_po
struct list_head *head, *p;
struct nss_source *this;
struct map_source *map;
+ enum nsswitch_status status;
int result = 0;
/*
@@ -445,17 +446,16 @@ int lookup_nss_read_map(struct autofs_po
INIT_LIST_HEAD(&nsslist);
- result = nsswitch_parse(&nsslist);
- if (result) {
+ status = nsswitch_parse(&nsslist);
+ if (status) {
error(ap->logopt,
"can't to read name service switch config.");
+ result = 1;
break;
}
head = &nsslist;
list_for_each(p, head) {
- int status;
-
this = list_entry(p, struct nss_source, list);
debug(ap->logopt,
@@ -721,6 +721,7 @@ int lookup_nss_mount(struct autofs_point
struct list_head *head, *p;
struct nss_source *this;
struct map_source *map;
+ enum nsswitch_status status;
int result = 0;
/*
@@ -775,8 +776,8 @@ int lookup_nss_mount(struct autofs_point
INIT_LIST_HEAD(&nsslist);
- result = nsswitch_parse(&nsslist);
- if (result) {
+ status = nsswitch_parse(&nsslist);
+ if (status) {
error(ap->logopt,
"can't to read name service switch config.");
result = 1;
@@ -961,3 +962,58 @@ next:
return 1;
}
+/* Return with cache readlock held */
+struct mapent *lookup_source_mapent(struct autofs_point *ap, const char *key)
+{
+ struct master_mapent *entry = ap->entry;
+ struct map_source *map;
+ struct mapent_cache *mc;
+ struct mapent *me;
+
+ pthread_cleanup_push(master_source_lock_cleanup, entry);
+ master_source_readlock(entry);
+ map = entry->first;
+ while (map) {
+ mc = map->mc;
+ cache_readlock(mc);
+ me = cache_lookup_distinct(mc, key);
+ if (me)
+ break;
+ cache_unlock(mc);
+ map = map->next;
+ }
+ pthread_cleanup_pop(1);
+
+ return me;
+}
+
+int lookup_source_close_ioctlfd(struct autofs_point *ap, const char *key)
+{
+ struct master_mapent *entry = ap->entry;
+ struct map_source *map;
+ struct mapent_cache *mc;
+ struct mapent *me;
+ int ret = 0;
+
+ pthread_cleanup_push(master_source_lock_cleanup, entry);
+ master_source_readlock(entry);
+ map = entry->first;
+ while (map) {
+ mc = map->mc;
+ cache_readlock(mc);
+ me = cache_lookup_distinct(mc, key);
+ if (me) {
+ close(me->ioctlfd);
+ me->ioctlfd = -1;
+ cache_unlock(mc);
+ ret = 1;
+ break;
+ }
+ cache_unlock(mc);
+ map = map->next;
+ }
+ pthread_cleanup_pop(1);
+
+ return ret;
+}
+
diff --git a/daemon/state.c b/daemon/state.c
index e74674a..caeb3e3 100644
--- a/daemon/state.c
+++ b/daemon/state.c
@@ -103,7 +103,6 @@ void expire_cleanup(void *arg)
/* Check to see if expire process finished */
if (thid == ap->exp_thread) {
ap->exp_thread = 0;
- st_set_thid(ap, 0);
switch (ap->state) {
case ST_EXPIRE:
@@ -174,7 +173,7 @@ static unsigned int st_ready(struct auto
ap->state = ST_READY;
if (ap->submount)
- master_signal_submount(ap);
+ master_signal_submount(ap, MASTER_SUBMNT_CONTINUE);
return 1;
}
@@ -362,7 +361,7 @@ static void *do_readmap(void *arg)
while (me) {
/* TODO: check return of do_... */
if (me->age < now) {
- if (!tree_is_mounted(mnts, me->key))
+ if (!tree_is_mounted(mnts, me->key, MNTS_REAL))
do_umount_autofs_direct(ap, mnts, me);
else
debug(ap->logopt,
@@ -586,18 +585,14 @@ int st_add_task(struct autofs_point *ap,
state_mutex_unlock(ap);
- status = pthread_mutex_lock(&mutex);
- if (status)
- fatal(status);
+ st_mutex_lock();
signaled = 1;
status = pthread_cond_signal(&cond);
if (status)
fatal(status);
- status = pthread_mutex_unlock(&mutex);
- if (status)
- fatal(status);
+ st_mutex_unlock();
return 1;
}
@@ -620,9 +615,7 @@ int st_add_task(struct autofs_point *ap,
INIT_LIST_HEAD(&new->list);
INIT_LIST_HEAD(&new->pending);
- status = pthread_mutex_lock(&mutex);
- if (status)
- fatal(status);
+ st_mutex_lock();
head = &state_queue;
@@ -648,9 +641,7 @@ int st_add_task(struct autofs_point *ap,
if (status)
fatal(status);
- status = pthread_mutex_unlock(&mutex);
- if (status)
- fatal(status);
+ st_mutex_unlock();
return 1;
}
diff --git a/include/automount.h b/include/automount.h
index a689046..b10cfad 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -224,6 +224,8 @@ int lookup_ghost(struct autofs_point *ap
int lookup_nss_mount(struct autofs_point *ap, const char *name, int name_len);
void lookup_close_lookup(struct autofs_point *ap);
int lookup_prune_cache(struct autofs_point *ap, time_t age);
+struct mapent *lookup_source_mapent(struct autofs_point *ap, const char *key);
+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);
@@ -313,9 +315,9 @@ int ncat_path(char *buf, size_t len,
/* mount table utilities */
-#define MNTS_ALL 0x0000
-#define MNTS_REAL 0x0001
-#define MNTS_AUTOFS 0x0002
+#define MNTS_ALL 0x0001
+#define MNTS_REAL 0x0002
+#define MNTS_AUTOFS 0x0004
struct mnt_list {
char *path;
@@ -356,7 +358,7 @@ void tree_free_mnt_tree(struct mnt_list
struct mnt_list *tree_make_mnt_tree(const char *table, const char *path);
int tree_get_mnt_list(struct mnt_list *mnts, struct list_head *list, const char *path, int include);
int tree_find_mnt_ents(struct mnt_list *mnts, struct list_head *list, const char *path);
-int tree_is_mounted(struct mnt_list *mnts, const char *path);
+int tree_is_mounted(struct mnt_list *mnts, const char *path, unsigned int type);
/* Core automount definitions */
diff --git a/include/master.h b/include/master.h
index 57760a6..ada18d4 100644
--- a/include/master.h
+++ b/include/master.h
@@ -20,6 +20,10 @@
#ifndef MASTER_H
#define MASTER_H
+#define MASTER_SUBMNT_WAIT 0
+#define MASTER_SUBMNT_CONTINUE 1
+#define MASTER_SUBMNT_JOIN 2
+
struct map_source {
char *type;
char *format;
@@ -94,7 +98,7 @@ void master_free_mapent(struct master_ma
struct master *master_new(const char *, unsigned int, unsigned int);
int master_read_master(struct master *, time_t, int);
void master_notify_submounts(struct autofs_point *, enum states);
-void master_signal_submount(struct autofs_point *);
+void master_signal_submount(struct autofs_point *, unsigned int);
void master_notify_state_change(struct master *, int);
int master_mount_mounts(struct master *, time_t, int);
int master_list_empty(struct master *);
diff --git a/include/state.h b/include/state.h
index 69355b0..ea4c62a 100644
--- a/include/state.h
+++ b/include/state.h
@@ -59,6 +59,20 @@ struct expire_args {
int status; /* Return status */
};
+#define expire_args_mutex_lock(ea) \
+do { \
+ int status = pthread_mutex_lock(&ea->mutex); \
+ if (status) \
+ fatal(status); \
+} while (0)
+
+#define expire_args_mutex_unlock(ea) \
+do { \
+ int status = pthread_mutex_unlock(&ea->mutex); \
+ if (status) \
+ fatal(status); \
+} while (0)
+
struct readmap_args {
pthread_mutex_t mutex;
pthread_cond_t cond;
@@ -75,4 +89,18 @@ int st_add_task(struct autofs_point *, e
void st_remove_tasks(struct autofs_point *);
int st_start_handler(void);
+#define st_mutex_lock() \
+do { \
+ int status = pthread_mutex_lock(&mutex); \
+ if (status) \
+ fatal(status); \
+} while (0)
+
+#define st_mutex_unlock() \
+do { \
+ int status = pthread_mutex_unlock(&mutex); \
+ if (status) \
+ fatal(status); \
+} while (0)
+
#endif
diff --git a/lib/master.c b/lib/master.c
index 6bf21ad..d5e58d2 100644
--- a/lib/master.c
+++ b/lib/master.c
@@ -754,15 +754,20 @@ int master_read_master(struct master *ma
static void notify_submounts(struct autofs_point *ap, enum states state)
{
- struct list_head *p;
+ struct list_head *head, *p;
struct autofs_point *this;
+ pthread_t thid;
int status;
mounts_mutex_lock(ap);
- list_for_each(p, &ap->submounts) {
+ head = &ap->submounts;
+ p = head->next;
+ while (p != head) {
this = list_entry(p, struct autofs_point, mounts);
+ p = p->next;
+
if (!list_empty(&this->submounts))
notify_submounts(this, state);
@@ -777,11 +782,19 @@ static void notify_submounts(struct auto
state_mutex_unlock(this);
- ap->mounts_signaled = 0;
- while (!ap->mounts_signaled) {
+ thid = this->thid;
+ ap->mounts_signaled = MASTER_SUBMNT_WAIT;
+ while (ap->mounts_signaled == MASTER_SUBMNT_WAIT) {
status = pthread_cond_wait(&ap->mounts_cond, &ap->mounts_mutex);
if (status)
fatal(status);
+ if (ap->mounts_signaled == MASTER_SUBMNT_JOIN) {
+ mounts_mutex_unlock(ap);
+ status = pthread_join(thid, NULL);
+ if (status)
+ fatal(status);
+ mounts_mutex_lock(ap);
+ }
}
}
@@ -801,7 +814,7 @@ void master_notify_submounts(struct auto
return;
}
-void master_signal_submount(struct autofs_point *ap)
+void master_signal_submount(struct autofs_point *ap, unsigned int join)
{
int status;
@@ -810,7 +823,10 @@ void master_signal_submount(struct autof
mounts_mutex_lock(ap->parent);
- ap->parent->mounts_signaled = 1;
+ if (join)
+ ap->parent->mounts_signaled = 1;
+ else
+ ap->parent->mounts_signaled = 2;
status = pthread_cond_signal(&ap->parent->mounts_cond);
if (status)
fatal(status);
diff --git a/lib/mounts.c b/lib/mounts.c
index dd73f9f..b11c4c7 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -744,7 +744,7 @@ int tree_find_mnt_ents(struct mnt_list *
return 0;
}
-int tree_is_mounted(struct mnt_list *mnts, const char *path)
+int tree_is_mounted(struct mnt_list *mnts, const char *path, unsigned int type)
{
struct list_head *p;
struct list_head list;
@@ -760,13 +760,27 @@ int tree_is_mounted(struct mnt_list *mnt
mptr = list_entry(p, struct mnt_list, list);
- /* We only want real mounts */
- if (!strcmp(mptr->fs_type, "autofs"))
- continue;
+ if (type) {
+ unsigned int autofs_fs;
- mounted++;
- }
+ autofs_fs = !strcmp(mptr->fs_type, "autofs");
+ if (type & MNTS_REAL) {
+ if (!autofs_fs) {
+ mounted = 1;
+ break;
+ }
+ } else if (type & MNTS_AUTOFS) {
+ if (autofs_fs) {
+ mounted = 1;
+ break;
+ }
+ } else {
+ mounted = 1;
+ break;
+ }
+ }
+ }
return mounted;
}
diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c
index 95fe00d..9bccdd1 100644
--- a/modules/mount_autofs.c
+++ b/modules/mount_autofs.c
@@ -201,7 +201,7 @@ int mount_mount(struct autofs_point *ap,
mounts_mutex_lock(ap);
- if (pthread_create(&thid, &thread_attr, handle_mounts, nap)) {
+ if (pthread_create(&thid, NULL, handle_mounts, nap)) {
crit(ap->logopt,
MODPREFIX
"failed to create mount handler thread for %s",
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index c6dffef..6007828 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -839,7 +839,7 @@ static int parse_mapent(const char *ent,
l = chunklen(p, check_colon(p));
ent = dequote(p, l, logopt);
if (!ent) {
- error(logopt, MODPREFIX "out of memory");
+ warn(logopt, MODPREFIX "null location or out of memory");
free(myoptions);
free(loc);
return 0;
@@ -1056,7 +1056,7 @@ int parse_mount(struct autofs_point *ap,
}
if (!path) {
- error(ap->logopt, MODPREFIX "out of memory");
+ warn(ap->logopt, MODPREFIX "null path or out of memory");
cache_readlock(mc);
cache_multi_lock(mc);
cache_delete_offset_list(mc, name);
@@ -1174,6 +1174,7 @@ int parse_mount(struct autofs_point *ap,
return rv;
} else {
/* Normal (and non-root multi-mount) entries */
+ struct autofs_point *oap = ap;
char *loc;
int loclen;
int l;
@@ -1185,14 +1186,11 @@ int parse_mount(struct autofs_point *ap,
free(options);
return 1;
}
-/*
- if (*p == ':')
- p++; /* Sun escape for entries starting with / */ /*
-*/
+
l = chunklen(p, check_colon(p));
loc = dequote(p, l, ap->logopt);
if (!loc) {
- error(ap->logopt, MODPREFIX "out of memory");
+ warn(ap->logopt, MODPREFIX "null location or out of memory");
free(options);
return 1;
}
@@ -1216,7 +1214,8 @@ int parse_mount(struct autofs_point *ap,
l = chunklen(p, check_colon(p));
ent = dequote(p, l, ap->logopt);
if (!ent) {
- error(ap->logopt, MODPREFIX "out of memory");
+ warn(ap->logopt,
+ MODPREFIX "null location or out of memory");
free(loc);
free(options);
return 1;
@@ -1277,13 +1276,24 @@ int parse_mount(struct autofs_point *ap,
* If it's a multi-mount insert the triggers
* These are always direct mount triggers so root = ""
*/
- cache_readlock(mc);
- me = cache_lookup_distinct(mc, name);
- if (me && me->multi) {
- char *m_key = me->multi->key;
+ if (ap->submount)
+ oap = ap->parent;
+
+ me = lookup_source_mapent(oap, name);
+ if (me) {
+ char *m_key;
int start;
char *base, *m_root;
+ mc = me->source->mc;
+
+ if (!me->multi) {
+ cache_unlock(mc);
+ return rv;
+ }
+
+ m_key = me->multi->key;
+
if (*m_key == '/') {
m_root = m_key;
start = strlen(m_key);
@@ -1308,14 +1318,14 @@ int parse_mount(struct autofs_point *ap,
base = &me->key[start];
cache_multi_lock(mc);
- if (!mount_multi_triggers(ap, m_root, me->multi, base)) {
+ if (!mount_multi_triggers(oap, m_root, me->multi, base)) {
error(ap->logopt,
MODPREFIX "failed to mount offset triggers");
rv = 1;
}
cache_multi_unlock(mc);
+ cache_unlock(mc);
}
- cache_unlock(mc);
}
return rv;
}
Index: autofs.spec
===================================================================
RCS file: /cvs/dist/rpms/autofs/devel/autofs.spec,v
retrieving revision 1.132
retrieving revision 1.133
diff -u -r1.132 -r1.133
--- autofs.spec 24 Jul 2006 13:09:24 -0000 1.132
+++ autofs.spec 27 Jul 2006 08:41:42 -0000 1.133
@@ -4,7 +4,7 @@
Summary: A tool for automatically mounting and unmounting filesystems.
Name: autofs
%define version 5.0.1
-%define release 0.rc1.6
+%define release 0.rc1.7
Version: %{version}
Release: %{release}
Epoch: 1
@@ -23,6 +23,7 @@
Patch10: autofs-5.0.1-rc1-cthon-host-name-validation.patch
Patch11: autofs-5.0.1-rc1-cthon-submount-fix.patch
Patch12: autofs-5.0.1-rc1-cthon-parse-and-submounts.patch
+Patch13: autofs-5.0.1-rc1-cthon-expire-nested.patch
Buildroot: /var/tmp/autofs-tmp
BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, libxml2-devel, cyrus-sasl-devel, openssl-devel
Prereq: chkconfig
@@ -74,6 +75,7 @@
%patch10 -p1
%patch11 -p1
%patch12 -p1
+%patch13 -p1
%build
#CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir}
@@ -130,7 +132,10 @@
%{_libdir}/autofs/*
%changelog
-* Thu Jul 24 2006 Ian Kent <ikent at redhat.com> - 5.0.1-0.rc1.6
+* Thu Jul 27 2006 Ian Kent <ikent at redhat.com> - 5.0.1-0.rc1.7
+- cthon fix expire of various forms of nested mounts.
+
+* Mon Jul 24 2006 Ian Kent <ikent at redhat.com> - 5.0.1-0.rc1.6
- cthon more parser corrections and attempt to fix multi-mounts
with various combinations of submounts (still not right).
More information about the fedora-cvs-commits
mailing list