c401cc
From 1efacd76a430275796d45e26cac47af59c0e571a Mon Sep 17 00:00:00 2001
c401cc
Message-Id: <1efacd76a430275796d45e26cac47af59c0e571a.1387385061.git.jdenemar@redhat.com>
c401cc
From: Hu Tao <hutao@cn.fujitsu.com>
c401cc
Date: Mon, 16 Dec 2013 11:58:21 -0700
c401cc
Subject: [PATCH] conf: add support for panic device
c401cc
c401cc
RHEL 7.0: https://bugzilla.redhat.com/show_bug.cgi?id=996520
c401cc
c401cc
panic device is a device that enables libvirt to receive notification
c401cc
of guest panic event.
c401cc
c401cc
Signed-off-by: Eric Blake <eblake@redhat.com>
c401cc
(cherry picked from commit 4313feade44e24ca215416e75299c7d29a70db11)
c401cc
c401cc
Conflicts:
c401cc
	src/conf/domain_conf.h - context (commit b471066, blkio array clear)
c401cc
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
c401cc
---
c401cc
 docs/formatdomain.html.in     | 28 +++++++++++++++++
c401cc
 docs/schemas/domaincommon.rng | 10 ++++++
c401cc
 src/conf/domain_conf.c        | 72 +++++++++++++++++++++++++++++++++++++++++++
c401cc
 src/conf/domain_conf.h        | 10 ++++++
c401cc
 4 files changed, 120 insertions(+)
c401cc
c401cc
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
c401cc
index fb557f6..fc8a397 100644
c401cc
--- a/docs/formatdomain.html.in
c401cc
+++ b/docs/formatdomain.html.in
c401cc
@@ -5033,6 +5033,34 @@ qemu-kvm -net nic,model=? /dev/null
c401cc
     
c401cc
   
c401cc
 
c401cc
+    

panic device

c401cc
+    

c401cc
+      panic device enables libvirt to receive panic notification from a QEMU
c401cc
+      guest.
c401cc
+      Since 1.2.1, QEMU and KVM only
c401cc
+    

c401cc
+    

c401cc
+      Example: usage of panic configuration
c401cc
+    

c401cc
+
c401cc
+  ...
c401cc
+  <devices>
c401cc
+    <panic>
c401cc
+      <address type='isa' iobase='0x505'/>
c401cc
+    </panic>
c401cc
+  </devices>
c401cc
+  ...
c401cc
+
c401cc
+  
c401cc
+    
address
c401cc
+    
c401cc
+      

c401cc
+        address of panic. The default ioport is 0x505. Most users
c401cc
+        don't need to specify an address.
c401cc
+      

c401cc
+    
c401cc
+  
c401cc
+
c401cc
     

Security label

c401cc
 
c401cc
     

c401cc
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
c401cc
index 871ae30..91b36e2 100644
c401cc
--- a/docs/schemas/domaincommon.rng
c401cc
+++ b/docs/schemas/domaincommon.rng
c401cc
@@ -3505,6 +3505,9 @@
c401cc
         <optional>
c401cc
           <ref name="nvram"/>
c401cc
         </optional>
c401cc
+        <optional>
c401cc
+          <ref name="panic"/>
c401cc
+        </optional>
c401cc
       </interleave>
c401cc
     </element>
c401cc
   </define>
c401cc
@@ -4364,4 +4367,11 @@
c401cc
       </data>
c401cc
     </choice>
c401cc
   </define>
c401cc
+  <define name="panic">
c401cc
+    <element name="panic">
c401cc
+      <optional>
c401cc
+        <ref name="address"/>
c401cc
+      </optional>
c401cc
+    </element>
c401cc
+  </define>
c401cc
 </grammar>
c401cc
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
c401cc
index f35ec44..9cf5432 100644
c401cc
--- a/src/conf/domain_conf.c
c401cc
+++ b/src/conf/domain_conf.c
c401cc
@@ -1870,6 +1870,15 @@ virDomainResourceDefFree(virDomainResourceDefPtr resource)
c401cc
     VIR_FREE(resource);
