All of lore.kernel.org
 help / color / mirror / Atom feed
* [ndctl PATCH v3 00/11] Policy based reconfiguration for daxctl
@ 2021-12-10 22:34 Vishal Verma
  2021-12-10 22:34 ` [ndctl PATCH v3 01/11] ndctl, util: add parse-configs helper Vishal Verma
                   ` (10 more replies)
  0 siblings, 11 replies; 20+ messages in thread
From: Vishal Verma @ 2021-12-10 22:34 UTC (permalink / raw)
  To: nvdimm; +Cc: Dan Williams, QI Fuli, fenghua.hu, Vishal Verma

Changes since v2[1]:
- Remove stale Link: trailers from commit messages (Dan)
- Link to the iniparser library already packaged by distros instead of
  forking it (Dan).
- Improve commit message for "ndctl, util: add parse-configs helper"
  (Dan)
- Squash "util/parse-config: refactor filter_conf_files into util/" into
  the original patch it modifies since I'm modifying Qi's original
  patchset anyway
- Rename {ndctl,daxctl}_{get,set}_configs_dir to
  {ndctl,daxctl}_{get,set}_config_path (Dan)
- Replace {ndctl,daxctl}_ctx ** ctx with *ctx respectively, as the
  former is unnecessary. (Dan)
- Allow *_set_config_path() to return errors (Dan)
- Move {ndctl,daxctl}_set_config_path into {ndctl,daxctl}_new (Dan)
- Update config paths to {sysconfdir}/{ndctl,daxctl}.conf.d/  (Dan)
- Move the config_path scandir() call deeper in the stack so we don't
  have to store scandir results anywhere, and so that it is run just
  before the config parsing happens. This way the only thing that's
  stored in 'ctx' is the config_path itself, and lib{nd,dax}ctl are
  freed of having to link to GPL utils such as util/strbuf.  (Dan)


These patches add policy (config file) support to daxctl. The
introductory user is daxctl-reconfigure-device. Sysadmins may wish to
use daxctl devices as system-ram, but it may be cumbersome to automate
the reconfiguration step for every device upon boot.

Introduce a new option for daxctl-reconfigure-device, --check-config.
This is at the heart of policy based reconfiguration, as it allows
daxctl to look up reconfiguration parameters for a given device from the
config system instead of the command line.

Some systemd and udev glue then automates this for every new dax device
that shows up, providing a way for the administrator to simply list all
the 'system-ram' UUIDs in a config file, and not have to worry about
anything else.

An example config file can be:

  # cat /etc/daxctl.conf.d/daxctl.conf

  [reconfigure-device unique_identifier_foo]
  nvdimm.uuid = 48d8e42c-a2f0-4312-9e70-a837faafe862
  mode = system-ram
  online = true
  movable = false

Any file under '/etc/daxctl.conf.d/' can be used - all files with a
'.conf' suffix will be considered when looking for matches.

These patches depend on the initial config file support from Qi Fuli,
which is included here after some modifications from review feedback.

A branch containing these patches is available at [2].

[1]: https://lore.kernel.org/nvdimm/20211206222830.2266018-1-vishal.l.verma@intel.com/
[2]: https://github.com/pmem/ndctl/tree/vv/daxctl_config_v3


QI Fuli (4):
  ndctl, util: add parse-configs helper
  ndctl: make ndctl support configuration files
  ndctl, config: add the default ndctl configuration file
  ndctl, monitor: refator monitor for supporting multiple config files

Vishal Verma (7):
  ndctl: Update ndctl.spec.in for 'ndctl.conf'
  daxctl: Documentation updates for persistent reconfiguration
  daxctl: add basic config parsing support
  util/parse-configs: add a key/value search helper
  daxctl/device.c: add an option for getting params from a config file
  daxctl: add systemd service and udev rule for automatic
    reconfiguration
  daxctl: add and install an example config file

 .../daxctl/daxctl-reconfigure-device.txt      |  75 ++++++++
 Documentation/ndctl/ndctl-monitor.txt         |   8 +-
 configure.ac                                  |  22 ++-
 Makefile.am                                   |   2 +
 ndctl/lib/private.h                           |   1 +
 daxctl/lib/libdaxctl.c                        |  20 ++
 ndctl/lib/libndctl.c                          |  20 ++
 daxctl/libdaxctl.h                            |   2 +
 ndctl/libndctl.h                              |   2 +
 util/parse-configs.h                          |  53 ++++++
 daxctl/device.c                               | 174 +++++++++++++++++-
 ndctl/monitor.c                               |  73 ++++----
 util/parse-configs.c                          | 156 ++++++++++++++++
 Documentation/daxctl/Makefile.am              |  11 +-
 Documentation/ndctl/Makefile.am               |   2 +-
 daxctl/90-daxctl-device.rules                 |   1 +
 daxctl/Makefile.am                            |  14 +-
 daxctl/daxctl.example.conf                    |  27 +++
 daxctl/daxdev-reconfigure@.service            |   8 +
 daxctl/lib/Makefile.am                        |   6 +
 daxctl/lib/libdaxctl.sym                      |   2 +
 ndctl.spec.in                                 |   7 +-
 ndctl/Makefile.am                             |  11 +-
 ndctl/lib/Makefile.am                         |   6 +
 ndctl/lib/libndctl.sym                        |   2 +
 ndctl/ndctl.conf                              |  56 ++++++
 26 files changed, 710 insertions(+), 51 deletions(-)
 create mode 100644 util/parse-configs.h
 create mode 100644 util/parse-configs.c
 create mode 100644 daxctl/90-daxctl-device.rules
 create mode 100644 daxctl/daxctl.example.conf
 create mode 100644 daxctl/daxdev-reconfigure@.service
 create mode 100644 ndctl/ndctl.conf


base-commit: 4e646fa490ba4b782afa188dd8818b94c419924e
-- 
2.33.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [ndctl PATCH v3 01/11] ndctl, util: add parse-configs helper
  2021-12-10 22:34 [ndctl PATCH v3 00/11] Policy based reconfiguration for daxctl Vishal Verma
@ 2021-12-10 22:34 ` Vishal Verma
  2021-12-16 21:42   ` Dan Williams
  2021-12-21 12:54   ` Joao Martins
  2021-12-10 22:34 ` [ndctl PATCH v3 02/11] ndctl: make ndctl support configuration files Vishal Verma
                   ` (9 subsequent siblings)
  10 siblings, 2 replies; 20+ messages in thread
From: Vishal Verma @ 2021-12-10 22:34 UTC (permalink / raw)
  To: nvdimm; +Cc: Dan Williams, QI Fuli, fenghua.hu, QI Fuli, Vishal Verma

From: QI Fuli <qi.fuli@fujitsu.com>

Add parse-config util to help ndctl commands parse ndctl global
configuration files. This provides a parse_configs_prefix() helper which
uses the iniparser APIs to read all applicable config files, and either
return a 'value' for a requested 'key', or perform a callback if
requested. The operation is defined by a 'struct config' which
encapsulates the key to search for, the location to store the value, and
any callbacks to be executed.

Signed-off-by: QI Fuli <qi.fuli@fujitsu.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
 configure.ac         |   4 ++
 Makefile.am          |   2 +
 util/parse-configs.h |  38 ++++++++++++++++
 util/parse-configs.c | 105 +++++++++++++++++++++++++++++++++++++++++++
 ndctl/Makefile.am    |   3 +-
 5 files changed, 151 insertions(+), 1 deletion(-)
 create mode 100644 util/parse-configs.h
 create mode 100644 util/parse-configs.c

diff --git a/configure.ac b/configure.ac
index dc39dbe..cbd5a6f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -199,6 +199,10 @@ ndctl_keysreadme=keys.readme
 AC_SUBST([ndctl_keysdir])
 AC_SUBST([ndctl_keysreadme])
 
+AC_CHECK_HEADERS([iniparser.h],,[
+		  AC_MSG_ERROR([iniparser.h not found, install iniparser-devel, libiniparser-dev, or so])
+		 ])
+
 my_CFLAGS="\
 -Wall \
 -Wchar-subscripts \
diff --git a/Makefile.am b/Makefile.am
index 60a1998..c547459 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -70,6 +70,8 @@ noinst_LIBRARIES += libutil.a
 libutil_a_SOURCES = \
 	util/parse-options.c \
 	util/parse-options.h \
+	util/parse-configs.c \
+	util/parse-configs.h \
 	util/usage.c \
 	util/size.c \
 	util/main.c \
diff --git a/util/parse-configs.h b/util/parse-configs.h
new file mode 100644
index 0000000..32783b5
--- /dev/null
+++ b/util/parse-configs.h
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2021, FUJITSU LIMITED. ALL rights reserved.
+
+#include <dirent.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <util/util.h>
+
+enum parse_conf_type {
+	CONFIG_STRING,
+	CONFIG_END,
+	MONITOR_CALLBACK,
+};
+
+int filter_conf_files(const struct dirent *dir);
+
+struct config;
+typedef int parse_conf_cb(const struct config *, const char *config_file);
+
+struct config {
+	enum parse_conf_type type;
+	const char *key;
+	void *value;
+	void *defval;
+	parse_conf_cb *callback;
+};
+
+#define check_vtype(v, type) ( BUILD_BUG_ON_ZERO(!__builtin_types_compatible_p(typeof(v), type)) + v )
+
+#define CONF_END() { .type = CONFIG_END }
+#define CONF_STR(k,v,d) \
+	{ .type = CONFIG_STRING, .key = (k), .value = check_vtype(v, const char **), .defval = (d) }
+#define CONF_MONITOR(k,f) \
+	{ .type = MONITOR_CALLBACK, .key = (k), .callback = (f)}
+
+int parse_configs_prefix(const char *config_path, const char *prefix,
+			 const struct config *configs);
diff --git a/util/parse-configs.c b/util/parse-configs.c
new file mode 100644
index 0000000..61352d8
--- /dev/null
+++ b/util/parse-configs.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2021, FUJITSU LIMITED. ALL rights reserved.
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <iniparser/iniparser.h>
+#include <sys/stat.h>
+#include <util/parse-configs.h>
+#include <util/strbuf.h>
+
+int filter_conf_files(const struct dirent *dir)
+{
+	if (!dir)
+		return 0;
+
+	if (dir->d_type == DT_REG) {
+		const char *ext = strrchr(dir->d_name, '.');
+
+		if ((!ext) || (ext == dir->d_name))
+			return 0;
+		if (strcmp(ext, ".conf") == 0)
+			return 1;
+	}
+
+	return 0;
+}
+
+static void set_str_val(const char **value, const char *val)
+{
+	struct strbuf buf = STRBUF_INIT;
+	size_t len = *value ? strlen(*value) : 0;
+
+	if (!val)
+		return;
+
+	if (len) {
+		strbuf_add(&buf, *value, len);
+		strbuf_addstr(&buf, " ");
+	}
+	strbuf_addstr(&buf, val);
+	*value = strbuf_detach(&buf, NULL);
+}
+
+static int parse_config_file(const char *config_file,
+			const struct config *configs)
+{
+	dictionary *dic;
+
+	if ((configs->type == MONITOR_CALLBACK) &&
+			(strcmp(config_file, configs->key) == 0))
+		return configs->callback(configs, configs->key);
+
+	dic = iniparser_load(config_file);
+	if (!dic)
+		return -errno;
+
+	for (; configs->type != CONFIG_END; configs++) {
+		switch (configs->type) {
+		case CONFIG_STRING:
+			set_str_val((const char **)configs->value,
+					iniparser_getstring(dic,
+					configs->key, configs->defval));
+			break;
+		case MONITOR_CALLBACK:
+		case CONFIG_END:
+			break;
+		}
+	}
+
+	iniparser_freedict(dic);
+	return 0;
+}
+
+int parse_configs_prefix(const char *config_path, const char *prefix,
+			 const struct config *configs)
+{
+	const char *config_file = NULL;
+	struct dirent **namelist;
+	int rc, count;
+
+	if (configs->type == MONITOR_CALLBACK)
+		return parse_config_file(config_path, configs);
+
+	count = scandir(config_path, &namelist, filter_conf_files, alphasort);
+	if (count == -1)
+		return -errno;
+
+	while (count--) {
+		char *conf_abspath;
+
+		config_file = namelist[count]->d_name;
+		rc = asprintf(&conf_abspath, "%s/%s", config_path, config_file);
+		if (rc < 0)
+			return -ENOMEM;
+
+		rc = parse_config_file(conf_abspath, configs);
+
+		free(conf_abspath);
+		if (rc)
+			return rc;
+	}
+
+	return 0;
+}
diff --git a/ndctl/Makefile.am b/ndctl/Makefile.am
index a63b1e0..afdd03c 100644
--- a/ndctl/Makefile.am
+++ b/ndctl/Makefile.am
@@ -56,7 +56,8 @@ ndctl_LDADD =\
 	../libutil.a \
 	$(UUID_LIBS) \
 	$(KMOD_LIBS) \
-	$(JSON_LIBS)
+	$(JSON_LIBS) \
+	-liniparser
 
 if ENABLE_KEYUTILS
 ndctl_LDADD += -lkeyutils
-- 
2.33.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ndctl PATCH v3 02/11] ndctl: make ndctl support configuration files
  2021-12-10 22:34 [ndctl PATCH v3 00/11] Policy based reconfiguration for daxctl Vishal Verma
  2021-12-10 22:34 ` [ndctl PATCH v3 01/11] ndctl, util: add parse-configs helper Vishal Verma
