diff mbox series

[1/3] nfs-utils: Enable the retrieval of raw config settings without expansion

Message ID 20210414181040.7108-2-steved@redhat.com (mailing list archive)
State New, archived
Headers show
Series Enable the setting of a kernel module parameter from nfs.conf | expand

Commit Message

Steve Dickson April 14, 2021, 6:10 p.m. UTC
From: Alice Mitchell <ajmitchell@redhat.com>

Config entries sometimes contain variable expansions, this adds options
to retrieve the config entry rather than its current expanded value.

Signed-off-by: Alice Mitchell <ajmitchell@redhat.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
---
 support/include/conffile.h |  1 +
 support/nfs/conffile.c     | 23 +++++++++++++++++++++++
 tools/nfsconf/nfsconf.man  | 10 +++++++++-
 tools/nfsconf/nfsconfcli.c | 22 ++++++++++++++++------
 4 files changed, 49 insertions(+), 7 deletions(-)

Comments

Steve Dickson May 6, 2021, 5:29 p.m. UTC | #1
On 4/14/21 2:10 PM, Steve Dickson wrote:
> From: Alice Mitchell <ajmitchell@redhat.com>
> 
> Config entries sometimes contain variable expansions, this adds options
> to retrieve the config entry rather than its current expanded value.
> 
> Signed-off-by: Alice Mitchell <ajmitchell@redhat.com>
> Signed-off-by: Steve Dickson <steved@redhat.com>
> ---
>  support/include/conffile.h |  1 +
>  support/nfs/conffile.c     | 23 +++++++++++++++++++++++
>  tools/nfsconf/nfsconf.man  | 10 +++++++++-
>  tools/nfsconf/nfsconfcli.c | 22 ++++++++++++++++------
>  4 files changed, 49 insertions(+), 7 deletions(-)
Committed (tag: nfs-utils-2-5-4-rc3)