c401cc
 }
c401cc
 
c401cc
+void
c401cc
+virDomainPanicDefFree(virDomainPanicDefPtr panic)
c401cc
+{
c401cc
+    if (!panic)
c401cc
+        return;
c401cc
+
c401cc
+    virDomainDeviceInfoClear(&panic->info);
c401cc
+    VIR_FREE(panic);
c401cc
+}
c401cc
 
c401cc
 void virDomainDefFree(virDomainDefPtr def)
c401cc
 {
c401cc
@@ -1958,6 +1967,8 @@ void virDomainDefFree(virDomainDefPtr def)
c401cc
 
c401cc
     virDomainTPMDefFree(def->tpm);
c401cc
 
c401cc
+    virDomainPanicDefFree(def->panic);
c401cc
+
c401cc
     VIR_FREE(def->idmap.uidmap);
c401cc
     VIR_FREE(def->idmap.gidmap);
c401cc
 
c401cc
@@ -10553,6 +10564,22 @@ cleanup:
c401cc
     return idmap;
c401cc
 }
c401cc
 
c401cc
+static virDomainPanicDefPtr
c401cc
+virDomainPanicDefParseXML(xmlNodePtr node)
c401cc
+{
c401cc
+    virDomainPanicDefPtr panic;
c401cc
+
c401cc
+    if (VIR_ALLOC(panic) < 0)
c401cc
+        return NULL;
c401cc
+
c401cc
+    if (virDomainDeviceInfoParseXML(node, NULL, &panic->info, 0) < 0)
c401cc
+        goto error;
c401cc
+
c401cc
+    return panic;
c401cc
+error:
c401cc
+    virDomainPanicDefFree(panic);
c401cc
+    return NULL;
c401cc
+}
c401cc
 
c401cc
 /* Parse the XML definition for a vcpupin or emulatorpin.
c401cc
  *
c401cc
@@ -12390,6 +12417,27 @@ virDomainDefParseXML(xmlDocPtr xml,
c401cc
     }
c401cc
     VIR_FREE(nodes);
c401cc
 
c401cc
+    /* analysis of the panic devices */
c401cc
+    def->panic = NULL;
c401cc
+    if ((n = virXPathNodeSet("./devices/panic", ctxt, &nodes)) < 0) {
c401cc
+        goto error;
c401cc
+    }
c401cc
+    if (n > 1) {
c401cc
+        virReportError(VIR_ERR_XML_ERROR, "%s",
c401cc
+                       _("only a single panic device is supported"));
c401cc
+        goto error;
c401cc
+    }
c401cc
+    if (n > 0) {
c401cc
+        virDomainPanicDefPtr panic =
c401cc
+            virDomainPanicDefParseXML(nodes[0]);
c401cc
+        if (!panic)
c401cc
+            goto error;
c401cc
+
c401cc
+        def->panic = panic;
c401cc
+        VIR_FREE(nodes);
c401cc
+    }
c401cc
+
c401cc
+
c401cc
     /* analysis of the user namespace mapping */
c401cc
     if ((n = virXPathNodeSet("./idmap/uid", ctxt, &nodes)) < 0)
c401cc
         goto error;
c401cc
@@ -13486,6 +13534,13 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
c401cc
     return true;
c401cc
 }
c401cc
 
c401cc
+static bool
c401cc
+virDomainPanicCheckABIStability(virDomainPanicDefPtr src,
c401cc
+                                virDomainPanicDefPtr dst)
c401cc
+{
c401cc
+    return virDomainDeviceInfoCheckABIStability(&src->info, &dst->info);
c401cc
+}
c401cc
+
c401cc
 