@ 2021-12-10 22:34 ` Vishal Verma
  2021-12-16 21:47   ` Dan Williams
  2021-12-10 22:34 ` [ndctl PATCH v3 03/11] ndctl, config: add the default ndctl configuration file Vishal Verma
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 20+ messages in thread
From: Vishal Verma @ 2021-12-10 22:34 UTC (permalink / raw)
  To: nvdimm; +Cc: Dan Williams, QI Fuli, fenghua.hu, QI Fuli, Vishal Verma

From: QI Fuli <qi.fuli@fujitsu.com>

Add a 'config_path' to ndctl_ctx for supporting ndctl global configuration
files. Any file with a .conf suffix under {sysconfdir}/ndctl.conf.d/ will
be regarded as a global configuration file which can have INI-style config
sections. Add an ndctl_set_config_path() API for setting the default
configuration files' path for ndctl. Add an ndctl_get_config_path() API for
getting ndctl configuration files' path from ndctl_ctx.

Signed-off-by: QI Fuli <qi.fuli@fujitsu.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
 configure.ac           |  5 +++--
 ndctl/lib/private.h    |  1 +
 ndctl/lib/libndctl.c   | 20 ++++++++++++++++++++
 ndctl/libndctl.h       |  2 ++
 ndctl/Makefile.am      |  4 ++--
 ndctl/lib/Makefile.am  |  6 ++++++
 ndctl/lib/libndctl.sym |  2 ++
 7 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/configure.ac b/configure.ac
index cbd5a6f..a264af7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -171,9 +171,10 @@ fi
 AC_SUBST([systemd_unitdir])
 AM_CONDITIONAL([ENABLE_SYSTEMD_UNITS], [test "x$with_systemd" = "xyes"])
 
-ndctl_monitorconfdir=${sysconfdir}/ndctl
+ndctl_confdir=${sysconfdir}/ndctl.conf.d
+ndctl_conf=ndctl.conf
 ndctl_monitorconf=monitor.conf
-AC_SUBST([ndctl_monitorconfdir])
+AC_SUBST([ndctl_confdir])
 AC_SUBST([ndctl_monitorconf])
 
 daxctl_modprobe_datadir=${datadir}/daxctl
diff --git a/ndctl/lib/private.h b/ndctl/lib/private.h
index 8f4510e..d442e6c 100644
--- a/ndctl/lib/private.h
+++ b/ndctl/lib/private.h
@@ -129,6 +129,7 @@ struct ndctl_ctx {
 	int regions_init;
 	void *userdata;
 	struct list_head busses;
+	const char *config_path;
 	int busses_init;
 	struct udev *udev;
 	struct udev_queue *udev_queue;
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index 536e142..1f742ff 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -265,6 +265,22 @@ NDCTL_EXPORT void ndctl_set_userdata(struct ndctl_ctx *ctx, void *userdata)
 	ctx->userdata = userdata;
 }
 
+NDCTL_EXPORT int ndctl_set_config_path(struct ndctl_ctx *ctx, char *config_path)
+{
+	if ((!ctx) || (!config_path))
+		return -EINVAL;
+	ctx->config_path = config_path;
+
+	return 0;
+}
+
+NDCTL_EXPORT const char *ndctl_get_config_path(struct ndctl_ctx *ctx)
+{
+	if (ctx == NULL)
+		return NULL;
+	return ctx->config_path;
+}
+
 /**
  * ndctl_new - instantiate a new library context
  * @ctx: context to establish
@@ -327,6 +343,10 @@ NDCTL_EXPORT int ndctl_new(struct ndctl_ctx **ctx)
 	if (!c->udev_queue)
 		err(c, "failed to retrieve udev queue\n");
 
+	rc = ndctl_set_config_path(c, NDCTL_CONF_DIR);
+	if (rc)
+		dbg(c, "Unable to set config path: %s\n", strerror(-rc));
+
 	c->kmod_ctx = kmod_ctx;
 	c->daxctl_ctx = daxctl_ctx;
 
diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h
index 87d07b7..3cc7f20 100644
--- a/ndctl/libndctl.h
+++ b/ndctl/libndctl.h
@@ -92,6 +92,8 @@ int ndctl_get_log_priority(struct ndctl_ctx *ctx);
 void ndctl_set_log_priority(struct ndctl_ctx *ctx, int priority);
 void ndctl_set_userdata(struct ndctl_ctx *ctx, void *userdata);
 void *ndctl_get_userdata(struct ndctl_ctx *ctx);
+int ndctl_set_config_path(struct ndctl_ctx *ctx, char *config_path);
+const char *ndctl_get_config_path(struct ndctl_ctx *ctx);
 
 enum ndctl_persistence_domain {
 	PERSISTENCE_NONE = 0,
diff --git a/ndctl/Makefile.am b/ndctl/Makefile.am
index afdd03c..00d2612 100644
--- a/ndctl/Makefile.am
+++ b/ndctl/Makefile.am
@@ -7,7 +7,7 @@ BUILT_SOURCES = config.h
 config.h: $(srcdir)/Makefile.am
 	$(AM_V_GEN) echo "/* Autogenerated by ndctl/Makefile.am */" >$@ && \
 	echo '#define NDCTL_CONF_FILE \
-		"$(ndctl_monitorconfdir)/$(ndctl_monitorconf)"' >>$@
+		"$(ndctl_confdir)/$(ndctl_monitorconf)"' >>$@
 	$(AM_V_GEN) echo '#define NDCTL_KEYS_DIR  "$(ndctl_keysdir)"' >>$@
 
 ndctl_SOURCES = ndctl.c \
@@ -74,7 +74,7 @@ ndctl_SOURCES += ../test/libndctl.c \
 		 test.c
 endif
 
-monitor_configdir = $(ndctl_monitorconfdir)
+monitor_configdir = $(ndctl_confdir)
 monitor_config_DATA = $(ndctl_monitorconf)
 
 if ENABLE_SYSTEMD_UNITS
diff --git a/ndctl/lib/Makefile.am b/ndctl/lib/Makefile.am
index e15bb22..0a52c01 100644
--- a/ndctl/lib/Makefile.am
+++ b/ndctl/lib/Makefile.am
@@ -3,6 +3,12 @@ include $(top_srcdir)/Makefile.am.in
 %.pc: %.pc.in Makefile
 	$(SED_PROCESS)
 
+DISTCLEANFILES = config.h
+BUILT_SOURCES = config.h
+config.h: $(srcdir)/Makefile.am
+	$(AM_V_GEN) echo "/* Autogenerated by ndctl/Makefile.am */" >$@ && \
+		echo '#define NDCTL_CONF_DIR  "$(ndctl_confdir)"' >>$@
+
 pkginclude_HEADERS = ../libndctl.h ../ndctl.h
 lib_LTLIBRARIES = libndctl.la
 
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index 58afb74..66d7f21 100644
--- a/ndctl/lib/libndctl.sym
+++ b/ndctl/lib/libndctl.sym
@@ -454,4 +454,6 @@ LIBNDCTL_25 {
 
 LIBNDCTL_26 {
 	ndctl_bus_nfit_translate_spa;
+	ndctl_set_config_path;
+	ndctl_get_config_path;
 } LIBNDCTL_25;
-- 
2.33.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ndctl PATCH v3 03/11] ndctl, config: add the default ndctl configuration file
  2021-12-10 22:34 [ndctl PATCH v3 00/11] Policy based reconfiguration for daxctl Vishal Verma
  2021-12-10 22:34 ` [ndctl PATCH v3 01/11] ndctl, util: add parse-configs helper Vishal Verma
  2021-12-10 22:34 ` [ndctl PATCH v3 02/11] ndctl: make ndctl support configuration files Vishal Verma
@ 2021-12-10 22:34 ` Vishal Verma
  2021-12-10 22:34 ` [ndctl PATCH v3 04/11] ndctl, monitor: refator monitor for supporting multiple config files Vishal Verma
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Vishal Verma @ 2021-12-10 22:34 UTC (permalink / raw)
  To: nvdimm; +Cc: Dan Williams, QI Fuli, fenghua.hu, QI Fuli, Vishal Verma

From: QI Fuli <qi.fuli@fujitsu.com>

Install ndctl/ndctl.conf a default/example ndctl configuration file.

Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: QI Fuli <qi.fuli@fujitsu.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
 configure.ac      |  1 +
 ndctl/Makefile.am |  4 +++-
 ndctl/ndctl.conf  | 56 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 60 insertions(+), 1 deletion(-)
 create mode 100644 ndctl/ndctl.conf

diff --git a/configure.ac b/configure.ac
index a264af7..3f15a7b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -175,6 +175,7 @@ ndctl_confdir=${sysconfdir}/ndctl.conf.d
 ndctl_conf=ndctl.conf
 ndctl_monitorconf=monitor.conf
 AC_SUBST([ndctl_confdir])
+AC_SUBST([ndctl_conf])
 AC_SUBST([ndctl_monitorconf])
 
 daxctl_modprobe_datadir=${datadir}/daxctl
diff --git a/ndctl/Makefile.am b/ndctl/Makefile.am
index 00d2612..4e99510 100644
--- a/ndctl/Makefile.am
+++ b/ndctl/Makefile.am
@@ -42,7 +42,7 @@ keys_configdir = $(ndctl_keysdir)
 keys_config_DATA = $(ndctl_keysreadme)
 endif
 
-EXTRA_DIST += keys.readme monitor.conf ndctl-monitor.service
+EXTRA_DIST += keys.readme monitor.conf ndctl-monitor.service ndctl.conf
 
 if ENABLE_DESTRUCTIVE
 ndctl_SOURCES += ../test/blk_namespaces.c \
@@ -74,6 +74,8 @@ ndctl_SOURCES += ../test/libndctl.c \
 		 test.c
 endif
 
+ndctl_configdir = $(ndctl_confdir)
+ndctl_config_DATA = $(ndctl_conf)
 monitor_configdir = $(ndctl_confdir)
 monitor_config_DATA = $(ndctl_monitorconf)
 
diff --git a/ndctl/ndctl.conf b/ndctl/ndctl.conf
new file mode 100644
index 0000000..ebb4c66
--- /dev/null
+++ b/ndctl/ndctl.conf
@@ -0,0 +1,56 @@
+# This is the default ndctl configuration file. It contains the
+# configuration directives that give ndctl instructions.
+# Ndctl supports multiple configuration files. All files with the
+# .conf suffix under {sysconfdir}/ndctl.conf.d will be regarded as
+# valid ndctl configuration files.
+
+# In this file, lines starting with a hash (#) are comments.
+# The configurations should be in a [section] and follow <key> = <value>
+# style. Multiple space-separated values are allowed, but except the
+# following characters: : ? / \ % " ' $ & ! * { } [ ] ( ) = < > @
+
+[core]
+# The values in [core] section work for all ndctl sub commands.
+# dimm = all
+# bus = all
+# region = all
+# namespace = all
+
+[monitor]
+# The values in [monitor] section work for ndctl monitor.
+# You can change the configuration of ndctl monitor by editing this
+# file or use [--config-file=<file>] option to override this one.
+# The changed value will work after restart ndctl monitor service.
+
+# The objects to monitor are filtered via dimm's name by setting key "dimm".
+# If this value is different from the value of [--dimm=<value>] option,
+# both of the values will work.
+# dimm = all
+
+# The objects to monitor are filtered via its parent bus by setting key "bus".
+# If this value is different from the value of [--bus=<value>] option,
+# both of the values will work.
+# bus = all
+
+# The objects to monitor are filtered via region by setting key "region".
+# If this value is different from the value of [--region=<value>] option,
+# both of the values will work.
+# region = all
+
+# The objects to monitor are filtered via namespace by setting key "namespace".
+# If this value is different from the value of [--namespace=<value>] option,
+# both of the values will work.
+# namespace = all
+
+# The DIMM events to monitor are filtered via event type by setting key
+# "dimm-event". If this value is different from the value of
+# [--dimm-event=<value>] option, both of the values will work.
+# dimm-event = all
+
+# Users can choose to output the notifications to syslog (log=syslog),
+# to standard output (log=standard) or to write into a special file (log=<file>)
+# by setting key "log". If this value is in conflict with the value of
+# [--log=<value>] option, this value will be ignored.
+# Note: Setting value to "standard" or relative path for <file> will not work
+# when running monitor as a daemon.
+# log = /var/log/ndctl/monitor.log
-- 
2.33.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ndctl PATCH v3 04/11] ndctl, monitor: refator monitor for supporting multiple config files
  2021-12-10 22:34 [ndctl PATCH v3 00/11] Policy based reconfiguration for daxctl Vishal Verma
                   ` (2 preceding siblings ...)
  2021-12-10 22:34 ` [ndctl PATCH v3 03/11] ndctl, config: add the default ndctl configuration file Vishal Verma
@ 2021-12-10 22:34 ` Vishal Verma
  2021-12-10 22:34 ` [ndctl PATCH v3 05/11] ndctl: Update ndctl.spec.in for 'ndctl.conf' Vishal Verma
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Vishal Verma @ 2021-12-10 22:34 UTC (permalink / raw)
  To: nvdimm; +Cc: Dan Williams, QI Fuli, fenghua.hu, QI Fuli, Vishal Verma

From: QI Fuli <qi.fuli@fujitsu.com>

Refactor ndctl monitor by using parse-configs helper to support multiple
configuration files.

Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: QI Fuli <qi.fuli@fujitsu.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
 Documentation/ndctl/ndctl-monitor.txt |  8 +--
 ndctl/monitor.c                       | 73 ++++++++++++++-------------
 Documentation/ndctl/Makefile.am       |  2 +-
 3 files changed, 44 insertions(+), 39 deletions(-)

diff --git a/Documentation/ndctl/ndctl-monitor.txt b/Documentation/ndctl/ndctl-monitor.txt
index dbc9070..8c8c35b 100644
--- a/Documentation/ndctl/ndctl-monitor.txt
+++ b/Documentation/ndctl/ndctl-monitor.txt
@@ -21,8 +21,8 @@ objects and dumping the json format notifications to syslog, standard
 output or a logfile.
 
 The objects to monitor and smart events to notify can be selected by
-setting options and/or the configuration file at
-{ndctl_monitorconfdir}/{ndctl_monitorconf}
+setting options and/or configuration files with .conf suffix under
+{ndctl_confdir}
 
 Both, the values in configuration file and in options will work. If
 there is a conflict, the values in options will override the values in
@@ -81,8 +81,8 @@ will not work if "--daemon" is specified.
 
 -c::
 --config-file=::
-	Provide the config file to use. This overrides the default config
-	typically found in {ndctl_monitorconfdir}
+	Provide the config file(s) to use. This overrides the default config
+	typically found in {ndctl_confdir}
 
 --daemon::
 	Run a monitor as a daemon.
diff --git a/ndctl/monitor.c b/ndctl/monitor.c
index ca36179..0e9b65c 100644
--- a/ndctl/monitor.c
+++ b/ndctl/monitor.c
@@ -10,6 +10,7 @@
 #include <util/filter.h>
 #include <util/util.h>
 #include <util/parse-options.h>
+#include <util/parse-configs.h>
 #include <util/strbuf.h>
 #include <ndctl/config.h>
 #include <ndctl/ndctl.h>
@@ -28,7 +29,7 @@
 
 static struct monitor {
 	const char *log;
-	const char *config_file;
+	const char *configs;
 	const char *dimm_event;
 	FILE *log_file;
 	bool daemon;
@@ -463,7 +464,7 @@ out:
 	return rc;
 }
 
-static void parse_config(const char **arg, char *key, char *val, char *ident)
+static void set_monitor_conf(const char **arg, char *key, char *val, char *ident)
 {
 	struct strbuf value = STRBUF_INIT;
 	size_t arg_len = *arg ? strlen(*arg) : 0;
@@ -479,39 +480,25 @@ static void parse_config(const char **arg, char *key, char *val, char *ident)
 	*arg = strbuf_detach(&value, NULL);
 }
 
-static int read_config_file(struct ndctl_ctx *ctx, struct monitor *_monitor,
-		struct util_filter_params *_param)
+static int parse_monitor_config(const struct config *configs,
+					const char *config_file)
 {
 	FILE *f;
 	size_t len = 0;
 	int line = 0, rc = 0;
-	char *buf = NULL, *seek, *value, *config_file;
-
-	if (_monitor->config_file)
-		config_file = strdup(_monitor->config_file);
-	else
-		config_file = strdup(NDCTL_CONF_FILE);
-	if (!config_file) {
-		fail("strdup default config file failed\n");
-		rc = -ENOMEM;
-		goto out;
-	}
+	char *buf = NULL, *seek, *value;
 
 	buf = malloc(BUF_SIZE);
 	if (!buf) {
 		fail("malloc read config-file buf error\n");
-		rc = -ENOMEM;
-		goto out;
+		return -ENOMEM;
 	}
 	seek = buf;
 
 	f = fopen(config_file, "r");
 	if (!f) {
-		if (_monitor->config_file) {
-			err(&monitor, "config-file: %s cannot be opened\n",
-				config_file);
-			rc = -errno;
-		}
+		err(&monitor, "%s cannot be opened\n", config_file);
+		rc = -errno;
 		goto out;
 	}
 
@@ -554,19 +541,18 @@ static int read_config_file(struct ndctl_ctx *ctx, struct monitor *_monitor,
 		if (len == 0)
 			continue;
 
-		parse_config(&_param->bus, "bus", value, seek);
-		parse_config(&_param->dimm, "dimm", value, seek);
-		parse_config(&_param->region, "region", value, seek);
-		parse_config(&_param->namespace, "namespace", value, seek);
-		parse_config(&_monitor->dimm_event, "dimm-event", value, seek);
+		set_monitor_conf(&param.bus, "bus", value, seek);
+		set_monitor_conf(&param.dimm, "dimm", value, seek);
+		set_monitor_conf(&param.region, "region", value, seek);
+		set_monitor_conf(&param.namespace, "namespace", value, seek);
+		set_monitor_conf(&monitor.dimm_event, "dimm-event", value, seek);
 
-		if (!_monitor->log)
-			parse_config(&_monitor->log, "log", value, seek);
+		if (!monitor.log)
+			set_monitor_conf(&monitor.log, "log", value, seek);
 	}
 	fclose(f);
 out:
 	free(buf);
-	free(config_file);
 	return rc;
 }
 
@@ -585,8 +571,8 @@ int cmd_monitor(int argc, const char **argv, struct ndctl_ctx *ctx)
 		OPT_FILENAME('l', "log", &monitor.log,
 				"<file> | syslog | standard",
 				"where to output the monitor's notification"),
-		OPT_FILENAME('c', "config-file", &monitor.config_file,
-				"config-file", "override the default config"),
+		OPT_STRING('c', "config-file", &monitor.configs,
+				"config-file", "override default configs"),
 		OPT_BOOLEAN('\0', "daemon", &monitor.daemon,
 				"run ndctl monitor as a daemon"),
 		OPT_BOOLEAN('u', "human", &monitor.human,
@@ -601,7 +587,20 @@ int cmd_monitor(int argc, const char **argv, struct ndctl_ctx *ctx)
 		"ndctl monitor [<options>]",
 		NULL
 	};
-	const char *prefix = "./";
+	const struct config configs[] = {
+		CONF_MONITOR(NDCTL_CONF_FILE, parse_monitor_config),
+		CONF_STR("core:bus", &param.bus, NULL),
+		CONF_STR("core:region", &param.region, NULL),
+		CONF_STR("core:dimm", &param.dimm, NULL),
+		CONF_STR("core:namespace", &param.namespace, NULL),
+		CONF_STR("monitor:bus", &param.bus, NULL),
+		CONF_STR("monitor:region", &param.region, NULL),
+		CONF_STR("monitor:dimm", &param.dimm, NULL),
+		CONF_STR("monitor:namespace", &param.namespace, NULL),
+		CONF_STR("monitor:dimm-event", &monitor.dimm_event, NULL),
+		CONF_END(),
+	};
+	const char *prefix = "./", *ndctl_configs;
 	struct util_filter_ctx fctx = { 0 };
 	struct monitor_filter_arg mfa = { 0 };
 	int i, rc;
@@ -621,7 +620,13 @@ int cmd_monitor(int argc, const char **argv, struct ndctl_ctx *ctx)
 	else
 		monitor.ctx.log_priority = LOG_INFO;
 
-	rc = read_config_file(ctx, &monitor, &param);
+	ndctl_configs = ndctl_get_config_path(ctx);
+	if (monitor.configs)
+		rc = parse_configs_prefix(monitor.configs, prefix, configs);
+	else if (ndctl_configs)
+		rc = parse_configs_prefix(ndctl_configs, prefix, configs);
+	else
+		rc = 0;
 	if (rc)
 		goto out;
 
diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index f0d5b21..37855cc 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -59,7 +59,7 @@ CLEANFILES = $(man1_MANS)
 .ONESHELL:
 attrs.adoc: $(srcdir)/Makefile.am
 	$(AM_V_GEN) cat <<- EOF >$@
-		:ndctl_monitorconfdir: $(ndctl_monitorconfdir)
+		:ndctl_confdir: $(ndctl_confdir)
 		:ndctl_monitorconf: $(ndctl_monitorconf)
 		:ndctl_keysdir: $(ndctl_keysdir)
 		EOF
-- 
2.33.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ndctl PATCH v3 05/11] ndctl: Update ndctl.spec.in for 'ndctl.conf'
  2021-12-10 22:34 [ndctl PATCH v3 00/11] Policy based reconfiguration for daxctl Vishal Verma
                   ` (3 preceding siblings ...)
  2021-12-10 22:34 ` [ndctl PATCH v3 04/11] ndctl, monitor: refator monitor for supporting multiple config files Vishal Verma
@ 2021-12-10 22:34 ` Vishal Verma
  2021-12-10 22:34 ` [ndctl PATCH v3 06/11] daxctl: Documentation updates for persistent reconfiguration Vishal Verma
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Vishal Verma @ 2021-12-10 22:34 UTC (permalink / raw)
  To: nvdimm; +Cc: Dan Williams, QI Fuli, fenghua.hu, Vishal Verma, QI Fuli

The new config system introduces and installs a sample config file
called ndctl.conf. Update the RPM spec to include this in the %files
section for ndctl.

Cc: QI Fuli <qi.fuli@fujitsu.com>
Reviewed-by: QI Fuli <qi.fuli@jp.fujitsu.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
 ndctl.spec.in | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/ndctl.spec.in b/ndctl.spec.in
index 0563b2d..b46bd74 100644
--- a/ndctl.spec.in
+++ b/ndctl.spec.in
@@ -117,7 +117,8 @@ make check
 %{_sysconfdir}/ndctl/keys/keys.readme
 %{_sysconfdir}/modprobe.d/nvdimm-security.conf
 
-%config(noreplace) %{_sysconfdir}/ndctl/monitor.conf
+%config(noreplace) %{_sysconfdir}/ndctl.conf.d/monitor.conf
+%config(noreplace) %{_sysconfdir}/ndctl.conf.d/ndctl.conf
 
 %files -n daxctl
 %defattr(-,root,root)
-- 
2.33.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ndctl PATCH v3 06/11] daxctl: Documentation updates for persistent reconfiguration
  2021-12-10 22:34 [ndctl PATCH v3 00/11] Policy based reconfiguration for daxctl Vishal Verma
                   ` (4 preceding siblings ...)
  2021-12-10 22:34 ` [ndctl PATCH v3 05/11] ndctl: Update ndctl.spec.in for 'ndctl.conf' Vishal Verma
@ 2021-12-10 22:34 ` Vishal Verma
  2021-12-10 22:34 ` [ndctl PATCH v3 07/11] daxctl: add basic config parsing support Vishal Verma
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Vishal Verma @ 2021-12-10 22:34 UTC (permalink / raw)
  To: nvdimm; +Cc: Dan Williams, QI Fuli, fenghua.hu, Vishal Verma

Add a man page update describing how daxctl-reconfigure-device(1) can
be used for persistent reconfiguration of a daxctl device using a
config file.

Cc: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
 .../daxctl/daxctl-reconfigure-device.txt      | 67 +++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/Documentation/daxctl/daxctl-reconfigure-device.txt b/Documentation/daxctl/daxctl-reconfigure-device.txt
index f112b3c..aa87d45 100644
--- a/Documentation/daxctl/daxctl-reconfigure-device.txt
+++ b/Documentation/daxctl/daxctl-reconfigure-device.txt
@@ -162,6 +162,15 @@ include::region-option.txt[]
 	brought online automatically and immediately with the 'online_movable'
 	policy. Use this option to disable the automatic onlining behavior.
 
+-C::
+--check-config::
+	Get reconfiguration parameters from the global daxctl config file.
+	This is typically used when daxctl-reconfigure-device is called from
+	a systemd-udevd device unit file. The reconfiguration proceeds only
+	if the match parameters in a 'reconfigure-device' section of the
+	config match the dax device specified on the command line. See the
+	'PERSISTENT RECONFIGURATION' section for more details.
+
 include::movable-options.txt[]
 
 -f::
@@ -183,6 +192,64 @@ include::human-option.txt[]
 
 include::verbose-option.txt[]
 
+PERSISTENT RECONFIGURATION
+--------------------------
+
+The 'mode' of a daxctl device is not persistent across reboots by default. This
+is because the device itself does not hold any metadata that hints at what mode
+it was set to, or is intended to be used. The default mode for such a device
+on boot is 'devdax'.
+
+The administrator may set policy such that certain dax devices are always
+reconfigured into a target configuration every boot. This is accomplished via a
+daxctl config file.
+
+The config file may have multiple sections influencing different aspects of
+daxctl operation. The section of interest for persistent reconfiguration is
+'reconfigure-device'. The format of this is as follows:
+
+----
+[reconfigure-device <unique_subsection_name>]
+nvdimm.uuid = <NVDIMM namespace uuid>
+mode = <desired reconfiguration mode> (default: system-ram)
+online = <true|false> (default: true)
+movable = <true|false> (default: true)
+----
+
+Here is an example of a config snippet for managing three devdax namespaces,
+one is left in devdax mode, the second is changed to system-ram mode with
+default options (online, movable), and the third is set to system-ram mode,
+the memory is onlined, but not movable.
+
+Note that the 'subsection name' can be arbitrary, and is only used to
+identify a specific config section. It does not have to match the 'device
+name' (e.g. 'dax0.0' etc).
+
+----
+[reconfigure-device dax0]
+nvdimm.uuid = ed93e918-e165-49d8-921d-383d7b9660c5
+mode = devdax
+
+[reconfigure-device dax1]
+nvdimm.uuid = f36d02ff-1d9f-4fb9-a5b9-8ceb10a00fe3
+mode = system-ram
+
+[reconfigure-device dax2]
+nvdimm.uuid = f36d02ff-1d9f-4fb9-a5b9-8ceb10a00fe3
+mode = system-ram
+online = true
+movable = false
+----
+
+The following example can be used to create a devdax mode namespace, and
+simultaneously add the newly created namespace to the config file for
+system-ram conversion.
+
+----
+ndctl create-namespace --mode=devdax | \
+	jq -r "\"[reconfigure-device $(uuidgen)]\", \"nvdimm.uuid = \(.uuid)\", \"mode = system-ram\"" >> $config_path
+----
+
 include::../copyright.txt[]
 
 SEE ALSO
-- 
2.33.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ndctl PATCH v3 07/11] daxctl: add basic config parsing support
  2021-12-10 22:34 [ndctl PATCH v3 00/11] Policy based reconfiguration for daxctl Vishal Verma
                   ` (5 preceding siblings ...)
  2021-12-10 22:34 ` [ndctl PATCH v3 06/11] daxctl: Documentation updates for persistent reconfiguration Vishal Verma
@ 2021-12-10 22:34 ` Vishal Verma
  2021-12-16 22:37   ` Dan Williams
  2021-12-10 22:34 ` [ndctl PATCH v3 08/11] util/parse-configs: add a key/value search helper Vishal Verma
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 20+ messages in thread
From: Vishal Verma @ 2021-12-10 22:34 UTC (permalink / raw)
  To: nvdimm; +Cc: Dan Williams, QI Fuli, fenghua.hu, Vishal Verma, QI Fuli

