From 0c8df11071cc91e1b34d15ad62fe8c3fab10191c Mon Sep 17 00:00:00 2001 From: Roman Bogorodskiy Date: Thu, 17 Jan 2019 19:07:20 +0400 Subject: [PATCH] bhyve: implement support for commandline args Implement support for passing custom command line arguments to bhyve using the 'bhyve:commandline' element: * Define virDomainXMLNamespace for the bhyve driver, which at this point supports only the 'commandline' element described above, * Update command generation code to inject these command line arguments between driver-generated arguments and the vmname positional argument. Signed-off-by: Roman Bogorodskiy Reviewed-by: John Ferlan --- docs/schemas/domaincommon.rng | 17 +++ src/bhyve/bhyve_command.c | 9 ++ src/bhyve/bhyve_conf.c | 16 +++ src/bhyve/bhyve_conf.h | 9 ++ src/bhyve/bhyve_domain.c | 103 +++++++++++++++++- src/bhyve/bhyve_domain.h | 1 + .../bhyvexml2argv-commandline.args | 9 ++ .../bhyvexml2argv-commandline.ldargs | 3 + .../bhyvexml2argv-commandline.xml | 27 +++++ tests/bhyvexml2argvtest.c | 1 + .../bhyvexml2xmlout-commandline.xml | 37 +++++++ tests/bhyvexml2xmltest.c | 1 + 12 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-commandline.args create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-commandline.ldargs create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-commandline.xml create mode 100644 tests/bhyvexml2xmloutdata/bhyvexml2xmlout-commandline.xml diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index aa50eac424..7672639cb6 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -81,6 +81,9 @@ + + + @@ -6127,6 +6130,20 @@ + + + + + + + + + + + diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c index 84fda08943..a1ae2026a0 100644 --- a/src/bhyve/bhyve_command.c +++ b/src/bhyve/bhyve_command.c @@ -28,6 +28,7 @@ #include "bhyve_capabilities.h" #include "bhyve_command.h" #include "bhyve_domain.h" +#include "bhyve_conf.h" #include "bhyve_driver.h" #include "datatypes.h" #include "viralloc.h" @@ -626,6 +627,14 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn, if (bhyveBuildConsoleArgStr(def, cmd) < 0) goto error; + if (def->namespaceData) { + bhyveDomainCmdlineDefPtr bhyvecmd; + + bhyvecmd = def->namespaceData; + for (i = 0; i < bhyvecmd->num_args; i++) + virCommandAddArg(cmd, bhyvecmd->args[i]); + } + virCommandAddArg(cmd, def->name); return cmd; diff --git a/src/bhyve/bhyve_conf.c b/src/bhyve/bhyve_conf.c index 60baa2e848..0cdb3b1d72 100644 --- a/src/bhyve/bhyve_conf.c +++ b/src/bhyve/bhyve_conf.c @@ -25,6 +25,7 @@ #include "virlog.h" #include "virstring.h" #include "bhyve_conf.h" +#include "bhyve_domain.h" #include "configmake.h" #define VIR_FROM_THIS VIR_FROM_BHYVE @@ -107,3 +108,18 @@ virBhyveDriverConfigDispose(void *obj) VIR_FREE(cfg->firmwareDir); } + +void +bhyveDomainCmdlineDefFree(bhyveDomainCmdlineDefPtr def) +{ + size_t i; + + if (!def) + return; + + for (i = 0; i < def->num_args; i++) + VIR_FREE(def->args[i]); + + VIR_FREE(def->args); + VIR_FREE(def); +} diff --git a/src/bhyve/bhyve_conf.h b/src/bhyve/bhyve_conf.h index 8da39fde7a..eb4a2e0fb8 100644 --- a/src/bhyve/bhyve_conf.h +++ b/src/bhyve/bhyve_conf.h @@ -29,4 +29,13 @@ virBhyveDriverConfigPtr virBhyveDriverGetConfig(bhyveConnPtr driver); int virBhyveLoadDriverConfig(virBhyveDriverConfigPtr cfg, const char *filename); +typedef struct _bhyveDomainCmdlineDef bhyveDomainCmdlineDef; +typedef bhyveDomainCmdlineDef *bhyveDomainCmdlineDefPtr; +struct _bhyveDomainCmdlineDef { + size_t num_args; + char **args; +}; + +void bhyveDomainCmdlineDefFree(bhyveDomainCmdlineDefPtr def); + #endif /* LIBVIRT_BHYVE_CONF_H */ diff --git a/src/bhyve/bhyve_domain.c b/src/bhyve/bhyve_domain.c index e54af75f4d..e422fffb37 100644 --- a/src/bhyve/bhyve_domain.c +++ b/src/bhyve/bhyve_domain.c @@ -20,16 +20,21 @@ #include +#include "bhyve_conf.h" #include "bhyve_device.h" #include "bhyve_domain.h" #include "bhyve_capabilities.h" #include "viralloc.h" #include "virlog.h" +#include + #define VIR_FROM_THIS VIR_FROM_BHYVE VIR_LOG_INIT("bhyve.bhyve_domain"); +#define BHYVE_NAMESPACE_HREF "http://libvirt.org/schemas/domain/bhyve/1.0" + static void * bhyveDomainObjPrivateAlloc(void *opaque ATTRIBUTE_UNUSED) { @@ -157,7 +162,8 @@ virBhyveDriverCreateXMLConf(bhyveConnPtr driver) virBhyveDriverDomainDefParserConfig.priv = driver; return virDomainXMLOptionNew(&virBhyveDriverDomainDefParserConfig, &virBhyveDriverPrivateDataCallbacks, - NULL, NULL, NULL); + &virBhyveDriverDomainXMLNamespace, + NULL, NULL); } virDomainDefParserConfig virBhyveDriverDomainDefParserConfig = { @@ -165,3 +171,98 @@ virDomainDefParserConfig virBhyveDriverDomainDefParserConfig = { .domainPostParseCallback = bhyveDomainDefPostParse, .assignAddressesCallback = bhyveDomainDefAssignAddresses, }; + +static void +bhyveDomainDefNamespaceFree(void *nsdata) +{ + bhyveDomainCmdlineDefPtr cmd = nsdata; + + bhyveDomainCmdlineDefFree(cmd); +} + +static int +bhyveDomainDefNamespaceParse(xmlDocPtr xml ATTRIBUTE_UNUSED, + xmlNodePtr root ATTRIBUTE_UNUSED, + xmlXPathContextPtr ctxt, + void **data) +{ + bhyveDomainCmdlineDefPtr cmd = NULL; + xmlNodePtr *nodes = NULL; + int n; + size_t i; + int ret = -1; + + if (xmlXPathRegisterNs(ctxt, BAD_CAST "bhyve", BAD_CAST BHYVE_NAMESPACE_HREF) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to register xml namespace '%s'"), + BHYVE_NAMESPACE_HREF); + return -1; + } + + if (VIR_ALLOC(cmd) < 0) + return -1; + + n = virXPathNodeSet("./bhyve:commandline/bhyve:arg", ctxt, &nodes); + if (n == 0) + ret = 0; + if (n <= 0) + goto cleanup; + + if (VIR_ALLOC_N(cmd->args, n) < 0) + goto cleanup; + + for (i = 0; i < n; i++) { + cmd->args[cmd->num_args] = virXMLPropString(nodes[i], "value"); + if (cmd->args[cmd->num_args] == NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("No bhyve command-line argument specified")); + goto cleanup; + } + cmd->num_args++; + } + + VIR_STEAL_PTR(*data, cmd); + ret = 0; + + cleanup: + VIR_FREE(nodes); + bhyveDomainDefNamespaceFree(cmd); + + return ret; +} + +static int +bhyveDomainDefNamespaceFormatXML(virBufferPtr buf ATTRIBUTE_UNUSED, + void *nsdata) +{ + bhyveDomainCmdlineDefPtr cmd = nsdata; + size_t i; + + if (!cmd->num_args) + return 0; + + virBufferAddLit(buf, "\n"); + virBufferAdjustIndent(buf, 2); + + for (i = 0; i < cmd->num_args; i++) + virBufferEscapeString(buf, "\n", + cmd->args[i]); + + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); + + return 0; +} + +static const char * +bhyveDomainDefNamespaceHref(void) +{ + return "xmlns:bhyve='" BHYVE_NAMESPACE_HREF "'"; +} + +virDomainXMLNamespace virBhyveDriverDomainXMLNamespace = { + .parse = bhyveDomainDefNamespaceParse, + .free = bhyveDomainDefNamespaceFree, + .format = bhyveDomainDefNamespaceFormatXML, + .href = bhyveDomainDefNamespaceHref, +}; diff --git a/src/bhyve/bhyve_domain.h b/src/bhyve/bhyve_domain.h index f34e5fe967..5f94038e89 100644 --- a/src/bhyve/bhyve_domain.h +++ b/src/bhyve/bhyve_domain.h @@ -39,5 +39,6 @@ virDomainXMLOptionPtr virBhyveDriverCreateXMLConf(bhyveConnPtr); extern virDomainXMLPrivateDataCallbacks virBhyveDriverPrivateDataCallbacks; extern virDomainDefParserConfig virBhyveDriverDomainDefParserConfig; +extern virDomainXMLNamespace virBhyveDriverDomainXMLNamespace; #endif /* LIBVIRT_BHYVE_DOMAIN_H */ diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-commandline.args b/tests/bhyvexml2argvdata/bhyvexml2argv-commandline.args new file mode 100644 index 0000000000..cb21b99cd6 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-commandline.args @@ -0,0 +1,9 @@ +/usr/sbin/bhyve \ +-c 1 \ +-m 214 \ +-u \ +-H \ +-P \ +-s 0:0,hostbridge \ +-s 2:0,ahci,hd:/tmp/freebsd.img \ +-s 3:0,virtio-net,faketapdev,mac=52:54:00:b9:94:02 ARGUMENT1 ARGUMENT2 bhyve diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-commandline.ldargs b/tests/bhyvexml2argvdata/bhyvexml2argv-commandline.ldargs new file mode 100644 index 0000000000..32538b558e --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-commandline.ldargs @@ -0,0 +1,3 @@ +/usr/sbin/bhyveload \ +-m 214 \ +-d /tmp/freebsd.img bhyve diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-commandline.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-commandline.xml new file mode 100644 index 0000000000..0b222e4f8f --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-commandline.xml @@ -0,0 +1,27 @@ + + bhyve + df3be7e7-a104-11e3-aeb0-50e5492bd3dc + 219136 + 1 + + hvm + + + + + + +
+ + + + + +
+ + + + + + + diff --git a/tests/bhyvexml2argvtest.c b/tests/bhyvexml2argvtest.c index d1b486fa64..4a7f65a8e2 100644 --- a/tests/bhyvexml2argvtest.c +++ b/tests/bhyvexml2argvtest.c @@ -210,6 +210,7 @@ mymain(void) DO_TEST("vnc-autoport"); DO_TEST("cputopology"); DO_TEST_FAILURE("cputopology-nvcpu-mismatch"); + DO_TEST("commandline"); /* Address allocation tests */ DO_TEST("addr-single-sata-disk"); diff --git a/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-commandline.xml b/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-commandline.xml new file mode 100644 index 0000000000..7e6b0e430f --- /dev/null +++ b/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-commandline.xml @@ -0,0 +1,37 @@ + + bhyve + df3be7e7-a104-11e3-aeb0-50e5492bd3dc + 219136 + 219136 + 1 + + hvm + + + + destroy + restart + destroy + + + + + +
+ + + +
+ + + + + +
+ + + + + + + diff --git a/tests/bhyvexml2xmltest.c b/tests/bhyvexml2xmltest.c index 6aaeab741e..ed421b8839 100644 --- a/tests/bhyvexml2xmltest.c +++ b/tests/bhyvexml2xmltest.c @@ -110,6 +110,7 @@ mymain(void) DO_TEST_DIFFERENT("vnc-vgaconf-off"); DO_TEST_DIFFERENT("vnc-vgaconf-io"); DO_TEST_DIFFERENT("vnc-autoport"); + DO_TEST_DIFFERENT("commandline"); /* Address allocation tests */ DO_TEST_DIFFERENT("addr-single-sata-disk");