2020-11-05 14:57:25

by Steve Dickson

[permalink] [raw]
Subject: [PATCH 0/3 V2] Enable config.d directory to be processed.

Here is the second attempt to use conf.d directories
to set configuration variables.

When a conf.d directory exists and files with the
".conf" extension exist they will be used to set
configuration variables.

Files not using that extension or files beginning
with a "." (ex .nfs.conf) will be ignored.

The conf.d files will take priority over the main
config files. Meaning a variable set in both the
main config and the conf.d file, the conf.d file
will have priority over the variable in the main config.

The ordering of when the conf.d are processed
can be set by alphabetical naming convention.
Prefixing file name with a 001-nfs.conf,
002-nfs.conf will control when the config is
process. Note the last config file process
with have the highest priority.

Steve Dickson (3):
conffile: process config.d directory config files.
conffile: Only process files in the config.d dirs that end with ".conf"
manpage: Update nfs.conf and nfsmount.conf manpages

support/nfs/conffile.c | 139 +++++++++++++++++++++++++++++++++-
systemd/nfs.conf.man | 8 ++
utils/mount/nfsmount.conf.man | 7 ++
3 files changed, 151 insertions(+), 3 deletions(-)

--
2.26.2


2020-11-05 14:57:26

by Steve Dickson

[permalink] [raw]
Subject: [PATCH 3/3] manpage: Update nfs.conf and nfsmount.conf manpages

Update the man pages to explain how the config.d
directories will be use.

Signed-off-by: Steve Dickson <[email protected]>
---
systemd/nfs.conf.man | 8 ++++++++
utils/mount/nfsmount.conf.man | 7 +++++++
2 files changed, 15 insertions(+)

diff --git a/systemd/nfs.conf.man b/systemd/nfs.conf.man
index 3f1c726..16e0ec4 100644
--- a/systemd/nfs.conf.man
+++ b/systemd/nfs.conf.man
@@ -265,7 +265,15 @@ Only
is recognized.

.SH FILES
+.TP 10n
.I /etc/nfs.conf
+Default NFS client configuration file
+.TP 10n
+.I /etc/nfs.conf.d
+When this directory exists and files ending
+with ".conf" exist, those files will be
+used to set configuration variables. These
+files will override variables set in /etc/nfs.conf
.SH SEE ALSO
.BR nfsdcltrack (8),
.BR rpc.nfsd (8),
diff --git a/utils/mount/nfsmount.conf.man b/utils/mount/nfsmount.conf.man
index 3aa3456..4f8f351 100644
--- a/utils/mount/nfsmount.conf.man
+++ b/utils/mount/nfsmount.conf.man
@@ -88,6 +88,13 @@ the background (i.e. done asynchronously).
.TP 10n
.I /etc/nfsmount.conf
Default NFS mount configuration file
+.TP 10n
+.I /etc/nfsmount.conf.d
+When this directory exists and files ending
+with ".conf" exist, those files will be
+used to set configuration variables. These
+files will override variables set
+in /etc/nfsmount.conf
.PD
.SH SEE ALSO
.BR nfs (5),
--
2.26.2

2020-11-05 14:58:15

by Steve Dickson

[permalink] [raw]
Subject: [PATCH 2/3] conffile: Only process files in the config.d dirs that end with ".conf"

This allows admins or admin systems to change configurations
by renaming the files, only process file that end with ".conf"

Signed-off-by: Steve Dickson <[email protected]>
---
support/nfs/conffile.c | 24 ++++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/support/nfs/conffile.c b/support/nfs/conffile.c
index 456bcf6..1574531 100644
--- a/support/nfs/conffile.c
+++ b/support/nfs/conffile.c
@@ -57,6 +57,9 @@
#include "conffile.h"
#include "xlog.h"

+#define CONF_FILE_EXT ".conf"
+#define CONF_FILE_EXT_LEN ((int) (sizeof(CONF_FILE_EXT) - 1))
+
#pragma GCC visibility push(hidden)

