All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vishal Verma <vishal.l.verma@intel.com>
To: <nvdimm@lists.linux.dev>
Cc: Dan Williams <dan.j.williams@intel.com>,
	QI Fuli <qi.fuli@jp.fujitsu.com>,
	fenghua.hu@intel.com, Vishal Verma <vishal.l.verma@intel.com>,
	QI Fuli <qi.fuli@fujitsu.com>
Subject: [ndctl PATCH v3 08/11] util/parse-configs: add a key/value search helper
Date: Fri, 10 Dec 2021 15:34:37 -0700	[thread overview]
Message-ID: <20211210223440.3946603-9-vishal.l.verma@intel.com> (raw)
In-Reply-To: <20211210223440.3946603-1-vishal.l.verma@intel.com>

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


  parent reply	other threads:[~2021-12-10 22:34 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 ` Vishal Verma [this message]
2021-12-16 22:44   ` [ndctl PATCH v3 08/11] util/parse-configs: add a key/value search helper 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211210223440.3946603-9-vishal.l.verma@intel.com \
    --to=vishal.l.verma@intel.com \
    --cc=dan.j.williams@intel.com \
    --cc=fenghua.hu@intel.com \
    --cc=nvdimm@lists.linux.dev \
    --cc=qi.fuli@fujitsu.com \
    --cc=qi.fuli@jp.fujitsu.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.