Add support similar to ndctl and libndctl for parsing config files. This
allows storing a config file path/list in the daxctl_ctx, and adds APIs
for setting and retrieving it.

Cc: QI Fuli <qi.fuli@fujitsu.com>
Reviewed-by: QI Fuli <qi.fuli@jp.fujitsu.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
 .../daxctl/daxctl-reconfigure-device.txt      |  8 ++++++++
 configure.ac                                  |  3 +++
 daxctl/lib/libdaxctl.c                        | 20 +++++++++++++++++++
 daxctl/libdaxctl.h                            |  2 ++
 Documentation/daxctl/Makefile.am              | 11 +++++++++-
 daxctl/Makefile.am                            |  3 ++-
 daxctl/lib/Makefile.am                        |  6 ++++++
 daxctl/lib/libdaxctl.sym                      |  2 ++
 8 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/Documentation/daxctl/daxctl-reconfigure-device.txt b/Documentation/daxctl/daxctl-reconfigure-device.txt
index aa87d45..09556cc 100644
--- a/Documentation/daxctl/daxctl-reconfigure-device.txt
+++ b/Documentation/daxctl/daxctl-reconfigure-device.txt
@@ -1,5 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 
+include::attrs.adoc[]
+
 daxctl-reconfigure-device(1)
 ============================
 
