diff options
author | Benjamin Coddington <bcodding@redhat.com> | 2014-12-08 15:34:51 -0500 |
---|---|---|
committer | Steve Dickson <steved@redhat.com> | 2015-01-23 14:08:18 -0500 |
commit | 5bea22e33b7a0f1d2348100cbefbe45dd49cb23d (patch) | |
tree | 9284fc0ce002d612b2fd6c870dfbeedd0f0f92c1 /utils/mount/network.c | |
parent | 0ffc25463b3e6c5a87c14f782a7c1d19b13d318f (diff) | |
download | nfs-utils-5bea22e33b7a0f1d2348100cbefbe45dd49cb23d.tar.gz nfs-utils-5bea22e33b7a0f1d2348100cbefbe45dd49cb23d.tar.xz nfs-utils-5bea22e33b7a0f1d2348100cbefbe45dd49cb23d.zip |
mount.nfs: Add struct nfs_version and generalize version parsing
The nfs_version needs to carry major, minor, and basic mode information to
allow decisions to be made to override, discard, or negotiate various
versions. Update nfs_nfs_version() to work against this struct and set the
various modes. This change also makes nfs_nfs_version() parse properly
for future version number additions.
The general rules for version.v_mode are
- not set V_DEFAULT
- single digit => 4 V_GENERAL
- single digit < 4 V_SPECIFIC
- decimal included V_SPECIFIC
- miss all others V_PARSE_ERR
Signed-off-by: Benjamin Coddington <bcodding@redhat.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
Diffstat (limited to 'utils/mount/network.c')
-rw-r--r-- | utils/mount/network.c | 122 |
1 files changed, 60 insertions, 62 deletions
diff --git a/utils/mount/network.c b/utils/mount/network.c index 4f8c15c..b5ed850 100644 --- a/utils/mount/network.c +++ b/utils/mount/network.c @@ -92,9 +92,6 @@ static const char *nfs_version_opttbl[] = { "v4", "vers", "nfsvers", - "v4.0", - "v4.1", - "v4.2", NULL, }; @@ -1242,71 +1239,69 @@ nfs_nfs_program(struct mount_options *options, unsigned long *program) * or FALSE if the option was specified with an invalid value. */ int -nfs_nfs_version(struct mount_options *options, unsigned long *version) +nfs_nfs_version(struct mount_options *options, struct nfs_version *version) { - long tmp; + char *version_key, *version_val, *cptr; + int i, found = 0; - switch (po_rightmost(options, nfs_version_opttbl)) { - case 0: /* v2 */ - *version = 2; - return 1; - case 1: /* v3 */ - *version = 3; - return 1; - case 2: /* v4 */ - *version = 4; - return 1; - case 3: /* vers */ - switch (po_get_numeric(options, "vers", &tmp)) { - case PO_FOUND: - if (tmp >= 2 && tmp <= 4) { - *version = tmp; - return 1; - } - nfs_error(_("%s: parsing error on 'vers=' option\n"), - progname); - return 0; - case PO_NOT_FOUND: - nfs_error(_("%s: parsing error on 'vers=' option\n"), - progname); - return 0; - case PO_BAD_VALUE: - nfs_error(_("%s: invalid value for 'vers=' option"), - progname); - return 0; - } - case 4: /* nfsvers */ - switch (po_get_numeric(options, "nfsvers", &tmp)) { - case PO_FOUND: - if (tmp >= 2 && tmp <= 4) { - *version = tmp; - return 1; - } - nfs_error(_("%s: parsing error on 'nfsvers=' option\n"), - progname); - return 0; - case PO_NOT_FOUND: - nfs_error(_("%s: parsing error on 'nfsvers=' option\n"), - progname); - return 0; - case PO_BAD_VALUE: - nfs_error(_("%s: invalid value for 'nfsvers=' option"), - progname); - return 0; + version->v_mode = V_DEFAULT; + + for (i = 0; nfs_version_opttbl[i]; i++) { + if (po_contains_prefix(options, nfs_version_opttbl[i], + &version_key) == PO_FOUND) { + found++; + break; } - case 5: /* v4.0 */ - case 6: /* v4.1 */ - case 7: /* v4.2 */ - *version = 4; + } + + if (!found) return 1; + + if (i <= 2 ) { + /* v2, v3, v4 */ + version_val = version_key + 1; + version->v_mode = V_SPECIFIC; + } else if (i > 2 ) { + /* vers=, nfsvers= */ + version_val = po_get(options, version_key); } - /* - * NFS version wasn't specified. The pmap version value - * will be filled in later by an rpcbind query in this case. - */ - *version = 0; + if (!version_val) + goto ret_error; + + if (!(version->major = strtol(version_val, &cptr, 10))) + goto ret_error; + + if (version->major < 4) + version->v_mode = V_SPECIFIC; + + if (*cptr == '.') { + version_val = ++cptr; + if (!(version->minor = strtol(version_val, &cptr, 10)) && cptr == version_val) + goto ret_error; + version->v_mode = V_SPECIFIC; + } else if (version->major > 3 && *cptr == '\0') + version->v_mode = V_GENERAL; + + if (*cptr != '\0') + goto ret_error; + return 1; + +ret_error: + if (i <= 2 ) { + nfs_error(_("%s: parsing error on 'v' option"), + progname); + } else if (i == 3 ) { + nfs_error(_("%s: parsing error on 'vers=' option"), + progname); + } else if (i == 4) { + nfs_error(_("%s: parsing error on 'nfsvers=' option"), + progname); + } + version->v_mode = V_PARSE_ERR; + errno = EINVAL; + return 0; } /* @@ -1625,10 +1620,13 @@ out_err: int nfs_options2pmap(struct mount_options *options, struct pmap *nfs_pmap, struct pmap *mnt_pmap) { + struct nfs_version version; + if (!nfs_nfs_program(options, &nfs_pmap->pm_prog)) return 0; - if (!nfs_nfs_version(options, &nfs_pmap->pm_vers)) + if (!nfs_nfs_version(options, &version)) return 0; + nfs_pmap->pm_vers = version.major; if (!nfs_nfs_protocol(options, &nfs_pmap->pm_prot)) return 0; if (!nfs_nfs_port(options, &nfs_pmap->pm_port)) |