mount.nfs default version
Subsystems (2)
v2 cover mount.nfs default version
Here's the work posted yesterday broken out a bit with an addition of enabling nfsmount.conf by default, and the change to autonegotiate starting with version 4.2 (instead of 4.0) when no version is specified in either config or mount option.
Benjamin Coddington (6):
mount.nfs: default enable mount config file (nfsmount.conf) mount.nfs: fix a comment typo in parse options mount.nfs: parse options - add helper po_contains_prefix mount.nfs: Add struct nfs_version and generalize version parsing nfsmount.conf: Always parse versions
mount.nfs: configurable minor version defaults
configure.ac | 8 +- utils/mount/configfile.c | 36 +----------- utils/mount/network.c | 122 ++++++++++++++++++------------------- utils/mount/network.h | 15 ++++- utils/mount/nfsumount.c | 4 +- utils/mount/parse_opt.c | 26 ++++++++- utils/mount/parse_opt.h | 2 + utils/mount/stropts.c | 150 +++++++++++++++++++++++++++++++--------------- 8 files changed, 209 insertions(+), 154 deletions(-)
PATCH v2 1/6 mount.nfs: default enable mount config file (nfsmount.conf)
--- configure.ac | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-)
configure.ac +4 -4
@@ -178,8 +178,10 @@ if test "$enable_mount" = yes; then [AC_HELP_STRING([--enable-mountconfig], [enable mount to use a configuration file])], mountconfig=$enableval, - mountconfig=no) - if test "$enable_mountconfig" = yes; then + mountconfig=yes) + if test "$enable_mountconfig" = no; then + enable_mountconfig= + else AC_DEFINE(MOUNT_CONFIG, 1, [Define this if you want mount to read a configuration file]) AC_ARG_WITH(mountfile,
@@ -191,8 +193,6 @@ if test "$enable_mount" = yes; then AC_SUBST(mountfile) AC_DEFINE_UNQUOTED(MOUNTOPTS_CONFFILE, "$mountfile", [This defines the location of the NFS mount configuration file]) - else - enable_mountconfig= fi AC_SUBST(enable_mountconfig) AM_CONDITIONAL(MOUNT_CONFIG, [test "$enable_mountconfig" = "yes"])
Signature · 1 line
1.7.1
PATCH v2 2/6 mount.nfs: fix a comment typo in parse options
In reply to Benjamin Coddington--- utils/mount/parse_opt.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
utils/mount/parse_opt.c +1 -1
@@ -391,7 +391,7 @@ po_return_t po_append(struct mount_options *options, char *str) }/** -* po_contains - check for presense of an option in a group +* po_contains - check for presence of an option in a group * @options: pointer to mount options * @keyword: pointer to a C string containing option keyword for which to search *
Signature · 1 line
1.7.1
PATCH v2 3/6 mount.nfs: parse options - add helper po_contains_prefix
In reply to Benjamin CoddingtonThe version options (v2,v4,v4.2) may increase in the future, but they have a predictable prefix. Add a parse option helper to locate and return these options by prefix so that a future increment of version does not require the addition of strings to a search table.
--- utils/mount/parse_opt.c | 24 ++++++++++++++++++++++++ utils/mount/parse_opt.h | 2 ++ 2 files changed, 26 insertions(+), 0 deletions(-)
utils/mount/parse_opt.c +24 -0
@@ -410,6 +410,30 @@ po_found_t po_contains(struct mount_options *options, char *keyword) }/** +* po_contains_prefix - check for presence of an option matching a prefix +* @options: pointer to mount options +* @prefix: pointer to prefix to match against a keyword +* @keyword: pointer to a C string containing the option keyword if found +* +* On success, *keyword contains the pointer of the matching option's keyword. +*/ +po_found_t po_contains_prefix (struct mount_options *options, +const char *prefix,char **keyword) +{ +struct mount_option *option; + +if (options && prefix) { +for (option = options->head; option; option = option->next) +if (strncmp (option->keyword, prefix,strlen (prefix)) ==0 ) { + *keyword = option->keyword; +return PO_FOUND ; + } + } + +return PO_NOT_FOUND ; +} + +/** * po_get - return the value of the rightmost instance of an option * @options: pointer to mount options * @keyword: pointer to a C string containing option keyword for which to search
utils/mount/parse_opt.h +2 -0
@@ -45,6 +45,8 @@ po_return_t po_join(struct mount_options *, char **);po_return_t po_append (struct mount_options *,char *);po_found_t po_contains (struct mount_options *,char *); +po_found_t po_contains_prefix (struct mount_options *options, +const char *prefix,char **keyword);char *po_get (struct mount_options *,char *);po_found_t po_get_numeric (struct mount_options *,char *,long *);
Signature · 1 line
1.7.1
PATCH v2 4/6 mount.nfs: Add struct nfs_version and generalize version parsing
In reply to Benjamin CoddingtonThe 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
--- utils/mount/configfile.c | 2 +- utils/mount/network.c | 122 ++++++++++++++++++++++----------------------- utils/mount/network.h | 15 +++++- utils/mount/nfsumount.c | 4 +- utils/mount/stropts.c | 22 ++++---- 5 files changed, 88 insertions(+), 77 deletions(-)
utils/mount/configfile.c +1 -1
@@ -258,7 +258,7 @@ check_vers(char *mopt, char *field)return 0 ; } -unsigned long config_default_vers; +struct nfs_version config_default_vers;unsigned long config_default_proto;extern sa_family_t config_default_family;
utils/mount/network.c +60 -62
150 lines not on this page · raw message
utils/mount/network.h +14 -1
@@ -57,9 +57,22 @@ int clnt_ping(struct sockaddr_in *, const unsigned long,struct mount_options ; +enum { +V_DEFAULT =0 , +V_GENERAL , +V_SPECIFIC , +V_PARSE_ERR , +}; + +struct nfs_version { +unsigned long major; +unsigned long minor; +int v_mode; +}; +int nfs_nfs_proto_family (struct mount_options *options,sa_family_t *family);int nfs_mount_proto_family (struct mount_options *options,sa_family_t *family); -int nfs_nfs_version (struct mount_options *options,unsigned long *version); +int nfs_nfs_version (struct mount_options *options,struct nfs_version *version);int nfs_nfs_protocol (struct mount_options *options,unsigned long *protocol); int nfs_options2pmap(struct mount_options *,
utils/mount/nfsumount.c +2 -2
@@ -179,10 +179,10 @@ static int nfs_umount_is_vers4(const struct mntentchn *mc) options =po_split (pmc->m.mnt_opts);if (options !=NULL ) { -unsigned long version; +struct nfs_version version;int rc =nfs_nfs_version (options, &version);po_destroy (options); -if (rc && version ==4 ) +if (rc && version.major ==4 ) goto out_nfs4; }
utils/mount/stropts.c +11 -11
@@ -88,7 +88,7 @@ struct nfsmount_info {struct mount_options *options;/* parsed mount options */ char **extra_opts;/* string for /etc/mtab */ -unsigned long version;/* NFS version */ +struct nfs_version version;/* NFS version */ int flags,/* MS_ flags */ fake,/* actually do the mount? */ child;/* forked bg child? */
@@ -99,13 +99,13 @@ static void nfs_default_version(struct nfsmount_info *mi);static void nfs_default_version (struct nfsmount_info *mi) { -extern unsigned long config_default_vers; +extern struct nfs_version config_default_vers;/* * Use the default value set in the config file when * the version has not been explicitly set. */ -if (mi->version ==0 && config_default_vers) { -if (config_default_vers <4 ) +if (mi->version.major ==0 && config_default_vers.major) { +if (config_default_vers.major <4 ) mi->version = config_default_vers; } }
@@ -300,7 +300,7 @@ static int nfs_set_version(struct nfsmount_info *mi)return 0 ;if (strncmp (mi->type,"nfs4" ,4 ) ==0 ) - mi->version =4 ; + mi->version.major =4 ;/* * Before 2.6.32, the kernel NFS client didn't
@@ -308,20 +308,20 @@ static int nfs_set_version(struct nfsmount_info *mi)* 4 cannot be included when autonegotiating * while running on those kernels. */ -if (mi->version ==0 && +if (mi->version.major ==0 &&linux_version_code () <=MAKE_VERSION (2 ,6 ,31 )) - mi->version =3 ; + mi->version.major =3 ;/* * If we still don't know, check for version-specific * mount options. */ -if (mi->version ==0 ) { +if (mi->version.major ==0 ) {if (po_contains (mi->options,"mounthost" ) ||po_contains (mi->options,"mountaddr" ) ||po_contains (mi->options,"mountvers" ) ||po_contains (mi->options,"mountproto" )) - mi->version =3 ; + mi->version.major =3 ; }/*
@@ -691,7 +691,7 @@ static int nfs_do_mount_v4(struct nfsmount_info *mi,return result; } -if (mi->version ==0 ) { +if (mi->version.major ==0 ) { if (po_contains(options, "mounthost") || po_contains(options, "mountaddr") || po_contains(options, "mountvers") ||
@@ -839,7 +839,7 @@ static int nfs_try_mount(struct nfsmount_info *mi) {int result =0 ; -switch (mi->version) { +switch (mi->version.major) {case 0 : result =nfs_autonegotiate (mi);break ;
Signature · 1 line
1.7.1
PATCH v2 5/6 nfsmount.conf: Always parse versions
In reply to Benjamin CoddingtonIn order to make decisions about which default version to use when only the major version is specified, the nfsmount.conf Defaultvers options should always be parsed, even when a version has already been specified. Remove the check and bypass for parsing the Defaultvers options from nfsmount.conf.
--- utils/mount/configfile.c | 34 ---------------------------------- 1 files changed, 0 insertions(+), 34 deletions(-)
utils/mount/configfile.c +0 -34
@@ -228,35 +228,6 @@ void free_all(void)free (entry); } } -static char *versions[] = {"v2" ,"v3" ,"v4" ,"vers" ,"nfsvers" ,NULL }; -static int -check_vers (char *mopt,char *field) -{ -int i, found=0 ; - -/* -* First check to see if the config setting is one -* of the many version settings -*/ -for (i=0 ; versions[i]; i++) { -if (strcasestr (field, versions[i]) !=NULL ) { - found++; -break ; - } - } -if (!found) -return 0 ; -/* -* It appears the version is being set, now see -* if the version appears on the command -*/ -for (i=0 ; versions[i]; i++) { -if (strcasestr (mopt, versions[i]) !=NULL ) -return 1 ; - } - -return 0 ; -}struct nfs_version config_default_vers;unsigned long config_default_proto;
@@ -331,11 +302,6 @@ conf_parse_mntopts(char *section, char *arg, char *opts)snprintf (buf,BUFSIZ ,"%s=" , node->field);if (opts &&strcasestr (opts, buf) !=NULL )continue ; -/* -* Protocol verions can be set in a number of ways -*/ -if (opts &&check_vers (opts, node->field)) -continue ;if (lookup_entry (node->field) !=NULL )continue ;
Signature · 1 line
1.7.1
PATCH v2 6/6 mount.nfs: configurable minor version defaults
In reply to Benjamin CoddingtonUpdate nfsmount.conf to allow minor version specification, and rearrange the autonegotiation logic to agreed upon best behavior. Depending upon the combination of values specified within nfsmount.conf and given to mount.nfs, the retry behavior of mount.nfs varies according to the general rule of defaulting to the most specific setting, with some exceptions. A general guide to the expected behavior follows:
┌────────────────┐ │ nfsmount.conf ├──────────────┬───────────────────┐ │ Defaultvers= │ arg option │ attempts: │ ├────────────────┼──────────────┼───────────────────┤ │ 4.2 │ not set │ v4.2 v4.1 v4.0 v3 │ │ 4.2 │ v4 │ v4.2 v4.1 v4.0 │ │ 4.1 │ not set │ v4.1 v4.0 v3 │ │ 4.1 │ v4 │ v4.1 v4.0 │ │ 4 │ not set │ v4.0 v3 │ │ 4 │ v4 │ v4.0 │ │ 3 │ not set │ v3 │ │ any set │ v4.2 │ v4.2 │ │ any set │ v4.1 │ v4.1 │ │ any set │ v4 │ v4.0 │ │ any set │ v3 │ v3 │ │ not set │ not set │ v4.2 v4.1 v4.0 v3 │ └────────────────┴──────────────┴───────────────────┘
If built with --enable-mountconfig=no, then the behavior is the same as if nfsmount.conf did not set Defaultvers.
--- utils/mount/stropts.c | 138 +++++++++++++++++++++++++++++++++--------------- 1 files changed, 95 insertions(+), 43 deletions(-)
utils/mount/stropts.c +95 -43
@@ -94,24 +94,44 @@ struct nfsmount_info { child;/* forked bg child? */ }; -#ifdef MOUNT_CONFIG -static void nfs_default_version (struct nfsmount_info *mi);static void nfs_default_version (struct nfsmount_info *mi) { +#ifdef MOUNT_CONFIG extern struct nfs_version config_default_vers;/* * Use the default value set in the config file when * the version has not been explicitly set. */ -if (mi->version.major ==0 && config_default_vers.major) { -if (config_default_vers.major <4 ) - mi->version = config_default_vers; +if (config_default_vers.v_mode ==V_PARSE_ERR ) { + mi->version.v_mode =V_PARSE_ERR ; +return ; } -} -#else -inline void nfs_default_version (__attribute__ ((unused))struct nfsmount_info *mi) {} + +if (mi->version.v_mode ==V_GENERAL && + config_default_vers.v_mode ==V_DEFAULT ) { + mi->version.v_mode =V_SPECIFIC ; +return ; + } + +if (mi->version.v_mode ==V_DEFAULT && + config_default_vers.v_mode !=V_DEFAULT ) { + mi->version.major = config_default_vers.major; + mi->version.minor = config_default_vers.minor; +return ; + } + +if (mi->version.v_mode ==V_GENERAL && + config_default_vers.v_mode !=V_DEFAULT ) { +if (mi->version.major == config_default_vers.major) + mi->version.minor = config_default_vers.minor; +return ; + } +#endif /* MOUNT_CONFIG */ + mi->version.major =4 ; + mi->version.minor =2 ; +}/* * Obtain a retry timeout value based on the value of the "retry=" option.
@@ -308,28 +328,44 @@ static int nfs_set_version(struct nfsmount_info *mi)* 4 cannot be included when autonegotiating * while running on those kernels. */ -if (mi->version.major ==0 && -linux_version_code () <=MAKE_VERSION (2 ,6 ,31 )) +if (mi->version.v_mode ==V_DEFAULT && +linux_version_code () <=MAKE_VERSION (2 ,6 ,31 )) { mi->version.major =3 ; + mi->version.v_mode =V_SPECIFIC ; + }/* * If we still don't know, check for version-specific * mount options. */ -if (mi->version.major ==0 ) { +if (mi->version.v_mode ==V_DEFAULT ) {if (po_contains (mi->options,"mounthost" ) ||po_contains (mi->options,"mountaddr" ) ||po_contains (mi->options,"mountvers" ) || -po_contains (mi->options,"mountproto" )) +po_contains (mi->options,"mountproto" )) { mi->version.major =3 ; + mi->version.v_mode =V_SPECIFIC ; + } }/* * If enabled, see if the default version was * set in the config file */ -nfs_default_version (mi); - +if (mi->version.v_mode !=V_SPECIFIC ) { +nfs_default_version (mi); +/* +* If the version was not specifically set, it will +* be set by autonegotiation later, so remove it now: +*/ +po_remove_all (mi->options,"v4" ); +po_remove_all (mi->options,"vers" ); +po_remove_all (mi->options,"nfsvers" ); + } + +if (mi->version.v_mode ==V_PARSE_ERR ) +return 0 ; +return 1 ; }
@@ -684,6 +720,7 @@ static int nfs_do_mount_v4(struct nfsmount_info *mi, {struct mount_options *options =po_dup (mi->options);int result =0 ; +char version_opt[16 ];char *extra_opts =NULL ;if (!options) {
@@ -691,20 +728,24 @@ static int nfs_do_mount_v4(struct nfsmount_info *mi,return result; } -if (mi->version.major ==0 ) { -if (po_contains (options,"mounthost" ) || -po_contains (options,"mountaddr" ) || -po_contains (options,"mountvers" ) || -po_contains (options,"mountproto" )) { -/* -* Since these mountd options are set assume version 3 -* is wanted so error out with EPROTONOSUPPORT so the -* protocol negation starts with v3. -*/ - errno =EPROTONOSUPPORT ; - goto out_fail; - } -if (po_append (options,"vers=4" ) ==PO_FAILED ) { +if (po_contains (options,"mounthost" ) || +po_contains (options,"mountaddr" ) || +po_contains (options,"mountvers" ) || +po_contains (options,"mountproto" )) { +/* +* Since these mountd options are set assume version 3 +* is wanted so error out with EPROTONOSUPPORT so the +* protocol negation starts with v3. +*/ + errno =EPROTONOSUPPORT ; + goto out_fail; + } + +if (mi->version.v_mode !=V_SPECIFIC ) { +snprintf (version_opt,sizeof (version_opt) -1 , +"vers=%lu.%lu" , mi->version.major, mi->version.minor); + +if (po_append (options, version_opt) ==PO_FAILED ) { errno =EINVAL ; goto out_fail; }
@@ -792,14 +833,25 @@ static int nfs_autonegotiate(struct nfsmount_info *mi)int result; result =nfs_try_mount_v4 (mi); +check_result:if (result)return result; -check_errno:switch (errno) {case EPROTONOSUPPORT :/* A clear indication that the server or our -* client does not support NFS version 4. */ +* client does not support NFS version 4 and minor */ +if (mi->version.v_mode ==V_GENERAL && + mi->version.minor ==0 ) +return result; +if (mi->version.v_mode !=V_SPECIFIC ) { +if (mi->version.minor >0 ) { + mi->version.minor--; + result =nfs_try_mount_v4 (mi); + goto check_result; + } + } + goto fall_back;case ENOENT :/* Legacy Linux servers don't export an NFS
@@ -818,7 +870,7 @@ check_errno:/* v4 server seems to be registered now. */ result =nfs_try_mount_v4 (mi);if (result ==0 && errno !=ECONNREFUSED ) - goto check_errno; + goto check_result; }return result;default :
@@ -840,18 +892,18 @@ static int nfs_try_mount(struct nfsmount_info *mi)int result =0 ;switch (mi->version.major) { -case 0 : - result =nfs_autonegotiate (mi); -break ; -case 2 : -case 3 : - result =nfs_try_mount_v3v2 (mi, FALSE); -break ; -case 4 : - result =nfs_try_mount_v4 (mi); -break ; -default : - errno =EIO ; +case 2 : +case 3 : + result =nfs_try_mount_v3v2 (mi, FALSE); +break ; +case 4 : +if (mi->version.v_mode !=V_SPECIFIC ) + result =nfs_autonegotiate (mi); +else + result =nfs_try_mount_v4 (mi); +break ; +default : + errno =EIO ; }return result;
Signature · 1 line
1.7.1
Quoted 23 lines · Benjamin Coddington
Here's the work posted yesterday broken out a bit with an addition of enabling nfsmount.conf by default, and the change to autonegotiate starting with version 4.2 (instead of 4.0) when no version is specified in either config or mount option.
Benjamin Coddington (6):
mount.nfs: default enable mount config file (nfsmount.conf) mount.nfs: fix a comment typo in parse options mount.nfs: parse options - add helperpo_contains_prefixmount.nfs: Add structnfs_versionand generalize version parsing nfsmount.conf: Always parse versions
mount.nfs: configurable minor version defaultsconfigure.ac | 8 +- utils/mount/configfile.c | 36 +----------- utils/mount/network.c | 122 ++++++++++++++++++------------------- utils/mount/network.h | 15 ++++- utils/mount/nfsumount.c | 4 +- utils/mount/parse_opt.c | 26 ++++++++- utils/mount/parse_opt.h | 2 + utils/mount/stropts.c | 150 +++++++++++++++++++++++++++++++--------------- 8 files changed, 209 insertions(+), 154 deletions(-)
Quoted 5 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Committed... But I did have to fix an issue with the first patch See commit e1a49cf3... No biggie...
steved.