Ian Kent 5ec16e5
autofs-5.0.6 - add function to check mount.nfs version
Ian Kent 5ec16e5
Ian Kent 5ec16e5
From: Ian Kent <ikent@redhat.com>
Ian Kent 5ec16e5
Ian Kent 5ec16e5
Add a function to check if the mount.nfs version is greater than or
Ian Kent 5ec16e5
equal to a given version.
Ian Kent 5ec16e5
---
Ian Kent 5ec16e5
Ian Kent 5ec16e5
 CHANGELOG           |    1 
Ian Kent 5ec16e5
 configure           |   62 +++++++++++++++++++++
Ian Kent 5ec16e5
 configure.in        |    1 
Ian Kent 5ec16e5
 include/config.h.in |    6 ++
Ian Kent 5ec16e5
 include/mounts.h    |    7 ++
Ian Kent 5ec16e5
 lib/mounts.c        |  147 ++++++++++++++++++++++++++++++++++++++++++++++++++++
Ian Kent 5ec16e5
 6 files changed, 224 insertions(+)
Ian Kent 5ec16e5
Ian Kent 5ec16e5
Ian Kent 5ec16e5
--- autofs-5.0.6.orig/CHANGELOG
Ian Kent 5ec16e5
+++ autofs-5.0.6/CHANGELOG
Ian Kent 5ec16e5
@@ -25,6 +25,7 @@
Ian Kent 5ec16e5
 - teach automount about sss source.
Ian Kent 5ec16e5
 - ignore duplicate exports in auto.net.
Ian Kent 5ec16e5
 - add kernel verion check function.
Ian Kent 5ec16e5
+- add function to check mount.nfs version.
Ian Kent 5ec16e5
 
Ian Kent 5ec16e5
 28/06/2011 autofs-5.0.6
Ian Kent 5ec16e5
 -----------------------
Ian Kent 5ec16e5
--- autofs-5.0.6.orig/configure
Ian Kent 5ec16e5
+++ autofs-5.0.6/configure
Ian Kent 5ec16e5
@@ -645,6 +645,8 @@ HAVE_E2FSCK
Ian Kent 5ec16e5
 E2FSCK
Ian Kent 5ec16e5
 HAVE_UMOUNT
Ian Kent 5ec16e5
 UMOUNT
Ian Kent 5ec16e5
+HAVE_MOUNT_NFS
Ian Kent 5ec16e5
+MOUNT_NFS
Ian Kent 5ec16e5
 HAVE_MOUNT
Ian Kent 5ec16e5
 MOUNT
Ian Kent 5ec16e5
 DMALLOCLIB
Ian Kent 5ec16e5
@@ -3248,6 +3250,66 @@ else
Ian Kent 5ec16e5
   HAVE_MOUNT=0
Ian Kent 5ec16e5
 fi
Ian Kent 5ec16e5
 