steved.
> 
> diff --git a/support/include/conffile.h b/support/include/conffile.h
> index 7d974fe9..c4a3ca62 100644
> --- a/support/include/conffile.h
> +++ b/support/include/conffile.h
> @@ -61,6 +61,7 @@ extern _Bool    conf_get_bool(const char *, const char *, _Bool);
>  extern char    *conf_get_str(const char *, const char *);
>  extern char    *conf_get_str_with_def(const char *, const char *, char *);
>  extern char    *conf_get_section(const char *, const char *, const char *);
> +extern char    *conf_get_entry(const char *, const char *, const char *);
>  extern int      conf_init_file(const char *);
>  extern void     conf_cleanup(void);
>  extern int      conf_match_num(const char *, const char *, int);
> diff --git a/support/nfs/conffile.c b/support/nfs/conffile.c
> index 1e15e7d5..fd4a17ad 100644
> --- a/support/nfs/conffile.c
> +++ b/support/nfs/conffile.c
> @@ -891,6 +891,29 @@ conf_get_str_with_def(const char *section, const char *tag, char *def)
>  	return result;
>  }
>  
> +/*
> + * Retrieve an entry without interpreting its contents
> + */
> +char *
> +conf_get_entry(const char *section, const char *arg, const char *tag)
> +{
> +	struct conf_binding *cb;
> +
> +	cb = LIST_FIRST (&conf_bindings[conf_hash (section)]);
> +	for (; cb; cb = LIST_NEXT (cb, link)) {
> +		if (strcasecmp(section, cb->section) != 0)
> +			continue;
> +		if (arg && (cb->arg == NULL || strcasecmp(arg, cb->arg) != 0))
> +			continue;
> +		if (!arg && cb->arg)
> +			continue;
> +		if (strcasecmp(tag, cb->tag) != 0)
> +			continue;
> +		return cb->value;
> +	}
> +	return 0;
> +}
> +
>  /*
>   * Find a section that may or may not have an argument
>   */
> diff --git a/tools/nfsconf/nfsconf.man b/tools/nfsconf/nfsconf.man
> index 30791988..d44e86fb 100644
> --- a/tools/nfsconf/nfsconf.man
> +++ b/tools/nfsconf/nfsconf.man
> @@ -11,6 +11,12 @@ nfsconf \- Query various NFS configuration settings
>  .IR infile.conf ]
>  .RI [ outfile ]
>  .P
> +.B nfsconf \-\-entry
> +.RB [ \-\-arg  
> +.IR subsection]
> +.IR section
> +.IR tag
> +.P
>  .B nfsconf \-\-get
>  .RB [ \-v | \-\-verbose ]
>  .RB [ \-f | \-\-file
> @@ -58,6 +64,8 @@ from a range of nfs-utils configuration files.
>  The following modes are available:
>  .IP "\fB\-d, \-\-dump\fP"
>  Output an alphabetically sorted dump of the current configuration in conf file format. Accepts an optional filename in which to write the output.
> +.IP "\fB\-e, \-\-entry\fP"
> +retrieve the config entry rather than its current expanded value
>  .IP "\fB\-i, \-\-isset\fP"
>  Test if a specific tag has a value set.
>  .IP "\fB\-g, \-\-get\fP"
> @@ -75,7 +83,7 @@ Increase verbosity and print debugging information.
>  .B \-f, \-\-file \fIinfile\fR
>  Select a different config file to operate upon, default is
>  .I /etc/nfs.conf
> -.SS Options only valid in \fB\-\-get\fR and \fB\-\-isset\fR modes.
> +.SS Options only valid in \fB\-\-entry\fR and \fB\-\-get\fR and \fB\-\-isset\fR modes.
>  .TP
>  .B \-a, \-\-arg \fIsubsection\fR
>  Select a specific sub-section
> diff --git a/tools/nfsconf/nfsconfcli.c b/tools/nfsconf/nfsconfcli.c
> index 361d386e..b2ef96d1 100644
> --- a/tools/nfsconf/nfsconfcli.c
> +++ b/tools/nfsconf/nfsconfcli.c
> @@ -11,6 +11,7 @@
>  typedef enum {
>  	MODE_NONE,
>  	MODE_GET,
> +	MODE_ENTRY,
>  	MODE_ISSET,
>  	MODE_DUMP,
>  	MODE_SET,
> @@ -30,6 +31,8 @@ static void usage(const char *name)
>  	fprintf(stderr, "      Outputs the configuration to the named file\n");
>  	fprintf(stderr, "  --get [--arg subsection] {section} {tag}\n");
>  	fprintf(stderr, "      Output one specific config value\n");
> +	fprintf(stderr, "  --entry [--arg subsection] {section} {tag}\n");
> +	fprintf(stderr, "      Output the uninterpreted config entry\n");
>  	fprintf(stderr, "  --isset [--arg subsection] {section} {tag}\n");
>  	fprintf(stderr, "      Return code indicates if config value is present\n");
>  	fprintf(stderr, "  --set [--arg subsection] {section} {tag} {value}\n");
> @@ -55,6 +58,7 @@ int main(int argc, char **argv)
>  		int index = 0;
>  		struct option long_options[] = {
>  			{"get",		no_argument, 0, 'g' },
> +			{"entry",	no_argument, 0, 'e' },
>  			{"set",		no_argument, 0, 's' },
>  			{"unset",	no_argument, 0, 'u' },
>  			{"arg",	  required_argument, 0, 'a' },
> @@ -66,7 +70,7 @@ int main(int argc, char **argv)
>  			{NULL,			  0, 0, 0 }
>  		};
>  
> -		c = getopt_long(argc, argv, "gsua:id::f:vm:", long_options, &index);
> +		c = getopt_long(argc, argv, "gesua:id::f:vm:", long_options, &index);
>  		if (c == -1) break;
>  
>  		switch (c) {
> @@ -86,6 +90,9 @@ int main(int argc, char **argv)
>  			case 'g':
>  				mode = MODE_GET;
>  				break;
> +			case 'e':
> +				mode = MODE_ENTRY;
> +				break;
>  			case 's':
>  				mode = MODE_SET;
>  				break;
> @@ -167,8 +174,8 @@ int main(int argc, char **argv)
>  		if (dumpfile)
>  			fclose(out);
>  	} else
> -	/* --iset and --get share a lot of code */
> -	if (mode == MODE_GET || mode == MODE_ISSET) {
> +	/* --isset and --get share a lot of code */
> +	if (mode == MODE_GET || mode == MODE_ISSET || mode == MODE_ENTRY) {
>  		char * section = NULL;
>  		char * tag = NULL;
>  		const char * val;
> @@ -186,14 +193,17 @@ int main(int argc, char **argv)
>  		tag = argv[optind++];
>  
>  		/* retrieve the specified tags value */
> -		val = conf_get_section(section, arg, tag);
> +		if (mode == MODE_ENTRY)
> +			val = conf_get_entry(section, arg, tag);
> +		else
> +			val = conf_get_section(section, arg, tag);
>  		if (val != NULL) {
>  			/* ret=0, success, mode --get wants to output the value as well */
> -			if (mode == MODE_GET)
> +			if (mode != MODE_ISSET)
>  				printf("%s\n", val);
>  		} else {
>  			/* ret=1, no value found, tell the user if they asked */
> -			if (mode == MODE_GET && verbose)
> +			if (mode != MODE_ISSET && verbose)
>  				fprintf(stderr, "Tag '%s' not found\n", tag);
>  			ret = 1;
>  		}
>
diff mbox series

Patch

diff --git a/support/include/conffile.h b/support/include/conffile.h
index 7d974fe9..c4a3ca62 100644
--- a/support/include/conffile.h
+++ b/support/include/conffile.h
@@ -61,6 +61,7 @@  extern _Bool    conf_get_bool(const char *, const char *, _Bool);
 extern char    *conf_get_str(const char *, const char *);
 extern char    *conf_get_str_with_def(const char *, const char *, char *);
 extern char    *conf_get_section(const char *, const char *, const char *);
+extern char    *conf_get_entry(const char *, const char *, const char *);
 extern int      conf_init_file(const char *);
 extern void     conf_cleanup(void);
 extern int      conf_match_num(const char *, const char *, int);
diff --git a/support/nfs/conffile.c b/support/nfs/conffile.c
index 1e15e7d5..fd4a17ad 100644
--- a/support/nfs/conffile.c
+++ b/support/nfs/conffile.c
@@ -891,6 +891,29 @@  conf_get_str_with_def(const char *section, const char *tag, char *def)
 	return result;
 }
 
+/*
+ * Retrieve an entry without interpreting its contents
+ */
+char *
+conf_get_entry(const char *section, const char *arg, const char *tag)
+{
+	struct conf_binding *cb;
+
+	cb = LIST_FIRST (&conf_bindings[conf_hash (section)]);
+	for (; cb; cb = LIST_NEXT (cb, link)) {
+		if (strcasecmp(section, cb->section) != 0)
+			continue;
+		if (arg && (cb->arg == NULL || strcasecmp(arg, cb->arg) != 0))
+			continue;
+		if (!arg && cb->arg)
+			continue;
+		if (strcasecmp(tag, cb->tag) != 0)
+			continue;
+		return cb->value;
+	}
+	return 0;
+}
+
 /*
  * Find a section that may or may not have an argument
  */
diff --git a/tools/nfsconf/nfsconf.man b/tools/nfsconf/nfsconf.man
index 30791988..d44e86fb 100644
--- a/tools/nfsconf/nfsconf.man
+++ b/tools/nfsconf/nfsconf.man
@@ -11,6 +11,12 @@  nfsconf \- Query various NFS configuration settings
 .IR infile.conf ]
 .RI [ outfile ]
 .P
+.B nfsconf \-\-entry
+.RB [ \-\-arg  
+.IR subsection]
+.IR section
+.IR tag
+.P
 .B nfsconf \-\-get
 .RB [ \-v | \-\-verbose ]
 .RB [ \-f | \-\-file
@@ -58,6 +64,8 @@  from a range of nfs-utils configuration files.
 The following modes are available:
 .IP "\fB\-d, \-\-dump\fP"
 Output an alphabetically sorted dump of the current configuration in conf file format. Accepts an optional filename in which to write the output.
+.IP "\fB\-e, \-\-entry\fP"
+retrieve the config entry rather than its current expanded value
 .IP "\fB\-i, \-\-isset\fP"
 Test if a specific tag has a value set.
 .IP "\fB\-g, \-\-get\fP"
@@ -75,7 +83,7 @@  Increase verbosity and print debugging information.
 .B \-f, \-\-file \fIinfile\fR
 Select a different config file to operate upon, default is
 .I /etc/nfs.conf
-.SS Options only valid in \fB\-\-get\fR and \fB\-\-isset\fR modes.
+.SS Options only valid in \fB\-\-entry\fR and \fB\-\-get\fR and \fB\-\-isset\fR modes.
 .TP
 .B \-a, \-\-arg \fIsubsection\fR
 Select a specific sub-section
diff --git a/tools/nfsconf/nfsconfcli.c b/tools/nfsconf/nfsconfcli.c
index 361d386e..b2ef96d1 100644
--- a/tools/nfsconf/nfsconfcli.c
+++ b/tools/nfsconf/nfsconfcli.c
@@ -11,6 +11,7 @@ 
 typedef enum {
 	MODE_NONE,
 	MODE_GET,
+	MODE_ENTRY,
 	MODE_ISSET,
 	MODE_DUMP,
 	MODE_SET,
@@ -30,6 +31,8 @@  static void usage(const char *name)
 	fprintf(stderr, "      Outputs the configuration to the named file\n");
 	fprintf(stderr, "  --get [--arg subsection] {section} {tag}\n");
 	fprintf(stderr, "      Output one specific config value\n");
+	fprintf(stderr, "  --entry [--arg subsection] {section} {tag}\n");
+	fprintf(stderr, "      Output the uninterpreted config entry\n");
 	fprintf(stderr, "  --isset [--arg subsection] {section} {tag}\n");
 	fprintf(stderr, "      Return code indicates if config value is present\n");
 	fprintf(stderr, "  --set [--arg subsection] {section} {tag} {value}\n");
@@ -55,6 +58,7 @@  int main(int argc, char **argv)
 		int index = 0;
 		struct option long_options[] = {
 			{"get",		no_argument, 0, 'g' },
+			{"entry",	no_argument, 0, 'e' },
 			{"set",		no_argument, 0, 's' },
 			{"unset",	no_argument, 0, 'u' },
 			{"arg",	  required_argument, 0, 'a' },
@@ -66,7 +70,7 @@  int main(int argc, char **argv)
 			{NULL,			  0, 0, 0 }
 		};
 
-		c = getopt_long(argc, argv, "gsua:id::f:vm:", long_options, &index);
+		c = getopt_long(argc, argv, "gesua:id::f:vm:", long_options, &index);
 		if (c == -1) break;
 
 		switch (c) {
@@ -86,6 +90,9 @@  int main(int argc, char **argv)
 			case 'g':
 				mode = MODE_GET;
 				break;
+			case 'e':
+				mode = MODE_ENTRY;
+				break;
 			case 's':
 				mode = MODE_SET;
 				break;
@@ -167,8 +174,8 @@  int main(int argc, char **argv)
 		if (dumpfile)
 			fclose(out);
 	} else
-	/* --iset and --get share a lot of code */
-	if (mode == MODE_GET || mode == MODE_ISSET) {
+	/* --isset and --get share a lot of code */
+	if (mode == MODE_GET || mode == MODE_ISSET || mode == MODE_ENTRY) {
 		char * section = NULL;
 		char * tag = NULL;
 		const char * val;
@@ -186,14 +193,17 @@  int main(int argc, char **argv)
 		tag = argv[optind++];
 
 		/* retrieve the specified tags value */
-		val = conf_get_section(section, arg, tag);
+		if (mode == MODE_ENTRY)
+			val = conf_get_entry(section, arg, tag);
+		else
+			val = conf_get_section(section, arg, tag);
 		if (val != NULL) {
 			/* ret=0, success, mode --get wants to output the value as well */
-			if (mode == MODE_GET)
+			if (mode != MODE_ISSET)
 				printf("%s\n", val);
 		} else {
 			/* ret=1, no value found, tell the user if they asked */
-			if (mode == MODE_GET && verbose)
+			if (mode != MODE_ISSET && verbose)
 				fprintf(stderr, "Tag '%s' not found\n", tag);
 			ret = 1;
 		}