| 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(+) |
| |
| |
| |
| |
| @@ -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 |
| ----------------------- |
| |
| |
| @@ -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. |
| |
| |
| @@ -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) |
| |
| |
| @@ -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 |
| |
| |
| |
| @@ -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); |
| |
| |
| @@ -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 |
| */ |