Ian Kent 5ec16e5
+for ac_prog in mount.nfs
Ian Kent 5ec16e5
+do
Ian Kent 5ec16e5
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
Ian Kent 5ec16e5
+set dummy $ac_prog; ac_word=$2
Ian Kent 5ec16e5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
Ian Kent 5ec16e5
+$as_echo_n "checking for $ac_word... " >&6; }
Ian Kent 5ec16e5
+if ${ac_cv_path_MOUNT_NFS+:} false; then :
Ian Kent 5ec16e5
+  $as_echo_n "(cached) " >&6
Ian Kent 5ec16e5
+else
Ian Kent 5ec16e5
+  case $MOUNT_NFS in
Ian Kent 5ec16e5
+  [\\/]* | ?:[\\/]*)
Ian Kent 5ec16e5
+  ac_cv_path_MOUNT_NFS="$MOUNT_NFS" # Let the user override the test with a path.
Ian Kent 5ec16e5
+  ;;
Ian Kent 5ec16e5
+  *)
Ian Kent 5ec16e5
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
Ian Kent 5ec16e5
+for as_dir in $searchpath
Ian Kent 5ec16e5
+do
Ian Kent 5ec16e5
+  IFS=$as_save_IFS
Ian Kent 5ec16e5
+  test -z "$as_dir" && as_dir=.
Ian Kent 5ec16e5
+    for ac_exec_ext in '' $ac_executable_extensions; do
Ian Kent 5ec16e5
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
Ian Kent 5ec16e5
+    ac_cv_path_MOUNT_NFS="$as_dir/$ac_word$ac_exec_ext"
Ian Kent 5ec16e5
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
Ian Kent 5ec16e5
+    break 2
Ian Kent 5ec16e5
+  fi
Ian Kent 5ec16e5
+done
Ian Kent 5ec16e5
+  done
Ian Kent 5ec16e5
+IFS=$as_save_IFS
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+  ;;
Ian Kent 5ec16e5
+esac
Ian Kent 5ec16e5
+fi
Ian Kent 5ec16e5
+MOUNT_NFS=$ac_cv_path_MOUNT_NFS
Ian Kent 5ec16e5
+if test -n "$MOUNT_NFS"; then
Ian Kent 5ec16e5
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MOUNT_NFS" >&5
Ian Kent 5ec16e5
+$as_echo "$MOUNT_NFS" >&6; }
Ian Kent 5ec16e5
+else
Ian Kent 5ec16e5
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
Ian Kent 5ec16e5
+$as_echo "no" >&6; }
Ian Kent 5ec16e5
+fi
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+  test -n "$MOUNT_NFS" && break
Ian Kent 5ec16e5
+done
Ian Kent 5ec16e5
+test -n "$MOUNT_NFS" || MOUNT_NFS="/sbin/mount.nfs "
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+if test -n "$MOUNT_NFS"; then
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+$as_echo "#define HAVE_MOUNT_NFS 1" >>confdefs.h
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+cat >>confdefs.h <<_ACEOF
Ian Kent 5ec16e5
+#define PATH_MOUNT_NFS "$MOUNT_NFS"
Ian Kent 5ec16e5
+_ACEOF
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+  HAVE_MOUNT_NFS=1
Ian Kent 5ec16e5
+else
Ian Kent 5ec16e5
+  HAVE_MOUNT_NFS=0
Ian Kent 5ec16e5
+fi
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
 for ac_prog in umount
Ian Kent 5ec16e5
 do
Ian Kent 5ec16e5
   # Extract the first word of "$ac_prog", so it can be a program name with args.
Ian Kent 5ec16e5
--- autofs-5.0.6.orig/configure.in
Ian Kent 5ec16e5
+++ autofs-5.0.6/configure.in
Ian Kent 5ec16e5
@@ -137,6 +137,7 @@ AC_SUBST(DMALLOCLIB)
Ian Kent 5ec16e5
 # Programs needed for various system functions or modules
Ian Kent 5ec16e5
 #
Ian Kent 5ec16e5
 AF_PATH_INCLUDE(MOUNT, mount, /bin/mount, $searchpath)
Ian Kent 5ec16e5
+AF_PATH_INCLUDE(MOUNT_NFS, mount.nfs, /sbin/mount.nfs , $searchpath)
Ian Kent 5ec16e5
 AF_PATH_INCLUDE(UMOUNT, umount, /bin/umount, $searchpath)
Ian Kent 5ec16e5
 AF_PATH_INCLUDE(E2FSCK, fsck.ext2 e2fsck, , $searchpath)
Ian Kent 5ec16e5
 AF_PATH_INCLUDE(E3FSCK, fsck.ext3 e3fsck, , $searchpath)
Ian Kent 5ec16e5
--- autofs-5.0.6.orig/include/config.h.in
Ian Kent 5ec16e5
+++ autofs-5.0.6/include/config.h.in
Ian Kent 5ec16e5
@@ -45,6 +45,9 @@
Ian Kent 5ec16e5
 /* define if you have MOUNT */
