diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 139223b9d6..a094524a15 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -5088,6 +5088,34 @@ qemu-kvm -net nic,model=? /dev/null
+
+
+ panic device enables libvirt to receive panic notification from a QEMU
+ guest.
+ Since 1.2.1, QEMU and KVM only
+
+
+ Example: usage of panic configuration
+
+
+ ...
+ <devices>
+ <panic>
+ <address type='isa' iobase='0x505'/>
+ </panic>
+ </devices>
+ ...
+
+
+ address
+ -
+
+ address of panic. The default ioport is 0x505. Most users
+ don't need to specify an address.
+
+
+
+
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index c91044c7a7..be32c6bc6e 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -3556,6 +3556,9 @@
+
+
+
@@ -4415,4 +4418,11 @@
+
+
+
+
+
+
+
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b12f788ae0..00792340eb 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1937,6 +1937,15 @@ virDomainResourceDefFree(virDomainResourceDefPtr resource)
VIR_FREE(resource);
}
+void
+virDomainPanicDefFree(virDomainPanicDefPtr panic)
+{
+ if (!panic)
+ return;
+
+ virDomainDeviceInfoClear(&panic->info);
+ VIR_FREE(panic);
+}
void virDomainDefFree(virDomainDefPtr def)
{
@@ -2025,6 +2034,8 @@ void virDomainDefFree(virDomainDefPtr def)
virDomainTPMDefFree(def->tpm);
+ virDomainPanicDefFree(def->panic);
+
VIR_FREE(def->idmap.uidmap);
VIR_FREE(def->idmap.gidmap);
@@ -10733,6 +10744,22 @@ cleanup:
return idmap;
}
+static virDomainPanicDefPtr
+virDomainPanicDefParseXML(xmlNodePtr node)
+{
+ virDomainPanicDefPtr panic;
+
+ if (VIR_ALLOC(panic) < 0)
+ return NULL;
+
+ if (virDomainDeviceInfoParseXML(node, NULL, &panic->info, 0) < 0)
+ goto error;
+
+ return panic;
+error:
+ virDomainPanicDefFree(panic);
+ return NULL;
+}
/* Parse the XML definition for a vcpupin or emulatorpin.
*
@@ -12561,6 +12588,27 @@ virDomainDefParseXML(xmlDocPtr xml,
}
VIR_FREE(nodes);
+ /* analysis of the panic devices */
+ def->panic = NULL;
+ if ((n = virXPathNodeSet("./devices/panic", ctxt, &nodes)) < 0) {
+ goto error;
+ }
+ if (n > 1) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("only a single panic device is supported"));
+ goto error;
+ }
+ if (n > 0) {
+ virDomainPanicDefPtr panic =
+ virDomainPanicDefParseXML(nodes[0]);
+ if (!panic)
+ goto error;
+
+ def->panic = panic;
+ VIR_FREE(nodes);
+ }
+
+
/* analysis of the user namespace mapping */
if ((n = virXPathNodeSet("./idmap/uid", ctxt, &nodes)) < 0)
goto error;
@@ -13657,6 +13705,13 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
return true;
}
+static bool
+virDomainPanicCheckABIStability(virDomainPanicDefPtr src,
+ virDomainPanicDefPtr dst)
+{
+ return virDomainDeviceInfoCheckABIStability(&src->info, &dst->info);
+}
+
/* This compares two configurations and looks for any differences
* which will affect the guest ABI. This is primarily to allow
@@ -13998,6 +14053,9 @@ virDomainDefCheckABIStability(virDomainDefPtr src,
if (!virDomainRNGDefCheckABIStability(src->rng, dst->rng))
return false;
+ if (!virDomainPanicCheckABIStability(src->panic, dst->panic))
+ return false;
+
return true;
}
@@ -15861,6 +15919,16 @@ virDomainWatchdogDefFormat(virBufferPtr buf,
return 0;
}
+static int virDomainPanicDefFormat(virBufferPtr buf,
+ virDomainPanicDefPtr def)
+{
+ virBufferAddLit(buf, " \n");
+ if (virDomainDeviceInfoFormat(buf, &def->info, 0) < 0)
+ return -1;
+ virBufferAddLit(buf, " \n");
+
+ return 0;
+}
static int
virDomainRNGDefFormat(virBufferPtr buf,
@@ -17293,6 +17361,10 @@ virDomainDefFormatInternal(virDomainDefPtr def,
if (def->nvram)
virDomainNVRAMDefFormat(buf, def->nvram, flags);
+ if (def->panic &&
+ virDomainPanicDefFormat(buf, def->panic) < 0)
+ goto error;
+
virBufferAddLit(buf, " \n");
virBufferAdjustIndent(buf, 2);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 6d635c3252..647d11556f 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -126,6 +126,9 @@ typedef virDomainIdMapEntry *virDomainIdMapEntryPtr;
typedef struct _virDomainIdMapDef virDomainIdMapDef;
typedef virDomainIdMapDef *virDomainIdMapDefPtr;
+typedef struct _virDomainPanicDef virDomainPanicDef;
+typedef virDomainPanicDef *virDomainPanicDefPtr;
+
/* Flags for the 'type' field in virDomainDeviceDef */
typedef enum {
VIR_DOMAIN_DEVICE_NONE = 0,
@@ -1920,6 +1923,11 @@ struct _virDomainIdMapDef {
};
+struct _virDomainPanicDef {
+ virDomainDeviceInfo info;
+};
+
+
void virBlkioDeviceArrayClear(virBlkioDevicePtr deviceWeights,
int ndevices);
@@ -2071,6 +2079,7 @@ struct _virDomainDef {
virSysinfoDefPtr sysinfo;
virDomainRedirFilterDefPtr redirfilter;
virDomainRNGDefPtr rng;
+ virDomainPanicDefPtr panic;
void *namespaceData;
virDomainXMLNamespace ns;
@@ -2214,6 +2223,7 @@ virDomainObjPtr virDomainObjListFindByName(virDomainObjListPtr doms,
bool virDomainObjTaint(virDomainObjPtr obj,
enum virDomainTaintFlags taint);
+void virDomainPanicDefFree(virDomainPanicDefPtr panic);
void virDomainResourceDefFree(virDomainResourceDefPtr resource);
void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def);
void virDomainInputDefFree(virDomainInputDefPtr def);