[libvirt] [PATCH v4 1/2 RESEND] Add NVRAM device

Li Zhang zhlcindy at gmail.com
Thu Apr 18 05:40:02 UTC 2013


From: Li Zhang <zhlcindy at linux.vnet.ibm.com>

For pSeries guest in QEMU, NVRAM is one kind of spapr-vio device.
Users are allowed to specify spapr-vio devices'address.
But NVRAM is not supported in libvirt. So this patch is to
add NVRAM device to allow users to specify its address.

In QEMU, NVRAM device's address is specified by
 "-global spapr-nvram.reg=xxxxx".

In libvirt, XML file is defined as the following:

  <nvram>
    <address type='spapr-vio' reg='0x3000'/>
  </nvram>

Signed-off-by: Li Zhang <zhlcindy at linux.vnet.ibm.com>
---
 v4 -> v3:
  * Sperate NVRAM definition from qemu command line parser.

 v3 -> v2:
  * Add NVRAM in domaincommon.rng and formatdomain.xml.in suggested by Daniel P.Berrange
  * Add NVRAM test cases suggested by Daniel P.Berrange
  * Remove nvram allocation when it is not specified suggested by Daniel P.Berrange
  * Add several error reports suggested by Daniel P.Berrange

 v2 -> v1:
  * Add NVRAM parameters parsing in qemuParseCommandLine

 docs/formatdomain.html.in     | 35 ++++++++++++++++++++
 docs/schemas/domaincommon.rng | 10 ++++++
 src/conf/domain_conf.c        | 76 +++++++++++++++++++++++++++++++++++++++++++
 src/conf/domain_conf.h        | 10 ++++++
 4 files changed, 131 insertions(+)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index d400e35..f590304 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -4415,6 +4415,41 @@ qemu-kvm -net nic,model=? /dev/null
 
     </dl>
 
+    <h4><a name="elementsNVRAM">NVRAM device</a></h4>
+    <p>
+      One NVRAM device is always added to pSeries guests on PPC64.
+      And on PPC64, NVRAM devices' address type are VIO which
+      allows users to change.<code>nvram</code> element in XML file
+      is provided to specify its address.
+      Currently, libvirt only considers configuration for pSeries guests.
+    </p>
+    <p>
+      Example: usage of NVRAM configuration
+    </p>
+<pre>
+  ...
+  <devices>
+    <nvram>
+      <address type='spapr-vio' reg='0x3000'/>
+    </nvram>
+  </devices>
+  ...
+</pre>
+  <dl>
+    <dt><code>spapr-vio</code></dt>
+    <dd>
+      <p>
+        VIO device address type, this is only for PPC64.
+      </p>
+    </dd>
+    <dt><code>reg</code></dt>
+    <dd>
+      <p>
+        Devices' address
+      </p>
+    </dd>
+  </dl>
+
     <h3><a name="seclabel">Security label</a></h3>
 
     <p>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 2c31f76..2b58d95 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2764,6 +2764,13 @@
       </optional>
     </element>
   </define>
+  <define name="nvram">
+    <element name="nvram">
+      <optional>
+        <ref name="address"/>
+      </optional>
+    </element>
+  </define>
   <define name="memballoon">
     <element name="memballoon">
       <attribute name="model">
@@ -3208,6 +3215,9 @@
         <optional>
           <ref name="memballoon"/>
         </optional>
+        <optional>
+          <ref name="nvram"/>
+        </optional>
       </interleave>
     </element>
   </define>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 36a46da..3a5e59a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -193,6 +193,7 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST,
               "smartcard",
               "chr",
               "memballoon",
+              "nvram",
               "rng")
 
 VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
@@ -1552,6 +1553,16 @@ void virDomainMemballoonDefFree(virDomainMemballoonDefPtr def)
     VIR_FREE(def);
 }
 