@@ -250,6 +252,12 @@ ndctl create-namespace --mode=devdax | \
 	jq -r "\"[reconfigure-device $(uuidgen)]\", \"nvdimm.uuid = \(.uuid)\", \"mode = system-ram\"" >> $config_path
 ----
 
+The default location for daxctl config files is under {daxctl_confdir}/,
+and any file with a '.conf' suffix at this location is considered. It is
+acceptable to have multiple files containing ini-style config sections,
+but the {section, subsection} tuple must be unique across all config files
+under {daxctl_confdir}/.
+
 include::../copyright.txt[]
 
 SEE ALSO
diff --git a/configure.ac b/configure.ac
index 3f15a7b..39ad0d4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -178,6 +178,9 @@ AC_SUBST([ndctl_confdir])
 AC_SUBST([ndctl_conf])
 AC_SUBST([ndctl_monitorconf])
 
+daxctl_confdir=${sysconfdir}/daxctl.conf.d
+AC_SUBST([daxctl_confdir])
+
 daxctl_modprobe_datadir=${datadir}/daxctl
 daxctl_modprobe_data=daxctl.conf
 AC_SUBST([daxctl_modprobe_datadir])
diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c
index 860bd9c..f173bbb 100644
--- a/daxctl/lib/libdaxctl.c
+++ b/daxctl/lib/libdaxctl.c
@@ -37,6 +37,7 @@ struct daxctl_ctx {
 	struct log_ctx ctx;
 	int refcount;
 	void *userdata;
+	const char *config_path;
 	int regions_init;
 	struct list_head regions;
 	struct kmod_ctx *kmod_ctx;
@@ -68,6 +69,22 @@ DAXCTL_EXPORT void daxctl_set_userdata(struct daxctl_ctx *ctx, void *userdata)
 	ctx->userdata = userdata;
 }
 
