mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-01 01:15:19 +00:00
Support QEMU watchdog device.
This adds simple support for configuring a guest with a QEMU/KVM virtual hardware watchdog device.
This commit is contained in:
parent
b03fe2d0ae
commit
08bed02515
@ -1028,6 +1028,81 @@ qemu-kvm -net nic,model=? /dev/null
|
|||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
|
<h4><a name="elementsWatchdog">Watchdog device</a></h4>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
A virtual hardware watchdog device can be added to the guest via
|
||||||
|
the <code>watchdog</code> element.
|
||||||
|
<span class="since">Since 0.7.3, QEMU and KVM only</span>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The watchdog device requires an additional driver and management
|
||||||
|
daemon in the guest. Just enabling the watchdog in the libvirt
|
||||||
|
configuration does not do anything useful on its own.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Currently libvirt does not support notification when the
|
||||||
|
watchdog fires. This feature is planned for a future version of
|
||||||
|
libvirt.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
...
|
||||||
|
<watchdog model='i6300esb'/>
|
||||||
|
...</pre>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
...
|
||||||
|
<watchdog model='i6300esb' action='poweroff'/>
|
||||||
|
...</pre>
|
||||||
|
|
||||||
|
<dl>
|
||||||
|
<dt><code>model</code></dt>
|
||||||
|
<dd>
|
||||||
|
<p>
|
||||||
|
The required <code>model</code> attribute specifies what real
|
||||||
|
watchdog device is emulated. Valid values are specific to the
|
||||||
|
underlying hypervisor.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
QEMU and KVM support:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li> 'i6300esb' — the recommended device,
|
||||||
|
emulating a PCI Intel 6300ESB </li>
|
||||||
|
<li> 'ib700' — emulating an ISA iBase IB700 </li>
|
||||||
|
</ul>
|
||||||
|
</dd>
|
||||||
|
<dt><code>action</code></dt>
|
||||||
|
<dd>
|
||||||
|
<p>
|
||||||
|
The optional <code>action</code> attribute describes what
|
||||||
|
action to take when the watchdog expires. Valid values are
|
||||||
|
specific to the underlying hypervisor.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
QEMU and KVM support:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>'reset' — default, forcefully reset the guest</li>
|
||||||
|
<li>'shutdown' — gracefully shutdown the guest
|
||||||
|
(not recommended) </li>
|
||||||
|
<li>'poweroff' — forcefully power off the guest</li>
|
||||||
|
<li>'pause' — pause the guest</li>
|
||||||
|
<li>'none' — do nothing</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
Note that the 'shutdown' action requires that the guest
|
||||||
|
is responsive to ACPI signals. In the sort of situations
|
||||||
|
where the watchdog has expired, guests are usually unable
|
||||||
|
to respond to ACPI signals. Therefore using 'shutdown'
|
||||||
|
is not recommended.
|
||||||
|
</p>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
<h2><a name="examples">Example configs</a></h2>
|
<h2><a name="examples">Example configs</a></h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@ -275,13 +275,13 @@
|
|||||||
</element>
|
</element>
|
||||||
</optional>
|
</optional>
|
||||||
<optional>
|
<optional>
|
||||||
<element name="memoryBacking">
|
<element name="memoryBacking">
|
||||||
<optional>
|
<optional>
|
||||||
<element name="hugepages">
|
<element name="hugepages">
|
||||||
<empty/>
|
<empty/>
|
||||||
</element>
|
</element>
|
||||||
</optional>
|
</optional>
|
||||||
</element>
|
</element>
|
||||||
</optional>
|
</optional>
|
||||||
<optional>
|
<optional>
|
||||||
<element name="vcpu">
|
<element name="vcpu">
|
||||||
@ -842,7 +842,7 @@
|
|||||||
<define name="video">
|
<define name="video">
|
||||||
<element name="video">
|
<element name="video">
|
||||||
<optional>
|
<optional>
|
||||||
<element name="model">
|
<element name="model">
|
||||||
<attribute name="type">
|
<attribute name="type">
|
||||||
<choice>
|
<choice>
|
||||||
<value>vga</value>
|
<value>vga</value>
|
||||||
@ -882,7 +882,7 @@
|
|||||||
</optional>
|
</optional>
|
||||||
</element>
|
</element>
|
||||||
</optional>
|
</optional>
|
||||||
</element>
|
</element>
|
||||||
</optional>
|
</optional>
|
||||||
</element>
|
</element>
|
||||||
</define>
|
</define>
|
||||||
@ -1013,6 +1013,27 @@
|
|||||||
</attribute>
|
</attribute>
|
||||||
</element>
|
</element>
|
||||||
</define>
|
</define>
|
||||||
|
<define name="watchdog">
|
||||||
|
<element name="watchdog">
|
||||||
|
<attribute name="model">
|
||||||
|
<choice>
|
||||||
|
<value>i6300esb</value>
|
||||||
|
<value>ib700</value>
|
||||||
|
</choice>
|
||||||
|
</attribute>
|
||||||
|
<optional>
|
||||||
|
<attribute name="action">
|
||||||
|
<choice>
|
||||||
|
<value>reset</value>
|
||||||
|
<value>shutdown</value>
|
||||||
|
<value>poweroff</value>
|
||||||
|
<value>pause</value>
|
||||||
|
<value>none</value>
|
||||||
|
</choice>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
</element>
|
||||||
|
</define>
|
||||||
<define name="parallel">
|
<define name="parallel">
|
||||||
<element name="parallel">
|
<element name="parallel">
|
||||||
<ref name="qemucdev"/>
|
<ref name="qemucdev"/>
|
||||||
@ -1139,6 +1160,9 @@
|
|||||||
<ref name="serial"/>
|
<ref name="serial"/>
|
||||||
</choice>
|
</choice>
|
||||||
</zeroOrMore>
|
</zeroOrMore>
|
||||||
|
<optional>
|
||||||
|
<ref name="watchdog"/>
|
||||||
|
</optional>
|
||||||
</interleave>
|
</interleave>
|
||||||
</element>
|
</element>
|
||||||
</define>
|
</define>
|
||||||
|
@ -84,7 +84,8 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST,
|
|||||||
"input",
|
"input",
|
||||||
"sound",
|
"sound",
|
||||||
"video",
|
"video",
|
||||||
"hostdev")
|
"hostdev",
|
||||||
|
"watchdog")
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST,
|
VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST,
|
||||||
"block",
|
"block",
|
||||||
@ -144,6 +145,17 @@ VIR_ENUM_IMPL(virDomainSoundModel, VIR_DOMAIN_SOUND_MODEL_LAST,
|
|||||||
"pcspk",
|
"pcspk",
|
||||||
"ac97")
|
"ac97")
|
||||||
|
|
||||||
|
VIR_ENUM_IMPL(virDomainWatchdogModel, VIR_DOMAIN_WATCHDOG_MODEL_LAST,
|
||||||
|
"i6300esb",
|
||||||
|
"ib700")
|
||||||
|
|
||||||
|
VIR_ENUM_IMPL(virDomainWatchdogAction, VIR_DOMAIN_WATCHDOG_ACTION_LAST,
|
||||||
|
"reset",
|
||||||
|
"shutdown",
|
||||||
|
"poweroff",
|
||||||
|
"pause",
|
||||||
|
"none")
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virDomainVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
|
VIR_ENUM_IMPL(virDomainVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
|
||||||
"vga",
|
"vga",
|
||||||
"cirrus",
|
"cirrus",
|
||||||
@ -387,6 +399,14 @@ void virDomainSoundDefFree(virDomainSoundDefPtr def)
|
|||||||
VIR_FREE(def);
|
VIR_FREE(def);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void virDomainWatchdogDefFree(virDomainWatchdogDefPtr def)
|
||||||
|
{
|
||||||
|
if (!def)
|
||||||
|
return;
|
||||||
|
|
||||||
|
VIR_FREE(def);
|
||||||
|
}
|
||||||
|
|
||||||
void virDomainVideoDefFree(virDomainVideoDefPtr def)
|
void virDomainVideoDefFree(virDomainVideoDefPtr def)
|
||||||
{
|
{
|
||||||
if (!def)
|
if (!def)
|
||||||
@ -429,6 +449,9 @@ void virDomainDeviceDefFree(virDomainDeviceDefPtr def)
|
|||||||
case VIR_DOMAIN_DEVICE_HOSTDEV:
|
case VIR_DOMAIN_DEVICE_HOSTDEV:
|
||||||
virDomainHostdevDefFree(def->data.hostdev);
|
virDomainHostdevDefFree(def->data.hostdev);
|
||||||
break;
|
break;
|
||||||
|
case VIR_DOMAIN_DEVICE_WATCHDOG:
|
||||||
|
virDomainWatchdogDefFree(def->data.watchdog);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
VIR_FREE(def);
|
VIR_FREE(def);
|
||||||
@ -508,6 +531,8 @@ void virDomainDefFree(virDomainDefPtr def)
|
|||||||
VIR_FREE(def->emulator);
|
VIR_FREE(def->emulator);
|
||||||
VIR_FREE(def->description);
|
VIR_FREE(def->description);
|
||||||
|
|
||||||
|
virDomainWatchdogDefFree(def->watchdog);
|
||||||
|
|
||||||
virSecurityLabelDefFree(def);
|
virSecurityLabelDefFree(def);
|
||||||
|
|
||||||
VIR_FREE(def);
|
VIR_FREE(def);
|
||||||
@ -1739,6 +1764,58 @@ error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static virDomainWatchdogDefPtr
|
||||||
|
virDomainWatchdogDefParseXML(virConnectPtr conn,
|
||||||
|
const xmlNodePtr node,
|
||||||
|
int flags ATTRIBUTE_UNUSED) {
|
||||||
|
|
||||||
|
char *model = NULL;
|
||||||
|
char *action = NULL;
|
||||||
|
virDomainWatchdogDefPtr def;
|
||||||
|
|
||||||
|
if (VIR_ALLOC (def) < 0) {
|
||||||
|
virReportOOMError (conn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
model = virXMLPropString (node, "model");
|
||||||
|
if (model == NULL) {
|
||||||
|
virDomainReportError (conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("watchdog must contain model name"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
def->model = virDomainWatchdogModelTypeFromString (model);
|
||||||
|
if (def->model < 0) {
|
||||||
|
virDomainReportError (conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("unknown watchdog model '%s'"), model);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
action = virXMLPropString (node, "action");
|
||||||
|
if (action == NULL)
|
||||||
|
def->action = VIR_DOMAIN_WATCHDOG_ACTION_RESET;
|
||||||
|
else {
|
||||||
|
def->action = virDomainWatchdogActionTypeFromString (action);
|
||||||
|
if (def->action < 0) {
|
||||||
|
virDomainReportError (conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("unknown watchdog action '%s'"), action);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE (action);
|
||||||
|
VIR_FREE (model);
|
||||||
|
|
||||||
|
return def;
|
||||||
|
|
||||||
|
error:
|
||||||
|
virDomainWatchdogDefFree (def);
|
||||||
|
def = NULL;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
virDomainVideoDefaultRAM(virDomainDefPtr def,
|
virDomainVideoDefaultRAM(virDomainDefPtr def,
|
||||||
int type)
|
int type)
|
||||||
@ -2365,6 +2442,11 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virConnectPtr conn,
|
|||||||
dev->type = VIR_DOMAIN_DEVICE_SOUND;
|
dev->type = VIR_DOMAIN_DEVICE_SOUND;
|
||||||
if (!(dev->data.sound = virDomainSoundDefParseXML(conn, node, flags)))
|
if (!(dev->data.sound = virDomainSoundDefParseXML(conn, node, flags)))
|
||||||
goto error;
|
goto error;
|
||||||
|
} else if (xmlStrEqual(node->name, BAD_CAST "watchdog")) {
|
||||||
|
dev->type = VIR_DOMAIN_DEVICE_WATCHDOG;
|
||||||
|
if (!(dev->data.watchdog = virDomainWatchdogDefParseXML(conn, node,
|
||||||
|
flags)))
|
||||||
|
goto error;
|
||||||
} else if (xmlStrEqual(node->name, BAD_CAST "video")) {
|
} else if (xmlStrEqual(node->name, BAD_CAST "video")) {
|
||||||
dev->type = VIR_DOMAIN_DEVICE_VIDEO;
|
dev->type = VIR_DOMAIN_DEVICE_VIDEO;
|
||||||
if (!(dev->data.video = virDomainVideoDefParseXML(conn, node, def, flags)))
|
if (!(dev->data.video = virDomainVideoDefParseXML(conn, node, def, flags)))
|
||||||
@ -3039,6 +3121,28 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
VIR_FREE(nodes);
|
VIR_FREE(nodes);
|
||||||
|
|
||||||
|
/* analysis of the watchdog devices */
|
||||||
|
def->watchdog = NULL;
|
||||||
|
if ((n = virXPathNodeSet(conn, "./devices/watchdog", ctxt, &nodes)) < 0) {
|
||||||
|
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"%s", _("cannot extract watchdog devices"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (n > 1) {
|
||||||
|
virDomainReportError (conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"%s", _("only a single watchdog device is supported"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (n > 0) {
|
||||||
|
virDomainWatchdogDefPtr watchdog =
|
||||||
|
virDomainWatchdogDefParseXML (conn, nodes[0], flags);
|
||||||
|
if (!watchdog)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
def->watchdog = watchdog;
|
||||||
|
VIR_FREE(nodes);
|
||||||
|
}
|
||||||
|
|
||||||
/* analysis of security label */
|
/* analysis of security label */
|
||||||
if (virSecurityLabelDefParseXML(conn, def, ctxt, flags) == -1)
|
if (virSecurityLabelDefParseXML(conn, def, ctxt, flags) == -1)
|
||||||
goto error;
|
goto error;
|
||||||
@ -3946,6 +4050,33 @@ virDomainSoundDefFormat(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virDomainWatchdogDefFormat(virConnectPtr conn,
|
||||||
|
virBufferPtr buf,
|
||||||
|
virDomainWatchdogDefPtr def)
|
||||||
|
{
|
||||||
|
const char *model = virDomainWatchdogModelTypeToString (def->model);
|
||||||
|
const char *action = virDomainWatchdogActionTypeToString (def->action);
|
||||||
|
|
||||||
|
if (!model) {
|
||||||
|
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("unexpected watchdog model %d"), def->model);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!action) {
|
||||||
|
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("unexpected watchdog action %d"), def->action);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
virBufferVSprintf(buf, " <watchdog model='%s' action='%s'/>\n",
|
||||||
|
model, action);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
virDomainVideoAccelDefFormat(virBufferPtr buf,
|
virDomainVideoAccelDefFormat(virBufferPtr buf,
|
||||||
virDomainVideoAccelDefPtr def)
|
virDomainVideoAccelDefPtr def)
|
||||||
@ -4392,6 +4523,9 @@ char *virDomainDefFormat(virConnectPtr conn,
|
|||||||
if (virDomainHostdevDefFormat(conn, &buf, def->hostdevs[n], flags) < 0)
|
if (virDomainHostdevDefFormat(conn, &buf, def->hostdevs[n], flags) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
if (def->watchdog)
|
||||||
|
virDomainWatchdogDefFormat (conn, &buf, def->watchdog);
|
||||||
|
|
||||||
virBufferAddLit(&buf, " </devices>\n");
|
virBufferAddLit(&buf, " </devices>\n");
|
||||||
|
|
||||||
if (def->seclabel.model) {
|
if (def->seclabel.model) {
|
||||||
|
@ -298,6 +298,30 @@ struct _virDomainSoundDef {
|
|||||||
int model;
|
int model;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum virDomainWatchdogModel {
|
||||||
|
VIR_DOMAIN_WATCHDOG_MODEL_I6300ESB,
|
||||||
|
VIR_DOMAIN_WATCHDOG_MODEL_IB700,
|
||||||
|
|
||||||
|
VIR_DOMAIN_WATCHDOG_MODEL_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
enum virDomainWatchdogAction {
|
||||||
|
VIR_DOMAIN_WATCHDOG_ACTION_RESET,
|
||||||
|
VIR_DOMAIN_WATCHDOG_ACTION_SHUTDOWN,
|
||||||
|
VIR_DOMAIN_WATCHDOG_ACTION_POWEROFF,
|
||||||
|
VIR_DOMAIN_WATCHDOG_ACTION_PAUSE,
|
||||||
|
VIR_DOMAIN_WATCHDOG_ACTION_NONE,
|
||||||
|
|
||||||
|
VIR_DOMAIN_WATCHDOG_ACTION_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _virDomainWatchdogDef virDomainWatchdogDef;
|
||||||
|
typedef virDomainWatchdogDef *virDomainWatchdogDefPtr;
|
||||||
|
struct _virDomainWatchdogDef {
|
||||||
|
int model;
|
||||||
|
int action;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
enum virDomainVideoType {
|
enum virDomainVideoType {
|
||||||
VIR_DOMAIN_VIDEO_TYPE_VGA,
|
VIR_DOMAIN_VIDEO_TYPE_VGA,
|
||||||
@ -438,6 +462,7 @@ enum virDomainDeviceType {
|
|||||||
VIR_DOMAIN_DEVICE_SOUND,
|
VIR_DOMAIN_DEVICE_SOUND,
|
||||||
VIR_DOMAIN_DEVICE_VIDEO,
|
VIR_DOMAIN_DEVICE_VIDEO,
|
||||||
VIR_DOMAIN_DEVICE_HOSTDEV,
|
VIR_DOMAIN_DEVICE_HOSTDEV,
|
||||||
|
VIR_DOMAIN_DEVICE_WATCHDOG,
|
||||||
|
|
||||||
VIR_DOMAIN_DEVICE_LAST,
|
VIR_DOMAIN_DEVICE_LAST,
|
||||||
};
|
};
|
||||||
@ -454,6 +479,7 @@ struct _virDomainDeviceDef {
|
|||||||
virDomainSoundDefPtr sound;
|
virDomainSoundDefPtr sound;
|
||||||
virDomainVideoDefPtr video;
|
virDomainVideoDefPtr video;
|
||||||
virDomainHostdevDefPtr hostdev;
|
virDomainHostdevDefPtr hostdev;
|
||||||
|
virDomainWatchdogDefPtr watchdog;
|
||||||
} data;
|
} data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -586,6 +612,7 @@ struct _virDomainDef {
|
|||||||
/* Only 1 */
|
/* Only 1 */
|
||||||
virDomainChrDefPtr console;
|
virDomainChrDefPtr console;
|
||||||
virSecurityLabelDef seclabel;
|
virSecurityLabelDef seclabel;
|
||||||
|
virDomainWatchdogDefPtr watchdog;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Guest VM runtime state */
|
/* Guest VM runtime state */
|
||||||
@ -639,6 +666,7 @@ void virDomainFSDefFree(virDomainFSDefPtr def);
|
|||||||
void virDomainNetDefFree(virDomainNetDefPtr def);
|
void virDomainNetDefFree(virDomainNetDefPtr def);
|
||||||
void virDomainChrDefFree(virDomainChrDefPtr def);
|
void virDomainChrDefFree(virDomainChrDefPtr def);
|
||||||
void virDomainSoundDefFree(virDomainSoundDefPtr def);
|
void virDomainSoundDefFree(virDomainSoundDefPtr def);
|
||||||
|
void virDomainWatchdogDefFree(virDomainWatchdogDefPtr def);
|
||||||
void virDomainVideoDefFree(virDomainVideoDefPtr def);
|
void virDomainVideoDefFree(virDomainVideoDefPtr def);
|
||||||
void virDomainHostdevDefFree(virDomainHostdevDefPtr def);
|
void virDomainHostdevDefFree(virDomainHostdevDefPtr def);
|
||||||
void virDomainDeviceDefFree(virDomainDeviceDefPtr def);
|
void virDomainDeviceDefFree(virDomainDeviceDefPtr def);
|
||||||
@ -769,6 +797,8 @@ VIR_ENUM_DECL(virDomainFS)
|
|||||||
VIR_ENUM_DECL(virDomainNet)
|
VIR_ENUM_DECL(virDomainNet)
|
||||||
VIR_ENUM_DECL(virDomainChr)
|
VIR_ENUM_DECL(virDomainChr)
|
||||||
VIR_ENUM_DECL(virDomainSoundModel)
|
VIR_ENUM_DECL(virDomainSoundModel)
|
||||||
|
VIR_ENUM_DECL(virDomainWatchdogModel)
|
||||||
|
VIR_ENUM_DECL(virDomainWatchdogAction)
|
||||||
VIR_ENUM_DECL(virDomainVideo)
|
VIR_ENUM_DECL(virDomainVideo)
|
||||||
VIR_ENUM_DECL(virDomainHostdevMode)
|
VIR_ENUM_DECL(virDomainHostdevMode)
|
||||||
VIR_ENUM_DECL(virDomainHostdevSubsys)
|
VIR_ENUM_DECL(virDomainHostdevSubsys)
|
||||||
|
@ -132,6 +132,10 @@ virDomainSaveStatus;
|
|||||||
virDomainSoundDefFree;
|
virDomainSoundDefFree;
|
||||||
virDomainSoundModelTypeFromString;
|
virDomainSoundModelTypeFromString;
|
||||||
virDomainSoundModelTypeToString;
|
virDomainSoundModelTypeToString;
|
||||||
|
virDomainWatchdogModelTypeFromString;
|
||||||
|
virDomainWatchdogModelTypeToString;
|
||||||
|
virDomainWatchdogActionTypeFromString;
|
||||||
|
virDomainWatchdogActionTypeToString;
|
||||||
virDomainVideoDefFree;
|
virDomainVideoDefFree;
|
||||||
virDomainVideoTypeToString;
|
virDomainVideoTypeToString;
|
||||||
virDomainVideoTypeFromString;
|
virDomainVideoTypeFromString;
|
||||||
|
@ -2233,6 +2233,28 @@ int qemudBuildCommandLine(virConnectPtr conn,
|
|||||||
ADD_ARG(modstr);
|
ADD_ARG(modstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add watchdog hardware */
|
||||||
|
if (def->watchdog) {
|
||||||
|
virDomainWatchdogDefPtr watchdog = def->watchdog;
|
||||||
|
const char *model = virDomainWatchdogModelTypeToString(watchdog->model);
|
||||||
|
if (!model) {
|
||||||
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"%s", _("invalid watchdog model"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
ADD_ARG_LIT("-watchdog");
|
||||||
|
ADD_ARG_LIT(model);
|
||||||
|
|
||||||
|
const char *action = virDomainWatchdogActionTypeToString(watchdog->action);
|
||||||
|
if (!action) {
|
||||||
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"%s", _("invalid watchdog action"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
ADD_ARG_LIT("-watchdog-action");
|
||||||
|
ADD_ARG_LIT(action);
|
||||||
|
}
|
||||||
|
|
||||||
/* Add host passthrough hardware */
|
/* Add host passthrough hardware */
|
||||||
for (i = 0 ; i < def->nhostdevs ; i++) {
|
for (i = 0 ; i < def->nhostdevs ; i++) {
|
||||||
int ret;
|
int ret;
|
||||||
@ -3482,6 +3504,24 @@ virDomainDefPtr qemuParseCommandLine(virConnectPtr conn,
|
|||||||
|
|
||||||
start = tmp ? tmp + 1 : NULL;
|
start = tmp ? tmp + 1 : NULL;
|
||||||
}
|
}
|
||||||
|
} else if (STREQ(arg, "-watchdog")) {
|
||||||
|
WANT_VALUE();
|
||||||
|
int model = virDomainWatchdogModelTypeFromString (val);
|
||||||
|
|
||||||
|
if (model != -1) {
|
||||||
|
virDomainWatchdogDefPtr wd;
|
||||||
|
if (VIR_ALLOC(wd) < 0)
|
||||||
|
goto no_memory;
|
||||||
|
wd->model = model;
|
||||||
|
wd->action = VIR_DOMAIN_WATCHDOG_ACTION_RESET;
|
||||||
|
def->watchdog = wd;
|
||||||
|
}
|
||||||
|
} else if (STREQ(arg, "-watchdog-action") && def->watchdog) {
|
||||||
|
WANT_VALUE();
|
||||||
|
int action = virDomainWatchdogActionTypeFromString (val);
|
||||||
|
|
||||||
|
if (action != -1)
|
||||||
|
def->watchdog->action = action;
|
||||||
} else if (STREQ(arg, "-bootloader")) {
|
} else if (STREQ(arg, "-bootloader")) {
|
||||||
WANT_VALUE();
|
WANT_VALUE();
|
||||||
def->os.bootloader = strdup(val);
|
def->os.bootloader = strdup(val);
|
||||||
|
@ -212,6 +212,7 @@ mymain(int argc, char **argv)
|
|||||||
DO_TEST("parallel-tcp", 0);
|
DO_TEST("parallel-tcp", 0);
|
||||||
DO_TEST("console-compat", 0);
|
DO_TEST("console-compat", 0);
|
||||||
DO_TEST("sound", 0);
|
DO_TEST("sound", 0);
|
||||||
|
DO_TEST("watchdog", 0);
|
||||||
|
|
||||||
DO_TEST("hostdev-usb-product", 0);
|
DO_TEST("hostdev-usb-product", 0);
|
||||||
DO_TEST("hostdev-usb-address", 0);
|
DO_TEST("hostdev-usb-address", 0);
|
||||||
|
1
tests/qemuxml2argvdata/qemuxml2argv-watchdog.args
Normal file
1
tests/qemuxml2argvdata/qemuxml2argv-watchdog.args
Normal file
@ -0,0 +1 @@
|
|||||||
|
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb -watchdog ib700 -watchdog-action poweroff
|
23
tests/qemuxml2argvdata/qemuxml2argv-watchdog.xml
Normal file
23
tests/qemuxml2argvdata/qemuxml2argv-watchdog.xml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<domain type='qemu'>
|
||||||
|
<name>QEMUGuest1</name>
|
||||||
|
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
||||||
|
<memory>219200</memory>
|
||||||
|
<currentMemory>219200</currentMemory>
|
||||||
|
<vcpu>1</vcpu>
|
||||||
|
<os>
|
||||||
|
<type arch='i686' machine='pc'>hvm</type>
|
||||||
|
<boot dev='hd'/>
|
||||||
|
</os>
|
||||||
|
<clock offset='utc'/>
|
||||||
|
<on_poweroff>destroy</on_poweroff>
|
||||||
|
<on_reboot>restart</on_reboot>
|
||||||
|
<on_crash>destroy</on_crash>
|
||||||
|
<devices>
|
||||||
|
<emulator>/usr/bin/qemu</emulator>
|
||||||
|
<disk type='block' device='disk'>
|
||||||
|
<source dev='/dev/HostVG/QEMUGuest1'/>
|
||||||
|
<target dev='hda' bus='ide'/>
|
||||||
|
</disk>
|
||||||
|
<watchdog model='ib700' action='poweroff'/>
|
||||||
|
</devices>
|
||||||
|
</domain>
|
Loading…
x
Reference in New Issue
Block a user