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