+DAXCTL_EXPORT int daxctl_set_config_path(struct daxctl_ctx *ctx,
+					 char *config_path)
+{
+	if ((!ctx) || (!config_path))
+		return -EINVAL;
+	ctx->config_path = config_path;
+	return 0;
+}
+
+DAXCTL_EXPORT const char *daxctl_get_config_path(struct daxctl_ctx *ctx)
+{
+	if (ctx == NULL)
+		return NULL;
+	return ctx->config_path;
+}
+
 /**
  * daxctl_new - instantiate a new library context
  * @ctx: context to establish
@@ -99,6 +116,9 @@ DAXCTL_EXPORT int daxctl_new(struct daxctl_ctx **ctx)
 	*ctx = c;
 	list_head_init(&c->regions);
 	c->kmod_ctx = kmod_ctx;
+	rc = daxctl_set_config_path(c, DAXCTL_CONF_DIR);
+	if (rc)
+		dbg(c, "Unable to set config path: %s\n", strerror(-rc));
 
 	return 0;
 out:
diff --git a/daxctl/libdaxctl.h b/daxctl/libdaxctl.h
index 683ae9c..6b6c71f 100644
--- a/daxctl/libdaxctl.h
+++ b/daxctl/libdaxctl.h
@@ -28,6 +28,8 @@ int daxctl_get_log_priority(struct daxctl_ctx *ctx);
 void daxctl_set_log_priority(struct daxctl_ctx *ctx, int priority);
 void daxctl_set_userdata(struct daxctl_ctx *ctx, void *userdata);
 void *daxctl_get_userdata(struct daxctl_ctx *ctx);
+int daxctl_set_config_path(struct daxctl_ctx *ctx, char *config_path);
+const char *daxctl_get_config_path(struct daxctl_ctx *ctx);
 
 struct daxctl_region;
 struct daxctl_region *daxctl_new_region(struct daxctl_ctx *ctx, int id,
diff --git a/Documentation/daxctl/Makefile.am b/Documentation/daxctl/Makefile.am
index 5991731..9c43e61 100644
--- a/Documentation/daxctl/Makefile.am
+++ b/Documentation/daxctl/Makefile.am
@@ -33,11 +33,20 @@ EXTRA_DIST = $(man1_MANS)
 
 CLEANFILES = $(man1_MANS)
 
+.ONESHELL:
+attrs.adoc: $(srcdir)/Makefile.am
+	$(AM_V_GEN) cat <<- EOF >$@
+		:daxctl_confdir: $(daxctl_confdir)
+		:daxctl_conf: $(daxctl_conf)
+		:ndctl_keysdir: $(ndctl_keysdir)
+		EOF
+
 XML_DEPS = \
 	../../version.m4 \
 	../copyright.txt \
 	Makefile \
-	$(CONFFILE)
+	$(CONFFILE) \
+	attrs.adoc
 
 RM ?= rm -f
 
diff --git a/daxctl/Makefile.am b/daxctl/Makefile.am
index 9b1313a..7ee65c4 100644
--- a/daxctl/Makefile.am
+++ b/daxctl/Makefile.am
@@ -25,4 +25,5 @@ daxctl_LDADD =\
 	../libutil.a \
 	$(UUID_LIBS) \
 	$(KMOD_LIBS) \
-	$(JSON_LIBS)
+	$(JSON_LIBS) \
+	-liniparser
diff --git a/daxctl/lib/Makefile.am b/daxctl/lib/Makefile.am
index 25efd83..3c47a4b 100644
--- a/daxctl/lib/Makefile.am
+++ b/daxctl/lib/Makefile.am
@@ -3,6 +3,12 @@ include $(top_srcdir)/Makefile.am.in
 %.pc: %.pc.in Makefile
 	$(SED_PROCESS)
 
+DISTCLEANFILES = config.h
+BUILT_SOURCES = config.h
+config.h: $(srcdir)/Makefile.am
+	$(AM_V_GEN) echo "/* Autogenerated by daxctl/Makefile.am */" >$@ && \
+		echo '#define DAXCTL_CONF_DIR  "$(daxctl_confdir)"' >>$@
+
 pkginclude_HEADERS = ../libdaxctl.h
 lib_LTLIBRARIES = libdaxctl.la
 
diff --git a/daxctl/lib/libdaxctl.sym b/daxctl/lib/libdaxctl.sym
index a13e93d..fe68fd0 100644
--- a/daxctl/lib/libdaxctl.sym
+++ b/daxctl/lib/libdaxctl.sym
@@ -96,4 +96,6 @@ LIBDAXCTL_9 {
 global:
 	daxctl_dev_will_auto_online_memory;
 	daxctl_dev_has_online_memory;
+	daxctl_set_config_path;
+	daxctl_get_config_path;
 } LIBDAXCTL_8;
-- 
2.33.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ndctl PATCH v3 08/11] util/parse-configs: add a key/value search helper
  2021-12-10 22:34 [ndctl PATCH v3 00/11] Policy based reconfiguration for daxctl Vishal Verma
                   ` (6 preceding siblings ...)
  2021-12-10 22:34 ` [ndctl PATCH v3 07/11] daxctl: add basic config parsing support Vishal Verma