+void virDomainNVRAMDefFree(virDomainNVRAMDefPtr def)
+{
+    if (!def)
+        return;
+
+    virDomainDeviceInfoClear(&def->info);
+
+    VIR_FREE(def);
+}
+
 void virDomainWatchdogDefFree(virDomainWatchdogDefPtr def)
 {
     if (!def)
@@ -1718,6 +1729,7 @@ void virDomainDeviceDefFree(virDomainDeviceDefPtr def)
     case VIR_DOMAIN_DEVICE_SMARTCARD:
     case VIR_DOMAIN_DEVICE_CHR:
     case VIR_DOMAIN_DEVICE_MEMBALLOON:
+    case VIR_DOMAIN_DEVICE_NVRAM:
     case VIR_DOMAIN_DEVICE_LAST:
         break;
     }
@@ -1910,6 +1922,7 @@ void virDomainDefFree(virDomainDefPtr def)
     virDomainWatchdogDefFree(def->watchdog);
 
     virDomainMemballoonDefFree(def->memballoon);
+    virDomainNVRAMDefFree(def->nvram);
 
     for (i = 0; i < def->nseclabels; i++)
         virSecurityLabelDefFree(def->seclabels[i]);
@@ -2478,6 +2491,12 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr def,
         if (cb(def, &device, &def->rng->info, opaque) < 0)
             return -1;
     }
+    if (def->nvram) {
+        device.type = VIR_DOMAIN_DEVICE_NVRAM;
+        device.data.nvram = def->nvram;
+        if (cb(def, &device, &def->nvram->info, opaque) < 0)
+            return -1;
+    }
     device.type = VIR_DOMAIN_DEVICE_HUB;
     for (i = 0; i < def->nhubs ; i++) {
         device.data.hub = def->hubs[i];
@@ -2509,6 +2528,7 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr def,
     case VIR_DOMAIN_DEVICE_SMARTCARD:
     case VIR_DOMAIN_DEVICE_CHR:
     case VIR_DOMAIN_DEVICE_MEMBALLOON:
+    case VIR_DOMAIN_DEVICE_NVRAM:
     case VIR_DOMAIN_DEVICE_LAST:
     case VIR_DOMAIN_DEVICE_RNG:
         break;
@@ -7994,6 +8014,23 @@ error:
     goto cleanup;
 }
 
+static virDomainNVRAMDefPtr
+virDomainNVRAMDefParseXML(const xmlNodePtr node,
+                               unsigned int flags)
+{
+   virDomainNVRAMDefPtr def;
+
+    if (VIR_ALLOC(def) < 0) {
+        virReportOOMError();
+        return NULL;
+    }
+
+    if ( virDomainDeviceInfoParseXML(node, NULL, &def->info, flags) < 0 )
+        return NULL;
+
+    return def;
+}
+
 static virSysinfoDefPtr
 virSysinfoParseXML(const xmlNodePtr node,
                   xmlXPathContextPtr ctxt)
@@ -11105,6 +11142,26 @@ virDomainDefParseXML(xmlDocPtr xml,
         VIR_FREE(nodes);
     }
 
