From 5ec16e526bf19bd6bdaa39e9d18d316ad406102d Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Feb 24 2012 02:16:04 +0000 Subject: * Fri Feb 24 2012 Ian Kent - 1:5.0.6-12 - ignore duplicate exports in auto.net. - add kernel verion check function. - add function to check mount.nfs version. - reinstate singleton mount probe. - rework error return handling in rpc code. - catch EHOSTUNREACH and bail out early. - systemd support fixes. - fix segmentation fault in do_remount_indirect(). --- diff --git a/autofs-5.0.6-add-function-to-check-mount-nfs-version.patch b/autofs-5.0.6-add-function-to-check-mount-nfs-version.patch new file mode 100644 index 0000000..c95d6d1 --- /dev/null +++ b/autofs-5.0.6-add-function-to-check-mount-nfs-version.patch @@ -0,0 +1,323 @@ +autofs-5.0.6 - add function to check mount.nfs version + +From: Ian Kent + +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 + #include + #include ++#include ++#include + #include + #include + #include +@@ -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 + */ diff --git a/autofs-5.0.6-add-kernel-verion-check-function.patch b/autofs-5.0.6-add-kernel-verion-check-function.patch new file mode 100644 index 0000000..7309178 --- /dev/null +++ b/autofs-5.0.6-add-kernel-verion-check-function.patch @@ -0,0 +1,55 @@ +autofs-5.0.6 - add kernel verion check function + +From: Ian Kent + +Add a function to check kernel version. +--- + + CHANGELOG | 1 + + include/mounts.h | 17 +++++++++++++++++ + 2 files changed, 18 insertions(+) + + +--- autofs-5.0.6.orig/CHANGELOG ++++ autofs-5.0.6/CHANGELOG +@@ -24,6 +24,7 @@ + - add sss lookup module. + - teach automount about sss source. + - ignore duplicate exports in auto.net. ++- add kernel verion check function. + + 28/06/2011 autofs-5.0.6 + ----------------------- +--- autofs-5.0.6.orig/include/mounts.h ++++ autofs-5.0.6/include/mounts.h +@@ -16,6 +16,9 @@ + #ifndef MOUNTS_H + #define MOUNTS_H + ++#include ++#include ++ + #ifndef AUTOFS_TYPE_ANY + #define AUTOFS_TYPE_ANY 0x0000 + #endif +@@ -72,6 +75,20 @@ struct mnt_list { + struct list_head ordered; + }; + ++static inline unsigned int linux_version_code(void) ++{ ++ struct utsname my_utsname; ++ unsigned int p, q, r; ++ ++ if (uname(&my_utsname)) ++ return 0; ++ ++ p = (unsigned int)atoi(strtok(my_utsname.release, ".")); ++ q = (unsigned int)atoi(strtok(NULL, ".")); ++ r = (unsigned int)atoi(strtok(NULL, ".")); ++ return KERNEL_VERSION(p, q, r); ++} ++ + unsigned int query_kproto_ver(void); + unsigned int get_kver_major(void); + unsigned int get_kver_minor(void); diff --git a/autofs-5.0.6-catch-EHOSTUNREACH-and-bail-out-early.patch b/autofs-5.0.6-catch-EHOSTUNREACH-and-bail-out-early.patch new file mode 100644 index 0000000..1847b5c --- /dev/null +++ b/autofs-5.0.6-catch-EHOSTUNREACH-and-bail-out-early.patch @@ -0,0 +1,166 @@ +autofs-5.0.6 - catch EHOSTUNREACH and bail out early + +From: Ian Kent + +Now that the lower layers of the rpc code has been reworked +to propogate error returns up to the top level code we can +catch the EHOSTUNREACH return and stop the probe since the +host isn't responding. + +Also, since UDP is a broadcast protocol we don't get the +EHOSTUNREACH and always have to wait, so change the probe +order to try TCP first. Using UDP first was originally +done to reduce reserved port usage but autofs probing uses +higher numbered ports now so this shouldn't introduce +problem even for older implementations. +--- + + CHANGELOG | 1 + include/replicated.h | 3 ++ + modules/replicated.c | 55 +++++++++++++++++++++++++++++++++++++-------------- + 3 files changed, 44 insertions(+), 15 deletions(-) + + +--- autofs-5.0.6.orig/CHANGELOG ++++ autofs-5.0.6/CHANGELOG +@@ -28,6 +28,7 @@ + - add function to check mount.nfs version. + - reinstate singleton mount probe. + - rework error return handling in rpc code. ++- catch EHOSTUNREACH and bail out early. + + 28/06/2011 autofs-5.0.6 + ----------------------- +--- autofs-5.0.6.orig/include/replicated.h ++++ autofs-5.0.6/include/replicated.h +@@ -48,6 +48,9 @@ + #define TCP_SELECTED_MASK 0x00FF + #define UDP_SELECTED_MASK 0xFF00 + ++#define IS_ERR(supported) (0x8000 & supported) ++#define ERR(supported) (IS_ERR(supported) ? (~supported + 1) : supported) ++ + #define RPC_TIMEOUT 5 + + struct host { +--- autofs-5.0.6.orig/modules/replicated.c ++++ autofs-5.0.6/modules/replicated.c +@@ -563,7 +563,9 @@ static unsigned int get_nfs_info(unsigne + status = rpc_udp_getclient(rpc_info, NFS_PROGRAM, NFS4_VERSION); + else + status = rpc_tcp_getclient(rpc_info, NFS_PROGRAM, NFS4_VERSION); +- if (!status) { ++ if (status == -EHOSTUNREACH) ++ return (unsigned int) status; ++ else if (!status) { + gettimeofday(&start, &tz); + status = rpc_ping_proto(rpc_info); + gettimeofday(&end, &tz); +@@ -589,7 +591,10 @@ v3_ver: + status = rpc_portmap_getclient(pm_info, + host->name, host->addr, host->addr_len, + proto, RPC_CLOSE_DEFAULT); +- if (status) ++ if (status == -EHOSTUNREACH) { ++ supported = status; ++ goto done_ver; ++ } else if (status) + goto done_ver; + } + +@@ -602,16 +607,23 @@ v3_ver: + } else { + parms.pm_prot = rpc_info->proto->p_proto; + parms.pm_vers = NFS3_VERSION; +- rpc_info->port = rpc_portmap_getport(pm_info, &parms); +- if (rpc_info->port < 0) ++ status = rpc_portmap_getport(pm_info, &parms); ++ if (status == -EHOSTUNREACH) { ++ supported = status; ++ goto done_ver; ++ } else if (status < 0) + goto v2_ver; ++ rpc_info->port = status; + } + + if (rpc_info->proto->p_proto == IPPROTO_UDP) + status = rpc_udp_getclient(rpc_info, NFS_PROGRAM, NFS3_VERSION); + else + status = rpc_tcp_getclient(rpc_info, NFS_PROGRAM, NFS3_VERSION); +- if (!status) { ++ if (status == -EHOSTUNREACH) { ++ supported = status; ++ goto done_ver; ++ } else if (!status) { + gettimeofday(&start, &tz); + status = rpc_ping_proto(rpc_info); + gettimeofday(&end, &tz); +@@ -643,15 +655,23 @@ v2_ver: + parms.pm_prot = rpc_info->proto->p_proto; + parms.pm_vers = NFS2_VERSION; + rpc_info->port = rpc_portmap_getport(pm_info, &parms); +- if (rpc_info->port < 0) ++ status = rpc_portmap_getport(pm_info, &parms); ++ if (status == -EHOSTUNREACH) { ++ supported = status; ++ goto done_ver; ++ } else if (status < 0) + goto done_ver; ++ rpc_info->port = status; + } + + if (rpc_info->proto->p_proto == IPPROTO_UDP) + status = rpc_udp_getclient(rpc_info, NFS_PROGRAM, NFS2_VERSION); + else + status = rpc_tcp_getclient(rpc_info, NFS_PROGRAM, NFS2_VERSION); +- if (!status) { ++ if (status == -EHOSTUNREACH) { ++ supported = status; ++ goto done_ver; ++ } else if (!status) { + gettimeofday(&start, &tz); + status = rpc_ping_proto(rpc_info); + gettimeofday(&end, &tz); +@@ -728,21 +748,24 @@ static int get_vers_and_cost(unsigned lo + + vers &= version; + +- if (version & UDP_REQUESTED) { ++ if (version & TCP_REQUESTED) { + supported = get_nfs_info(logopt, host, +- &pm_info, &rpc_info, "udp", vers, options); +- if (supported) { ++ &pm_info, &rpc_info, "tcp", vers, options); ++ if (IS_ERR(supported)) { ++ if (ERR(supported) == EHOSTUNREACH) ++ return ret; ++ } else if (supported) { + ret = 1; +- host->version |= (supported << 8); ++ host->version |= supported; + } + } + +- if (version & TCP_REQUESTED) { ++ if (version & UDP_REQUESTED) { + supported = get_nfs_info(logopt, host, +- &pm_info, &rpc_info, "tcp", vers, options); ++ &pm_info, &rpc_info, "udp", vers, options); + if (supported) { + ret = 1; +- host->version |= supported; ++ host->version |= (supported << 8); + } + } + +@@ -848,7 +871,9 @@ static int get_supported_ver_and_cost(un + status = rpc_udp_getclient(&rpc_info, NFS_PROGRAM, parms.pm_vers); + else + status = rpc_tcp_getclient(&rpc_info, NFS_PROGRAM, parms.pm_vers); +- if (!status) { ++ if (status == -EHOSTUNREACH) ++ goto done; ++ else if (!status) { + gettimeofday(&start, &tz); + status = rpc_ping_proto(&rpc_info); + gettimeofday(&end, &tz); diff --git a/autofs-5.0.6-fix-segmentation-fault-in-do-remount-indirect.patch b/autofs-5.0.6-fix-segmentation-fault-in-do-remount-indirect.patch new file mode 100644 index 0000000..9b16a97 --- /dev/null +++ b/autofs-5.0.6-fix-segmentation-fault-in-do-remount-indirect.patch @@ -0,0 +1,86 @@ +autofs-5.0.6 - fix segmentation fault in do_remount_indirect() + +From: Leonardo Chiquitto + +In some rare circumstance, it's possible that automount will crash +on startup while trying to reconnect to a "half-broken" NFS mount +point. + +The segmentation fault happens because we're not testing scandir()'s +return value in do_remount_indirect(): + +lib/mounts.c: +1210 i = j = scandir(buf, &de2, 0, alphasort); +1211 while (i--) +1212 free(de2[i]); + +So, if scandir() returns -1, it will try to free de2[-1], de2[-2], etc. + +Here's the call trace, for reference: + +Program terminated with signal 11, Segmentation fault. +#0 0x00007ffff7fe2425 in do_remount_indirect (ap=0x7ffff821e070, fd=15, + path=0x7ffff821e150 "/nfs/iil") at mounts.c:1212 +1212 free(de2[i]); +(gdb) print j +$1 = -1 +(gdb) print de2 +$3 = (struct dirent **) 0x0 + +#0 0x00007ffff7fe2425 in do_remount_indirect (ap=0x7ffff821e070, fd=15, + path=0x7ffff821e150 "/nfs/iil") at mounts.c:1212 +#1 0x00007ffff7fe2a48 in remount_active_mount (ap=0x7ffff821e070, mc=0x0, + path=0x7ffff821e150 "/nfs/iil", devid=20, type=, + ioctlfd=0x7ffff6e5babc) at mounts.c:1327 +#2 0x00007ffff7fe2ac6 in try_remount (ap=0x7ffff821e070, me=0x0, type=1) + at mounts.c:1357 +#3 0x00007ffff7fd35e0 in do_mount_autofs_indirect (root=, + ap=) at indirect.c:103 +#4 mount_autofs_indirect (ap=0x7ffff821e070, root=0x7ffff8202d50 "/nfs/iil") + at indirect.c:213 +#5 0x00007ffff7fd1473 in mount_autofs (root=, + ap=) at automount.c:1005 +#6 handle_mounts (arg=0x7fffffffdfd0) at automount.c:1526 +#7 0x00007ffff7b8e5f0 in start_thread (arg=) + at pthread_create.c:297 +#8 0x00007ffff6f3187d in clone () + at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112 +#9 0x0000000000000000 in ?? () + +Suggested fix: + +Check scandir() return value + +In some rare circumstance, it's possible that automount will crash +on startup while trying to reconnect to a "half-broken" NFS mount +point. +--- + + CHANGELOG | 1 + + lib/mounts.c | 4 ++++ + 2 files changed, 5 insertions(+) + + +--- autofs-5.0.6.orig/CHANGELOG ++++ autofs-5.0.6/CHANGELOG +@@ -30,6 +30,7 @@ + - rework error return handling in rpc code. + - catch EHOSTUNREACH and bail out early. + - systemd support fixes. ++- check scandir() return value. + + 28/06/2011 autofs-5.0.6 + ----------------------- +--- autofs-5.0.6.orig/lib/mounts.c ++++ autofs-5.0.6/lib/mounts.c +@@ -1355,6 +1355,10 @@ static int do_remount_indirect(struct au + int i, j; + + i = j = scandir(buf, &de2, 0, alphasort); ++ if (i < 0) { ++ free(de[n]); ++ continue; ++ } + while (i--) + free(de2[i]); + free(de2); diff --git a/autofs-5.0.6-ignore-duplicate-exports-in-auto-net.patch b/autofs-5.0.6-ignore-duplicate-exports-in-auto-net.patch new file mode 100644 index 0000000..66a91aa --- /dev/null +++ b/autofs-5.0.6-ignore-duplicate-exports-in-auto-net.patch @@ -0,0 +1,33 @@ +autofs-5.0.6 - ignore duplicate exports in auto.net + +From: Paul Smith + + +--- + + CHANGELOG | 1 + + samples/auto.net | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + + +--- autofs-5.0.6.orig/CHANGELOG ++++ autofs-5.0.6/CHANGELOG +@@ -23,6 +23,7 @@ + - fix rpc build error. + - add sss lookup module. + - teach automount about sss source. ++- ignore duplicate exports in auto.net. + + 28/06/2011 autofs-5.0.6 + ----------------------- +--- autofs-5.0.6.orig/samples/auto.net ++++ autofs-5.0.6/samples/auto.net +@@ -35,7 +35,7 @@ done + # Newer distributions get this right + SHOWMOUNT="$SMNT --no-headers -e $key" + +-$SHOWMOUNT | LC_ALL=C sort -k 1 | \ ++$SHOWMOUNT | LC_ALL=C cut -d' ' -f1 | LC_ALL=C sort -u | \ + awk -v key="$key" -v opts="$opts" -- ' + BEGIN { ORS=""; first=1 } + { if (first) { print opts; first=0 }; print " \\\n\t" $1, key ":" $1 } diff --git a/autofs-5.0.6-reinstate-singleton-mount-probe.patch b/autofs-5.0.6-reinstate-singleton-mount-probe.patch new file mode 100644 index 0000000..4e9a078 --- /dev/null +++ b/autofs-5.0.6-reinstate-singleton-mount-probe.patch @@ -0,0 +1,105 @@ +autofs-5.0.6 - reinstate singleton mount probe + +From: Ian Kent + +The change to have the kernel process text based mount options can +introduce lengthy timeout waits when attempting a mount to a host +that is not available. + +To avoid these waits autofs should probe singleton mounts if it +thinks mount.nfs will pass text options to the kernel (which of +course implies the kernel supports this). +--- + + CHANGELOG | 1 + + daemon/automount.c | 7 +++++++ + include/mounts.h | 1 + + modules/replicated.c | 18 ++++++++++++++++-- + 4 files changed, 25 insertions(+), 2 deletions(-) + + +--- autofs-5.0.6.orig/CHANGELOG ++++ autofs-5.0.6/CHANGELOG +@@ -26,6 +26,7 @@ + - ignore duplicate exports in auto.net. + - add kernel verion check function. + - add function to check mount.nfs version. ++- reinstate singleton mount probe. + + 28/06/2011 autofs-5.0.6 + ----------------------- +--- autofs-5.0.6.orig/daemon/automount.c ++++ autofs-5.0.6/daemon/automount.c +@@ -51,6 +51,9 @@ const char *libdir = AUTOFS_LIB_DIR; /* + const char *mapdir = AUTOFS_MAP_DIR; /* Location of mount maps */ + const char *confdir = AUTOFS_CONF_DIR; /* Location of autofs config file */ + ++unsigned int nfs_mount_uses_string_options = 0; ++static struct nfs_mount_vers vers, check = {1, 1, 1}; ++ + /* autofs fifo name prefix */ + const char *fifodir = AUTOFS_FIFO_DIR "/autofs.fifo"; + +@@ -1273,6 +1276,8 @@ static int do_hup_signal(struct master * + if (status) + fatal(status); + ++ nfs_mount_uses_string_options = check_nfs_mount_version(&vers, &check); ++ + master_mutex_lock(); + if (master->reading) { + status = pthread_mutex_unlock(&mrc.mutex); +@@ -1936,6 +1941,8 @@ int main(int argc, char *argv[]) + + defaults_read_config(0); + ++ nfs_mount_uses_string_options = check_nfs_mount_version(&vers, &check); ++ + kpkt_len = get_kpkt_len(); + timeout = defaults_get_timeout(); + ghost = defaults_get_browse_mode(); +--- autofs-5.0.6.orig/include/mounts.h ++++ autofs-5.0.6/include/mounts.h +@@ -95,6 +95,7 @@ struct nfs_mount_vers { + unsigned int fix; + }; + int check_nfs_mount_version(struct nfs_mount_vers *, struct nfs_mount_vers *); ++extern unsigned int nfs_mount_uses_string_options; + + unsigned int query_kproto_ver(void); + unsigned int get_kver_major(void); +--- autofs-5.0.6.orig/modules/replicated.c ++++ autofs-5.0.6/modules/replicated.c +@@ -901,6 +901,7 @@ int prune_host_list(unsigned logopt, str + unsigned int v2_udp_count, v3_udp_count, v4_udp_count; + unsigned int max_udp_count, max_tcp_count, max_count; + int status; ++ int kern_vers; + + if (!*list) + return 0; +@@ -920,9 +921,22 @@ int prune_host_list(unsigned logopt, str + * or a single host entry whose proximity isn't local. If so + * return immediately as we don't want to add probe latency for + * the common case of a single filesystem mount request. ++ * ++ * But, if the kernel understands text nfs mount options then ++ * mount.nfs most likely bypasses its probing and lets the kernel ++ * do all the work. This can lead to long timeouts for hosts that ++ * are not available so check the kernel version and mount.nfs ++ * version and probe singleton mounts if the kernel version is ++ * greater than 2.6.22 and mount.nfs version is greater than 1.1.1. + */ +- if (!this || !this->next) +- return 1; ++ if (nfs_mount_uses_string_options && ++ (kern_vers = linux_version_code()) > KERNEL_VERSION(2, 6, 22)) { ++ if (!this) ++ return 1; ++ } else { ++ if (!this || !this->next) ++ return 1; ++ } + + proximity = this->proximity; + while (this) { diff --git a/autofs-5.0.6-remove-empty-command-line-arguments.patch b/autofs-5.0.6-remove-empty-command-line-arguments.patch index 6c5c226..32ce534 100644 --- a/autofs-5.0.6-remove-empty-command-line-arguments.patch +++ b/autofs-5.0.6-remove-empty-command-line-arguments.patch @@ -17,11 +17,9 @@ getopt(3). 2 files changed, 36 insertions(+), 4 deletions(-) -diff --git a/CHANGELOG b/CHANGELOG -index d951b5a..8dec17f 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -19,6 +19,7 @@ +--- autofs-5.0.6.orig/CHANGELOG ++++ autofs-5.0.6/CHANGELOG +@@ -18,6 +18,7 @@ - fix ipv6 configure check. - add piddir to configure. - add systemd unit support. @@ -29,11 +27,9 @@ index d951b5a..8dec17f 100644 28/06/2011 autofs-5.0.6 ----------------------- -diff --git a/daemon/automount.c b/daemon/automount.c -index 6bb5aa8..c0b4b85 100644 ---- a/daemon/automount.c -+++ b/daemon/automount.c -@@ -1865,6 +1865,34 @@ static int convert_log_priority(char *priority_name) +--- autofs-5.0.6.orig/daemon/automount.c ++++ autofs-5.0.6/daemon/automount.c +@@ -1865,6 +1865,34 @@ static int convert_log_priority(char *pr return -1; } diff --git a/autofs-5.0.6-rework-error-return-handling-in-rpc-code.patch b/autofs-5.0.6-rework-error-return-handling-in-rpc-code.patch new file mode 100644 index 0000000..81be29c --- /dev/null +++ b/autofs-5.0.6-rework-error-return-handling-in-rpc-code.patch @@ -0,0 +1,618 @@ +autofs-5.0.6 - rework error return handling in rpc code + +From: Ian Kent + +With the changes to the way mount.nfs performs nfs mounts for +kernels that support passing of text based options mounts to +hosts that are down or unreachable can take a long time to +fail due to lengthy timeouts. The kernel rpc code is duty +bound to honour these timeouts so we need to find a way to +catch EHOSTUNREACH errors during host probing. + +The first thing to do is to rework the lower level autofs +rpc code to propogate error returns up to the higher levels. +--- + + CHANGELOG | 1 + lib/rpc_subs.c | 178 ++++++++++++++++++++++++++++----------------------- + modules/replicated.c | 26 +++---- + 3 files changed, 114 insertions(+), 91 deletions(-) + + +--- autofs-5.0.6.orig/CHANGELOG ++++ autofs-5.0.6/CHANGELOG +@@ -27,6 +27,7 @@ + - add kernel verion check function. + - add function to check mount.nfs version. + - reinstate singleton mount probe. ++- rework error return handling in rpc code. + + 28/06/2011 autofs-5.0.6 + ----------------------- +--- autofs-5.0.6.orig/lib/rpc_subs.c ++++ autofs-5.0.6/lib/rpc_subs.c +@@ -76,11 +76,11 @@ static int connect_nb(int fd, struct soc + + flags = fcntl(fd, F_GETFL, 0); + if (flags < 0) +- return -1; ++ return -errno; + + ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK); + if (ret < 0) +- return -1; ++ return -errno; + + /* + * From here on subsequent sys calls could change errno so +@@ -150,14 +150,16 @@ done: + } + + #ifndef WITH_LIBTIRPC +-static CLIENT *rpc_do_create_client(struct sockaddr *addr, struct conn_info *info, int *fd) ++static int rpc_do_create_client(struct sockaddr *addr, struct conn_info *info, int *fd, CLIENT **client) + { +- CLIENT *client = NULL; ++ CLIENT *clnt = NULL; + struct sockaddr_in in4_laddr; + struct sockaddr_in *in4_raddr; + int type, proto; + socklen_t slen; + ++ *client = NULL; ++ + proto = info->proto->p_proto; + if (proto == IPPROTO_UDP) + type = SOCK_DGRAM; +@@ -179,11 +181,11 @@ static CLIENT *rpc_do_create_client(stru + + *fd = open_sock(addr->sa_family, type, proto); + if (*fd < 0) +- return NULL; ++ return -errno; + + laddr = (struct sockaddr *) &in4_laddr; + if (bind(*fd, laddr, slen) < 0) +- return NULL; ++ return -errno; + } + + in4_raddr = (struct sockaddr_in *) addr; +@@ -191,26 +193,29 @@ static CLIENT *rpc_do_create_client(stru + + switch (info->proto->p_proto) { + case IPPROTO_UDP: +- client = clntudp_bufcreate(in4_raddr, +- info->program, info->version, +- info->timeout, fd, +- info->send_sz, info->recv_sz); ++ clnt = clntudp_bufcreate(in4_raddr, ++ info->program, info->version, ++ info->timeout, fd, ++ info->send_sz, info->recv_sz); + break; + + case IPPROTO_TCP: +- if (connect_nb(*fd, addr, slen, &info->timeout) < 0) +- break; +- +- client = clnttcp_create(in4_raddr, +- info->program, info->version, fd, +- info->send_sz, info->recv_sz); ++ int ret = connect_nb(*fd, addr, slen, &info->timeout); ++ if (ret < 0) ++ return ret; ++ ++ clnt = clnttcp_create(in4_raddr, ++ info->program, info->version, fd, ++ info->send_sz, info->recv_sz); + break; + + default: + break; + } + +- return client; ++ *client = clnt; ++ ++ return 0; + } + #else + struct netconfig *find_netconf(void *handle, char *family, char *proto) +@@ -226,9 +231,9 @@ struct netconfig *find_netconf(void *han + return nconf; + } + +-static CLIENT *rpc_do_create_client(struct sockaddr *addr, struct conn_info *info, int *fd) ++static int rpc_do_create_client(struct sockaddr *addr, struct conn_info *info, int *fd, CLIENT **client) + { +- CLIENT *client = NULL; ++ CLIENT *clnt = NULL; + struct sockaddr_in in4_laddr; + struct sockaddr_in6 in6_laddr; + struct sockaddr *laddr = NULL; +@@ -238,6 +243,9 @@ static CLIENT *rpc_do_create_client(stru + char *nc_family, *nc_proto; + void *handle; + size_t slen; ++ int ret; ++ ++ *client = NULL; + + proto = info->proto->p_proto; + if (proto == IPPROTO_UDP) { +@@ -272,16 +280,16 @@ static CLIENT *rpc_do_create_client(stru + slen = sizeof(struct sockaddr_in6); + nc_family = NC_INET6; + } else +- return NULL; ++ return -EINVAL; + + handle = setnetconfig(); + if (!handle) +- return NULL; ++ return -EINVAL; + + nconf = find_netconf(handle, nc_family, nc_proto); + if (!nconf) { + endnetconfig(handle); +- return NULL; ++ return -EINVAL; + } + + /* +@@ -292,13 +300,15 @@ static CLIENT *rpc_do_create_client(stru + if (!info->client) { + *fd = open_sock(addr->sa_family, type, proto); + if (*fd < 0) { ++ ret = -errno; + endnetconfig(handle); +- return NULL; ++ return ret; + } + + if (bind(*fd, laddr, slen) < 0) { ++ ret = -errno; + endnetconfig(handle); +- return NULL; ++ return ret; + } + } + +@@ -306,28 +316,30 @@ static CLIENT *rpc_do_create_client(stru + nb_addr.buf = addr; + + if (info->proto->p_proto == IPPROTO_TCP) { +- if (connect_nb(*fd, addr, slen, &info->timeout) < 0) { ++ ret = connect_nb(*fd, addr, slen, &info->timeout); ++ if (ret < 0) { + endnetconfig(handle); +- return NULL; ++ return ret; + } + } + +- client = clnt_tli_create(*fd, nconf, &nb_addr, +- info->program, info->version, +- info->send_sz, info->recv_sz); ++ clnt = clnt_tli_create(*fd, nconf, &nb_addr, ++ info->program, info->version, ++ info->send_sz, info->recv_sz); + + endnetconfig(handle); + +- return client; ++ *client = clnt; ++ ++ return 0; + } + #endif + + /* + * Create an RPC client + */ +-static CLIENT *create_client(struct conn_info *info) ++static int create_client(struct conn_info *info, CLIENT **client) + { +- CLIENT *client = NULL; + struct addrinfo *ai, *haddr; + struct addrinfo hints; + int fd, ret; +@@ -346,9 +358,11 @@ static CLIENT *create_client(struct conn + } + + if (info->addr) { +- client = rpc_do_create_client(info->addr, info, &fd); +- if (client) ++ ret = rpc_do_create_client(info->addr, info, &fd, client); ++ if (ret == 0) + goto done; ++ if (ret == -EHOSTUNREACH) ++ goto out_close; + + if (!info->client && fd != RPC_ANYSOCK) { + close(fd); +@@ -376,9 +390,11 @@ static CLIENT *create_client(struct conn + continue; + } + +- client = rpc_do_create_client(haddr->ai_addr, info, &fd); +- if (client) ++ ret = rpc_do_create_client(haddr->ai_addr, info, &fd, client); ++ if (ret == 0) + break; ++ if (ret == -EHOSTUNREACH) ++ goto out_close; + + if (!info->client && fd != RPC_ANYSOCK) { + close(fd); +@@ -390,24 +406,26 @@ static CLIENT *create_client(struct conn + + freeaddrinfo(ai); + +- if (!client) { ++ if (!*client) { + info->client = NULL; ++ ret = -ENOTCONN; + goto out_close; + } + done: + /* Close socket fd on destroy, as is default for rpcowned fds */ +- if (!clnt_control(client, CLSET_FD_CLOSE, NULL)) { +- clnt_destroy(client); ++ if (!clnt_control(*client, CLSET_FD_CLOSE, NULL)) { ++ clnt_destroy(*client); + info->client = NULL; ++ ret = -ENOTCONN; + goto out_close; + } + +- return client; ++ return 0; + + out_close: + if (fd != -1) + close(fd); +- return NULL; ++ return ret; + } + + int rpc_udp_getclient(struct conn_info *info, +@@ -415,11 +433,12 @@ int rpc_udp_getclient(struct conn_info * + { + struct protoent *pe_proto; + CLIENT *client; ++ int ret; + + if (!info->client) { + pe_proto = getprotobyname("udp"); + if (!pe_proto) +- return 0; ++ return -ENOENT; + + info->proto = pe_proto; + info->send_sz = UDPMSGSIZE; +@@ -429,14 +448,13 @@ int rpc_udp_getclient(struct conn_info * + info->program = program; + info->version = version; + +- client = create_client(info); +- +- if (!client) +- return 0; ++ ret = create_client(info, &client); ++ if (ret < 0) ++ return ret; + + info->client = client; + +- return 1; ++ return 0; + } + + void rpc_destroy_udp_client(struct conn_info *info) +@@ -454,11 +472,12 @@ int rpc_tcp_getclient(struct conn_info * + { + struct protoent *pe_proto; + CLIENT *client; ++ int ret; + + if (!info->client) { + pe_proto = getprotobyname("tcp"); + if (!pe_proto) +- return 0; ++ return -ENOENT; + + info->proto = pe_proto; + info->send_sz = 0; +@@ -468,14 +487,13 @@ int rpc_tcp_getclient(struct conn_info * + info->program = program; + info->version = version; + +- client = create_client(info); +- +- if (!client) +- return 0; ++ ret = create_client(info, &client); ++ if (ret < 0) ++ return ret; + + info->client = client; + +- return 1; ++ return 0; + } + + void rpc_destroy_tcp_client(struct conn_info *info) +@@ -509,10 +527,11 @@ int rpc_portmap_getclient(struct conn_in + { + struct protoent *pe_proto; + CLIENT *client; ++ int ret; + + pe_proto = getprotobyname(proto); + if (!pe_proto) +- return 0; ++ return -ENOENT; + + info->host = host; + info->addr = addr; +@@ -530,13 +549,14 @@ int rpc_portmap_getclient(struct conn_in + + if (pe_proto->p_proto == IPPROTO_TCP) + info->timeout.tv_sec = PMAP_TOUT_TCP; +- client = create_client(info); +- if (!client) +- return 0; ++ ++ ret = create_client(info, &client); ++ if (ret < 0) ++ return ret; + + info->client = client; + +- return 1; ++ return 0; + } + + unsigned short rpc_portmap_getport(struct conn_info *info, struct pmap *parms) +@@ -546,6 +566,7 @@ unsigned short rpc_portmap_getport(struc + CLIENT *client; + enum clnt_stat status; + int proto = info->proto->p_proto; ++ int ret; + + memset(&pmap_info, 0, sizeof(struct conn_info)); + +@@ -567,9 +588,9 @@ unsigned short rpc_portmap_getport(struc + pmap_info.send_sz = RPCSMALLMSGSIZE; + pmap_info.recv_sz = RPCSMALLMSGSIZE; + +- client = create_client(&pmap_info); +- if (!client) +- return 0; ++ ret = create_client(&pmap_info, &client); ++ if (ret < 0) ++ return ret; + } + + /* +@@ -611,7 +632,7 @@ unsigned short rpc_portmap_getport(struc + } + + if (status != RPC_SUCCESS) +- return 0; ++ return -EIO; + + return port; + } +@@ -621,6 +642,7 @@ int rpc_ping_proto(struct conn_info *inf + CLIENT *client; + enum clnt_stat status; + int proto = info->proto->p_proto; ++ int ret; + + if (info->client) + client = info->client; +@@ -629,9 +651,9 @@ int rpc_ping_proto(struct conn_info *inf + info->send_sz = UDPMSGSIZE; + info->recv_sz = UDPMSGSIZE; + } +- client = create_client(info); +- if (!client) +- return 0; ++ ret = create_client(info, &client); ++ if (ret < 0) ++ return ret; + } + + clnt_control(client, CLSET_TIMEOUT, (char *) &info->timeout); +@@ -665,7 +687,7 @@ int rpc_ping_proto(struct conn_info *inf + } + + if (status != RPC_SUCCESS) +- return 0; ++ return -EIO; + + return 1; + } +@@ -704,7 +726,7 @@ static unsigned int __rpc_ping(const cha + parms.pm_port = 0; + + info.port = rpc_portmap_getport(&info, &parms); +- if (!info.port) ++ if (info.port < 0) + return status; + + status = rpc_ping_proto(&info); +@@ -719,19 +741,19 @@ int rpc_ping(const char *host, long seco + unsigned int status; + + status = __rpc_ping(host, vers2, "udp", seconds, micros, option); +- if (status) ++ if (status > 0) + return RPC_PING_V2 | RPC_PING_UDP; + + status = __rpc_ping(host, vers3, "udp", seconds, micros, option); +- if (status) ++ if (status > 0) + return RPC_PING_V3 | RPC_PING_UDP; + + status = __rpc_ping(host, vers2, "tcp", seconds, micros, option); +- if (status) ++ if (status > 0) + return RPC_PING_V2 | RPC_PING_TCP; + + status = __rpc_ping(host, vers3, "tcp", seconds, micros, option); +- if (status) ++ if (status > 0) + return RPC_PING_V3 | RPC_PING_TCP; + + return status; +@@ -760,9 +782,8 @@ int rpc_time(const char *host, + status = __rpc_ping(host, vers, proto, seconds, micros, option); + gettimeofday(&end, &tz); + +- if (!status) { +- return 0; +- } ++ if (status == RPC_PING_FAIL || status < 0) ++ return status; + + taken = elapsed(start, end); + +@@ -779,13 +800,14 @@ static int rpc_get_exports_proto(struct + int proto = info->proto->p_proto; + unsigned int option = info->close_option; + int vers_entry; ++ int ret; + + if (info->proto->p_proto == IPPROTO_UDP) { + info->send_sz = UDPMSGSIZE; + info->recv_sz = UDPMSGSIZE; + } +- client = create_client(info); +- if (!client) ++ ret = create_client(info, &client); ++ if (ret < 0) + return 0; + + clnt_control(client, CLSET_TIMEOUT, (char *) &info->timeout); +@@ -894,7 +916,7 @@ exports rpc_get_exports(const char *host + parms.pm_prot = info.proto->p_proto; + + info.port = rpc_portmap_getport(&info, &parms); +- if (!info.port) ++ if (info.port < 0) + goto try_tcp; + + memset(&exportlist, '\0', sizeof(exportlist)); +@@ -911,7 +933,7 @@ try_tcp: + parms.pm_prot = info.proto->p_proto; + + info.port = rpc_portmap_getport(&info, &parms); +- if (!info.port) ++ if (info.port < 0) + return NULL; + + memset(&exportlist, '\0', sizeof(exportlist)); +--- autofs-5.0.6.orig/modules/replicated.c ++++ autofs-5.0.6/modules/replicated.c +@@ -563,11 +563,11 @@ static unsigned int get_nfs_info(unsigne + status = rpc_udp_getclient(rpc_info, NFS_PROGRAM, NFS4_VERSION); + else + status = rpc_tcp_getclient(rpc_info, NFS_PROGRAM, NFS4_VERSION); +- if (status) { ++ if (!status) { + gettimeofday(&start, &tz); + status = rpc_ping_proto(rpc_info); + gettimeofday(&end, &tz); +- if (status) { ++ if (status > 0) { + double reply; + if (random_selection) { + /* Random value between 0 and 1 */ +@@ -589,7 +589,7 @@ v3_ver: + status = rpc_portmap_getclient(pm_info, + host->name, host->addr, host->addr_len, + proto, RPC_CLOSE_DEFAULT); +- if (!status) ++ if (status) + goto done_ver; + } + +@@ -603,7 +603,7 @@ v3_ver: + parms.pm_prot = rpc_info->proto->p_proto; + parms.pm_vers = NFS3_VERSION; + rpc_info->port = rpc_portmap_getport(pm_info, &parms); +- if (!rpc_info->port) ++ if (rpc_info->port < 0) + goto v2_ver; + } + +@@ -611,11 +611,11 @@ v3_ver: + status = rpc_udp_getclient(rpc_info, NFS_PROGRAM, NFS3_VERSION); + else + status = rpc_tcp_getclient(rpc_info, NFS_PROGRAM, NFS3_VERSION); +- if (status) { ++ if (!status) { + gettimeofday(&start, &tz); + status = rpc_ping_proto(rpc_info); + gettimeofday(&end, &tz); +- if (status) { ++ if (status > 0) { + double reply; + if (random_selection) { + /* Random value between 0 and 1 */ +@@ -643,7 +643,7 @@ v2_ver: + parms.pm_prot = rpc_info->proto->p_proto; + parms.pm_vers = NFS2_VERSION; + rpc_info->port = rpc_portmap_getport(pm_info, &parms); +- if (!rpc_info->port) ++ if (rpc_info->port < 0) + goto done_ver; + } + +@@ -651,11 +651,11 @@ v2_ver: + status = rpc_udp_getclient(rpc_info, NFS_PROGRAM, NFS2_VERSION); + else + status = rpc_tcp_getclient(rpc_info, NFS_PROGRAM, NFS2_VERSION); +- if (status) { ++ if (!status) { + gettimeofday(&start, &tz); + status = rpc_ping_proto(rpc_info); + gettimeofday(&end, &tz); +- if (status) { ++ if (status > 0) { + double reply; + if (random_selection) { + /* Random value between 0 and 1 */ +@@ -835,12 +835,12 @@ static int get_supported_ver_and_cost(un + int ret = rpc_portmap_getclient(&pm_info, + host->name, host->addr, host->addr_len, + proto, RPC_CLOSE_DEFAULT); +- if (!ret) ++ if (ret) + return 0; + + parms.pm_prot = rpc_info.proto->p_proto; + rpc_info.port = rpc_portmap_getport(&pm_info, &parms); +- if (!rpc_info.port) ++ if (rpc_info.port < 0) + goto done; + } + +@@ -848,11 +848,11 @@ static int get_supported_ver_and_cost(un + status = rpc_udp_getclient(&rpc_info, NFS_PROGRAM, parms.pm_vers); + else + status = rpc_tcp_getclient(&rpc_info, NFS_PROGRAM, parms.pm_vers); +- if (status) { ++ if (!status) { + gettimeofday(&start, &tz); + status = rpc_ping_proto(&rpc_info); + gettimeofday(&end, &tz); +- if (status) { ++ if (status > 0) { + if (random_selection) { + /* Random value between 0 and 1 */ + taken = ((float) random())/((float) RAND_MAX+1); diff --git a/autofs-5.0.6-systemd-support-fixes.patch b/autofs-5.0.6-systemd-support-fixes.patch new file mode 100644 index 0000000..e16f695 --- /dev/null +++ b/autofs-5.0.6-systemd-support-fixes.patch @@ -0,0 +1,101 @@ +autofs-5.0.6 - systemd support fixes + +From: Ian Kent + +Fix up some of in spec file systemd scriptlets. + +The pre-system package verion uninstall scriptlet has been commented +out in the tar spec file. It's is an example of what might need to +be done in a distro spec file. +--- + + CHANGELOG | 1 + + autofs.spec | 35 +++++++++++++++++++++++++++-------- + samples/autofs.service.in | 1 + + 3 files changed, 29 insertions(+), 8 deletions(-) + + +--- autofs-5.0.6.orig/CHANGELOG ++++ autofs-5.0.6/CHANGELOG +@@ -29,6 +29,7 @@ + - reinstate singleton mount probe. + - rework error return handling in rpc code. + - catch EHOSTUNREACH and bail out early. ++- systemd support fixes. + + 28/06/2011 autofs-5.0.6 + ----------------------- +--- autofs-5.0.6.orig/autofs.spec ++++ autofs-5.0.6/autofs.spec +@@ -105,27 +105,36 @@ install -m 644 redhat/autofs.sysconfig $ + + %post + %if %{with_systemd} +-/bin/systemctl daemon-reload >/dev/null 2>&1 || : ++if [ $1 -eq 1 ]; then ++ %{_bindir}/systemctl daemon-reload >/dev/null 2>&1 || : ++ # autofs has been approved to be enabled by default ++ %{_bindir}systemctl enable %{name}.service >/dev/null 2>&1 || : ++fi + %else +-chkconfig --add autofs ++if [ $1 -eq 1 ]; then ++ chkconfig --add autofs ++fi + %endif + + %preun +-if [ "$1" = 0 ] ; then + %if %{with_systemd} +- /bin/systemctl --no-reload disable autofs.service > /dev/null 2>&1 || : +- /bin/systemctl stop autofs.service > /dev/null 2>&1 || : ++if [ $1 -eq 0 ] ; then ++ %{_bindir}/systemctl --no-reload disable %{name}.service > /dev/null 2>&1 || : ++ %{_bindir}/systemctl stop %{name}.service > /dev/null 2>&1 || : ++fi + %else ++if [ $1 -eq 0 ] ; then + /sbin/service autofs stop > /dev/null 2>&1 || : + /sbin/chkconfig --del autofs +-%endif + fi ++%endif + + %postun + %if %{with_systemd} +-/bin/systemctl daemon-reload >/dev/null 2>&1 || : ++%{_bindir}/systemctl daemon-reload >/dev/null 2>&1 || : + if [ $1 -ge 1 ] ; then +- /bin/systemctl try-restart autofs.service >/dev/null 2>&1 || : ++ # Package upgrade, not removal ++ /bin/systemctl try-restart %{name}.service >/dev/null 2>&1 || : + fi + %else + if [ $1 -ge 1 ] ; then +@@ -133,6 +142,16 @@ if [ $1 -ge 1 ] ; then + fi + %endif + ++#%triggerun -- %{name} < $bla release ++## Save the current service runlevel info ++## User must manually run systemd-sysv-convert --apply %{name} ++## to migrate them to systemd targets ++#%{_bindir}/systemd-sysv-convert --save %{name} >/dev/null 2>&1 ||: ++# ++## Run these because the SysV package being removed won't do them ++#%{_sbindir}/chkconfig --del %{name} >/dev/null 2>&1 || : ++#%{_bindir}/systemctl try-restart %{name}.service >/dev/null 2>&1 || : ++ + %files + %defattr(-,root,root) + %doc CREDITS CHANGELOG INSTALL COPY* README* samples/ldap* samples/autofs.schema samples/autofs_ldap_auth.conf +--- autofs-5.0.6.orig/samples/autofs.service.in ++++ autofs-5.0.6/samples/autofs.service.in +@@ -7,6 +7,7 @@ Type=forking + PIDFile=@@autofspiddir@@/autofs.pid + EnvironmentFile=-@@autofsconfdir@@/autofs + ExecStart=@@sbindir@@/automount ${OPTIONS} --pid-file @@autofspiddir@@/autofs.pid ++ExecReload=/usr/bin/kill -HUP $MAINPID + + [Install] + WantedBy=multi-user.target diff --git a/autofs.spec b/autofs.spec index a1af347..4188f91 100644 --- a/autofs.spec +++ b/autofs.spec @@ -8,7 +8,7 @@ Summary: A tool for automatically mounting and unmounting filesystems Name: autofs Version: 5.0.6 -Release: 11%{?dist} +Release: 12%{?dist} Epoch: 1 License: GPLv2+ Group: System Environment/Daemons @@ -39,6 +39,14 @@ Patch23: autofs-5.0.6-fix-improve-mount-location-error-reporting.patch Patch24: autofs-5.0.6-fix-rpc-build-error.patch Patch25: autofs-5.0.6-add-sss-lookup-module.patch Patch26: autofs-5.0.6-teach-automount-about-sss-source.patch +Patch27: autofs-5.0.6-ignore-duplicate-exports-in-auto-net.patch +Patch28: autofs-5.0.6-add-kernel-verion-check-function.patch +Patch29: autofs-5.0.6-add-function-to-check-mount-nfs-version.patch +Patch30: autofs-5.0.6-reinstate-singleton-mount-probe.patch +Patch31: autofs-5.0.6-rework-error-return-handling-in-rpc-code.patch +Patch32: autofs-5.0.6-catch-EHOSTUNREACH-and-bail-out-early.patch +Patch33: autofs-5.0.6-systemd-support-fixes.patch +Patch34: autofs-5.0.6-fix-segmentation-fault-in-do-remount-indirect.patch Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) %if %{with_systemd} BuildRequires: systemd-units @@ -120,6 +128,14 @@ echo %{version}-%{release} > .version %patch24 -p1 %patch25 -p1 %patch26 -p1 +%patch27 -p1 +%patch28 -p1 +%patch29 -p1 +%patch30 -p1 +%patch31 -p1 +%patch32 -p1 +%patch33 -p1 +%patch34 -p1 %build #CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir} @@ -203,6 +219,17 @@ fi %dir /etc/auto.master.d %changelog +* Fri Feb 24 2012 Ian Kent - 1:5.0.6-12 +- ignore duplicate exports in auto.net. +- add kernel verion check function. +- add function to check mount.nfs version. +- reinstate singleton mount probe. +- rework error return handling in rpc code. +- catch EHOSTUNREACH and bail out early. +- systemd support fixes. +- fix segmentation fault in do_remount_indirect(). + + * Thu Feb 9 2012 Ian Kent - 1:5.0.6-11 - fix fuzz in CHANGELOG hunk when applying patch26.