* [PATCH 1/3] conffile: process config.d directory config files.
2020-11-05 14:56 [PATCH 0/3 V2] Enable config.d directory to be processed Steve Dickson
@ 2020-11-05 14:56 ` Steve Dickson
2020-11-05 14:56 ` [PATCH 2/3] conffile: Only process files in the config.d dirs that end with ".conf" Steve Dickson
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Steve Dickson @ 2020-11-05 14:56 UTC (permalink / raw)
To: Linux NFS Mailing list
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 <steved@redhat.com>
---
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, §ion, &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
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/3] conffile: Only process files in the config.d dirs that end with ".conf"
2020-11-05 14:56 [PATCH 0/3 V2] Enable config.d directory to be processed Steve Dickson
2020-11-05 14:56 ` [PATCH 1/3] conffile: process config.d directory config files Steve Dickson
@ 2020-11-05 14:56 ` Steve Dickson
2020-11-05 14:56 ` [PATCH 3/3] manpage: Update nfs.conf and nfsmount.conf manpages Steve Dickson
2020-11-10 19:41 ` [PATCH 0/3 V2] Enable config.d directory to be processed Steve Dickson
3 siblings, 0 replies; 5+ messages in thread
From: Steve Dickson @ 2020-11-05 14:56 UTC (permalink / raw)
To: Linux NFS Mailing list
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 <steved@redhat.com>
---
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
^ permalink raw reply related [flat|nested] 5+ messages in thread