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


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(&param);
+	param.ioctlfd = ioctlfd;
+	param.arg1 = when;
+
+	return expire(logopt, AUTOFS_DEV_IOCTL_EXPIRE,
+		      ctl.devfd, ioctlfd, path, (void *) &param);
+}
+
+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(&param);
+	param.ioctlfd = ioctlfd;
+
+	if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_ASKUMOUNT, &param) == -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.
 




More information about the fedora-extras-commits mailing list