+    def->nvram = NULL;
+    if ((n = virXPathNodeSet("./devices/nvram", ctxt, &nodes)) < 0) {
+        goto error;
+    }
+
+    if (n > 1) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("only a single nvram device is supported"));
+        goto error;
+    }
+
+    if (n > 0) {
+        virDomainNVRAMDefPtr nvram =
+            virDomainNVRAMDefParseXML(nodes[0], flags);
+        if (!nvram)
+            goto error;
+        def->nvram = nvram;
+        VIR_FREE(nodes);
+    }
+
     /* analysis of the hub devices */
     if ((n = virXPathNodeSet("./devices/hub", ctxt, &nodes)) < 0) {
         goto error;
@@ -14159,6 +14216,21 @@ virDomainMemballoonDefFormat(virBufferPtr buf,
 }
 
 static int
+virDomainNVRAMDefFormat(virBufferPtr buf,
+                             virDomainNVRAMDefPtr def,
+                             unsigned int flags)
+{
+    virBufferAsprintf(buf, "    <nvram>\n");
+    if (virDomainDeviceInfoIsSet(&def->info, flags))
+        if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
+            return -1;
+
+    virBufferAddLit(buf, "    </nvram>\n");
+
+    return 0;
+}
+
+static int
 virDomainSysinfoDefFormat(virBufferPtr buf,
                           virSysinfoDefPtr def)
 {
@@ -15469,6 +15541,9 @@ virDomainDefFormatInternal(virDomainDefPtr def,
     if (def->rng)
         virDomainRNGDefFormat(buf, def->rng, flags);
 
+    if (def->nvram)
+        virDomainNVRAMDefFormat(buf, def->nvram, flags);
+
     virBufferAddLit(buf, "  </devices>\n");
 
     virBufferAdjustIndent(buf, 2);
@@ -16749,6 +16824,7 @@ virDomainDeviceDefCopy(virDomainDeviceDefPtr src,
     case VIR_DOMAIN_DEVICE_SMARTCARD:
     case VIR_DOMAIN_DEVICE_CHR:
     case VIR_DOMAIN_DEVICE_MEMBALLOON:
+    case VIR_DOMAIN_DEVICE_NVRAM:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Copying definition of '%d' type "
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 3ab0f15..d98bec1 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -109,6 +109,9 @@ typedef virDomainChrDef *virDomainChrDefPtr;
 typedef struct _virDomainMemballoonDef virDomainMemballoonDef;
 typedef virDomainMemballoonDef *virDomainMemballoonDefPtr;
 
+typedef struct _virDomainNVRAMDef virDomainNVRAMDef;
+typedef virDomainNVRAMDef *virDomainNVRAMDefPtr;
+
 typedef struct _virDomainSnapshotObj virDomainSnapshotObj;
 typedef virDomainSnapshotObj *virDomainSnapshotObjPtr;
 
@@ -137,6 +140,7 @@ typedef enum {
     VIR_DOMAIN_DEVICE_SMARTCARD,
     VIR_DOMAIN_DEVICE_CHR,
     VIR_DOMAIN_DEVICE_MEMBALLOON,
+    VIR_DOMAIN_DEVICE_NVRAM,
     VIR_DOMAIN_DEVICE_RNG,
 
     VIR_DOMAIN_DEVICE_LAST
@@ -163,6 +167,7 @@ struct _virDomainDeviceDef {
         virDomainSmartcardDefPtr smartcard;
         virDomainChrDefPtr chr;
         virDomainMemballoonDefPtr memballoon;
+        virDomainNVRAMDefPtr nvram;
         virDomainRNGDefPtr rng;
     } data;
 };
@@ -1442,6 +1447,9 @@ struct _virDomainMemballoonDef {
     virDomainDeviceInfo info;
 };
 
+struct _virDomainNVRAMDef {
+    virDomainDeviceInfo info;
+};
 
 enum virDomainSmbiosMode {
     VIR_DOMAIN_SMBIOS_NONE = 0,
@@ -1883,6 +1891,7 @@ struct _virDomainDef {
     /* Only 1 */
     virDomainWatchdogDefPtr watchdog;
     virDomainMemballoonDefPtr memballoon;
+    virDomainNVRAMDefPtr nvram;
     virCPUDefPtr cpu;
     virSysinfoDefPtr sysinfo;
     virDomainRedirFilterDefPtr redirfilter;
@@ -2041,6 +2050,7 @@ int virDomainChrSourceDefCopy(virDomainChrSourceDefPtr src,
 void virDomainSoundCodecDefFree(virDomainSoundCodecDefPtr def);
 void virDomainSoundDefFree(virDomainSoundDefPtr def);
 void virDomainMemballoonDefFree(virDomainMemballoonDefPtr def);
+void virDomainNVRAMDefFree(virDomainNVRAMDefPtr def);
 void virDomainWatchdogDefFree(virDomainWatchdogDefPtr def);
 void virDomainVideoDefFree(virDomainVideoDefPtr def);
 virDomainHostdevDefPtr virDomainHostdevDefAlloc(void);
-- 
1.8.1.4




More information about the libvir-list mailing list