Signed-off-by: Ivan Mishonov <ivan@xxxxxxxxxxx> --- docs/schemas/domaincommon.rng | 15 ++++++ src/bhyve/bhyve_command.c | 7 ++- src/bhyve/bhyve_conf.c | 12 +++++ src/bhyve/bhyve_conf.h | 9 ++++ src/bhyve/bhyve_device.c | 16 ++++--- src/bhyve/bhyve_domain.c | 86 ++++++++++++++++++++++++++++++++++- src/bhyve/bhyve_domain.h | 1 + 7 files changed, 138 insertions(+), 8 deletions(-) diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 1a786968cc..102bfbda87 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -75,6 +75,9 @@ <optional> <ref name='lxcsharens'/> </optional> + <optional> + <ref name='bhyveopt'/> + </optional> <optional> <ref name='keywrap'/> </optional> @@ -6015,6 +6018,18 @@ </element> </define> + <!-- + Optional hypervisor extensions in their own namespace: + BHYVE + --> + <define name="bhyveopt"> + <zeroOrMore> + <element name="lpcslotnumber" ns="http://libvirt.org/schemas/domain/bhyve/1.0"> + <attribute name='value'/> + </element> + </zeroOrMore> + </define> + <!-- Type library --> diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c index 802997bd2d..14e5635011 100644 --- a/src/bhyve/bhyve_command.c +++ b/src/bhyve/bhyve_command.c @@ -27,6 +27,7 @@ #include "bhyve_capabilities.h" #include "bhyve_command.h" +#include "bhyve_conf.h" #include "bhyve_domain.h" #include "bhyve_driver.h" #include "datatypes.h" @@ -329,7 +330,11 @@ static int bhyveBuildLPCArgStr(const virDomainDef *def ATTRIBUTE_UNUSED, virCommandPtr cmd) { - virCommandAddArgList(cmd, "-s", "1,lpc", NULL); + unsigned int lpcslotnumber = virBhyveGetLPCSlotNumber(def); + + virCommandAddArg(cmd, "-s"); + virCommandAddArgFormat(cmd, "%d,lpc", lpcslotnumber); + return 0; } diff --git a/src/bhyve/bhyve_conf.c b/src/bhyve/bhyve_conf.c index 153de7b391..ce234e4546 100644 --- a/src/bhyve/bhyve_conf.c +++ b/src/bhyve/bhyve_conf.c @@ -44,6 +44,18 @@ static int virBhyveConfigOnceInit(void) VIR_ONCE_GLOBAL_INIT(virBhyveConfig) +void bhyveDomainDefFree(bhyveDomainDefPtr def) +{ + VIR_FREE(def); +} + +int virBhyveGetLPCSlotNumber(const virDomainDef *def) { + bhyveDomainDefPtr bhyveopts; + + bhyveopts = def->namespaceData; + return bhyveopts ? bhyveopts->lpc_slot_number : 1; +} + virBhyveDriverConfigPtr virBhyveDriverConfigNew(void) { diff --git a/src/bhyve/bhyve_conf.h b/src/bhyve/bhyve_conf.h index 3f105ace1c..441b7ef2b9 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 _bhyveDomainDef bhyveDomainDef; +typedef bhyveDomainDef *bhyveDomainDefPtr; +struct _bhyveDomainDef { + unsigned int lpc_slot_number; +}; + +void bhyveDomainDefFree(bhyveDomainDefPtr def); +int virBhyveGetLPCSlotNumber(const virDomainDef *def); + #endif /* BHYVE_CONF_H */ diff --git a/src/bhyve/bhyve_device.c b/src/bhyve/bhyve_device.c index 03aa6c93bd..651b8f02f1 100644 --- a/src/bhyve/bhyve_device.c +++ b/src/bhyve/bhyve_device.c @@ -22,6 +22,7 @@ #include <config.h> +#include "bhyve_conf.h" #include "bhyve_device.h" #include "domain_addr.h" #include "viralloc.h" @@ -44,14 +45,16 @@ bhyveCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED, virDomainPCIAddressSetPtr addrs = opaque; virPCIDeviceAddressPtr addr = &info->addr.pci; + unsigned int lpcslotnumber = virBhyveGetLPCSlotNumber(def); if (addr->domain == 0 && addr->bus == 0) { if (addr->slot == 0) { return 0; - } else if (addr->slot == 1) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("PCI bus 0 slot 1 is reserved for the implicit " - "LPC PCI-ISA bridge")); + } else if (addr->slot == lpcslotnumber) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("PCI bus 0 slot %d is reserved for the implicit " + "LPC PCI-ISA bridge"), + lpcslotnumber); return -1; } } @@ -95,9 +98,10 @@ bhyveAssignDevicePCISlots(virDomainDefPtr def, size_t i; virPCIDeviceAddress lpc_addr; - /* explicitly reserve slot 1 for LPC-ISA bridge */ + /* explicitly reserve slot for LPC-ISA bridge */ + unsigned int lpcslotnumber = virBhyveGetLPCSlotNumber(def); memset(&lpc_addr, 0, sizeof(lpc_addr)); - lpc_addr.slot = 0x1; + lpc_addr.slot = lpcslotnumber; if (virDomainPCIAddressReserveAddr(addrs, &lpc_addr, VIR_PCI_CONNECT_TYPE_PCI_DEVICE, 0) < 0) { diff --git a/src/bhyve/bhyve_domain.c b/src/bhyve/bhyve_domain.c index 3c23441969..09715f3dd5 100644 --- a/src/bhyve/bhyve_domain.c +++ b/src/bhyve/bhyve_domain.c @@ -20,18 +20,23 @@ * Author: Roman Bogorodskiy */ +#include <libxml/xpathInternals.h> #include <config.h> +#include "bhyve_conf.h" #include "bhyve_device.h" #include "bhyve_domain.h" #include "bhyve_capabilities.h" #include "viralloc.h" #include "virlog.h" +#include "virstring.h" #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) { @@ -58,6 +63,84 @@ virDomainXMLPrivateDataCallbacks virBhyveDriverPrivateDataCallbacks = { .free = bhyveDomainObjPrivateFree, }; +static void +bhyveDomainDefNamespaceFree(void *nsdata) +{ + bhyveDomainDefPtr def = nsdata; + + bhyveDomainDefFree(def); +} + +static int +bhyveDomainDefNamespaceParse(xmlDocPtr xml ATTRIBUTE_UNUSED, + xmlNodePtr root ATTRIBUTE_UNUSED, + xmlXPathContextPtr ctxt, + void **data) +{ + bhyveDomainDefPtr domainDef = NULL; + char *lpcslotnumberstring = NULL; + + 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; + } + + xmlNodePtr lpcnode = virXPathNode("./bhyve:lpcslotnumber", ctxt); + if (lpcnode == NULL) + return 0; + + if (VIR_ALLOC(domainDef) < 0) + return -1; + + lpcslotnumberstring = virXMLPropString(lpcnode, "value"); + if (lpcslotnumberstring == NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("Bhyve lpcslotnumber value property not found")); + goto error; + } else if (virStrToLong_ui(lpcslotnumberstring, NULL, 10, &domainDef->lpc_slot_number) != 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s got %s", _("Bhyve lpcslotnumber value property must be integer"), lpcslotnumberstring); + VIR_FREE(lpcslotnumberstring); + goto error; + } + VIR_FREE(lpcslotnumberstring); + + *data = domainDef; + return 0; + error: + bhyveDomainDefFree(domainDef); + return -1; +} + +static int +bhyveDomainDefNamespaceFormatXML(virBufferPtr buf, + void *nsdata) +{ + bhyveDomainDefPtr domainDef = nsdata; + + if (domainDef) { + virBufferAsprintf(buf, "<bhyve:lpcslotnumber value='%d'/>\n", + domainDef->lpc_slot_number); + } + + return 0; +} + +static const char * +bhyveDomainDefNamespaceHref(void) +{ + return "xmlns:bhyve='" BHYVE_NAMESPACE_HREF "'"; +} + +virDomainXMLNamespace virBhyveDriverDomainXMLNamespace = { + .parse = bhyveDomainDefNamespaceParse, + .free = bhyveDomainDefNamespaceFree, + .format = bhyveDomainDefNamespaceFormatXML, + .href = bhyveDomainDefNamespaceHref, +}; + static int bhyveDomainDefPostParse(virDomainDefPtr def, virCapsPtr caps ATTRIBUTE_UNUSED, @@ -159,7 +242,8 @@ virBhyveDriverCreateXMLConf(bhyveConnPtr driver) virBhyveDriverDomainDefParserConfig.priv = driver; return virDomainXMLOptionNew(&virBhyveDriverDomainDefParserConfig, &virBhyveDriverPrivateDataCallbacks, - NULL, NULL, NULL); + &virBhyveDriverDomainXMLNamespace, + NULL, NULL); } virDomainDefParserConfig virBhyveDriverDomainDefParserConfig = { diff --git a/src/bhyve/bhyve_domain.h b/src/bhyve/bhyve_domain.h index bbc8ecd8cf..ce4b4bf7b8 100644 --- a/src/bhyve/bhyve_domain.h +++ b/src/bhyve/bhyve_domain.h @@ -39,6 +39,7 @@ struct _bhyveDomainObjPrivate { virDomainXMLOptionPtr virBhyveDriverCreateXMLConf(bhyveConnPtr); +extern virDomainXMLNamespace virBhyveDriverDomainXMLNamespace; extern virDomainXMLPrivateDataCallbacks virBhyveDriverPrivateDataCallbacks; extern virDomainDefParserConfig virBhyveDriverDomainDefParserConfig; -- 2.17.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list