提交 b8216ec9 编写于 作者: M Martin Kletzander

qemu: Add support for S3/S4 state configuration

This patch adds support for running qemu guests with the required
parameters to forcefully enable or disable BIOS advertising of S3 and
S4 states.  The support for this is added to capabilities and there is
also a qemu command parameter parsing implemented.
上级 09cd8f2d
...@@ -173,7 +173,9 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST, ...@@ -173,7 +173,9 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
"lsi", "lsi",
"virtio-scsi-pci", "virtio-scsi-pci",
"iolimits", "iolimits",
"disable-s3",
"disable-s4", /* 105 */
); );
struct qemu_feature_flags { struct qemu_feature_flags {
...@@ -1404,6 +1406,7 @@ qemuCapsExtractDeviceStr(const char *qemu, ...@@ -1404,6 +1406,7 @@ qemuCapsExtractDeviceStr(const char *qemu,
"-device", "virtio-blk-pci,?", "-device", "virtio-blk-pci,?",
"-device", "virtio-net-pci,?", "-device", "virtio-net-pci,?",
"-device", "scsi-disk,?", "-device", "scsi-disk,?",
"-device", "PIIX4_PM,?",
NULL); NULL);
/* qemu -help goes to stdout, but qemu -device ? goes to stderr. */ /* qemu -help goes to stdout, but qemu -device ? goes to stderr. */
virCommandSetErrorBuffer(cmd, &output); virCommandSetErrorBuffer(cmd, &output);
...@@ -1510,6 +1513,10 @@ qemuCapsParseDeviceStr(const char *str, virBitmapPtr flags) ...@@ -1510,6 +1513,10 @@ qemuCapsParseDeviceStr(const char *str, virBitmapPtr flags)
if (strstr(str, ".logical_block_size") && if (strstr(str, ".logical_block_size") &&
strstr(str, ".physical_block_size")) strstr(str, ".physical_block_size"))
qemuCapsSet(flags, QEMU_CAPS_IOLIMITS); qemuCapsSet(flags, QEMU_CAPS_IOLIMITS);
if (strstr(str, "PIIX4_PM.disable_s3="))
qemuCapsSet(flags, QEMU_CAPS_DISABLE_S3);
if (strstr(str, "PIIX4_PM.disable_s4="))
qemuCapsSet(flags, QEMU_CAPS_DISABLE_S4);
return 0; return 0;
} }
......
...@@ -139,6 +139,8 @@ enum qemuCapsFlags { ...@@ -139,6 +139,8 @@ enum qemuCapsFlags {
QEMU_CAPS_SCSI_LSI = 101, /* -device lsi */ QEMU_CAPS_SCSI_LSI = 101, /* -device lsi */
QEMU_CAPS_VIRTIO_SCSI_PCI = 102, /* -device virtio-scsi-pci */ QEMU_CAPS_VIRTIO_SCSI_PCI = 102, /* -device virtio-scsi-pci */
QEMU_CAPS_IOLIMITS = 103, /* -device ...logical_block_size & co */ QEMU_CAPS_IOLIMITS = 103, /* -device ...logical_block_size & co */
QEMU_CAPS_DISABLE_S3 = 104, /* S3 BIOS Advertisement on/off */
QEMU_CAPS_DISABLE_S4 = 105, /* S4 BIOS Advertisement on/off */
QEMU_CAPS_LAST, /* this must always be the last item */ QEMU_CAPS_LAST, /* this must always be the last item */
}; };
......
...@@ -4790,6 +4790,28 @@ qemuBuildCommandLine(virConnectPtr conn, ...@@ -4790,6 +4790,28 @@ qemuBuildCommandLine(virConnectPtr conn,
virCommandAddArg(cmd, "-no-acpi"); virCommandAddArg(cmd, "-no-acpi");
} }
if (def->pm.s3) {
if (!qemuCapsGet(qemuCaps, QEMU_CAPS_DISABLE_S3)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
"%s", _("setting ACPI S3 not supported"));
goto error;
}
virCommandAddArg(cmd, "-global");
virCommandAddArgFormat(cmd, "PIIX4_PM.disable_s3=%d",
def->pm.s3 == VIR_DOMAIN_PM_STATE_DISABLED);
}
if (def->pm.s4) {
if (!qemuCapsGet(qemuCaps, QEMU_CAPS_DISABLE_S4)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
"%s", _("setting ACPI S4 not supported"));
goto error;
}
virCommandAddArg(cmd, "-global");
virCommandAddArgFormat(cmd, "PIIX4_PM.disable_s4=%d",
def->pm.s4 == VIR_DOMAIN_PM_STATE_DISABLED);
}
if (!def->os.bootloader) { if (!def->os.bootloader) {
/* /*
* We prefer using explicit bootindex=N parameters for predictable * We prefer using explicit bootindex=N parameters for predictable
...@@ -8376,6 +8398,42 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps, ...@@ -8376,6 +8398,42 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
*monConfig = chr; *monConfig = chr;
} }
} else if (STREQ(arg, "-global") &&
STRPREFIX(progargv[i + 1], "PIIX4_PM.disable_s3=")) {
/* We want to parse only the known "-global" parameters,
* so the ones that we don't know are still added to the
* namespace */
WANT_VALUE();
val += strlen("PIIX4_PM.disable_s3=");
if (STREQ(val, "0"))
def->pm.s3 = VIR_DOMAIN_PM_STATE_ENABLED;
else if (STREQ(val, "1"))
def->pm.s3 = VIR_DOMAIN_PM_STATE_DISABLED;
else {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("invalid value for disable_s3 parameter: "
"'%s'"), val);
goto error;
}
} else if (STREQ(arg, "-global") &&
STRPREFIX(progargv[i + 1], "PIIX4_PM.disable_s4=")) {
WANT_VALUE();
val += strlen("PIIX4_PM.disable_s4=");
if (STREQ(val, "0"))
def->pm.s4 = VIR_DOMAIN_PM_STATE_ENABLED;
else if (STREQ(val, "1"))
def->pm.s4 = VIR_DOMAIN_PM_STATE_DISABLED;
else {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("invalid value for disable_s4 parameter: "
"'%s'"), val);
goto error;
}
} else if (STREQ(arg, "-S")) { } else if (STREQ(arg, "-S")) {
/* ignore, always added by libvirt */ /* ignore, always added by libvirt */
} else { } else {
......
...@@ -13722,6 +13722,23 @@ qemuDomainPMSuspendForDuration(virDomainPtr dom, ...@@ -13722,6 +13722,23 @@ qemuDomainPMSuspendForDuration(virDomainPtr dom,
goto cleanup; goto cleanup;
} }
if (vm->def->pm.s3 || vm->def->pm.s4) {
if (vm->def->pm.s3 == VIR_DOMAIN_PM_STATE_DISABLED &&
(target == VIR_NODE_SUSPEND_TARGET_MEM ||
target == VIR_NODE_SUSPEND_TARGET_HYBRID)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("S3 state is disabled for this domain"));
goto cleanup;
}
if (vm->def->pm.s4 == VIR_DOMAIN_PM_STATE_DISABLED &&
target == VIR_NODE_SUSPEND_TARGET_DISK) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("S4 state is disabled for this domain"));
goto cleanup;
}
}
if (priv->agentError) { if (priv->agentError) {
virReportError(VIR_ERR_AGENT_UNRESPONSIVE, "%s", virReportError(VIR_ERR_AGENT_UNRESPONSIVE, "%s",
_("QEMU guest agent is not " _("QEMU guest agent is not "
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册