mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-11-07 04:36:52 -10:00
bhyve: add command to list config options
For a software built on top of bhyve(8) and/or managing bhyve(8),
it is very convenient to know what specific features the given binary supports.
Currently, bhyve(8) provides some of this information, and it could be
retrieved by parsing `bhyve -h`, `bhyve -s help`, `bhyve -l help`.
Sometimes it is not enough, for example, the recently added
"oemstrings" feature cannot be fully probed using these commands.
Over time, some workarounds were suggested. Specifically:
- Mapping features to __FreeBSD_version. I see at least two issues with
that:
* __FreeBSD_version does not directly map to bhyve(8) features,
so this is simply not accurate.
* bhyve(8) might be updated separately from the system, which
is not so uncommon, especially for development purposes.
Then such a probing will be inaccurate.
- Manual pages parsing. I see more disadvantages with that:
* Manual pages are meant to be read by a human. Extracting
information from it by a machine is not the most convenient thing.
Especially understanding side notes like: "Note, feature 'foo'
is arm64-only!".
* Manual pages might be inaccurate, they might miss options.
* bhyve(8) could be used in an environment where manual pages
are not installed.
This commit attempts to close this gap by introducing the "bhyve -o
help" command which prints all the supported configuration variables.
In my opinion, it is, in combination with the other commands mentioned
above, sufficient to retrieve most of the capabilities of the given
bhyve(8) binary.
The current implementation defines a simple configuration schema for
common and machdep code and prints out a list of supported configuration
variables for the current architecture.
The next step as I see it would be extending set_config*() functions
to validate the user provided values against the schema, so users get
notified early on incorrect or misspelled configuration variables.
It would also be nice to allow users to only validate their
configuration, think of 'nginx configtest / -t'.
Reviewed by: chuck (previous revision), bnovkov
MFC after: 1 month
MFC to: stable/15
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D58419
This commit is contained in:
1 parent
a03b051f23
commit
e809c7d810
10 files changed
+423
-1
No files matched your search
@@ -25,6 +25,7 @@ SRCS= \
|
||||
block_if.c \
|
||||
bootrom.c \
|
||||
config.c \
|
||||
config_schema.c \
|
||||
console.c \
|
||||
crc16.c \
|
||||
ctl_nvme_all.c \
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "bhyve_machdep.h"
|
||||
#include "bhyverun.h"
|
||||
#include "config.h"
|
||||
#include "config_schema.h"
|
||||
#include "debug.h"
|
||||
#include "fdt.h"
|
||||
#include "mem.h"
|
||||
@@ -55,6 +56,23 @@
|
||||
#include "rtc_pl031.h"
|
||||
#include "uart_emul.h"
|
||||
|
||||
static const struct config_option config_options_machdep[] = {
|
||||
{ "gdb.address", CONFIG_OPTION_STRING },
|
||||
{ "gdb.port", CONFIG_OPTION_INTEGER },
|
||||
{ "gdb.wait", CONFIG_OPTION_BOOL },
|
||||
{ "rtc.use_localtime", CONFIG_OPTION_BOOL },
|
||||
{ "console", CONFIG_OPTION_STRING },
|
||||
{ "fdt.bootargs", CONFIG_OPTION_STRING },
|
||||
};
|
||||
|
||||
void
|
||||
config_schema_merge_options_machdep(struct config_schema *schema)
|
||||
{
|
||||
|
||||
config_schema_merge_options(schema, NULL, config_options_machdep,
|
||||
nitems(config_options_machdep));
|
||||
}
|
||||
|
||||
/* Start of mem + 1M */
|
||||
#define FDT_BASE 0x100000
|
||||
#define FDT_SIZE (64 * 1024)
|
||||
@@ -161,6 +179,10 @@ bhyve_optparse(int argc, char **argv)
|
||||
set_config_bool("monitor.no_reboot", true);
|
||||
break;
|
||||
case 'o':
|
||||
if (strcmp(optarg, "help") == 0) {
|
||||
print_config_options();
|
||||
exit(0);
|
||||
}
|
||||
if (!bhyve_parse_config_option(optarg)) {
|
||||
errx(EX_USAGE,
|
||||
"invalid configuration option '%s'",
|
||||
|
||||
@@ -26,10 +26,13 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
|
||||
#include <vmmapi.h>
|
||||
@@ -42,6 +45,7 @@
|
||||
#endif
|
||||
#include "bootrom.h"
|
||||
#include "config.h"
|
||||
#include "config_schema.h"
|
||||
#include "debug.h"
|
||||
#include "e820.h"
|
||||
#include "fwctl.h"
|
||||
@@ -57,6 +61,93 @@
|
||||
#include "smbiostbl.h"
|
||||
#include "xmsr.h"
|
||||
|
||||
static const struct config_option config_options_machdep[] = {
|
||||
{ "bootvars", CONFIG_OPTION_STRING },
|
||||
{ "acpi_tables", CONFIG_OPTION_BOOL },
|
||||
{ "acpi_tables_in_memory", CONFIG_OPTION_BOOL },
|
||||
|
||||
{ "gdb.address", CONFIG_OPTION_STRING },
|
||||
{ "gdb.port", CONFIG_OPTION_INTEGER },
|
||||
{ "gdb.wait", CONFIG_OPTION_BOOL },
|
||||
{ "keyboard.layout", CONFIG_OPTION_STRING },
|
||||
{ "rtc.use_localtime", CONFIG_OPTION_BOOL },
|
||||
|
||||
{ "bios.vendor", CONFIG_OPTION_STRING },
|
||||
{ "bios.version", CONFIG_OPTION_STRING },
|
||||
{ "bios.release_date", CONFIG_OPTION_STRING },
|
||||
{ "system.family_name", CONFIG_OPTION_STRING },
|
||||
{ "system.manufacturer", CONFIG_OPTION_STRING },
|
||||
{ "system.product_name", CONFIG_OPTION_STRING },
|
||||
{ "system.serial_number", CONFIG_OPTION_STRING },
|
||||
{ "system.sku", CONFIG_OPTION_STRING },
|
||||
{ "system.version", CONFIG_OPTION_STRING },
|
||||
{ "board.manufacturer", CONFIG_OPTION_STRING },
|
||||
{ "board.product_name", CONFIG_OPTION_STRING },
|
||||
{ "board.version", CONFIG_OPTION_STRING },
|
||||
{ "board.serial_number", CONFIG_OPTION_STRING },
|
||||
{ "board.asset_tag", CONFIG_OPTION_STRING },
|
||||
{ "board.location", CONFIG_OPTION_STRING },
|
||||
{ "chassis.manufacturer", CONFIG_OPTION_STRING },
|
||||
{ "chassis.version", CONFIG_OPTION_STRING },
|
||||
{ "chassis.serial_number", CONFIG_OPTION_STRING },
|
||||
{ "chassis.asset_tag", CONFIG_OPTION_STRING },
|
||||
{ "chassis.sku", CONFIG_OPTION_STRING },
|
||||
{ "oemstring.N", CONFIG_OPTION_STRING },
|
||||
|
||||
{ "x86.mptable", CONFIG_OPTION_BOOL },
|
||||
{ "x86.x2apic", CONFIG_OPTION_BOOL },
|
||||
{ "x86.strictio", CONFIG_OPTION_BOOL },
|
||||
{ "x86.strictmsr", CONFIG_OPTION_BOOL },
|
||||
{ "x86.verbosemsr", CONFIG_OPTION_BOOL },
|
||||
{ "x86.vmexit_on_hlt", CONFIG_OPTION_BOOL },
|
||||
{ "x86.vmexit_on_pause", CONFIG_OPTION_BOOL },
|
||||
|
||||
{ "pci.B.S.F.wait", CONFIG_OPTION_BOOL },
|
||||
{ "pci.B.S.F.rfb", CONFIG_OPTION_STRING },
|
||||
{ "pci.B.S.F.vga", CONFIG_OPTION_STRING },
|
||||
{ "pci.B.S.F.w", CONFIG_OPTION_INTEGER },
|
||||
{ "pci.B.S.F.h", CONFIG_OPTION_INTEGER },
|
||||
{ "pci.B.S.F.password", CONFIG_OPTION_STRING },
|
||||
{ "pci.B.S.F.tcp", CONFIG_OPTION_STRING },
|
||||
|
||||
{ "lpc.com1.path", CONFIG_OPTION_STRING },
|
||||
{ "lpc.com1.tcp", CONFIG_OPTION_STRING },
|
||||
{ "lpc.com2.path", CONFIG_OPTION_STRING },
|
||||
{ "lpc.com2.tcp", CONFIG_OPTION_STRING },
|
||||
{ "lpc.com3.path", CONFIG_OPTION_STRING },
|
||||
{ "lpc.com3.tcp", CONFIG_OPTION_STRING },
|
||||
{ "lpc.com4.path", CONFIG_OPTION_STRING },
|
||||
{ "lpc.com4.tcp", CONFIG_OPTION_STRING },
|
||||
{ "lpc.fwcfg", CONFIG_OPTION_STRING },
|
||||
{ "lpc.pc-testdev", CONFIG_OPTION_BOOL },
|
||||
{ "lpc.pcireg.*", CONFIG_OPTION_INTEGER },
|
||||
{ "lpc.pcireg.vendor", CONFIG_OPTION_INTEGER },
|
||||
{ "lpc.pcireg.device", CONFIG_OPTION_INTEGER },
|
||||
{ "lpc.pcireg.revid", CONFIG_OPTION_INTEGER },
|
||||
{ "lpc.pcireg.subvendor", CONFIG_OPTION_INTEGER },
|
||||
{ "lpc.pcireg.subdevice", CONFIG_OPTION_INTEGER },
|
||||
|
||||
{ "tpm.path", CONFIG_OPTION_STRING },
|
||||
{ "tpm.type", CONFIG_OPTION_STRING },
|
||||
{ "tpm.version", CONFIG_OPTION_STRING },
|
||||
{ "tpm.intf", CONFIG_OPTION_STRING },
|
||||
{ "tpm.ppi", CONFIG_OPTION_STRING },
|
||||
|
||||
{ "pci.B.S.F.bus", CONFIG_OPTION_INTEGER },
|
||||
{ "pci.B.S.F.slot", CONFIG_OPTION_INTEGER },
|
||||
{ "pci.B.S.F.func", CONFIG_OPTION_INTEGER },
|
||||
{ "pci.B.S.F.pptdev", CONFIG_OPTION_STRING },
|
||||
{ "pci.B.S.F.rom", CONFIG_OPTION_STRING },
|
||||
};
|
||||
|
||||
void
|
||||
config_schema_merge_options_machdep(struct config_schema *schema)
|
||||
{
|
||||
|
||||
config_schema_merge_options(schema, NULL, config_options_machdep,
|
||||
nitems(config_options_machdep));
|
||||
}
|
||||
|
||||
void
|
||||
bhyve_init_config(void)
|
||||
{
|
||||
@@ -219,6 +310,10 @@ bhyve_optparse(int argc, char **argv)
|
||||
set_config_bool("monitor.no_reboot", true);
|
||||
break;
|
||||
case 'o':
|
||||
if (strcmp(optarg, "help") == 0) {
|
||||
print_config_options();
|
||||
exit(0);
|
||||
}
|
||||
if (!bhyve_parse_config_option(optarg)) {
|
||||
errx(EX_USAGE,
|
||||
"invalid configuration option '%s'",
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd October 3, 2026
|
||||
.Dd October 24, 2026
|
||||
.Dt BHYVE 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -92,6 +92,8 @@
|
||||
.Nm
|
||||
.Fl l Cm help
|
||||
.Nm
|
||||
.Fl o Cm help
|
||||
.Nm
|
||||
.Fl s Cm help
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
@@ -352,6 +354,8 @@ This option has no effect unless the
|
||||
configuration option is enabled or
|
||||
.Fl M
|
||||
was specified.
|
||||
.It Fl o Cm help
|
||||
Print a list of supported configuration variables.
|
||||
.It Fl o Ar var Ns Cm = Ns Ar value
|
||||
Set the configuration variable
|
||||
.Ar var
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
|
||||
#include "bhyverun.h"
|
||||
#include "config.h"
|
||||
#include "config_schema.h"
|
||||
#include "debug.h"
|
||||
#include "mevent.h"
|
||||
#include "pci_emul.h"
|
||||
@@ -67,6 +68,22 @@
|
||||
#define BLOCKIF_NUMTHR 8
|
||||
#define BLOCKIF_MAXREQ (BLOCKIF_RING_MAX + BLOCKIF_NUMTHR)
|
||||
|
||||
static const struct config_option blockif_config_options[] = {
|
||||
{ "path", CONFIG_OPTION_STRING },
|
||||
{ "nocache", CONFIG_OPTION_BOOL },
|
||||
{ "nodelete", CONFIG_OPTION_BOOL },
|
||||
{ "sync", CONFIG_OPTION_BOOL },
|
||||
{ "direct", CONFIG_OPTION_BOOL },
|
||||
{ "ro", CONFIG_OPTION_BOOL },
|
||||
{ "sectorsize", CONFIG_OPTION_STRING },
|
||||
{ "bootindex", CONFIG_OPTION_INTEGER },
|
||||
};
|
||||
|
||||
const struct config_option_set blockif_config_option_set = {
|
||||
.options = blockif_config_options,
|
||||
.count = nitems(blockif_config_options),
|
||||
};
|
||||
|
||||
enum blockop {
|
||||
BOP_READ,
|
||||
BOP_WRITE,
|
||||
|
||||
@@ -40,8 +40,11 @@
|
||||
#include <sys/uio.h>
|
||||
#include <sys/unistd.h>
|
||||
|
||||
struct config_option_set;
|
||||
struct vm_snapshot_meta;
|
||||
|
||||
extern const struct config_option_set blockif_config_option_set;
|
||||
|
||||
|
||||
/*
|
||||
* BLOCKIF_IOV_MAX is the maximum number of scatter/gather entries in
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright (c) 2026 The FreeBSD Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/tree.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
|
||||
#include "config_schema.h"
|
||||
|
||||
SET_DECLARE(config_option_set, struct config_option_set);
|
||||
|
||||
struct config_schema_option {
|
||||
RB_ENTRY(config_schema_option) entry;
|
||||
char *name;
|
||||
enum config_option_type type;
|
||||
};
|
||||
|
||||
RB_HEAD(config_schema, config_schema_option);
|
||||
|
||||
static int
|
||||
config_schema_option_compare(struct config_schema_option *a,
|
||||
struct config_schema_option *b)
|
||||
{
|
||||
|
||||
return (strcmp(a->name, b->name));
|
||||
}
|
||||
|
||||
RB_GENERATE_STATIC(config_schema, config_schema_option, entry,
|
||||
config_schema_option_compare);
|
||||
|
||||
static const struct config_option config_options[] = {
|
||||
{ "name", CONFIG_OPTION_STRING },
|
||||
{ "cpus", CONFIG_OPTION_INTEGER },
|
||||
{ "cores", CONFIG_OPTION_INTEGER },
|
||||
{ "threads", CONFIG_OPTION_INTEGER },
|
||||
{ "sockets", CONFIG_OPTION_INTEGER },
|
||||
{ "memory.guest_in_core", CONFIG_OPTION_BOOL },
|
||||
{ "memory.size", CONFIG_OPTION_STRING },
|
||||
{ "memory.wired", CONFIG_OPTION_BOOL },
|
||||
{ "bootrom", CONFIG_OPTION_STRING },
|
||||
{ "destroy_on_poweroff", CONFIG_OPTION_BOOL },
|
||||
{ "pci.enable_bars", CONFIG_OPTION_BOOL },
|
||||
{ "uuid", CONFIG_OPTION_STRING },
|
||||
{ "virtio.msix", CONFIG_OPTION_BOOL },
|
||||
{ "config.dump", CONFIG_OPTION_BOOL },
|
||||
{ "rundir", CONFIG_OPTION_STRING },
|
||||
{ "monitor.enabled", CONFIG_OPTION_BOOL },
|
||||
{ "monitor.no_reboot", CONFIG_OPTION_BOOL },
|
||||
|
||||
{ "vcpu.N.cpuset", CONFIG_OPTION_STRING },
|
||||
{ "domains.N.size", CONFIG_OPTION_STRING },
|
||||
{ "domains.N.domain_policy", CONFIG_OPTION_STRING },
|
||||
{ "domains.N.cpus", CONFIG_OPTION_STRING },
|
||||
|
||||
{ "pci.B.S.F.device", CONFIG_OPTION_STRING },
|
||||
{ "pci.B.S.F.vendor", CONFIG_OPTION_INTEGER },
|
||||
{ "pci.B.S.F.devid", CONFIG_OPTION_INTEGER },
|
||||
{ "pci.B.S.F.pcireg.*", CONFIG_OPTION_INTEGER },
|
||||
{ "pci.B.S.F.pcireg.vendor", CONFIG_OPTION_INTEGER },
|
||||
{ "pci.B.S.F.pcireg.device", CONFIG_OPTION_INTEGER },
|
||||
{ "pci.B.S.F.port.N.type", CONFIG_OPTION_STRING },
|
||||
{ "pci.B.S.F.port.N.path", CONFIG_OPTION_STRING },
|
||||
{ "pci.B.S.F.port.N.nocache", CONFIG_OPTION_BOOL },
|
||||
{ "pci.B.S.F.port.N.nodelete", CONFIG_OPTION_BOOL },
|
||||
{ "pci.B.S.F.port.N.sync", CONFIG_OPTION_BOOL },
|
||||
{ "pci.B.S.F.port.N.direct", CONFIG_OPTION_BOOL },
|
||||
{ "pci.B.S.F.port.N.ro", CONFIG_OPTION_BOOL },
|
||||
{ "pci.B.S.F.port.N.sectorsize", CONFIG_OPTION_STRING },
|
||||
{ "pci.B.S.F.port.N.nmrr", CONFIG_OPTION_INTEGER },
|
||||
{ "pci.B.S.F.port.N.ser", CONFIG_OPTION_STRING },
|
||||
{ "pci.B.S.F.port.N.rev", CONFIG_OPTION_STRING },
|
||||
{ "pci.B.S.F.port.N.model", CONFIG_OPTION_STRING },
|
||||
{ "pci.B.S.F.port.N.bootindex", CONFIG_OPTION_INTEGER },
|
||||
|
||||
{ "pci.B.S.F.backend", CONFIG_OPTION_STRING },
|
||||
{ "pci.B.S.F.type", CONFIG_OPTION_STRING },
|
||||
{ "pci.B.S.F.peerhook", CONFIG_OPTION_STRING },
|
||||
{ "pci.B.S.F.socket", CONFIG_OPTION_STRING },
|
||||
{ "pci.B.S.F.hook", CONFIG_OPTION_STRING },
|
||||
{ "pci.B.S.F.hostfwd", CONFIG_OPTION_STRING },
|
||||
{ "pci.B.S.F.mac", CONFIG_OPTION_STRING },
|
||||
{ "pci.B.S.F.mtu", CONFIG_OPTION_INTEGER },
|
||||
{ "pci.B.S.F.play", CONFIG_OPTION_STRING },
|
||||
{ "pci.B.S.F.rec", CONFIG_OPTION_STRING },
|
||||
|
||||
{ "pci.B.S.F.serial", CONFIG_OPTION_STRING },
|
||||
{ "pci.B.S.F.sharename", CONFIG_OPTION_STRING },
|
||||
{ "pci.B.S.F.port.N.name", CONFIG_OPTION_STRING },
|
||||
|
||||
{ "pci.B.S.F.ctl_ringsz", CONFIG_OPTION_INTEGER },
|
||||
{ "pci.B.S.F.evt_ringsz", CONFIG_OPTION_INTEGER },
|
||||
{ "pci.B.S.F.req_ringsz", CONFIG_OPTION_INTEGER },
|
||||
{ "pci.B.S.F.num_queues", CONFIG_OPTION_INTEGER },
|
||||
{ "pci.B.S.F.seg_max", CONFIG_OPTION_INTEGER },
|
||||
{ "pci.B.S.F.thr_per_q", CONFIG_OPTION_INTEGER },
|
||||
{ "pci.B.S.F.target.N", CONFIG_OPTION_STRING },
|
||||
{ "pci.B.S.F.iid", CONFIG_OPTION_INTEGER },
|
||||
{ "pci.B.S.F.slot.N.device", CONFIG_OPTION_STRING },
|
||||
};
|
||||
|
||||
static const char *
|
||||
config_option_type_name(enum config_option_type type)
|
||||
{
|
||||
|
||||
switch (type) {
|
||||
case CONFIG_OPTION_BOOL:
|
||||
return ("bool");
|
||||
case CONFIG_OPTION_INTEGER:
|
||||
return ("integer");
|
||||
case CONFIG_OPTION_STRING:
|
||||
return ("string");
|
||||
}
|
||||
errx(EX_SOFTWARE, "invalid configuration option type");
|
||||
}
|
||||
|
||||
void
|
||||
config_schema_merge_options(struct config_schema *schema, const char *prefix,
|
||||
const struct config_option *options, size_t count)
|
||||
{
|
||||
struct config_schema_option *existing, *option;
|
||||
char *name;
|
||||
size_t i;
|
||||
|
||||
if (prefix == NULL)
|
||||
prefix = "";
|
||||
for (i = 0; i < count; i++) {
|
||||
if (asprintf(&name, "%s%s", prefix, options[i].name) == -1)
|
||||
err(EX_OSERR, "asprintf");
|
||||
option = malloc(sizeof(*option));
|
||||
if (option == NULL)
|
||||
err(EX_OSERR, "malloc");
|
||||
option->name = name;
|
||||
option->type = options[i].type;
|
||||
|
||||
existing = RB_INSERT(config_schema, schema, option);
|
||||
if (existing == NULL)
|
||||
continue;
|
||||
if (existing->type != option->type) {
|
||||
errx(EX_SOFTWARE,
|
||||
"conflicting types for configuration option "
|
||||
"'%s': %s and %s", option->name,
|
||||
config_option_type_name(existing->type),
|
||||
config_option_type_name(option->type));
|
||||
}
|
||||
free(option->name);
|
||||
free(option);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
config_schema_merge_option_set(struct config_schema *schema,
|
||||
const struct config_option_set *set, const char *inherited_prefix)
|
||||
{
|
||||
const char *prefix;
|
||||
|
||||
prefix = set->prefix != NULL ? set->prefix : inherited_prefix;
|
||||
if (set->base != NULL)
|
||||
config_schema_merge_option_set(schema, set->base, prefix);
|
||||
config_schema_merge_options(schema, prefix, set->options, set->count);
|
||||
}
|
||||
|
||||
static void
|
||||
config_schema_destroy(struct config_schema *schema)
|
||||
{
|
||||
struct config_schema_option *option, *tmp;
|
||||
|
||||
RB_FOREACH_SAFE(option, config_schema, schema, tmp) {
|
||||
RB_REMOVE(config_schema, schema, option);
|
||||
free(option->name);
|
||||
free(option);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
print_config_options(void)
|
||||
{
|
||||
struct config_schema_option *option;
|
||||
struct config_option_set **setp;
|
||||
struct config_schema schema;
|
||||
|
||||
RB_INIT(&schema);
|
||||
config_schema_merge_options(&schema, NULL, config_options,
|
||||
nitems(config_options));
|
||||
SET_FOREACH(setp, config_option_set) {
|
||||
config_schema_merge_option_set(&schema, *setp, NULL);
|
||||
}
|
||||
config_schema_merge_options_machdep(&schema);
|
||||
|
||||
RB_FOREACH(option, config_schema, &schema) {
|
||||
printf("%s\n", option->name);
|
||||
}
|
||||
config_schema_destroy(&schema);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2026 The FreeBSD Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_SCHEMA_H__
|
||||
#define __CONFIG_SCHEMA_H__
|
||||
|
||||
#include <sys/linker_set.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
enum config_option_type {
|
||||
CONFIG_OPTION_BOOL,
|
||||
CONFIG_OPTION_INTEGER,
|
||||
CONFIG_OPTION_STRING,
|
||||
};
|
||||
|
||||
struct config_option {
|
||||
const char *name;
|
||||
enum config_option_type type;
|
||||
};
|
||||
|
||||
struct config_option_set {
|
||||
const char *prefix;
|
||||
const struct config_option_set *base;
|
||||
const struct config_option *options;
|
||||
size_t count;
|
||||
};
|
||||
|
||||
struct config_schema;
|
||||
|
||||
#define CONFIG_OPTION_SET(x) DATA_SET(config_option_set, x)
|
||||
|
||||
void config_schema_merge_options(struct config_schema *, const char *,
|
||||
const struct config_option *, size_t);
|
||||
void config_schema_merge_options_machdep(struct config_schema *);
|
||||
void print_config_options(void);
|
||||
|
||||
#endif /* !__CONFIG_SCHEMA_H__ */
|
||||
@@ -55,6 +55,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/crc16.h>
|
||||
#include <net/ieee_oui.h>
|
||||
@@ -79,9 +80,28 @@
|
||||
#include "bhyverun.h"
|
||||
#include "block_if.h"
|
||||
#include "config.h"
|
||||
#include "config_schema.h"
|
||||
#include "debug.h"
|
||||
#include "pci_emul.h"
|
||||
|
||||
static const struct config_option pci_nvme_config_options[] = {
|
||||
{ "maxq", CONFIG_OPTION_INTEGER },
|
||||
{ "qsz", CONFIG_OPTION_INTEGER },
|
||||
{ "ioslots", CONFIG_OPTION_INTEGER },
|
||||
{ "sectsz", CONFIG_OPTION_INTEGER },
|
||||
{ "ser", CONFIG_OPTION_STRING },
|
||||
{ "eui64", CONFIG_OPTION_INTEGER },
|
||||
{ "dsm", CONFIG_OPTION_STRING },
|
||||
{ "ram", CONFIG_OPTION_INTEGER },
|
||||
};
|
||||
|
||||
static const struct config_option_set pci_nvme_config_option_set = {
|
||||
.prefix = "pci.B.S.F.",
|
||||
.base = &blockif_config_option_set,
|
||||
.options = pci_nvme_config_options,
|
||||
.count = nitems(pci_nvme_config_options),
|
||||
};
|
||||
CONFIG_OPTION_SET(pci_nvme_config_option_set);
|
||||
|
||||
static int nvme_debug = 0;
|
||||
#define DPRINTF(fmt, args...) if (nvme_debug) PRINTLN(fmt, ##args)
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
|
||||
#include "bhyverun.h"
|
||||
#include "config.h"
|
||||
#include "config_schema.h"
|
||||
#include "debug.h"
|
||||
#include "fdt.h"
|
||||
#include "ipc.h"
|
||||
@@ -58,6 +59,19 @@
|
||||
#include "uart_emul.h"
|
||||
#include "riscv.h"
|
||||
|
||||
static const struct config_option config_options_machdep[] = {
|
||||
{ "console", CONFIG_OPTION_STRING },
|
||||
{ "fdt.bootargs", CONFIG_OPTION_STRING },
|
||||
};
|
||||
|
||||
void
|
||||
config_schema_merge_options_machdep(struct config_schema *schema)
|
||||
{
|
||||
|
||||
config_schema_merge_options(schema, NULL, config_options_machdep,
|
||||
nitems(config_options_machdep));
|
||||
}
|
||||
|
||||
#define FDT_SIZE (64 * 1024)
|
||||
#define FDT_DTB_ALIGN 8
|
||||
|
||||
@@ -152,6 +166,10 @@ bhyve_optparse(int argc, char **argv)
|
||||
set_config_bool("monitor.no_reboot", true);
|
||||
break;
|
||||
case 'o':
|
||||
if (strcmp(optarg, "help") == 0) {
|
||||
print_config_options();
|
||||
exit(0);
|
||||
}
|
||||
if (!bhyve_parse_config_option(optarg)) {
|
||||
errx(EX_USAGE,
|
||||
"invalid configuration option '%s'",
|
||||
|
||||
Reference in new issue
Block a user