X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=utils%2Fmount%2Fstropts.c;h=024140082fcf56f65968453ca912158ab73f3668;hb=be5b2ed57b0e0a3da91f4ec785718302d0351199;hp=fc1b0da5da65a723ba6385a4f2bfbc34e339bab1;hpb=0f76458dd0f9a34210e44515a67d55e713a990ce;p=nfs-utils.git diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c index fc1b0da..0241400 100644 --- a/utils/mount/stropts.c +++ b/utils/mount/stropts.c @@ -538,7 +538,10 @@ nfs_rewrite_pmap_mount_options(struct mount_options *options) if (!nfs_construct_new_options(options, nfs_saddr, &nfs_pmap, mnt_saddr, &mnt_pmap)) { - errno = EINVAL; + if (rpc_createerr.cf_stat == RPC_UNKNOWNPROTO) + errno = EPROTONOSUPPORT; + else + errno = EINVAL; return 0; } @@ -576,12 +579,9 @@ static int nfs_sys_mount(struct nfsmount_info *mi, struct mount_options *opts) return !result; } -/* - * For "-t nfs vers=2" or "-t nfs vers=3" mounts. - */ -static int nfs_try_mount_v3v2(struct nfsmount_info *mi) +static int nfs_do_mount_v3v2(struct nfsmount_info *mi, + struct sockaddr *sap, socklen_t salen) { - struct addrinfo *ai = mi->address; struct mount_options *options = po_dup(mi->options); int result = 0; @@ -589,18 +589,21 @@ static int nfs_try_mount_v3v2(struct nfsmount_info *mi) errno = ENOMEM; return result; } - - if (!nfs_append_addr_option(ai->ai_addr, ai->ai_addrlen, options)) { - errno = EINVAL; + errno = 0; + if (!nfs_append_addr_option(sap, salen, options)) { + if (errno == 0) + errno = EINVAL; goto out_fail; } if (!nfs_fix_mounthost_option(options, mi->hostname)) { - errno = EINVAL; + if (errno == 0) + errno = EINVAL; goto out_fail; } if (!mi->fake && !nfs_verify_lock_option(options)) { - errno = EINVAL; + if (errno == 0) + errno = EINVAL; goto out_fail; } @@ -630,11 +633,36 @@ out_fail: } /* - * For "-t nfs -o vers=4" or "-t nfs4" mounts. + * Attempt a "-t nfs vers=2" or "-t nfs vers=3" mount. + * + * Returns TRUE if successful, otherwise FALSE. + * "errno" is set to reflect the individual error. */ -static int nfs_try_mount_v4(struct nfsmount_info *mi) +static int nfs_try_mount_v3v2(struct nfsmount_info *mi) +{ + struct addrinfo *ai; + int ret; + + for (ai = mi->address; ai != NULL; ai = ai->ai_next) { + ret = nfs_do_mount_v3v2(mi, ai->ai_addr, ai->ai_addrlen); + if (ret != 0) + return ret; + + switch (errno) { + case ECONNREFUSED: + case EOPNOTSUPP: + case EHOSTUNREACH: + continue; + default: + break; + } + } + return ret; +} + +static int nfs_do_mount_v4(struct nfsmount_info *mi, + struct sockaddr *sap, socklen_t salen) { - struct addrinfo *ai = mi->address; struct mount_options *options = po_dup(mi->options); int result = 0; @@ -662,12 +690,12 @@ static int nfs_try_mount_v4(struct nfsmount_info *mi) } } - if (!nfs_append_addr_option(ai->ai_addr, ai->ai_addrlen, options)) { + if (!nfs_append_addr_option(sap, salen, options)) { errno = EINVAL; goto out_fail; } - if (!nfs_append_clientaddr_option(ai->ai_addr, ai->ai_addrlen, options)) { + if (!nfs_append_clientaddr_option(sap, salen, options)) { errno = EINVAL; goto out_fail; } @@ -691,6 +719,33 @@ out_fail: return result; } +/* + * Attempt a "-t nfs -o vers=4" or "-t nfs4" mount. + * + * Returns TRUE if successful, otherwise FALSE. + * "errno" is set to reflect the individual error. + */ +static int nfs_try_mount_v4(struct nfsmount_info *mi) +{ + struct addrinfo *ai; + int ret; + + for (ai = mi->address; ai != NULL; ai = ai->ai_next) { + ret = nfs_do_mount_v4(mi, ai->ai_addr, ai->ai_addrlen); + if (ret != 0) + return ret; + + switch (errno) { + case ECONNREFUSED: + case EHOSTUNREACH: + continue; + default: + break; + } + } + return ret; +} + /* * This is a single pass through the fg/bg loop. * @@ -750,6 +805,7 @@ static int nfs_is_permanent_error(int error) case ESTALE: case ETIMEDOUT: case ECONNREFUSED: + case EHOSTUNREACH: return 0; /* temporary */ default: return 1; /* permanent */