@ 2021-12-10 22:34 ` Vishal Verma
  2021-12-16 22:44   ` Dan Williams
  2021-12-10 22:34 ` [ndctl PATCH v3 09/11] daxctl/device.c: add an option for getting params from a config file Vishal Verma
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 20+ messages in thread
From: Vishal Verma @ 2021-12-10 22:34 UTC (permalink / raw)
  To: nvdimm; +Cc: Dan Williams, QI Fuli, fenghua.hu, Vishal Verma, QI Fuli

Add a new config query type called CONFIG_SEARCH_SECTION, which searches
all loaded config files based on a query criteria of: specified section
name, specified key/value pair within that section, and can return other
key/values from the section that matched the search criteria.

This allows for multiple named subsections, where a subsection name is
of the type: '[section subsection]'.

Cc: QI Fuli <qi.fuli@fujitsu.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: QI Fuli <qi.fuli@jp.fujitsu.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
 util/parse-configs.h | 15 +++++++++++++
 util/parse-configs.c | 51 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+)

diff --git a/util/parse-configs.h b/util/parse-configs.h
index 32783b5..533480a 100644
--- a/util/parse-configs.h
+++ b/util/parse-configs.h
@@ -9,6 +9,7 @@
 
 enum parse_conf_type {
 	CONFIG_STRING,
+	CONFIG_SEARCH_SECTION,
 	CONFIG_END,
 	MONITOR_CALLBACK,
 };
@@ -20,6 +21,10 @@ typedef int parse_conf_cb(const struct config *, const char *config_file);
 
 struct config {
 	enum parse_conf_type type;
+	const char *section;
+	const char *search_key;
+	const char *search_val;
+	const char *get_key;
 	const char *key;
 	void *value;
 	void *defval;
@@ -31,6 +36,16 @@ struct config {
 #define CONF_END() { .type = CONFIG_END }
 #define CONF_STR(k,v,d) \
 	{ .type = CONFIG_STRING, .key = (k), .value = check_vtype(v, const char **), .defval = (d) }
+#define CONF_SEARCH(s, sk, sv, gk, v, d)	\
+{						\
+	.type = CONFIG_SEARCH_SECTION,		\
+	.section = (s),				\
+	.search_key = (sk),			\
+	.search_val = (sv),			\
+	.get_key = (gk),			\
+	.value = check_vtype(v, const char **),	\
+	.defval = (d)				\
+}
 #define CONF_MONITOR(k,f) \
 	{ .type = MONITOR_CALLBACK, .key = (k), .callback = (f)}
 
diff --git a/util/parse-configs.c b/util/parse-configs.c
index 61352d8..49ee4e0 100644
--- a/util/parse-configs.c
+++ b/util/parse-configs.c
@@ -42,6 +42,54 @@ static void set_str_val(const char **value, const char *val)
 	*value = strbuf_detach(&buf, NULL);
 }
 
+static const char *search_section_kv(dictionary *d, const struct config *c)
+{
+	int i;
+
+	for (i = 0; i < iniparser_getnsec(d); i++) {
+		const char *cur_sec_full = iniparser_getsecname(d, i);
+		char *cur_sec = strdup(cur_sec_full);
+		const char *search_val, *ret_val;
+		const char *delim = " \t\n\r";
+		char *save, *cur, *query;
+
+		if (!cur_sec)
+			return NULL;
+		if (!c->section || !c->search_key || !c->search_val || !c->get_key) {
+			fprintf(stderr, "warning: malformed config query, skipping\n");
+			return NULL;
+		}
+
+		cur = strtok_r(cur_sec, delim, &save);
+		if ((cur == NULL) || (strcmp(cur, c->section) != 0))
+			goto out_sec;
+
+		if (asprintf(&query, "%s:%s", cur_sec_full, c->search_key) < 0)
+			goto out_sec;
+		search_val = iniparser_getstring(d, query, NULL);
+		if (!search_val)
+			goto out_query;
+		if (strcmp(search_val, c->search_val) != 0)
+			goto out_query;
+
+		/* we're now in a matching section */
+		free(query);
+		if (asprintf(&query, "%s:%s", cur_sec_full, c->get_key) < 0)
+			goto out_sec;
+		ret_val = iniparser_getstring(d, query, NULL);
+		free(query);
+		free(cur_sec);
+		return ret_val;
+
+out_query:
+		free(query);
+out_sec:
+		free(cur_sec);
+	}
+
+	return NULL;
+}
+
 static int parse_config_file(const char *config_file,
 			const struct config *configs)
 {
@@ -62,6 +110,9 @@ static int parse_config_file(const char *config_file,
 					iniparser_getstring(dic,
 					configs->key, configs->defval));
 			break;
+		case CONFIG_SEARCH_SECTION:
+			set_str_val((const char **)configs->value,
+					search_section_kv(dic, configs));
 		case MONITOR_CALLBACK:
 		case CONFIG_END:
 			break;
-- 
2.33.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ndctl PATCH v3 09/11] daxctl/device.c: add an option for getting params from a config file
  2021-12-10 22:34 [ndctl PATCH v3 00/11] Policy based reconfiguration for daxctl Vishal Verma
                   ` (7 preceding siblings ...)
  2021-12-10 22:34 ` [ndctl PATCH v3 08/11] util/parse-configs: add a key/value search helper Vishal Verma
@ 2021-12-10 22:34 ` Vishal Verma
  2021-12-16 22:45   ` Dan Williams
  2021-12-10 22:34 ` [ndctl PATCH v3 10/11] daxctl: add systemd service and udev rule for automatic reconfiguration Vishal Verma
  2021-12-10 22:34 ` [ndctl PATCH v3 11/11] daxctl: add and install an example config file Vishal Verma
  10 siblings, 1 reply; 20+ messages in thread
From: Vishal Verma @ 2021-12-10 22:34 UTC (permalink / raw)
  To: nvdimm; +Cc: Dan Williams, QI Fuli, fenghua.hu, Vishal Verma, QI Fuli

Add a new option to daxctl-reconfigure-device that allows it to
comprehend the new global config system in ndctl/daxctl. With this, the
reconfigure-device command can query the config to match a specific
device UUID, and operate using the parameters supplied in that INI
section.

This is in preparation to make daxctl device reconfiguration (usually
as system-ram) policy based, so that reconfiguration can happen
automatically on boot.

Cc: QI Fuli <qi.fuli@fujitsu.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
 daxctl/device.c    | 174 ++++++++++++++++++++++++++++++++++++++++++++-
 daxctl/Makefile.am |   1 +
 2 files changed, 173 insertions(+), 2 deletions(-)

diff --git a/daxctl/device.c b/daxctl/device.c
index a427b7d..c2ff0cc 100644
--- a/daxctl/device.c
+++ b/daxctl/device.c
@@ -14,8 +14,10 @@
 #include <util/filter.h>
 #include <json-c/json.h>
 #include <json-c/json_util.h>
+#include <ndctl/libndctl.h>
 #include <daxctl/libdaxctl.h>
 #include <util/parse-options.h>
+#include <util/parse-configs.h>
 #include <ccan/array_size/array_size.h>
 
 static struct {
@@ -25,6 +27,7 @@ static struct {
 	const char *size;
 	const char *align;
 	const char *input;
+	bool check_config;
 	bool no_online;
 	bool no_movable;
 	bool force;
@@ -65,6 +68,9 @@ enum device_action {
 	ACTION_DESTROY,
 };
 
+#define CONF_SECTION		"reconfigure-device"
+#define CONF_NVDIMM_UUID_STR	"nvdimm.uuid"
+
 #define BASE_OPTIONS() \
 OPT_STRING('r', "region", &param.region, "region-id", "filter by region"), \
 OPT_BOOLEAN('u', "human", &param.human, "use human friendly number formats"), \
@@ -75,7 +81,9 @@ OPT_STRING('m', "mode", &param.mode, "mode", "mode to switch the device to"), \
 OPT_BOOLEAN('N', "no-online", &param.no_online, \
 	"don't auto-online memory sections"), \
 OPT_BOOLEAN('f', "force", &param.force, \
-		"attempt to offline memory sections before reconfiguration")
+		"attempt to offline memory sections before reconfiguration"), \
+OPT_BOOLEAN('C', "check-config", &param.check_config, \
+		"use config files to determine parameters for the operation")
 
 #define CREATE_OPTIONS() \
 OPT_STRING('s', "size", &param.size, "size", "size to switch the device to"), \
@@ -218,6 +226,137 @@ err:
 	return rc;
 }
 
+static int conf_string_to_bool(const char *str)
+{
+	if (!str)
+		return INT_MAX;
+	if (strncmp(str, "t", 1) == 0 ||
+			strncmp(str, "T", 1) == 0 ||
+			strncmp(str, "y", 1) == 0 ||
+			strncmp(str, "Y", 1) == 0 ||
+			strncmp(str, "1", 1) == 0)
+		return true;
+	if (strncmp(str, "f", 1) == 0 ||
+			strncmp(str, "F", 1) == 0 ||
+			strncmp(str, "n", 1) == 0 ||
+			strncmp(str, "N", 1) == 0 ||
+			strncmp(str, "0", 1) == 0)
+		return false;
+	return INT_MAX;
+}
+
+#define conf_assign_inverted_bool(p, conf_var) \
+do { \
+	if (conf_string_to_bool(conf_var) != INT_MAX) \
+		param.p = !conf_string_to_bool(conf_var); \
+} while(0)
+
+static int parse_config_reconfig_set_params(struct daxctl_ctx *ctx, const char *device,
+					    const char *uuid)
+{
+	const char *conf_online = NULL, *conf_movable = NULL;
+	const struct config configs[] = {
+		CONF_SEARCH(CONF_SECTION, CONF_NVDIMM_UUID_STR, uuid,
+			    "mode", &param.mode, NULL),
+		CONF_SEARCH(CONF_SECTION, CONF_NVDIMM_UUID_STR, uuid,
+			    "online", &conf_online, NULL),
+		CONF_SEARCH(CONF_SECTION, CONF_NVDIMM_UUID_STR, uuid,
+			    "movable", &conf_movable, NULL),
+		CONF_END(),
+	};
+	const char *prefix = "./", *daxctl_configs;
+	int rc;
+
+	daxctl_configs = daxctl_get_config_path(ctx);
+	if (daxctl_configs == NULL)
+		return 0;
+
+	rc = parse_configs_prefix(daxctl_configs, prefix, configs);
+	if (rc < 0)
+		return rc;
+
+	conf_assign_inverted_bool(no_online, conf_online);
+	conf_assign_inverted_bool(no_movable, conf_movable);
+
+	return 0;
+}
+
+static bool daxctl_ndns_has_device(struct ndctl_namespace *ndns,
+				    const char *device)
+{
+	struct daxctl_region *dax_region;
+	struct ndctl_dax *dax;
+
+	dax = ndctl_namespace_get_dax(ndns);
+	if (!dax)
+		return false;
+
+	dax_region = ndctl_dax_get_daxctl_region(dax);
+	if (dax_region) {
+		struct daxctl_dev *dev;
+
+		dev = daxctl_dev_get_first(dax_region);
+		if (dev) {
+			if (strcmp(daxctl_dev_get_devname(dev), device) == 0)
+				return true;
+		}
+	}
+	return false;
+}
+
+static int parse_config_reconfig(struct daxctl_ctx *ctx, const char *device)
+{
+	struct ndctl_namespace *ndns;
+	struct ndctl_ctx *ndctl_ctx;
+	struct ndctl_region *region;
+	struct ndctl_bus *bus;
+	struct ndctl_dax *dax;
+	int rc, found = 0;
+	char uuid_buf[40];
+	uuid_t uuid;
+
+	if (strcmp(device, "all") == 0)
+		return 0;
+
+	rc = ndctl_new(&ndctl_ctx);
+	if (rc < 0)
+		return rc;
+
+        ndctl_bus_foreach(ndctl_ctx, bus) {
+		ndctl_region_foreach(bus, region) {
+			ndctl_namespace_foreach(region, ndns) {
+				if (daxctl_ndns_has_device(ndns, device)) {
+					dax = ndctl_namespace_get_dax(ndns);
+					if (!dax)
+						continue;
+					ndctl_dax_get_uuid(dax, uuid);
+					found = 1;
+				}
+			}
+		}
+	}
+
+	if (!found) {
+		fprintf(stderr, "no UUID match for %s found in config files\n",
+			device);
+		return 0;
+	}
+
+	uuid_unparse(uuid, uuid_buf);
+	return parse_config_reconfig_set_params(ctx, device, uuid_buf);
+}
+
+static int parse_device_config(struct daxctl_ctx *ctx, const char *device,
+			       enum device_action action)
+{
+	switch (action) {
+	case ACTION_RECONFIG:
+		return parse_config_reconfig(ctx, device);
+	default:
+		return 0;
+	}
+}
+
 static const char *parse_device_options(int argc, const char **argv,
 		enum device_action action, const struct option *options,
 		const char *usage, struct daxctl_ctx *ctx)
@@ -228,8 +367,11 @@ static const char *parse_device_options(int argc, const char **argv,
 	};
 	unsigned long long units = 1;
 	int i, rc = 0;
+	char *device = NULL;
 
 	argc = parse_options(argc, argv, options, u, 0);
+	if (argc > 0)
+		device = basename(argv[0]);
 
 	/* Handle action-agnostic non-option arguments */
 	if (argc == 0 &&
@@ -279,6 +421,34 @@ static const char *parse_device_options(int argc, const char **argv,
 	if (param.human)
 		flags |= UTIL_JSON_HUMAN;
 
+	/* Scan config file(s) for options. This sets param.foo accordingly */
+	if (device && param.check_config) {
+		if (param.mode || param.no_online || param.no_movable) {
+			fprintf(stderr,
+				"%s: -C cannot be used with --mode, --(no-)movable, or --(no-)online\n",
+				device);
+				usage_with_options(u, options);
+		}
+		rc = parse_device_config(ctx, device, action);
+		if (rc) {
+			fprintf(stderr, "error parsing config file: %s\n",
+				strerror(-rc));
+			return NULL;
+		}
+		if (!param.mode && !param.no_online && !param.no_movable) {
+			fprintf(stderr, "%s: missing or malformed config section\n",
+				device);
+			/*
+			 * Exit with success since the most common case is there is
+			 * no config defined for this device, and we don't want to
+			 * treat that as an error. There isn't an easy way currently
+			 * to distinguish between a malformed config entry from a
+			 * completely missing config section.
+			 */
+			exit(0);
+		}
+	}
+
 	/* Handle action-specific options */
 	switch (action) {
 	case ACTION_RECONFIG:
@@ -336,7 +506,7 @@ static const char *parse_device_options(int argc, const char **argv,
 		return NULL;
 	}
 
-	return argv[0];
+	return device;
 }
 
 static int dev_online_memory(struct daxctl_dev *dev)
diff --git a/daxctl/Makefile.am b/daxctl/Makefile.am
index 7ee65c4..5cebb6c 100644
--- a/daxctl/Makefile.am
+++ b/daxctl/Makefile.am
@@ -22,6 +22,7 @@ daxctl_SOURCES =\
 
 daxctl_LDADD =\
 	lib/libdaxctl.la \
+	../ndctl/lib/libndctl.la \
 	../libutil.a \
 	$(UUID_LIBS) \
 	$(KMOD_LIBS) \
-- 
2.33.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ndctl PATCH v3 10/11] daxctl: add systemd service and udev rule for automatic reconfiguration
  2021-12-10 22:34 [ndctl PATCH v3 00/11] Policy based reconfiguration for daxctl Vishal Verma
                   ` (8 preceding siblings ...)
  2021-12-10 22:34 ` [ndctl PATCH v3 09/11] daxctl/device.c: add an option for getting params from a config file Vishal Verma
@ 2021-12-10 22:34 ` Vishal Verma
  2021-12-16 23:03   ` Dan Williams
  2021-12-10 22:34 ` [ndctl PATCH v3 11/11] daxctl: add and install an example config file Vishal Verma
  10 siblings, 1 reply; 20+ messages in thread
From: Vishal Verma @ 2021-12-10 22:34 UTC (permalink / raw)
  To: nvdimm; +Cc: Dan Williams, QI Fuli, fenghua.hu, Vishal Verma, QI Fuli

Install a systemd service that calls "daxctl-reconfigure-device
--check-config"  with a daxctl device passed in to it via the
environment.

Install a udev rule that is triggered for every daxctl device, and
triggers the above oneshot systemd service.

On boot, whenever a daxctl device is found, udev triggers a
device-specific systemd service called, for example:

  daxdev-reconfigure@-dev-dax0.0.service

This initiates a daxctl-reconfigure-device with a config lookup for the
'dax0.0' device. If the config has a '[reconfigure-device <unique_id>]'
section, it uses the information in that to set the operating mode of
the device.