static void conf_load_defaults(void);
@@ -638,8 +641,8 @@ static void
conf_init_dir(const char *conf_file)
{
struct dirent **namelist = NULL;
- char *dname, fname[PATH_MAX + 1];
- int n = 0, i, nfiles = 0, fname_len, dname_len;
+ char *dname, fname[PATH_MAX + 1], *cname;
+ int n = 0, nfiles = 0, i, fname_len, dname_len;
int trans;

dname = malloc(strlen(conf_file) + 3);
@@ -684,6 +687,23 @@ conf_init_dir(const char *conf_file)
d->d_name, dname);
continue;
}
+
+ /*
+ * Check the naming of the file. Only process files
+ * that end with CONF_FILE_EXT
+ */
+ if (fname_len <= CONF_FILE_EXT_LEN) {
+ xlog(D_GENERAL, "conf_init_dir: %s: name too short",
+ d->d_name);
+ continue;
+ }
+ cname = (d->d_name + (fname_len - CONF_FILE_EXT_LEN));
+ if (strcmp(cname, CONF_FILE_EXT) != 0) {
+ xlog(D_GENERAL, "conf_init_dir: %s: invalid file extension",
+ d->d_name);
+ continue;
+ }
+
sprintf(fname, "%s/%s", dname, d->d_name);

if (conf_load_files(trans, fname))
--
2.26.2

2020-11-05 14:58:15

by Steve Dickson

[permalink] [raw]
Subject: [PATCH 1/3] conffile: process config.d directory config files.

When a /etc/nfs.conf.d or /etc/nfsmount.conf.d directory
exists and config file(s) do exist in those directories,
those file(s) will be used and will override the same
settings that are set in the main config files.

Signed-off-by: Steve Dickson <[email protected]>
---
support/nfs/conffile.c | 119 +++++++++++++++++++++++++++++++++++++++--
1 file changed, 116 insertions(+), 3 deletions(-)

diff --git a/support/nfs/conffile.c b/support/nfs/conffile.c
index 3d13610..456bcf6 100644
--- a/support/nfs/conffile.c
+++ b/support/nfs/conffile.c
@@ -52,6 +52,7 @@
#include <libgen.h>
#include <sys/file.h>
#include <time.h>
+#include <dirent.h>

#include "conffile.h"
#include "xlog.h"
@@ -456,7 +457,7 @@ conf_parse_line(int trans, char *line, const char *filename, int lineno, char **
free(subconf);
} else {
/* XXX Perhaps should we not ignore errors? */
- conf_set(trans, *section, *subsection, line, val, 0, 0);
+ conf_set(trans, *section, *subsection, line, val, 1, 0);
}
}

@@ -577,6 +578,30 @@ static void conf_free_bindings(void)
}
}

+static int
+conf_load_files(int trans, const char *conf_file)
+{
+ char *conf_data;
+ char *section = NULL;
+ char *subsection = NULL;
+
+ conf_data = conf_readfile(conf_file);
+ if (conf_data == NULL)
+ return 1;
+
+ /* Load default configuration values. */
+ conf_load_defaults();
+
+ /* Parse config contents into the transaction queue */
+ conf_parse(trans, conf_data, &section, &subsection, conf_file);
+ if (section)
+ free(section);
+ if (subsection)
+ free(subsection);
+ free(conf_data);
+
+ return 0;
+}
/* Open the config file and map it into our address space, then parse it. */
static int
conf_load_file(const char *conf_file)
@@ -609,18 +634,106 @@ conf_load_file(const char *conf_file)
return 0;
}

