There is a new <pm/> element implemented that can control what ACPI
sleeping states will be advertised by BIOS and allowed to be switched
to by libvirt. The default keeps defaults on hypervisor, otherwise
forces chosen setting.
---
docs/schemas/domaincommon.rng | 33 ++++++++++++++++++++++++++++++
src/conf/domain_conf.c | 44 +++++++++++++++++++++++++++++++++++++++++
src/conf/domain_conf.h | 14 +++++++++++++
src/libvirt_private.syms | 2 +
4 files changed, 93 insertions(+), 0 deletions(-)
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index c85d763..657d723 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -53,6 +53,9 @@
<ref name="features"/>
<ref name="termination"/>
<optional>
+ <ref name="pm"/>
+ </optional>
+ <optional>
<ref name="devices"/>
</optional>
<optional>
@@ -2192,6 +2195,36 @@
</choice>
</define>
<!--
+ Control ACPI sleep states (dis)allowed for the domain
+ For each of the states the following rules apply:
+ on: the state will be forcefully enabled
+ off: the state will be forcefully disabled
+ not specified: hypervisor will be left to decide its defaults
+ -->
+ <define name="pm">
+ <element name="pm">
+ <interleave>
+ <optional>
+ <attribute name="s3">
+ <ref name="suspendChoices"/>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name="s4">
+ <ref name="suspendChoices"/>
+ </attribute>
+ </optional>
+ </interleave>
+ <empty/>
+ </element>
+ </define>
+ <define name="suspendChoices">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </define>
+ <!--
Specific setup for a qemu emulated character device. Note: this
definition doesn't fully specify the constraints on this node.
-->
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 43b3f80..7a8279b 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -124,6 +124,11 @@ VIR_ENUM_IMPL(virDomainLifecycleCrash,
VIR_DOMAIN_LIFECYCLE_CRASH_LAST,
"coredump-destroy",
"coredump-restart")
+VIR_ENUM_IMPL(virDomainPMState, VIR_DOMAIN_PM_STATE_LAST,
+ "default",
+ "on",
+ "off")
+
VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST,
"none",
"disk",
@@ -8381,6 +8386,19 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
virDomainLifecycleCrashTypeFromString) < 0)
goto error;
+ if (virXPathNode("./pm", ctxt)) {
+ tmp = virXPathString("string(./pm/@s3)", ctxt);
+ if (tmp) {
+ def->pm.s3 = virDomainPMStateTypeFromString(tmp);
+ VIR_FREE(tmp);
+ }
+ tmp = virXPathString("string(./pm/@s4)", ctxt);
+ if (tmp) {
+ def->pm.s4 = virDomainPMStateTypeFromString(tmp);
+ VIR_FREE(tmp);
+ }
+ }
+
tmp = virXPathString("string(./clock/@offset)", ctxt);
if (tmp) {
if ((def->clock.offset = virDomainClockOffsetTypeFromString(tmp)) < 0) {
@@ -13061,6 +13079,32 @@ virDomainDefFormatInternal(virDomainDefPtr def,
virDomainLifecycleCrashTypeToString) < 0)
goto cleanup;
+ if (def->pm.s3 || def->pm.s4) {
+ virBufferAddLit(buf, " <pm");
+
+ if (def->pm.s3) {
+ const char *tmp = virDomainPMStateTypeToString(def->pm.s3);
+ if (!tmp) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected PM state %d"), def->pm.s3);
+ goto cleanup;
+ }
+ virBufferAsprintf(buf, " s3='%s'", tmp);
+ }
+
+ if (def->pm.s4) {
+ const char *tmp = virDomainPMStateTypeToString(def->pm.s4);
+ if (!tmp) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected PM state %d"), def->pm.s4);
+ goto cleanup;
+ }
+ virBufferAsprintf(buf, " s4='%s'", tmp);
+ }
+
+ virBufferAddLit(buf, "/>\n");
+ }
+
virBufferAddLit(buf, " <devices>\n");
virBufferEscapeString(buf, " <emulator>%s</emulator>\n",
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 9fdda78..3eddd5f 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1372,6 +1372,14 @@ enum virDomainLifecycleCrashAction {
VIR_DOMAIN_LIFECYCLE_CRASH_LAST
};
+enum virDomainPMState {
+ VIR_DOMAIN_PM_STATE_DEFAULT = 0,
+ VIR_DOMAIN_PM_STATE_ON,
+ VIR_DOMAIN_PM_STATE_OFF,
+
+ VIR_DOMAIN_PM_STATE_LAST,
+};
+
enum virDomainBIOSUseserial {
VIR_DOMAIN_BIOS_USESERIAL_DEFAULT = 0,
VIR_DOMAIN_BIOS_USESERIAL_YES,
@@ -1618,6 +1626,11 @@ struct _virDomainDef {
int onPoweroff;
int onCrash;
+ struct {
+ int s3;
+ int s4;
+ } pm;
+
virDomainOSDef os;
char *emulator;
int features;
@@ -2165,6 +2178,7 @@ VIR_ENUM_DECL(virDomainBoot)
VIR_ENUM_DECL(virDomainFeature)
VIR_ENUM_DECL(virDomainLifecycle)
VIR_ENUM_DECL(virDomainLifecycleCrash)
+VIR_ENUM_DECL(virDomainPMState)
VIR_ENUM_DECL(virDomainDevice)
VIR_ENUM_DECL(virDomainDeviceAddress)
VIR_ENUM_DECL(virDomainDeviceAddressPciMulti)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index bb8849b..98bcb98 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -431,6 +431,8 @@ virDomainPausedReasonTypeFromString;
virDomainPausedReasonTypeToString;
virDomainPciRombarModeTypeFromString;
virDomainPciRombarModeTypeToString;
+virDomainPMStateTypeFromString;
+virDomainPMStateTypeToString;
virDomainRedirdevBusTypeFromString;
virDomainRedirdevBusTypeToString;
virDomainRemoveInactive;
--
1.7.8.6