If any device is in an unexpected status, 'journalctl' can be used to
view the reconfiguration log for that device, for example:

  journalctl --unit daxdev-reconfigure@-dev-dax0.0.service

Update the RPM spec file to include the newly added files to the RPM
build.

Cc: QI Fuli <qi.fuli@fujitsu.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
 configure.ac                       | 9 ++++++++-
 daxctl/90-daxctl-device.rules      | 1 +
 daxctl/Makefile.am                 | 7 +++++++
 daxctl/daxdev-reconfigure@.service | 8 ++++++++
 ndctl.spec.in                      | 3 +++
 5 files changed, 27 insertions(+), 1 deletion(-)
 create mode 100644 daxctl/90-daxctl-device.rules
 create mode 100644 daxctl/daxdev-reconfigure@.service

diff --git a/configure.ac b/configure.ac
index 39ad0d4..33cff60 100644
--- a/configure.ac
+++ b/configure.ac
@@ -160,7 +160,7 @@ AC_CHECK_FUNCS([ \
 
 AC_ARG_WITH([systemd],
 	AS_HELP_STRING([--with-systemd],
-		[Enable systemd functionality (monitor). @<:@default=yes@:>@]),
+		[Enable systemd functionality. @<:@default=yes@:>@]),
 	[], [with_systemd=yes])
 
 if test "x$with_systemd" = "xyes"; then
@@ -186,6 +186,13 @@ daxctl_modprobe_data=daxctl.conf
 AC_SUBST([daxctl_modprobe_datadir])
 AC_SUBST([daxctl_modprobe_data])
 
+AC_ARG_WITH(udevrulesdir,
+    [AS_HELP_STRING([--with-udevrulesdir=DIR], [udev rules.d directory])],
+    [UDEVRULESDIR="$withval"],
+    [UDEVRULESDIR='${prefix}/lib/udev/rules.d']
+)
+AC_SUBST(UDEVRULESDIR)
+
 AC_ARG_WITH([keyutils],
 	    AS_HELP_STRING([--with-keyutils],
 			[Enable keyutils functionality (security).  @<:@default=yes@:>@]), [], [with_keyutils=yes])
diff --git a/daxctl/90-daxctl-device.rules b/daxctl/90-daxctl-device.rules
new file mode 100644
index 0000000..ee0670f
--- /dev/null
+++ b/daxctl/90-daxctl-device.rules
@@ -0,0 +1 @@
+ACTION=="add", SUBSYSTEM=="dax", TAG+="systemd", ENV{SYSTEMD_WANTS}="daxdev-reconfigure@$env{DEVNAME}.service"
diff --git a/daxctl/Makefile.am b/daxctl/Makefile.am
index 5cebb6c..36dfc55 100644
--- a/daxctl/Makefile.am
+++ b/daxctl/Makefile.am
@@ -28,3 +28,10 @@ daxctl_LDADD =\
 	$(KMOD_LIBS) \
 	$(JSON_LIBS) \
 	-liniparser
+
+udevrulesdir = $(UDEVRULESDIR)
+udevrules_DATA = 90-daxctl-device.rules
+
+if ENABLE_SYSTEMD_UNITS
+systemd_unit_DATA = daxdev-reconfigure@.service
+endif
diff --git a/daxctl/daxdev-reconfigure@.service b/daxctl/daxdev-reconfigure@.service
new file mode 100644
index 0000000..13d570c
--- /dev/null
+++ b/daxctl/daxdev-reconfigure@.service
@@ -0,0 +1,8 @@
+[Unit]
+Description=Automatic daxctl device reconfiguration
+Documentation=man:daxctl-reconfigure-device(1)
+
+[Service]
+Type=forking
+GuessMainPID=false
+ExecStart=/bin/sh -c "exec daxctl reconfigure-device --check-config %I"
diff --git a/ndctl.spec.in b/ndctl.spec.in
index b46bd74..642670a 100644
--- a/ndctl.spec.in
+++ b/ndctl.spec.in
@@ -26,6 +26,7 @@ BuildRequires:	pkgconfig(json-c)
 BuildRequires:	pkgconfig(bash-completion)
 BuildRequires:	pkgconfig(systemd)
 BuildRequires:	keyutils-libs-devel
+BuildRequires:	systemd-rpm-macros
 
 %description
 Utility library for managing the "libnvdimm" subsystem.  The "libnvdimm"
@@ -126,6 +127,8 @@ make check
 %{_bindir}/daxctl
 %{_mandir}/man1/daxctl*
 %{_datadir}/daxctl/daxctl.conf
+%{_unitdir}/daxdev-reconfigure@.service
+%config %{_udevrulesdir}/90-daxctl-device.rules
 
 %files -n LNAME
 %defattr(-,root,root)
-- 
2.33.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ndctl PATCH v3 11/11] daxctl: add and install an example config file
  2021-12-10 22:34 [ndctl PATCH v3 00/11] Policy based reconfiguration for daxctl Vishal Verma
                   ` (9 preceding siblings ...)
  2021-12-10 22:34 ` [ndctl PATCH v3 10/11] daxctl: add systemd service and udev rule for automatic reconfiguration Vishal Verma
@ 2021-12-10 22:34 ` Vishal Verma
  10 siblings, 0 replies; 20+ messages in thread
From: Vishal Verma @ 2021-12-10 22:34 UTC (permalink / raw)
  To: nvdimm; +Cc: Dan Williams, QI Fuli, fenghua.hu, Vishal Verma

Add an example config file, and install it with 'make install' and via
the RPM, so that the config path gets established, and there is an
easily available template to edit as needed.

Cc: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
 daxctl/Makefile.am         |  3 +++
 daxctl/daxctl.example.conf | 27 +++++++++++++++++++++++++++
 ndctl.spec.in              |  1 +
 3 files changed, 31 insertions(+)
 create mode 100644 daxctl/daxctl.example.conf

diff --git a/daxctl/Makefile.am b/daxctl/Makefile.am
index 36dfc55..d1bf9fb 100644
--- a/daxctl/Makefile.am
+++ b/daxctl/Makefile.am
@@ -32,6 +32,9 @@ daxctl_LDADD =\
 udevrulesdir = $(UDEVRULESDIR)
 udevrules_DATA = 90-daxctl-device.rules
 
+daxctl_configdir = $(daxctl_confdir)
+daxctl_config_DATA = daxctl.example.conf
+
 if ENABLE_SYSTEMD_UNITS
 systemd_unit_DATA = daxdev-reconfigure@.service
 endif
diff --git a/daxctl/daxctl.example.conf b/daxctl/daxctl.example.conf
new file mode 100644
index 0000000..8181863
--- /dev/null
+++ b/daxctl/daxctl.example.conf
@@ -0,0 +1,27 @@
+# This is an example config file for daxctl
+# daxctl supports multiple configuration files. All files with the
+# .conf suffix under {sysconfdir}/daxctl.conf.d/ are valid config files.
+# Lines beginning with a '#' are treated as comments and ignored
+# The (section-name, subsection-name) tuple must be unique across all
+# config files.
+
+# The following example config snippet is used to automatically reconfigure
+# an nvdimm namespace with the specified UUID from 'devdax' mode to
+# 'system-ram'.
+
+# Uncomment the lines to activate it, and substitute the correct UUIDs and
+# other parameters for the desired behavior.
+
+# This can be replicated as many times as necessary to handle multiple
+# namespaces/dax devices, so long as the subsection name (e.g.
+# "unique_identifier_foo" in the example below) is unique across all
+# sections and all config files in the config path.
+
+# The nvdimm.uuid can be obtained from a command such as:
+#   "ndctl list --device-dax"
+
+# [reconfigure-device unique_identifier_foo]
+# nvdimm.uuid=ed93e918-e165-49d8-921d-383d7b9660c5
+# mode = system-ram
+# online = true
+# movable = false
diff --git a/ndctl.spec.in b/ndctl.spec.in
index 642670a..ce80f9d 100644
--- a/ndctl.spec.in
+++ b/ndctl.spec.in
@@ -129,6 +129,7 @@ make check
 %{_datadir}/daxctl/daxctl.conf
 %{_unitdir}/daxdev-reconfigure@.service
 %config %{_udevrulesdir}/90-daxctl-device.rules
+%config(noreplace) %{_sysconfdir}/daxctl.conf.d/daxctl.example.conf
 
 %files -n LNAME
 %defattr(-,root,root)
-- 
2.33.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [ndctl PATCH v3 01/11] ndctl, util: add parse-configs helper
  2021-12-10 22:34 ` [ndctl PATCH v3 01/11] ndctl, util: add parse-configs helper Vishal Verma
@ 2021-12-16 21:42   ` Dan Williams
  2021-12-17 21:31     ` Verma, Vishal L
  2021-12-21 12:54   ` Joao Martins
  1 sibling, 1 reply; 20+ messages in thread
From: Dan Williams @ 2021-12-16 21:42 UTC (permalink / raw)
  To: Vishal Verma; +Cc: Linux NVDIMM, QI Fuli, Hu, Fenghua, QI Fuli

On Fri, Dec 10, 2021 at 2:34 PM Vishal Verma <vishal.l.verma@intel.com> wrote:
>
> From: QI Fuli <qi.fuli@fujitsu.com>
>
> Add parse-config util to help ndctl commands parse ndctl global
> configuration files. This provides a parse_configs_prefix() helper which
> uses the iniparser APIs to read all applicable config files, and either
> return a 'value' for a requested 'key', or perform a callback if
> requested. The operation is defined by a 'struct config' which
> encapsulates the key to search for, the location to store the value, and
> any callbacks to be executed.
>
> Signed-off-by: QI Fuli <qi.fuli@fujitsu.com>
> Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
[..]
> diff --git a/ndctl/Makefile.am b/ndctl/Makefile.am
> index a63b1e0..afdd03c 100644
> --- a/ndctl/Makefile.am
> +++ b/ndctl/Makefile.am
> @@ -56,7 +56,8 @@ ndctl_LDADD =\
>         ../libutil.a \
>         $(UUID_LIBS) \
>         $(KMOD_LIBS) \
> -       $(JSON_LIBS)
> +       $(JSON_LIBS) \
> +       -liniparser

Darn, no pkgconfig for iniparser. Oh well.

Reviewed-by: Dan Williams <dan.j.williams@intel.com>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [ndctl PATCH v3 02/11] ndctl: make ndctl support configuration files
  2021-12-10 22:34 ` [ndctl PATCH v3 02/11] ndctl: make ndctl support configuration files Vishal Verma
@ 2021-12-16 21:47   ` Dan Williams
  0 siblings, 0 replies; 20+ messages in thread
From: Dan Williams @ 2021-12-16 21:47 UTC (permalink / raw)
  To: Vishal Verma; +Cc: Linux NVDIMM, QI Fuli, Hu, Fenghua, QI Fuli

On Fri, Dec 10, 2021 at 2:34 PM Vishal Verma <vishal.l.verma@intel.com> wrote:
>
> From: QI Fuli <qi.fuli@fujitsu.com>
>
> Add a 'config_path' to ndctl_ctx for supporting ndctl global configuration
> files. Any file with a .conf suffix under {sysconfdir}/ndctl.conf.d/ will
> be regarded as a global configuration file which can have INI-style config
> sections. Add an ndctl_set_config_path() API for setting the default
> configuration files' path for ndctl. Add an ndctl_get_config_path() API for
> getting ndctl configuration files' path from ndctl_ctx.
>
> Signed-off-by: QI Fuli <qi.fuli@fujitsu.com>
> Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>

LGTM

Reviewed-by: Dan Williams <dan.j.williams@intel.com>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [ndctl PATCH v3 07/11] daxctl: add basic config parsing support
  2021-12-10 22:34 ` [ndctl PATCH v3 07/11] daxctl: add basic config parsing support Vishal Verma