+static void
+conf_init_dir(const char *conf_file)
+{
+ struct dirent **namelist = NULL;
+ char *dname, fname[PATH_MAX + 1];
+ int n = 0, i, nfiles = 0, fname_len, dname_len;
+ int trans;
+
+ dname = malloc(strlen(conf_file) + 3);
+ if (dname == NULL) {
+ xlog(L_WARNING, "conf_init_dir: malloc: %s", strerror(errno));
+ return;
+ }
+ sprintf(dname, "%s.d", conf_file);
+
+ n = scandir(dname, &namelist, NULL, versionsort);
+ if (n < 0) {
+ if (errno != ENOENT) {
+ xlog(L_WARNING, "conf_init_dir: scandir %s: %s",
+ dname, strerror(errno));
+ }
+ free(dname);
+ return;
+ } else if (n == 0) {
+ free(dname);
+ return;
+ }
+
+ trans = conf_begin();
+ dname_len = strlen(dname);
+ for (i = 0; i < n; i++ ) {
+ struct dirent *d = namelist[i];
+
+ switch (d->d_type) {
+ case DT_UNKNOWN:
+ case DT_REG:
+ case DT_LNK:
+ break;
+ default:
+ continue;
+ }
+ if (*d->d_name == '.')
+ continue;
+
+ fname_len = strlen(d->d_name);
+ if (!fname_len || (fname_len + dname_len) > PATH_MAX) {
+ xlog(L_WARNING, "conf_init_dir: Too long file name: %s in %s",
+ d->d_name, dname);
+ continue;
+ }
+ sprintf(fname, "%s/%s", dname, d->d_name);
+
+ if (conf_load_files(trans, fname))
+ continue;
+ nfiles++;
+ }
+
+ if (nfiles) {
+ /* Apply the configuration values */
+ conf_end(trans, 1);
+ }
+ for (i = 0; i < n; i++)
+ free(namelist[i]);
+ free(namelist);
+ free(dname);
+
+ return;
+}
+
int
conf_init_file(const char *conf_file)
{
unsigned int i;
+ int ret;

for (i = 0; i < sizeof conf_bindings / sizeof conf_bindings[0]; i++)
LIST_INIT (&conf_bindings[i]);

TAILQ_INIT (&conf_trans_queue);

- if (conf_file == NULL) conf_file=NFS_CONFFILE;
- return conf_load_file(conf_file);
+ if (conf_file == NULL)
+ conf_file=NFS_CONFFILE;
+
+ /*
+ * First parse the give config file
+ * then parse the config.conf.d directory
+ * (if it exists)
+ *
+ */
+ ret = conf_load_file(conf_file);
+
+ /*
+ * When the same variable is set in both files
+ * the conf.d file will override the config file.
+ * This allows automated admin systems to
+ * have the final say.
+ */
+ conf_init_dir(conf_file);
+
+ return ret;
}

/*
--
2.26.2

2020-11-10 19:41:35

by Steve Dickson

[permalink] [raw]
Subject: Re: [PATCH 0/3 V2] Enable config.d directory to be processed.



On 11/5/20 9:56 AM, Steve Dickson wrote:
> Here is the second attempt to use conf.d directories
> to set configuration variables.
>
> When a conf.d directory exists and files with the
> ".conf" extension exist they will be used to set
> configuration variables.
>
> Files not using that extension or files beginning
> with a "." (ex .nfs.conf) will be ignored.
>
> The conf.d files will take priority over the main
> config files. Meaning a variable set in both the
> main config and the conf.d file, the conf.d file
> will have priority over the variable in the main config.
>
> The ordering of when the conf.d are processed
> can be set by alphabetical naming convention.
> Prefixing file name with a 001-nfs.conf,
> 002-nfs.conf will control when the config is
> process. Note the last config file process
> with have the highest priority.
>
> Steve Dickson (3):
> conffile: process config.d directory config files.
> conffile: Only process files in the config.d dirs that end with ".conf"
> manpage: Update nfs.conf and nfsmount.conf manpages
Committed... (tag: nfs-utils-2-5-3-rc1)

steved.
>
> support/nfs/conffile.c | 139 +++++++++++++++++++++++++++++++++-
> systemd/nfs.conf.man | 8 ++
> utils/mount/nfsmount.conf.man | 7 ++
> 3 files changed, 151 insertions(+), 3 deletions(-)
>