Ian Kent 5ec16e5
 #undef HAVE_MOUNT
Ian Kent 5ec16e5
 
Ian Kent 5ec16e5
+/* define if you have MOUNT_NFS */
Ian Kent 5ec16e5
+#undef HAVE_MOUNT_NFS
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
 /* define if the mount command supports the -s option */
Ian Kent 5ec16e5
 #undef HAVE_SLOPPY_MOUNT
Ian Kent 5ec16e5
 
Ian Kent 5ec16e5
@@ -111,6 +114,9 @@
Ian Kent 5ec16e5
 /* define if you have MOUNT */
Ian Kent 5ec16e5
 #undef PATH_MOUNT
Ian Kent 5ec16e5
 
Ian Kent 5ec16e5
+/* define if you have MOUNT_NFS */
Ian Kent 5ec16e5
+#undef PATH_MOUNT_NFS
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
 /* define if you have RANLIB */
Ian Kent 5ec16e5
 #undef PATH_RANLIB
Ian Kent 5ec16e5
 
Ian Kent 5ec16e5
--- autofs-5.0.6.orig/include/mounts.h
Ian Kent 5ec16e5
+++ autofs-5.0.6/include/mounts.h
Ian Kent 5ec16e5
@@ -89,6 +89,13 @@ static inline unsigned int linux_version
Ian Kent 5ec16e5
         return KERNEL_VERSION(p, q, r);
Ian Kent 5ec16e5
 }
Ian Kent 5ec16e5
 
Ian Kent 5ec16e5
+struct nfs_mount_vers {
Ian Kent 5ec16e5
+	unsigned int major;
Ian Kent 5ec16e5
+	unsigned int minor;
Ian Kent 5ec16e5
+	unsigned int fix;
Ian Kent 5ec16e5
+};
Ian Kent 5ec16e5
+int check_nfs_mount_version(struct nfs_mount_vers *, struct nfs_mount_vers *);
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
 unsigned int query_kproto_ver(void);
Ian Kent 5ec16e5
 unsigned int get_kver_major(void);
Ian Kent 5ec16e5
 unsigned int get_kver_minor(void);
Ian Kent 5ec16e5
--- autofs-5.0.6.orig/lib/mounts.c
Ian Kent 5ec16e5
+++ autofs-5.0.6/lib/mounts.c
Ian Kent 5ec16e5
@@ -19,6 +19,8 @@
Ian Kent 5ec16e5
 #include <sys/stat.h>
Ian Kent 5ec16e5
 #include <sys/ioctl.h>
Ian Kent 5ec16e5
 #include <sys/mount.h>
Ian Kent 5ec16e5
+#include <sys/wait.h>
Ian Kent 5ec16e5
+#include <ctype.h>
Ian Kent 5ec16e5
 #include <stdio.h>
Ian Kent 5ec16e5
 #include <dirent.h>
Ian Kent 5ec16e5
 #include <sys/vfs.h>
Ian Kent 5ec16e5
@@ -30,6 +32,8 @@
Ian Kent 5ec16e5
 #define MAX_OPTIONS_LEN		80
Ian Kent 5ec16e5
 #define MAX_MNT_NAME_LEN	30
Ian Kent 5ec16e5
 
Ian Kent 5ec16e5
+#define EBUFSIZ 1024
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
 const unsigned int t_indirect = AUTOFS_TYPE_INDIRECT;
Ian Kent 5ec16e5
 const unsigned int t_direct = AUTOFS_TYPE_DIRECT;
Ian Kent 5ec16e5
 const unsigned int t_offset = AUTOFS_TYPE_OFFSET;
Ian Kent 5ec16e5
@@ -131,6 +135,149 @@ unsigned int get_kver_minor(void)
Ian Kent 5ec16e5
 	return kver.minor;
Ian Kent 5ec16e5
 }
Ian Kent 5ec16e5
 
