Signed-off-by: Ivan Mishonov <ivan(a)conquex.com>
---
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