c401cc
 /* This compares two configurations and looks for any differences
c401cc
  * which will affect the guest ABI. This is primarily to allow
c401cc
@@ -13827,6 +13882,9 @@ virDomainDefCheckABIStability(virDomainDefPtr src,
c401cc
     if (!virDomainRNGDefCheckABIStability(src->rng, dst->rng))
c401cc
         return false;
c401cc
 
c401cc
+    if (!virDomainPanicCheckABIStability(src->panic, dst->panic))
c401cc
+        return false;
c401cc
+
c401cc
     return true;
c401cc
 }
c401cc
 
c401cc
@@ -15657,6 +15715,16 @@ virDomainWatchdogDefFormat(virBufferPtr buf,
c401cc
     return 0;
c401cc
 }
c401cc
 
c401cc
+static int virDomainPanicDefFormat(virBufferPtr buf,
c401cc
+                                     virDomainPanicDefPtr def)
c401cc
+{
c401cc
+    virBufferAddLit(buf, "    <panic>\n");
c401cc
+    if (virDomainDeviceInfoFormat(buf, &def->info, 0) < 0)
c401cc
+        return -1;
c401cc
+    virBufferAddLit(buf, "    </panic>\n");
c401cc
+
c401cc
+    return 0;
c401cc
+}
c401cc
 
c401cc
 static int
c401cc
 virDomainRNGDefFormat(virBufferPtr buf,
c401cc
@@ -17089,6 +17157,10 @@ virDomainDefFormatInternal(virDomainDefPtr def,
c401cc
     if (def->nvram)
c401cc
         virDomainNVRAMDefFormat(buf, def->nvram, flags);
c401cc
 
c401cc
+    if (def->panic &&
c401cc
+        virDomainPanicDefFormat(buf, def->panic) < 0)
c401cc
+        goto error;
c401cc
+
c401cc
     virBufferAddLit(buf, "  </devices>\n");
c401cc
 
c401cc
     virBufferAdjustIndent(buf, 2);
c401cc
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
c401cc
index 7f6096f..ed40def 100644
c401cc
--- a/src/conf/domain_conf.h
c401cc
+++ b/src/conf/domain_conf.h
c401cc
@@ -126,6 +126,9 @@ typedef virDomainIdMapEntry *virDomainIdMapEntryPtr;
c401cc
 typedef struct _virDomainIdMapDef virDomainIdMapDef;
c401cc
 typedef virDomainIdMapDef *virDomainIdMapDefPtr;
c401cc
 
c401cc
+typedef struct _virDomainPanicDef virDomainPanicDef;
c401cc
+typedef virDomainPanicDef *virDomainPanicDefPtr;
c401cc
+
c401cc
 /* Flags for the 'type' field in virDomainDeviceDef */
c401cc
 typedef enum {
c401cc
     VIR_DOMAIN_DEVICE_NONE = 0,
c401cc
@@ -1903,6 +1906,11 @@ struct _virDomainIdMapDef {
c401cc
 };
c401cc
 
c401cc
 
c401cc
+struct _virDomainPanicDef {
c401cc
+    virDomainDeviceInfo info;
c401cc
+};
c401cc
+
c401cc
+
c401cc
 void virBlkioDeviceWeightArrayClear(virBlkioDeviceWeightPtr deviceWeights,
c401cc
                                     int ndevices);
c401cc
 
c401cc
@@ -2054,6 +2062,7 @@ struct _virDomainDef {
c401cc
     virSysinfoDefPtr sysinfo;
c401cc
     virDomainRedirFilterDefPtr redirfilter;
c401cc
     virDomainRNGDefPtr rng;
c401cc
+    virDomainPanicDefPtr panic;
c401cc
 
c401cc
     void *namespaceData;
c401cc
     virDomainXMLNamespace ns;
c401cc
@@ -2193,6 +2202,7 @@ virDomainObjPtr virDomainObjListFindByName(const virDomainObjListPtr doms,
c401cc
 bool virDomainObjTaint(virDomainObjPtr obj,
c401cc
                        enum virDomainTaintFlags taint);
c401cc
 
c401cc
+void virDomainPanicDefFree(virDomainPanicDefPtr panic);
c401cc
 void virDomainResourceDefFree(virDomainResourceDefPtr resource);
c401cc
 void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def);
c401cc
 void virDomainInputDefFree(virDomainInputDefPtr def);
c401cc
-- 
c401cc
1.8.5.1
c401cc