Ian Kent 5ec16e5
+#ifdef HAVE_MOUNT_NFS
Ian Kent 5ec16e5
+static int extract_version(char *start, struct nfs_mount_vers *vers)
Ian Kent 5ec16e5
+{
Ian Kent 5ec16e5
+	char *s_ver = strchr(start, ' ');
Ian Kent 5ec16e5
+	while (*s_ver && !isdigit(*s_ver)) {
Ian Kent 5ec16e5
+		s_ver++;
Ian Kent 5ec16e5
+		if (!*s_ver)
Ian Kent 5ec16e5
+			return 0;
Ian Kent 5ec16e5
+		break;
Ian Kent 5ec16e5
+	}
Ian Kent 5ec16e5
+	vers->major = atoi(strtok(s_ver, "."));
Ian Kent 5ec16e5
+	vers->minor = (unsigned int) atoi(strtok(NULL, "."));
Ian Kent 5ec16e5
+	vers->fix = (unsigned int) atoi(strtok(NULL, "."));
Ian Kent 5ec16e5
+	return 1;
Ian Kent 5ec16e5
+}
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+int check_nfs_mount_version(struct nfs_mount_vers *vers,
Ian Kent 5ec16e5
+			    struct nfs_mount_vers *check)
Ian Kent 5ec16e5
+{
Ian Kent 5ec16e5
+	pid_t f;
Ian Kent 5ec16e5
+	int ret, status, pipefd[2];
Ian Kent 5ec16e5
+	char errbuf[EBUFSIZ + 1], *p, *sp;
Ian Kent 5ec16e5
+	int errp, errn;
Ian Kent 5ec16e5
+	sigset_t allsigs, tmpsig, oldsig;
Ian Kent 5ec16e5
+	char *s_ver;
Ian Kent 5ec16e5
+	int cancel_state;
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+	if (pipe(pipefd))
Ian Kent 5ec16e5
+		return -1;
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state);
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+	sigfillset(&allsigs);
Ian Kent 5ec16e5
+	pthread_sigmask(SIG_BLOCK, &allsigs, &oldsig);
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+	f = fork();
Ian Kent 5ec16e5
+	if (f == 0) {
Ian Kent 5ec16e5
+		reset_signals();
Ian Kent 5ec16e5
+		close(pipefd[0]);
Ian Kent 5ec16e5
+		dup2(pipefd[1], STDOUT_FILENO);
Ian Kent 5ec16e5
+		dup2(pipefd[1], STDERR_FILENO);
Ian Kent 5ec16e5
+		close(pipefd[1]);
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+		execl(PATH_MOUNT_NFS, PATH_MOUNT_NFS, "-V", (char *) NULL);
Ian Kent 5ec16e5
+		_exit(255);	/* execv() failed */
Ian Kent 5ec16e5
+	}
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+	ret = 0;
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+	tmpsig = oldsig;
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+	sigaddset(&tmpsig, SIGCHLD);
Ian Kent 5ec16e5
+	pthread_sigmask(SIG_SETMASK, &tmpsig, NULL);
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+	close(pipefd[1]);
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+	if (f < 0) {
Ian Kent 5ec16e5
+		close(pipefd[0]);
Ian Kent 5ec16e5
+		pthread_sigmask(SIG_SETMASK, &oldsig, NULL);
Ian Kent 5ec16e5
+		pthread_setcancelstate(cancel_state, NULL);
Ian Kent 5ec16e5
+		return -1;
Ian Kent 5ec16e5
+	}
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+	errp = 0;
Ian Kent 5ec16e5
+	do {
Ian Kent 5ec16e5
+		while (1) {
Ian Kent 5ec16e5
+			errn = read(pipefd[0], errbuf + errp, EBUFSIZ - errp);
Ian Kent 5ec16e5
+			if (errn == -1 && errno == EINTR)
Ian Kent 5ec16e5
+				continue;
Ian Kent 5ec16e5
+			break;
Ian Kent 5ec16e5
+		}
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+		if (errn > 0) {
Ian Kent 5ec16e5
+			errp += errn;
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+			sp = errbuf;
Ian Kent 5ec16e5
+			while (errp && (p = memchr(sp, '\n', errp))) {
Ian Kent 5ec16e5
+				*p++ = '\0';
Ian Kent 5ec16e5
+				errp -= (p - sp);
Ian Kent 5ec16e5
+				sp = p;
Ian Kent 5ec16e5
+			}
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+			if (errp && sp != errbuf)
Ian Kent 5ec16e5
+				memmove(errbuf, sp, errp);
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+			if (errp >= EBUFSIZ) {
Ian Kent 5ec16e5
+				/* Line too long, split */
Ian Kent 5ec16e5
+				errbuf[errp] = '\0';
Ian Kent 5ec16e5
+				if ((s_ver = strstr(errbuf, "nfs-utils"))) {
Ian Kent 5ec16e5
+					if (extract_version(s_ver, vers))
Ian Kent 5ec16e5
+						ret = 1;
Ian Kent 5ec16e5
+				}
Ian Kent 5ec16e5
+				errp = 0;
Ian Kent 5ec16e5
+			}
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+			if ((s_ver = strstr(errbuf, "nfs-utils"))) {
Ian Kent 5ec16e5
+				if (extract_version(s_ver, vers))
Ian Kent 5ec16e5
+					ret = 1;
Ian Kent 5ec16e5
+			}
Ian Kent 5ec16e5
+		}
Ian Kent 5ec16e5
+	} while (errn > 0);
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+	close(pipefd[0]);
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+	if (errp > 0) {
Ian Kent 5ec16e5
+		/* End of file without \n */
Ian Kent 5ec16e5
+		errbuf[errp] = '\0';
Ian Kent 5ec16e5
+		if ((s_ver = strstr(errbuf, "nfs-utils"))) {
Ian Kent 5ec16e5
+			if (extract_version(s_ver, vers))
Ian Kent 5ec16e5
+				ret = 1;
Ian Kent 5ec16e5
+		}
Ian Kent 5ec16e5
+	}
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+	if (ret) {
Ian Kent 5ec16e5
+		if (vers->major == check->major &&
Ian Kent 5ec16e5
+		    vers->minor == check->minor &&
Ian Kent 5ec16e5
+		    vers->fix == check->fix)
Ian Kent 5ec16e5
+			;
Ian Kent 5ec16e5
+		else {
Ian Kent 5ec16e5
+			if (vers->major < check->major)
Ian Kent 5ec16e5
+				ret = 0;
Ian Kent 5ec16e5
+			else if (vers->minor < check->minor)
Ian Kent 5ec16e5
+				ret = 0;
Ian Kent 5ec16e5
+			else if (vers->fix < check->fix)
Ian Kent 5ec16e5
+				ret = 0;
Ian Kent 5ec16e5
+		}
Ian Kent 5ec16e5
+	}
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+	if (waitpid(f, &status, 0) != f) ;
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+	pthread_sigmask(SIG_SETMASK, &oldsig, NULL);
Ian Kent 5ec16e5
+	pthread_setcancelstate(cancel_state, NULL);
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
+	return ret;
Ian Kent 5ec16e5
+}
Ian Kent 5ec16e5
+#else
Ian Kent 5ec16e5
+int check_nfs_mount_version(struct nfs_mount_vers *vers,
Ian Kent 5ec16e5
+			    struct nfs_mount_vers *check)
Ian Kent 5ec16e5
+{
Ian Kent 5ec16e5
+	return 0;
Ian Kent 5ec16e5
+}
Ian Kent 5ec16e5
+#endif
Ian Kent 5ec16e5
+
Ian Kent 5ec16e5
 /*
Ian Kent 5ec16e5
  * Make common autofs mount options string
Ian Kent 5ec16e5
  */