Page MenuHomeFreeBSD

D42572.diff
No OneTemporary

D42572.diff

diff --git a/usr.sbin/bhyve/config.h b/usr.sbin/bhyve/config.h
--- a/usr.sbin/bhyve/config.h
+++ b/usr.sbin/bhyve/config.h
@@ -58,6 +58,12 @@
*/
const char *get_config_value_node(const nvlist_t *parent, const char *name);
+/*
+ * Loop over duplicate values of a configuration variable.
+ */
+int config_value_node_foreach(const nvlist_t *parent, const char *name,
+ int (*cb)(const char *, void *), void *arg);
+
/*
* Similar to get_config_value_node but expects a full path to the
* leaf node.
@@ -93,12 +99,20 @@
* Adds or replaces the value of the specified variable.
*
* If 'parent' is NULL, 'name' is assumed to be a top-level variable.
+ * If 'name' is already set, the old value is overwritten.
*/
void set_config_value_node(nvlist_t *parent, const char *name,
const char *value);
/*
- * Similar to set_config_value_node but only sets value if it's unset yet.
+ * Similar to set_config_value_node, but an existing value with the same name is
+ * not overwritten.
+ */
+void set_config_value_node_dupok(nvlist_t *parent, const char *name,
+ const char *value);
+
+/*
+ * Similar to set_config_value_node but only sets value if it's unset.
*/
void set_config_value_node_if_unset(nvlist_t *const parent,
const char *const name, const char *const value);
diff --git a/usr.sbin/bhyve/config.c b/usr.sbin/bhyve/config.c
--- a/usr.sbin/bhyve/config.c
+++ b/usr.sbin/bhyve/config.c
@@ -25,7 +25,8 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
+#include <sys/cnv.h>
+
#include <assert.h>
#include <err.h>
#include <stdio.h>
@@ -36,13 +37,28 @@
static nvlist_t *config_root;
+static nvlist_t *
+config_node_alloc(void)
+{
+ nvlist_t *nvl;
+
+ /*
+ * Config nodes permit duplicate keys, but by default, an existing
+ * configuration value is overwritten when a new one is set. This
+ * behavior can be overridden by using set_config_value_node_dupok(),
+ * in which case, config_value_node_foreach() must be used to retrieve
+ * values.
+ */
+ nvl = nvlist_create(NV_FLAG_NO_UNIQUE);
+ if (nvl == NULL)
+ err(1, "nvlist_create");
+ return (nvl);
+}
+
void
init_config(void)
{
-
- config_root = nvlist_create(0);
- if (config_root == NULL)
- err(4, "Failed to create configuration root nvlist");
+ config_root = config_node_alloc();
}
static nvlist_t *
@@ -88,7 +104,7 @@
* XXX-MJ as with the case above, "new_nvl" shouldn't be
* mutated after its ownership is given to "nvl".
*/
- new_nvl = nvlist_create(0);
+ new_nvl = config_node_alloc();
if (new_nvl == NULL)
errx(4, "Failed to allocate memory");
nvlist_move_nvlist(nvl, name, new_nvl);
@@ -130,23 +146,39 @@
return (_lookup_config_node(parent, path, false));
}
-void
-set_config_value_node(nvlist_t *parent, const char *name, const char *value)
-{
+#define CONFIG_DUPOK 0x01
+static void
+set_config_value_node_flags(nvlist_t *parent, const char *name,
+ const char *value, int flags)
+{
if (strchr(name, '.') != NULL)
errx(4, "Invalid config node name %s", name);
if (parent == NULL)
parent = config_root;
- if (nvlist_exists_string(parent, name))
- nvlist_free_string(parent, name);
- else if (nvlist_exists(parent, name))
+ if (nvlist_exists_string(parent, name)) {
+ if ((flags & CONFIG_DUPOK) == 0)
+ nvlist_free_string(parent, name);
+ } else if (nvlist_exists(parent, name))
errx(4,
"Attempting to add value %s to existing node %s of list %p",
value, name, parent);
nvlist_add_string(parent, name, value);
}
+void
+set_config_value_node(nvlist_t *parent, const char *name, const char *value)
+{
+ set_config_value_node_flags(parent, name, value, 0);
+}
+
+void
+set_config_value_node_dupok(nvlist_t *parent, const char *name,
+ const char *value)
+{
+ set_config_value_node_flags(parent, name, value, CONFIG_DUPOK);
+}
+
void
set_config_value_node_if_unset(nvlist_t *const parent, const char *const name,
const char *const value)
@@ -358,6 +390,31 @@
return (expand_config_value(nvlist_get_string(parent, name)));
}
+int
+config_value_node_foreach(const nvlist_t *parent, const char *name,
+ int (*cb)(const char *, void *), void *arg)
+{
+ void *cookie;
+ const char *nvname;
+ int error, type;
+
+ if (strchr(name, '.') != NULL)
+ errx(4, "Invalid config node name %s", name);
+ if (parent == NULL)
+ parent = config_root;
+
+ for (cookie = NULL;
+ (nvname = nvlist_next(parent, &type, &cookie)) != NULL;) {
+ assert(type == NV_TYPE_STRING);
+ if (strcmp(nvname, name) == 0) {
+ error = cb(cnvlist_get_string(cookie), arg);
+ if (error != 0)
+ return (error);
+ }
+ }
+ return (0);
+}
+
static bool
_bool_value(const char *name, const char *value)
{

File Metadata

Mime Type
text/plain
Expires
Fri, Aug 7, 5:04 AM (4 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
36147365
Default Alt Text
D42572.diff (4 KB)

Event Timeline