rpms/autofs/devel autofs-5.0.3-active-restart.patch, NONE, 1.1 autofs-5.0.3-device-node-and-active-restart-fixes.patch, NONE, 1.1 autofs-5.0.3-device-node-control.patch, NONE, 1.1 autofs-5.0.3-expire-works-too-hard.patch, NONE, 1.1 autofs-5.0.3-make-is_mounted-use-dev-ioctl.patch, NONE, 1.1 autofs-5.0.3-unlink-mount-return-fix.patch, NONE, 1.1 autofs.spec, 1.233, 1.234
Ian Kent (iankent)
fedora-extras-commits at redhat.com
Mon Feb 25 00:41:29 UTC 2008
- Previous message (by thread): rpms/kernel-xen-2.6/devel kernel.spec,1.12,1.13
- Next message (by thread): rpms/cernlib/devel cernlib-217-abend-on-mathlib-test-failure.dpatch, NONE, 1.1 .cvsignore, 1.9, 1.10 cernlib-102-dont-optimize-some-code.dpatch, 1.2, 1.3 cernlib-216-use-cernlib-gamma-not-intrinsic.dpatch, 1.1, 1.2 cernlib-304-update-Imake-config-files.dpatch, 1.3, 1.4 cernlib-321-support-gfortran.dpatch, 1.4, 1.5 cernlib-800-implement-shared-library-rules-in-Imake.dpatch, 1.2, 1.3 cernlib.spec, 1.68, 1.69 paw-108-quote-protect-comis-script.dpatch, 1.1, 1.2 paw-200-comis-allow-special-chars-in-path.dpatch, 1.1, 1.2 paw-211-support-amd64-and-itanium.dpatch, 1.1, 1.2 paw-308-use-canonical-cfortran-location.dpatch, 1.1, 1.2 paw-320-support-ifort-and-gfortran.dpatch, 1.1, 1.2 paw-803-link-binaries-dynamically.dpatch, 1.1, 1.2 paw-804-workaround-for-comis-mdpool-struct-location.dpatch, 1.1, 1.2 sources, 1.10, 1.11
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: iankent
Update of /cvs/pkgs/rpms/autofs/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv7179
Modified Files:
autofs.spec
Added Files:
autofs-5.0.3-active-restart.patch
autofs-5.0.3-device-node-and-active-restart-fixes.patch
autofs-5.0.3-device-node-control.patch
autofs-5.0.3-expire-works-too-hard.patch
autofs-5.0.3-make-is_mounted-use-dev-ioctl.patch
autofs-5.0.3-unlink-mount-return-fix.patch
Log Message:
* Mon Feb 25 2008 Ian Kent <ikent at redhat.com> - 5.0.3-6
- fix expire calling kernel more often than needed.
- fix unlink of mount tree incorrectly causing autofs mount fail.
- add miscellaneous device node interface library.
- use miscellaneous device node, if available, for active restart.
- device node and active restart fixes.
- update is_mounted to use device node ioctl, if available.
autofs-5.0.3-active-restart.patch:
--- NEW FILE autofs-5.0.3-active-restart.patch ---
diff -up autofs-5.0.3/daemon/indirect.c.active-restart autofs-5.0.3/daemon/indirect.c
--- autofs-5.0.3/daemon/indirect.c.active-restart 2008-02-25 09:16:05.000000000 +0900
+++ autofs-5.0.3/daemon/indirect.c 2008-02-25 09:16:46.000000000 +0900
@@ -20,6 +20,7 @@
* ----------------------------------------------------------------------- */
#include <dirent.h>
+#include <libgen.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
@@ -32,9 +33,8 @@
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/mount.h>
+#include <sys/vfs.h>
#include <sched.h>
-#include <pwd.h>
-#include <grp.h>
#include "automount.h"
@@ -43,8 +43,6 @@ extern pthread_attr_t thread_attr;
static pthread_mutex_t ma_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER;
-static const unsigned int indirect = AUTOFS_TYPE_INDIRECT;
-
static int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts)
{
struct mnt_list *this;
@@ -90,6 +88,7 @@ static int unlink_mount_tree(struct auto
static int do_mount_autofs_indirect(struct autofs_point *ap)
{
+ const char *str_indirect = mount_type_str(indirect);
struct ioctl_ops *ops = get_ioctl_ops();
time_t timeout = ap->exp_timeout;
char *options = NULL;
@@ -98,8 +97,58 @@ static int do_mount_autofs_indirect(stru
struct mnt_list *mnts;
int ret;
- mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 1);
- if (mnts) {
+ ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
+
+ if (ops->version) {
+ char device[AUTOFS_DEVID_LEN];
+ struct statfs fst;
+ int ioctlfd;
+ dev_t devid;
+ char *tmp;
+
+ if (!find_mnt_devid(_PROC_MOUNTS, ap->path, device, indirect))
+ goto cont;
+
+ devid = strtoul(device, NULL, 0);
+
+ ret = remount_active_mount(ap, NULL, ap->path, devid, indirect, &ioctlfd);
+
+ /*
+ * The directory must exist since we found a device
+ * number for the mount above but we can't know if we
+ * created it or not. However, if we're mounted on an
+ * autofs fs then we need to cleanup the path anyway.
+ */
+ ap->dir_created = 0;
+ tmp = strdup(ap->path);
+ if (tmp) {
+ if (statfs(dirname(tmp), &fst) != -1)
+ if (fst.f_type == AUTOFS_SUPER_MAGIC)
+ ap->dir_created = 1;
+ free(tmp);
+ }
+
+ /*
+ * Either we opened the mount or we're re-reading the map.
+ * If we opened the mount and ioctlfd is not -1 we have
+ * a descriptor for the indirect mount so we need to
+ * record that in the mount point struct. Otherwise we're
+ * re-reading the map.
+ */
+ if (ret == REMOUNT_SUCCESS || ret == REMOUNT_READ_MAP) {
+ if (ioctlfd != -1)
+ ap->ioctlfd = ioctlfd;
+ return 0;
+ }
+ /*
+ * Since we got the device number above a mount exists so
+ * any other failure warrants a failure return here.
+ */
+ return -1;
+ } else {
+ mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 1);
+ if (!mnts)
+ goto cont;
ret = unlink_mount_tree(ap, mnts);
free_mnt_list(mnts);
if (!ret) {
@@ -109,7 +158,7 @@ static int do_mount_autofs_indirect(stru
goto out_err;
}
}
-
+cont:
options = make_options_string(ap->path, ap->kpipefd, NULL);
if (!options) {
error(ap->logopt, "options string error");
@@ -152,29 +201,21 @@ static int do_mount_autofs_indirect(stru
options = NULL;
- if (ops->open(ap->logopt, &ap->ioctlfd, -1, ap->path, indirect)) {
+ if (stat(ap->path, &st) == -1) {
+ error(ap->logopt,
+ "failed to stat mount %s", ap->path);
+ goto out_umount;
+ }
+ ap->dev = st.st_dev;
+
+ if (ops->open(ap->logopt, &ap->ioctlfd, ap->dev, ap->path, indirect)) {
crit(ap->logopt,
"failed to create ioctl fd for autofs path %s", ap->path);
goto out_umount;
}
- ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
-
ops->timeout(ap->logopt, ap->ioctlfd, &timeout);
-
- if (ap->exp_timeout)
- info(ap->logopt,
- "mounted indirect mount on %s "
- "with timeout %u, freq %u seconds", ap->path,
- (unsigned int) ap->exp_timeout,
- (unsigned int) ap->exp_runfreq);
- else
- info(ap->logopt,
- "mounted indirect mount on %s with timeouts disabled",
- ap->path);
-
- fstat(ap->ioctlfd, &st);
- ap->dev = st.st_dev; /* Device number for mount point checks */
+ notify_mount_result(ap, ap->path, str_indirect);
return 0;
@@ -636,15 +677,7 @@ static void *do_mount_indirect(void *arg
struct autofs_point *ap;
char buf[PATH_MAX + 1];
struct stat st;
- struct passwd pw;
- struct passwd *ppw = &pw;
- struct passwd **pppw = &ppw;
- struct group gr;
- struct group *pgr;
- struct group **ppgr;
- char *pw_tmp, *gr_tmp;
- struct thread_stdenv_vars *tsv;
- int len, tmplen, grplen, status, state;
+ int len, status, state;
mt = (struct pending_args *) arg;
@@ -687,125 +720,8 @@ static void *do_mount_indirect(void *arg
info(ap->logopt, "attempting to mount entry %s", buf);
- /*
- * Setup thread specific data values for macro
- * substution in map entries during the mount.
- * Best effort only as it must go ahead.
- */
+ set_tsd_user_vars(ap->logopt, mt->uid, mt->gid);
- tsv = malloc(sizeof(struct thread_stdenv_vars));
- if (!tsv)
- goto cont;
-
- tsv->uid = mt->uid;
- tsv->gid = mt->gid;
-
- /* Try to get passwd info */
-
- tmplen = sysconf(_SC_GETPW_R_SIZE_MAX);
- if (tmplen < 0) {
- error(ap->logopt, "failed to get buffer size for getpwuid_r");
- free(tsv);
- goto cont;
- }
-
- pw_tmp = malloc(tmplen + 1);
- if (!pw_tmp) {
- error(ap->logopt, "failed to malloc buffer for getpwuid_r");
- free(tsv);
- goto cont;
- }
-
[...1855 lines suppressed...]
+ if (oe->ioctlfd != -1)
+ left++;
+ }
+
+ if (left)
+ return left;
+
+ pos = NULL;
+ offset = path;
+
+ /* Make sure "none" of the offsets have an active mount. */
+ while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
+ oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list);
+ /* root offset is a special case */
+ if (!oe || (strlen(oe->key) - start) == 1)
+ continue;
+
+ debug(ap->logopt, "umount offset %s", oe->key);
+
+ if (umount_autofs_offset(ap, oe)) {
+ warn(ap->logopt, "failed to umount offset");
+ left++;
+ }
+ }
+
+ if (!left && me->multi == me) {
+ struct mapent_cache *mc = me->mc;
+ int status;
+
+ /*
+ * Special case.
+ * If we can't umount the root container then we can't
+ * delete the offsets from the cache and we need to put
+ * the offset triggers back.
+ */
+ if (is_mounted(_PATH_MOUNTED, root, MNTS_REAL)) {
+ info(ap->logopt, "unmounting dir = %s", root);
+ if (umount_ent(ap, root)) {
+ if (!mount_multi_triggers(ap, root, me, "/"))
+ warn(ap->logopt,
+ "failed to remount offset triggers");
+ return left++;
+ }
+ }
+
+ /* We're done - clean out the offsets */
+ status = cache_delete_offset_list(mc, me->key);
+ if (status != CHE_OK)
+ warn(ap->logopt, "couldn't delete offset list");
+ }
+
+ return left;
+}
+
diff -up autofs-5.0.3/lib/cache.c.active-restart autofs-5.0.3/lib/cache.c
--- autofs-5.0.3/lib/cache.c.active-restart 2008-01-14 13:39:16.000000000 +0900
+++ autofs-5.0.3/lib/cache.c 2008-02-25 09:16:46.000000000 +0900
@@ -111,14 +111,29 @@ void cache_lock_cleanup(void *arg)
return;
}
-void cache_multi_lock(struct mapent *me)
+void cache_multi_readlock(struct mapent *me)
{
int status;
if (!me)
return;
- status = pthread_mutex_lock(&me->multi_mutex);
+ status = pthread_rwlock_rdlock(&me->multi_rwlock);
+ if (status) {
+ logmsg("mapent cache multi mutex lock failed");
+ fatal(status);
+ }
+ return;
+}
+
+void cache_multi_writelock(struct mapent *me)
+{
+ int status;
+
+ if (!me)
+ return;
+
+ status = pthread_rwlock_wrlock(&me->multi_rwlock);
if (status) {
logmsg("mapent cache multi mutex lock failed");
fatal(status);
@@ -133,7 +148,7 @@ void cache_multi_unlock(struct mapent *m
if (!me)
return;
- status = pthread_mutex_unlock(&me->multi_mutex);
+ status = pthread_rwlock_unlock(&me->multi_rwlock);
if (status) {
logmsg("mapent cache multi mutex unlock failed");
fatal(status);
@@ -553,8 +568,9 @@ int cache_add(struct mapent_cache *mc, s
me->ioctlfd = -1;
me->dev = (dev_t) -1;
me->ino = (ino_t) -1;
+ me->dir_created = 0;
- status = pthread_mutex_init(&me->multi_mutex, NULL);
+ status = pthread_rwlock_init(&me->multi_rwlock, NULL);
if (status)
fatal(status);
@@ -760,7 +776,7 @@ int cache_delete(struct mapent_cache *mc
goto done;
}
pred->next = me->next;
- status = pthread_mutex_destroy(&me->multi_mutex);
+ status = pthread_rwlock_destroy(&me->multi_rwlock);
if (status)
fatal(status);
ino_index_lock(mc);
@@ -784,7 +800,7 @@ int cache_delete(struct mapent_cache *mc
goto done;
}
mc->hash[hashval] = me->next;
- status = pthread_mutex_destroy(&me->multi_mutex);
+ status = pthread_rwlock_destroy(&me->multi_rwlock);
if (status)
fatal(status);
ino_index_lock(mc);
diff -up autofs-5.0.3/lib/master.c.active-restart autofs-5.0.3/lib/master.c
--- autofs-5.0.3/lib/master.c.active-restart 2008-02-25 09:16:05.000000000 +0900
+++ autofs-5.0.3/lib/master.c 2008-02-25 09:16:46.000000000 +0900
@@ -997,28 +997,31 @@ next:
static int master_do_mount(struct master_mapent *entry)
{
+ struct startup_cond suc;
struct autofs_point *ap;
pthread_t thid;
int status;
- status = pthread_mutex_lock(&suc.mutex);
- if (status)
- fatal(status);
+ ap = entry->ap;
+
+ if (handle_mounts_startup_cond_init(&suc)) {
+ crit(ap->logopt,
+ "failed to init startup cond for mount %s", entry->path);
+ return 0;
+ }
+ suc.ap = ap;
suc.done = 0;
suc.status = 0;
- ap = entry->ap;
-
debug(ap->logopt, "mounting %s", entry->path);
- if (pthread_create(&thid, &thread_attr, handle_mounts, ap)) {
+ status = pthread_create(&thid, &thread_attr, handle_mounts, &suc);
+ if (status) {
crit(ap->logopt,
"failed to create mount handler thread for %s",
entry->path);
- status = pthread_mutex_unlock(&suc.mutex);
- if (status)
- fatal(status);
+ handle_mounts_startup_cond_destroy(&suc);
return 0;
}
entry->thid = thid;
@@ -1031,15 +1034,11 @@ static int master_do_mount(struct master
if (suc.status) {
error(ap->logopt, "failed to startup mount");
- status = pthread_mutex_unlock(&suc.mutex);
- if (status)
- fatal(status);
+ handle_mounts_startup_cond_destroy(&suc);
return 0;
}
- status = pthread_mutex_unlock(&suc.mutex);
- if (status)
- fatal(status);
+ handle_mounts_startup_cond_destroy(&suc);
return 1;
}
diff -up autofs-5.0.3/CHANGELOG.active-restart autofs-5.0.3/CHANGELOG
--- autofs-5.0.3/CHANGELOG.active-restart 2008-02-25 09:16:05.000000000 +0900
+++ autofs-5.0.3/CHANGELOG 2008-02-25 09:16:46.000000000 +0900
@@ -9,6 +9,7 @@
- fix expire working harder than needed.
- fix unlink of mount tree incorrectly causing autofs mount fail.
- add miscellaneous device node interface library.
+- use miscellaneous device node, if available, for active restart.
14/01/2008 autofs-5.0.3
-----------------------
autofs-5.0.3-device-node-and-active-restart-fixes.patch:
--- NEW FILE autofs-5.0.3-device-node-and-active-restart-fixes.patch ---
diff --git a/include/dev-ioctl-lib.h b/include/dev-ioctl-lib.h
index 5851c4c..007d7a6 100644
--- a/include/dev-ioctl-lib.h
+++ b/include/dev-ioctl-lib.h
@@ -26,7 +26,7 @@
#define CONTROL_DEVICE "/dev/autofs"
-#define DEV_IOCTL_IS_MOUNTED 0x0001
+#define DEV_IOCTL_IS_MOUNTPOINT 0x0001
#define DEV_IOCTL_IS_AUTOFS 0x0002
#define DEV_IOCTL_IS_OTHER 0x0004
diff --git a/include/mounts.h b/include/mounts.h
index ca7dee9..679a508 100644
--- a/include/mounts.h
+++ b/include/mounts.h
@@ -65,7 +65,7 @@ struct mnt_list {
unsigned int query_kproto_ver(void);
unsigned int get_kver_major(void);
unsigned int get_kver_minor(void);
-char *make_options_string(char *path, int kernel_pipefd, char *extra);
+char *make_options_string(char *path, int kernel_pipefd, const char *extra);
char *make_mnt_name_string(char *path);
struct mnt_list *get_mnt_list(const char *table, const char *path, int include);
struct mnt_list *reverse_mnt_list(struct mnt_list *list);
diff --git a/lib/dev-ioctl-lib.c b/lib/dev-ioctl-lib.c
index 8d4be77..719747f 100644
--- a/lib/dev-ioctl-lib.c
+++ b/lib/dev-ioctl-lib.c
@@ -698,11 +698,18 @@ static int ioctl_askumount(unsigned int logopt,
/*
* Check if the given path is a mountpoint.
*
- * The path is considered a mountpoint if it is itself a mountpoint
- * or contains a mount, such as a multi-mount without a root mount.
- * In addition, if the path is itself a mountpoint we return whether
- * the mounted file system is an autofs filesystem or other file
- * system.
+ * If we supply a file descriptor of an autofs mount we're
+ * looking for a specific mount. In this case the path is
+ * considered a mountpoint if it is itself a mountpoint or
+ * contains a mount, such as a multi-mount without a root
+ * mount.
+ *
+ * If we don't supply a file descriptor then we just want
+ * to know if the given path is an autofs mount point or
+ * is mounted within an autofs filesystem.
+ *
+ * In both cases we get an indication of whether the path
+ * is a mount point and the super magic of the top mount.
*/
static int dev_ioctl_ismountpoint(unsigned int logopt,
int ioctlfd, const char *path,
@@ -731,7 +738,7 @@ static int dev_ioctl_ismountpoint(unsigned int logopt,
}
if (param->arg1) {
- *mountpoint = DEV_IOCTL_IS_MOUNTED;
+ *mountpoint = DEV_IOCTL_IS_MOUNTPOINT;
if (param->arg2) {
if (param->arg2 == AUTOFS_SUPER_MAGIC)
diff --git a/lib/mounts.c b/lib/mounts.c
index 959fe99..ba49099 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -129,7 +129,7 @@ unsigned int get_kver_minor(void)
/*
* Make common autofs mount options string
*/
-char *make_options_string(char *path, int pipefd, char *extra)
+char *make_options_string(char *path, int pipefd, const char *extra)
{
char *options;
int len;
@@ -1207,8 +1207,8 @@ free_tsv:
const char *mount_type_str(const unsigned int type)
{
static const char *str_type[] = {
- "direct",
"indirect",
+ "direct",
"offset"
};
unsigned int pos, i;
@@ -1225,13 +1225,13 @@ void notify_mount_result(struct autofs_point *ap,
{
if (ap->exp_timeout)
info(ap->logopt,
- "mounted %s on %s with timeout %u, freq %u seconds",
+ "mounted %s mount on %s with timeout %u, freq %u seconds",
type, path,
(unsigned int) ap->exp_timeout,
(unsigned int) ap->exp_runfreq);
else
info(ap->logopt,
- "mounted %s on %s with timeouts disabled",
+ "mounted %s mount on %s with timeouts disabled",
type, path);
return;
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
index 1a9bef2..d493cde 100644
--- a/modules/mount_nfs.c
+++ b/modules/mount_nfs.c
@@ -173,6 +173,13 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
len = sprintf(fullpath, "%s", root);
fullpath[len] = '\0';
+ if (is_mounted(_PATH_MOUNTED, fullpath, MNTS_REAL)) {
+ info(ap->logopt, MODPREFIX
+ "%s is already mounted or is being re-mounted", fullpath);
+ free_host_list(&hosts);
+ return 0;
+ }
+
debug(ap->logopt, MODPREFIX "calling mkdir_path %s", fullpath);
status = mkdir_path(fullpath, 0555);
@@ -197,13 +204,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
while (this) {
char *loc, *port_opt = NULL;
- if (is_mounted(_PATH_MOUNTED, fullpath, MNTS_REAL)) {
- info(ap->logopt, MODPREFIX
- "%s is already mounted or is being re-mounted", fullpath);
- free_host_list(&hosts);
- return 0;
- }
-
/*
* If the "port" option is specified, then we don't want
* a bind mount. Use the "port" option if you want to
autofs-5.0.3-device-node-control.patch:
--- NEW FILE autofs-5.0.3-device-node-control.patch ---
diff -up autofs-5.0.3/daemon/indirect.c.device-node-control autofs-5.0.3/daemon/indirect.c
--- autofs-5.0.3/daemon/indirect.c.device-node-control 2008-02-25 08:58:46.000000000 +0900
+++ autofs-5.0.3/daemon/indirect.c 2008-02-25 09:03:12.000000000 +0900
@@ -43,6 +43,8 @@ extern pthread_attr_t thread_attr;
static pthread_mutex_t ma_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER;
+static const unsigned int indirect = AUTOFS_TYPE_INDIRECT;
+
static int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts)
{
struct mnt_list *this;
@@ -88,19 +90,20 @@ static int unlink_mount_tree(struct auto
static int do_mount_autofs_indirect(struct autofs_point *ap)
{
+ struct ioctl_ops *ops = get_ioctl_ops();
time_t timeout = ap->exp_timeout;
char *options = NULL;
const char *type, *map_name = NULL;
struct stat st;
struct mnt_list *mnts;
- int cl_flags, ret;
+ int ret;
mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 1);
if (mnts) {
ret = unlink_mount_tree(ap, mnts);
free_mnt_list(mnts);
if (!ret) {
- debug(ap->logopt,
+ error(ap->logopt,
"already mounted as other than autofs "
"or failed to unlink entry in tree");
goto out_err;
@@ -108,8 +111,10 @@ static int do_mount_autofs_indirect(stru
}
options = make_options_string(ap->path, ap->kpipefd, NULL);
- if (!options)
+ if (!options) {
+ error(ap->logopt, "options string error");
goto out_err;
+ }
/* In case the directory doesn't exist, try to mkdir it */
if (mkdir_path(ap->path, 0555) < 0) {
@@ -147,22 +152,15 @@ static int do_mount_autofs_indirect(stru
options = NULL;
- /* Root directory for ioctl()'s */
- ap->ioctlfd = open(ap->path, O_RDONLY);
- if (ap->ioctlfd < 0) {
+ if (ops->open(ap->logopt, &ap->ioctlfd, -1, ap->path, indirect)) {
crit(ap->logopt,
"failed to create ioctl fd for autofs path %s", ap->path);
goto out_umount;
}
- if ((cl_flags = fcntl(ap->ioctlfd, F_GETFD, 0)) != -1) {
- cl_flags |= FD_CLOEXEC;
- fcntl(ap->ioctlfd, F_SETFD, cl_flags);
- }
-
ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
- ioctl(ap->ioctlfd, AUTOFS_IOC_SETTIMEOUT, &timeout);
+ ops->timeout(ap->logopt, ap->ioctlfd, &timeout);
if (ap->exp_timeout)
info(ap->logopt,
@@ -235,8 +233,10 @@ int mount_autofs_indirect(struct autofs_
int umount_autofs_indirect(struct autofs_point *ap)
{
+ struct ioctl_ops *ops = get_ioctl_ops();
char buf[MAX_ERR_BUF];
- int ret, rv, retries;
+ int rv, retries;
+ unsigned int ret;
/*
* Since submounts look after themselves the parent never knows
@@ -248,7 +248,7 @@ int umount_autofs_indirect(struct autofs
lookup_source_close_ioctlfd(ap->parent, ap->path);
/* If we are trying to shutdown make sure we can umount */
- rv = ioctl(ap->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &ret);
+ rv = ops->askumount(ap->logopt, ap->ioctlfd, &ret);
if (rv == -1) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
logerr("ioctl failed: %s", estr);
@@ -258,8 +258,8 @@ int umount_autofs_indirect(struct autofs
return 1;
}
- ioctl(ap->ioctlfd, AUTOFS_IOC_CATATONIC, 0);
- close(ap->ioctlfd);
+ ops->catatonic(ap->logopt, ap->ioctlfd);
+ ops->close(ap->logopt, ap->ioctlfd);
ap->ioctlfd = -1;
close(ap->state_pipe[0]);
close(ap->state_pipe[1]);
@@ -320,48 +320,6 @@ force_umount:
return rv;
}
-static int expire_indirect(struct autofs_point *ap, int ioctlfd, const char *path, unsigned int when)
-{
- char buf[MAX_ERR_BUF];
- int ret, retries;
- struct stat st;
-
- if (fstat(ioctlfd, &st) == -1) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- debug(ap->logopt, "fstat failed: %s", estr);
- return 0;
- }
-
- retries = (count_mounts(ap->logopt, path, st.st_dev) + 1) * EXPIRE_RETRIES;
-
- while (retries--) {
- struct timespec tm = {0, 100000000};
-
- /* Ggenerate expire message for the mount. */
- ret = ioctl(ioctlfd, AUTOFS_IOC_EXPIRE_DIRECT, &when);
- if (ret == -1) {
- /* Mount has gone away */
- if (errno == EBADF || errno == EINVAL)
- return 1;
-
- /*
- * Other than EAGAIN is an expire error so continue.
- * Kernel will try the next mount.
- */
- if (errno == EAGAIN)
- break;
- }
- nanosleep(&tm, NULL);
- }
-
- if (!ioctl(ioctlfd, AUTOFS_IOC_ASKUMOUNT, &ret)) {
- if (!ret)
- return 0;
- }
-
- return 1;
-}
-
static void mnts_cleanup(void *arg)
{
struct mnt_list *mnts = (struct mnt_list *) arg;
@@ -371,6 +329,7 @@ static void mnts_cleanup(void *arg)
void *expire_proc_indirect(void *arg)
{
+ struct ioctl_ops *ops = get_ioctl_ops();
struct autofs_point *ap;
struct mapent *me = NULL;
struct mnt_list *mnts = NULL, *next;
@@ -458,8 +417,8 @@ void *expire_proc_indirect(void *arg)
debug(ap->logopt, "expire %s", next->path);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
- ret = expire_indirect(ap, ioctlfd, next->path, now);
- if (!ret)
+ ret = ops->expire(ap->logopt, ioctlfd, next->path, now);
+ if (ret)
left++;
pthread_setcancelstate(cur_state, NULL);
}
@@ -472,8 +431,8 @@ void *expire_proc_indirect(void *arg)
*/
if (mnts) {
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
- ret = expire_indirect(ap, ap->ioctlfd, ap->path, now);
- if (!ret)
+ ret = ops->expire(ap->logopt, ap->ioctlfd, ap->path, now);
+ if (ret)
left++;
pthread_setcancelstate(cur_state, NULL);
}
@@ -495,8 +454,8 @@ void *expire_proc_indirect(void *arg)
pthread_cleanup_pop(1);
if (submnts)
- debug(ap->logopt,
- "%d submounts remaining in %s", submnts, ap->path);
+ info(ap->logopt,
+ "%d submounts remaining in %s", submnts, ap->path);
/*
* EXPIRE_MULTI is synchronous, so we can be sure (famous last
@@ -527,8 +486,11 @@ static void pending_cond_destroy(void *a
static void expire_send_fail(void *arg)
{
+ struct ioctl_ops *ops = get_ioctl_ops();
[...2023 lines suppressed...]
+ int err;
+
+ if (!path)
+ errno = EINVAL;
+
+ *uid = -1;
+ *gid = -1;
+
+
+ param = alloc_dev_ioctl_path(ioctlfd, path);
+ if (!param)
+ return -1;
+
+ err = ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_REQUESTOR, param);
+ if (err == -1) {
+ int save_errno = errno;
+ free_dev_ioctl_open(param);
+ errno = save_errno;
+ return -1;
+ }
+
+ *uid = param->arg1;
+ *gid = param->arg2;
+
+ free_dev_ioctl_path(param);
+
+ return 0;
+}
+
+/*
+ * Call repeatedly until it returns EAGAIN, meaning there's nothing
+ * more that can be done.
+ */
+static int expire(unsigned int logopt, int cmd, int fd,
+ int ioctlfd, const char *path, void *arg)
+{
+ char buf[MAX_ERR_BUF];
+ struct stat st;
+ unsigned int retries;
+ unsigned int ret;
+
+ if (fstat(ioctlfd, &st) == -1) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ debug(logopt, "fstat failed: %s", estr);
+ return 0;
+ }
+
+ retries = (count_mounts(logopt, path, st.st_dev) + 1) * EXPIRE_RETRIES;
+
+ while (retries--) {
+ struct timespec tm = {0, 100000000};
+
+ ret = ioctl(fd, cmd, arg);
+ if (ret == -1) {
+ /* Mount has gone away */
+ if (errno == EBADF || errno == EINVAL)
+ return 0;
+
+ /*
+ * Other than EAGAIN is an expire error so continue.
+ * Kernel will try the next mount for indirect
+ * mounts. For direct mounts it will just try the
+ * same mount again, limited by retries (ie. number
+ * of mounts directly under mount point, should
+ * always be one for direct mounts).
+ */
+ if (errno == EAGAIN)
+ break;
+ }
+ nanosleep(&tm, NULL);
+ }
+
+ if (ctl.ops->askumount(logopt, ioctlfd, &ret))
+ return -1;
+
+ if (!ret)
+ return -1;
+
+ return 0;
+}
+
+static int dev_ioctl_expire(unsigned int logopt,
+ int ioctlfd, const char *path, unsigned int when)
+{
+ struct autofs_dev_ioctl param;
+
+ init_autofs_dev_ioctl(¶m);
+ param.ioctlfd = ioctlfd;
+ param.arg1 = when;
+
+ return expire(logopt, AUTOFS_DEV_IOCTL_EXPIRE,
+ ctl.devfd, ioctlfd, path, (void *) ¶m);
+}
+
+static int ioctl_expire(unsigned int logopt,
+ int ioctlfd, const char *path, unsigned int when)
+{
+ return expire(logopt, AUTOFS_IOC_EXPIRE_MULTI,
+ ioctlfd, ioctlfd, path, (void *) &when);
+}
+
+/* Check if autofs mount point is in use */
+static int dev_ioctl_askumount(unsigned int logopt,
+ int ioctlfd, unsigned int *busy)
+{
+ struct autofs_dev_ioctl param;
+
+ init_autofs_dev_ioctl(¶m);
+ param.ioctlfd = ioctlfd;
+
+ if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_ASKUMOUNT, ¶m) == -1)
+ return -1;
+
+ *busy = param.arg1;
+
+ return 0;
+}
+
+static int ioctl_askumount(unsigned int logopt,
+ int ioctlfd, unsigned int *busy)
+{
+ return ioctl(ioctlfd, AUTOFS_IOC_ASKUMOUNT, busy);
+}
+
+/*
+ * Check if the given path is a mountpoint.
+ *
+ * The path is considered a mountpoint if it is itself a mountpoint
+ * or contains a mount, such as a multi-mount without a root mount.
+ * In addition, if the path is itself a mountpoint we return whether
+ * the mounted file system is an autofs filesystem or other file
+ * system.
+ */
+static int dev_ioctl_ismountpoint(unsigned int logopt,
+ int ioctlfd, const char *path,
+ unsigned int *mountpoint)
+{
+ struct autofs_dev_ioctl *param;
+ int err;
+
+ *mountpoint = 0;
+
+ if (!path) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ param = alloc_dev_ioctl_path(ioctlfd, path);
+ if (!param)
+ return -1;
+
+ err = ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_ISMOUNTPOINT, param);
+ if (err == -1) {
+ int save_errno = errno;
+ free_dev_ioctl_open(param);
+ errno = save_errno;
+ return -1;
+ }
+
+ if (param->arg1) {
+ *mountpoint = DEV_IOCTL_IS_MOUNTED;
+
+ if (param->arg2) {
+ if (param->arg2 == AUTOFS_SUPER_MAGIC)
+ *mountpoint |= DEV_IOCTL_IS_AUTOFS;
+ else
+ *mountpoint |= DEV_IOCTL_IS_OTHER;
+ }
+ }
+
+ free_dev_ioctl_path(param);
+
+ return 0;
+}
diff -up autofs-5.0.3/samples/rc.autofs.in.device-node-control autofs-5.0.3/samples/rc.autofs.in
--- autofs-5.0.3/samples/rc.autofs.in.device-node-control 2008-01-14 13:39:16.000000000 +0900
+++ autofs-5.0.3/samples/rc.autofs.in 2008-02-25 09:03:12.000000000 +0900
@@ -12,6 +12,7 @@
DAEMON=@@sbindir@@/automount
prog=`basename $DAEMON`
MODULE="autofs4"
+DEVICE="autofs"
confdir=@@autofsconfdir@@
test -e $DAEMON || exit 0
@@ -47,6 +48,14 @@ function start() {
return 1
fi
+ # Check misc device
+ if [ -e "/proc/misc" ]; then
+ MINOR=`awk "/$DEVICE/ {print \\$1}" /proc/misc`
+ if [ -n "$MINOR" -a ! -c "/dev/$DEVICE" ]; then
+ mknod -m 0600 /dev/$DEVICE c 10 $MINOR
+ fi
+ fi
+
$prog $OPTIONS
RETVAL=$?
if [ $RETVAL -eq 0 ] ; then
autofs-5.0.3-expire-works-too-hard.patch:
--- NEW FILE autofs-5.0.3-expire-works-too-hard.patch ---
diff -up autofs-5.0.3/daemon/direct.c.expire-works-too-hard autofs-5.0.3/daemon/direct.c
--- autofs-5.0.3/daemon/direct.c.expire-works-too-hard 2008-01-14 13:39:16.000000000 +0900
+++ autofs-5.0.3/daemon/direct.c 2008-02-25 08:48:08.000000000 +0900
@@ -808,7 +808,7 @@ static int expire_direct(int ioctlfd, co
if (fstat(ioctlfd, &st) == -1) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- error(logopt, "fstat failed: %s", estr);
+ debug(logopt, "fstat failed: %s", estr);
return 0;
}
@@ -824,11 +824,16 @@ static int expire_direct(int ioctlfd, co
if (errno == EBADF || errno == EINVAL)
return 1;
- /* Other than need to wait for the kernel ? */
- if (errno != EAGAIN)
- return 0;
+ /*
+ * Other than EAGAIN is an expire error so continue.
+ * Kernel try the same mount again, limited by
+ * retries (ie. number of mounts directly under
+ * mount point, should always be one for direct
+ * mounts).
+ */
+ if (errno == EAGAIN)
+ break;
}
-
nanosleep(&tm, NULL);
}
diff -up autofs-5.0.3/daemon/indirect.c.expire-works-too-hard autofs-5.0.3/daemon/indirect.c
--- autofs-5.0.3/daemon/indirect.c.expire-works-too-hard 2008-01-14 13:39:16.000000000 +0900
+++ autofs-5.0.3/daemon/indirect.c 2008-02-25 08:48:53.000000000 +0900
@@ -328,7 +328,7 @@ static int expire_indirect(struct autofs
if (fstat(ioctlfd, &st) == -1) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- error(ap->logopt, "fstat failed: %s", estr);
+ debug(ap->logopt, "fstat failed: %s", estr);
return 0;
}
@@ -344,11 +344,13 @@ static int expire_indirect(struct autofs
if (errno == EBADF || errno == EINVAL)
return 1;
- /* Other than need to wait for the kernel ? */
- if (errno != EAGAIN)
- return 0;
+ /*
+ * Other than EAGAIN is an expire error so continue.
+ * Kernel will try the next mount.
+ */
+ if (errno == EAGAIN)
+ break;
}
-
nanosleep(&tm, NULL);
}
diff -up autofs-5.0.3/CHANGELOG.expire-works-too-hard autofs-5.0.3/CHANGELOG
--- autofs-5.0.3/CHANGELOG.expire-works-too-hard 2008-02-25 08:44:54.000000000 +0900
+++ autofs-5.0.3/CHANGELOG 2008-02-25 08:48:08.000000000 +0900
@@ -6,6 +6,7 @@
- avoid using UDP for probing NFSv4 mount requests.
- use libldap instead of libldap_r (Guillaume Rousse).
- another fix for don't fail on empty master map.
+- fix expire working harder than needed.
14/01/2008 autofs-5.0.3
-----------------------
autofs-5.0.3-make-is_mounted-use-dev-ioctl.patch:
--- NEW FILE autofs-5.0.3-make-is_mounted-use-dev-ioctl.patch ---
diff --git a/lib/mounts.c b/lib/mounts.c
index ba49099..e3e8066 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -391,7 +391,7 @@ int contained_in_local_fs(const char *path)
return ret;
}
-int is_mounted(const char *table, const char *path, unsigned int type)
+static int table_is_mounted(const char *table, const char *path, unsigned int type)
{
struct mntent *mnt;
struct mntent mnt_wrk;
@@ -437,6 +437,35 @@ int is_mounted(const char *table, const char *path, unsigned int type)
return ret;
}
+static int ioctl_is_mounted(const char *path, unsigned int type)
+{
+ struct ioctl_ops *ops = get_ioctl_ops();
+ unsigned int mounted;
+
+ ops->ismountpoint(LOGOPT_NONE, -1, path, &mounted);
+ if (mounted) {
+ switch (type) {
+ case MNTS_ALL:
+ return 1;
+ case MNTS_AUTOFS:
+ return (mounted & DEV_IOCTL_IS_AUTOFS);
+ case MNTS_REAL:
+ return (mounted & DEV_IOCTL_IS_OTHER);
+ }
+ }
+ return 0;
+}
+
+int is_mounted(const char *table, const char *path, unsigned int type)
+{
+ struct ioctl_ops *ops = get_ioctl_ops();
+
+ if (ops->version)
+ return ioctl_is_mounted(path, type);
+ else
+ return table_is_mounted(table, path, type);
+}
+
int has_fstab_option(const char *opt)
{
struct mntent *mnt;
autofs-5.0.3-unlink-mount-return-fix.patch:
--- NEW FILE autofs-5.0.3-unlink-mount-return-fix.patch ---
diff --git a/CHANGELOG b/CHANGELOG
index eb4cce1..a0c7fa3 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -7,6 +7,7 @@
- use libldap instead of libldap_r (Guillaume Rousse).
- another fix for don't fail on empty master map.
- fix expire working harder than needed.
+- fix unlink of mount tree incorrectly causing autofs mount fail.
14/01/2008 autofs-5.0.3
-----------------------
diff --git a/daemon/direct.c b/daemon/direct.c
index 760fbd4..8d1e9c6 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -275,7 +275,6 @@ static int unlink_mount_tree(struct autofs_point *ap, struct list_head *list)
else
rv = umount2(mnt->path, MNT_DETACH);
if (rv == -1) {
- ret = 0;
debug(ap->logopt,
"can't unlink %s from mount tree", mnt->path);
@@ -287,6 +286,7 @@ static int unlink_mount_tree(struct autofs_point *ap, struct list_head *list)
case ENOENT:
case EFAULT:
+ ret = 0;
warn(ap->logopt, "bad path for mount");
break;
}
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 39b42da..f0409ac 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -65,7 +65,6 @@ static int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts)
else
rv = umount2(this->path, MNT_DETACH);
if (rv == -1) {
- ret = 0;
debug(ap->logopt,
"can't unlink %s from mount tree", this->path);
@@ -77,6 +76,7 @@ static int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts)
case ENOENT:
case EFAULT:
+ ret = 0;
warn(ap->logopt, "bad path for mount");
break;
}
Index: autofs.spec
===================================================================
RCS file: /cvs/pkgs/rpms/autofs/devel/autofs.spec,v
retrieving revision 1.233
retrieving revision 1.234
diff -u -r1.233 -r1.234
--- autofs.spec 1 Feb 2008 07:12:55 -0000 1.233
+++ autofs.spec 25 Feb 2008 00:40:55 -0000 1.234
@@ -4,7 +4,7 @@
Summary: A tool for automatically mounting and unmounting filesystems
Name: autofs
Version: 5.0.3
-Release: 5
+Release: 6
Epoch: 1
License: GPL
Group: System Environment/Daemons
@@ -16,6 +16,12 @@
Patch4: autofs-5.0.3-nfs4-tcp-only.patch
Patch5: autofs-5.0.3-correct-ldap-lib.patch
Patch6: autofs-5.0.3-dont-fail-on-empty-master-fix-2.patch
+Patch7: autofs-5.0.3-expire-works-too-hard.patch
+Patch8: autofs-5.0.3-unlink-mount-return-fix.patch
+Patch9: autofs-5.0.3-device-node-control.patch
+Patch10: autofs-5.0.3-active-restart.patch
+Patch11: autofs-5.0.3-device-node-and-active-restart-fixes.patch
+Patch12: autofs-5.0.3-make-is_mounted-use-dev-ioctl.patch
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, libxml2-devel, cyrus-sasl-devel, openssl-devel module-init-tools util-linux nfs-utils e2fsprogs
Conflicts: kernel < 2.6.17
@@ -63,6 +69,12 @@
%patch4 -p1
%patch5 -p1
%patch6 -p1
+%patch7 -p1
+%patch8 -p1
+%patch9 -p1
+%patch10 -p1
+%patch11 -p1
+%patch12 -p1
%build
#CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir}
@@ -115,6 +127,14 @@
%{_libdir}/autofs/
%changelog
+* Mon Feb 25 2008 Ian Kent <ikent at redhat.com> - 5.0.3-6
+- fix expire calling kernel more often than needed.
+- fix unlink of mount tree incorrectly causing autofs mount fail.
+- add miscellaneous device node interface library.
+- use miscellaneous device node, if available, for active restart.
+- device node and active restart fixes.
+- update is_mounted to use device node ioctl, if available.
+
* Fri Feb 1 2008 Ian Kent <ikent at redhat.com> - 5.0.3-5
- another fix for don't fail on empty master map.
- Previous message (by thread): rpms/kernel-xen-2.6/devel kernel.spec,1.12,1.13
- Next message (by thread): rpms/cernlib/devel cernlib-217-abend-on-mathlib-test-failure.dpatch, NONE, 1.1 .cvsignore, 1.9, 1.10 cernlib-102-dont-optimize-some-code.dpatch, 1.2, 1.3 cernlib-216-use-cernlib-gamma-not-intrinsic.dpatch, 1.1, 1.2 cernlib-304-update-Imake-config-files.dpatch, 1.3, 1.4 cernlib-321-support-gfortran.dpatch, 1.4, 1.5 cernlib-800-implement-shared-library-rules-in-Imake.dpatch, 1.2, 1.3 cernlib.spec, 1.68, 1.69 paw-108-quote-protect-comis-script.dpatch, 1.1, 1.2 paw-200-comis-allow-special-chars-in-path.dpatch, 1.1, 1.2 paw-211-support-amd64-and-itanium.dpatch, 1.1, 1.2 paw-308-use-canonical-cfortran-location.dpatch, 1.1, 1.2 paw-320-support-ifort-and-gfortran.dpatch, 1.1, 1.2 paw-803-link-binaries-dynamically.dpatch, 1.1, 1.2 paw-804-workaround-for-comis-mdpool-struct-location.dpatch, 1.1, 1.2 sources, 1.10, 1.11
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the fedora-extras-commits
mailing list