@ 2021-12-16 22:37   ` Dan Williams
  0 siblings, 0 replies; 20+ messages in thread
From: Dan Williams @ 2021-12-16 22:37 UTC (permalink / raw)
  To: Vishal Verma; +Cc: Linux NVDIMM, QI Fuli, Hu, Fenghua, QI Fuli

On Fri, Dec 10, 2021 at 2:34 PM Vishal Verma <vishal.l.verma@intel.com> wrote:
>
> Add support similar to ndctl and libndctl for parsing config files. This
> allows storing a config file path/list in the daxctl_ctx, and adds APIs
> for setting and retrieving it.
>
> Cc: QI Fuli <qi.fuli@fujitsu.com>
> Reviewed-by: QI Fuli <qi.fuli@jp.fujitsu.com>
> Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>

LGTM

Reviewed-by: Dan Williams <dan.j.williams@intel.com>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [ndctl PATCH v3 08/11] util/parse-configs: add a key/value search helper
  2021-12-10 22:34 ` [ndctl PATCH v3 08/11] util/parse-configs: add a key/value search helper Vishal Verma
@ 2021-12-16 22:44   ` Dan Williams
  0 siblings, 0 replies; 20+ messages in thread
From: Dan Williams @ 2021-12-16 22:44 UTC (permalink / raw)
  To: Vishal Verma; +Cc: Linux NVDIMM, QI Fuli, Hu, Fenghua, QI Fuli

On Fri, Dec 10, 2021 at 2:34 PM Vishal Verma <vishal.l.verma@intel.com> wrote:
>
> Add a new config query type called CONFIG_SEARCH_SECTION, which searches
> all loaded config files based on a query criteria of: specified section
> name, specified key/value pair within that section, and can return other
> key/values from the section that matched the search criteria.
>
> This allows for multiple named subsections, where a subsection name is
> of the type: '[section subsection]'.

LGTM

Reviewed-by: Dan Wiilliams <dan.j.williams@intel.com>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [ndctl PATCH v3 09/11] daxctl/device.c: add an option for getting params from a config file
  2021-12-10 22:34 ` [ndctl PATCH v3 09/11] daxctl/device.c: add an option for getting params from a config file Vishal Verma
@ 2021-12-16 22:45   ` Dan Williams
  0 siblings, 0 replies; 20+ messages in thread
From: Dan Williams @ 2021-12-16 22:45 UTC (permalink / raw)
  To: Vishal Verma; +Cc: Linux NVDIMM, QI Fuli, Hu, Fenghua, QI Fuli

On Fri, Dec 10, 2021 at 2:35 PM Vishal Verma <vishal.l.verma@intel.com> wrote:
>
> Add a new option to daxctl-reconfigure-device that allows it to
> comprehend the new global config system in ndctl/daxctl. With this, the
> reconfigure-device command can query the config to match a specific
> device UUID, and operate using the parameters supplied in that INI
> section.
>
> This is in preparation to make daxctl device reconfiguration (usually
> as system-ram) policy based, so that reconfiguration can happen
> automatically on boot.
>
> Cc: QI Fuli <qi.fuli@fujitsu.com>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>

LGTM

Reviewed-by: Dan Williams <dan.j.williams@intel.com>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [ndctl PATCH v3 10/11] daxctl: add systemd service and udev rule for automatic reconfiguration
  2021-12-10 22:34 ` [ndctl PATCH v3 10/11] daxctl: add systemd service and udev rule for automatic reconfiguration Vishal Verma
@ 2021-12-16 23:03   ` Dan Williams
  0 siblings, 0 replies; 20+ messages in thread
From: Dan Williams @ 2021-12-16 23:03 UTC (permalink / raw)
  To: Vishal Verma; +Cc: Linux NVDIMM, QI Fuli, Hu, Fenghua, QI Fuli

On Fri, Dec 10, 2021 at 2:34 PM Vishal Verma <vishal.l.verma@intel.com> wrote:
>
> Install a systemd service that calls "daxctl-reconfigure-device
> --check-config"  with a daxctl device passed in to it via the
> environment.
>
> Install a udev rule that is triggered for every daxctl device, and
> triggers the above oneshot systemd service.
>
> On boot, whenever a daxctl device is found, udev triggers a
> device-specific systemd service called, for example:
>
>   daxdev-reconfigure@-dev-dax0.0.service
>
> This initiates a daxctl-reconfigure-device with a config lookup for the
> 'dax0.0' device. If the config has a '[reconfigure-device <unique_id>]'
> section, it uses the information in that to set the operating mode of
> the device.
>
> If any device is in an unexpected status, 'journalctl' can be used to
> view the reconfiguration log for that device, for example:
>
>   journalctl --unit daxdev-reconfigure@-dev-dax0.0.service
>
> Update the RPM spec file to include the newly added files to the RPM
> build.
>
> Cc: QI Fuli <qi.fuli@fujitsu.com>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>

LGTM. I don't know if udev rule numbering is correct, or not, but I
suspect the distros will tell us or fix it up in the distro package.

Reviewed-by: Dan Williams <dan.j.williams@intel.com>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [ndctl PATCH v3 01/11] ndctl, util: add parse-configs helper
  2021-12-16 21:42   ` Dan Williams
@ 2021-12-17 21:31     ` Verma, Vishal L
  0 siblings, 0 replies; 20+ messages in thread
From: Verma, Vishal L @ 2021-12-17 21:31 UTC (permalink / raw)
  To: Williams, Dan J; +Cc: nvdimm, qi.fuli, Hu, Fenghua, qi.fuli

On Thu, 2021-12-16 at 13:42 -0800, Dan Williams wrote:
> On Fri, Dec 10, 2021 at 2:34 PM Vishal Verma <vishal.l.verma@intel.com> wrote:
> > 
> > From: QI Fuli <qi.fuli@fujitsu.com>
> > 
> > Add parse-config util to help ndctl commands parse ndctl global
> > configuration files. This provides a parse_configs_prefix() helper which
> > uses the iniparser APIs to read all applicable config files, and either
> > return a 'value' for a requested 'key', or perform a callback if
> > requested. The operation is defined by a 'struct config' which
> > encapsulates the key to search for, the location to store the value, and
> > any callbacks to be executed.
> > 
> > Signed-off-by: QI Fuli <qi.fuli@fujitsu.com>
> > Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
> [..]
> > diff --git a/ndctl/Makefile.am b/ndctl/Makefile.am
> > index a63b1e0..afdd03c 100644
> > --- a/ndctl/Makefile.am
> > +++ b/ndctl/Makefile.am
> > @@ -56,7 +56,8 @@ ndctl_LDADD =\
> >         ../libutil.a \
> >         $(UUID_LIBS) \
> >         $(KMOD_LIBS) \
> > -       $(JSON_LIBS)
> > +       $(JSON_LIBS) \
> > +       -liniparser
> 
> Darn, no pkgconfig for iniparser. Oh well.

Actually upstream has a pkgconfig file, but Fedora didn't package it
for some reason. I've pinged the maintainer to see if it can be added.

https://github.com/ndevilla/iniparser/blob/master/iniparser.pc

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [ndctl PATCH v3 01/11] ndctl, util: add parse-configs helper
  2021-12-10 22:34 ` [ndctl PATCH v3 01/11] ndctl, util: add parse-configs helper Vishal Verma
  2021-12-16 21:42   ` Dan Williams
@ 2021-12-21 12:54   ` Joao Martins
  1 sibling, 0 replies; 20+ messages in thread
From: Joao Martins @ 2021-12-21 12:54 UTC (permalink / raw)
  To: Vishal Verma; +Cc: Dan Williams, QI Fuli, fenghua.hu, QI Fuli, nvdimm

On 12/10/21 22:34, Vishal Verma wrote:
> diff --git a/util/parse-configs.c b/util/parse-configs.c
> new file mode 100644
> index 0000000..61352d8
> --- /dev/null
> +++ b/util/parse-configs.c
> @@ -0,0 +1,105 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (C) 2021, FUJITSU LIMITED. ALL rights reserved.
> +
> +#include <dirent.h>
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <iniparser/iniparser.h>

Older builds[0] of iniparser-devel don't ship {/usr/include}/iniparser/iniparser.h
but rather {/usr/include}/iniparser.h . The new version[1] still creates a symlink to the
older path, so changing the include to be:

	#include <iniparser.h>

Should work on all distros.

[0] https://centos.pkgs.org/7/centos-x86_64/iniparser-devel-3.1-5.el7.x86_64.rpm.html
[1] https://centos.pkgs.org/8/epel-x86_64/iniparser-devel-4.1-5.el8.x86_64.rpm.html

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2021-12-21 12:54 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-10 22:34 [ndctl PATCH v3 00/11] Policy based reconfiguration for daxctl Vishal Verma
2021-12-10 22:34 ` [ndctl PATCH v3 01/11] ndctl, util: add parse-configs helper Vishal Verma
2021-12-16 21:42   ` Dan Williams
2021-12-17 21:31     ` Verma, Vishal L
2021-12-21 12:54   ` Joao Martins
2021-12-10 22:34 ` [ndctl PATCH v3 02/11] ndctl: make ndctl support configuration files Vishal Verma
2021-12-16 21:47   ` Dan Williams
2021-12-10 22:34 ` [ndctl PATCH v3 03/11] ndctl, config: add the default ndctl configuration file Vishal Verma
2021-12-10 22:34 ` [ndctl PATCH v3 04/11] ndctl, monitor: refator monitor for supporting multiple config files Vishal Verma
2021-12-10 22:34 ` [ndctl PATCH v3 05/11] ndctl: Update ndctl.spec.in for 'ndctl.conf' Vishal Verma
2021-12-10 22:34 ` [ndctl PATCH v3 06/11] daxctl: Documentation updates for persistent reconfiguration Vishal Verma
2021-12-10 22:34 ` [ndctl PATCH v3 07/11] daxctl: add basic config parsing support Vishal Verma
2021-12-16 22:37   ` Dan Williams
2021-12-10 22:34 ` [ndctl PATCH v3 08/11] util/parse-configs: add a key/value search helper Vishal Verma
2021-12-16 22:44   ` Dan Williams
2021-12-10 22:34 ` [ndctl PATCH v3 09/11] daxctl/device.c: add an option for getting params from a config file Vishal Verma
2021-12-16 22:45   ` Dan Williams
2021-12-10 22:34 ` [ndctl PATCH v3 10/11] daxctl: add systemd service and udev rule for automatic reconfiguration Vishal Verma
2021-12-16 23:03   ` Dan Williams
2021-12-10 22:34 ` [ndctl PATCH v3 11/11] daxctl: add and install an example config file Vishal Verma

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.