git: e2d7bec6bc5a - main - bhyve: Want walk_config_nodes

From: Joseph Mingrone <jrm_at_FreeBSD.org>
Date: Fri, 16 Jan 2026 15:02:19 UTC
The branch main has been updated by jrm:

URL: https://cgit.FreeBSD.org/src/commit/?id=e2d7bec6bc5a124091859ad134bc9cfc2a8b4688

commit e2d7bec6bc5a124091859ad134bc9cfc2a8b4688
Author:     Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
AuthorDate: 2026-01-16 14:43:44 +0000
Commit:     Joseph Mingrone <jrm@FreeBSD.org>
CommitDate: 2026-01-16 14:48:34 +0000

    bhyve: Want walk_config_nodes
    
    Add a function to all nodes under a config option node. This allows
    parsing an arbitrary number of similarly structured configuration
    options in a config option group.
    
    Reviewed by:    corvink, markj
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D51551
---
 usr.sbin/bhyve/config.c | 49 +++++++++++++++++++++++++++++++++----------------
 usr.sbin/bhyve/config.h |  9 +++++++++
 2 files changed, 42 insertions(+), 16 deletions(-)

diff --git a/usr.sbin/bhyve/config.c b/usr.sbin/bhyve/config.c
index cc9311624e5e..9f7e3061979a 100644
--- a/usr.sbin/bhyve/config.c
+++ b/usr.sbin/bhyve/config.c
@@ -2,6 +2,7 @@
  * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2021 John H. Baldwin <jhb@FreeBSD.org>
+ * Copyright 2026 Hans Rosenfeld
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -434,31 +435,47 @@ set_config_bool_node(nvlist_t *parent, const char *name, bool value)
 	set_config_value_node(parent, name, value ? "true" : "false");
 }
 
-static void
-dump_tree(const char *prefix, const nvlist_t *nvl)
+int
+walk_config_nodes(const char *prefix, const nvlist_t *parent, void *arg,
+    int (*cb)(const char *, const nvlist_t *, const char *, int, void *))
 {
+	void *cookie = NULL;
 	const char *name;
-	void *cookie;
 	int type;
 
-	cookie = NULL;
-	while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) {
-		if (type == NV_TYPE_NVLIST) {
-			char *new_prefix;
+	while ((name = nvlist_next(parent, &type, &cookie)) != NULL) {
+		int ret;
 
-			asprintf(&new_prefix, "%s%s.", prefix, name);
-			dump_tree(new_prefix, nvlist_get_nvlist(nvl, name));
-			free(new_prefix);
-		} else {
-			assert(type == NV_TYPE_STRING);
-			printf("%s%s=%s\n", prefix, name,
-			    nvlist_get_string(nvl, name));
-		}
+		ret = cb(prefix, parent, name, type, arg);
+		if (ret != 0)
+			return (ret);
+	}
+
+	return (0);
+}
+
+static int
+dump_node_cb(const char *prefix, const nvlist_t *parent, const char *name,
+    int type, void *arg)
+{
+	if (type == NV_TYPE_NVLIST) {
+		char *new_prefix;
+		int ret;
+
+		asprintf(&new_prefix, "%s%s.", prefix, name);
+		ret = walk_config_nodes(new_prefix,
+		    nvlist_get_nvlist(parent, name), arg, dump_node_cb);
+		free(new_prefix);
+		return (ret);
 	}
+
+	assert(type == NV_TYPE_STRING);
+	printf("%s%s=%s\n", prefix, name, nvlist_get_string(parent, name));
+	return (0);
 }
 
 void
 dump_config(void)
 {
-	dump_tree("", config_root);
+	(void)walk_config_nodes("", config_root, NULL, dump_node_cb);
 }
diff --git a/usr.sbin/bhyve/config.h b/usr.sbin/bhyve/config.h
index 35882e65ace7..acdd621af5ee 100644
--- a/usr.sbin/bhyve/config.h
+++ b/usr.sbin/bhyve/config.h
@@ -2,6 +2,7 @@
  * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2021 John H. Baldwin <jhb@FreeBSD.org>
+ * Copyright 2026 Hans Rosenfeld
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -45,6 +46,14 @@
  * OIDs.
  */
 
+/*
+ * Walk the nodes under a parent nvlist. For each node found, call the given
+ * callback function passing the current prefix, nvlist, node name and type,
+ * and the given argument.
+ */
+int walk_config_nodes(const char *, const nvlist_t *, void *,
+    int (*cb)(const char *, const nvlist_t *, const char *, int, void *));
+
 /*
  * Fetches the value of a configuration variable.  If the "raw" value
  * contains references to other configuration variables, this function