[libvirt] [PATCH 1/1] bhyve: Make LPC slot number configurable

Ivan Mishonov ivan at conquex.com
Fri Aug 10 11:22:33 UTC 2018


Signed-off-by: Ivan Mishonov <ivan at 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




More information about the libvir-list mailing list