From e352b1640090b06149b13fc8d49cf56f9c31caf8 Mon Sep 17 00:00:00 2001 From: "Srivatsa S. Bhat" Date: Tue, 22 Nov 2011 11:31:22 +0800 Subject: [PATCH] Export KVM Host Power Management capabilities This patch exports KVM Host Power Management capabilities as XML so that higher-level systems management software can make use of these features available in the host. The script "pm-is-supported" (from pm-utils package) is run to discover if Suspend-to-RAM (S3) or Suspend-to-Disk (S4) is supported by the host. If either of them are supported, then a new tag "" is introduced in the XML under the tag. However in case the query to check for power management features succeeded, but the host does not support any such feature, then the XML will contain an empty tag. In the event that the PM query itself failed, the XML will not contain any "power_management" tag. To use this, new APIs could be implemented in libvirt to exploit power management features such as S3/S4. --- AUTHORS | 1 + docs/formatcaps.html.in | 19 ++++++++++---- docs/schemas/capability.rng | 20 +++++++++++++++ include/libvirt/virterror.h | 1 + libvirt.spec.in | 2 ++ src/conf/capabilities.c | 27 ++++++++++++++++++- src/conf/capabilities.h | 4 +++ src/libvirt_private.syms | 1 + src/qemu/qemu_capabilities.c | 8 ++++++ src/util/util.c | 50 ++++++++++++++++++++++++++++++++++++ src/util/util.h | 14 ++++++++++ src/util/virterror.c | 3 +++ 12 files changed, 144 insertions(+), 6 deletions(-) diff --git a/AUTHORS b/AUTHORS index 272a82869e..9d5f8b52f6 100644 --- a/AUTHORS +++ b/AUTHORS @@ -206,6 +206,7 @@ Patches have also been contributed by: Eli Qiao Michael Wood Bharata B Rao + Srivatsa S. Bhat [....send patches to get your name here....] diff --git a/docs/formatcaps.html.in b/docs/formatcaps.html.in index a4297cefa1..ce6f9a644a 100644 --- a/docs/formatcaps.html.in +++ b/docs/formatcaps.html.in @@ -28,6 +28,10 @@ BIOS you will see

<feature name='xtpr'/> ... </cpu> + <power_management> + <S3/> + <S4/> + <power_management/> </host> <!-- xen-3.0-x86_64 --> @@ -61,11 +65,16 @@ BIOS you will see

... </capabilities>

The first block (in red) indicates the host hardware capabilities, currently -it is limited to the CPU properties but other information may be available, -it shows the CPU architecture, topology, model name, and additional features -which are not included in the model but the CPU provides them. Features of the -chip are shown within the feature block (the block is similar to what you will -find in a Xen fully virtualized domain description).

+it is limited to the CPU properties and the power management features of +the host platform, but other information may be available, it shows the CPU architecture, +topology, model name, and additional features which are not included in the model but the +CPU provides them. Features of the chip are shown within the feature block (the block is +similar to what you will find in a Xen fully virtualized domain description). Further, +the power management features supported by the host are shown, such as Suspend-to-RAM (S3) +and Suspend-to-Disk (S4). In case the query for power management features succeeded but the +host does not support any such feature, then an empty <power_management/> +tag will be shown. Otherwise, if the query itself failed, no such tag will +be displayed (i.e., there will not be any power_management block or empty tag in the XML).

The second block (in blue) indicates the paravirtualization support of the Xen support, you will see the os_type of xen to indicate a paravirtual kernel, then architecture information and potential features.

diff --git a/docs/schemas/capability.rng b/docs/schemas/capability.rng index 0a63a1c6a1..645769e330 100644 --- a/docs/schemas/capability.rng +++ b/docs/schemas/capability.rng @@ -34,6 +34,9 @@ + + + @@ -105,6 +108,23 @@ + + + + + + + + + + + + + + + + + diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index a8549b784f..7063ef6a8e 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -84,6 +84,7 @@ typedef enum { VIR_FROM_LIBXL = 41, /* Error from libxenlight driver */ VIR_FROM_LOCKING = 42, /* Error from lock manager */ VIR_FROM_HYPERV = 43, /* Error from Hyper-V driver */ + VIR_FROM_CAPABILITIES = 44, /* Error from capabilities */ } virErrorDomain; diff --git a/libvirt.spec.in b/libvirt.spec.in index ce541a7cc8..f61a243acb 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -506,6 +506,8 @@ Requires: nc Requires: gettext # Needed by virt-pki-validate script. Requires: gnutls-utils +# Needed for probing the power management features of the host. +Requires: pm-utils %if %{with_sasl} Requires: cyrus-sasl # Not technically required, but makes 'out-of-box' config diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c index 40e297678a..87b60b0c3e 100644 --- a/src/conf/capabilities.c +++ b/src/conf/capabilities.c @@ -29,6 +29,13 @@ #include "util.h" #include "uuid.h" #include "cpu_conf.h" +#include "virterror_internal.h" + + +#define VIR_FROM_THIS VIR_FROM_CAPABILITIES + +VIR_ENUM_IMPL(virHostPMCapability, VIR_HOST_PM_LAST, + "S3", "S4") /** * virCapabilitiesNew: @@ -201,7 +208,6 @@ virCapabilitiesAddHostFeature(virCapsPtr caps, return 0; } - /** * virCapabilitiesAddHostMigrateTransport: * @caps: capabilities to extend @@ -687,6 +693,25 @@ virCapabilitiesFormatXML(virCapsPtr caps) virBufferAddLit(&xml, " \n"); + if (caps->host.powerMgmt_valid) { + /* The PM query was successful. */ + if (caps->host.powerMgmt) { + /* The host supports some PM features. */ + unsigned int pm = caps->host.powerMgmt; + virBufferAddLit(&xml, " \n"); + while (pm) { + int bit = ffs(pm) - 1; + virBufferAsprintf(&xml, " <%s/>\n", + virHostPMCapabilityTypeToString(bit)); + pm &= ~(1U << bit); + } + virBufferAddLit(&xml, " \n"); + } else { + /* The host does not support any PM feature. */ + virBufferAddLit(&xml, " \n"); + } + } + if (caps->host.offlineMigrate) { virBufferAddLit(&xml, " \n"); if (caps->host.liveMigrate) diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h index dd4a8279b3..148c7cc939 100644 --- a/src/conf/capabilities.h +++ b/src/conf/capabilities.h @@ -105,6 +105,10 @@ struct _virCapsHost { size_t nfeatures; size_t nfeatures_max; char **features; + bool powerMgmt_valid; + unsigned int powerMgmt; /* Bitmask of the PM capabilities. + * See enum virHostPMCapability. + */ int offlineMigrate; int liveMigrate; size_t nmigrateTrans; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index e5784f579c..2cf50d30b0 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1094,6 +1094,7 @@ virFormatMacAddr; virGenerateMacAddr; virGetGroupID; virGetHostname; +virGetPMCapabilities; virGetUserDirectory; virGetUserID; virGetUserName; diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 26a7f11a67..c5fe41d9a8 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -848,6 +848,14 @@ virCapsPtr qemuCapsInit(virCapsPtr old_caps) old_caps->host.cpu = NULL; } + /* Add the power management features of the host */ + + if (virGetPMCapabilities(&caps->host.powerMgmt) < 0) { + VIR_WARN("Failed to get host power management capabilities"); + caps->host.powerMgmt_valid = false; + } else + caps->host.powerMgmt_valid = true; /* The PM query succeeded. */ + virCapabilitiesAddHostMigrateTransport(caps, "tcp"); diff --git a/src/util/util.c b/src/util/util.c index 9ecfa9dee8..ce697fb7b4 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -2621,3 +2621,53 @@ virTypedParameterArrayClear(virTypedParameterPtr params, int nparams) VIR_FREE(params[i].value.s); } } + +/** + * Get the Power Management Capabilities of the host system. + * The script 'pm-is-supported' (from the pm-utils package) is run + * to find out all the power management features supported by the host, + * such as Suspend-to-RAM (S3) and Suspend-to-Disk (S4). + * + * @bitmask: Pointer to the bitmask which will be set appropriately to + * indicate all the supported host power management features. + * + * Returns 0 if the query was successful, -1 upon failure. + */ +int +virGetPMCapabilities(unsigned int *bitmask) +{ + int ret = -1; + int status; + virCommandPtr cmd; + + *bitmask = 0; + + /* Check support for Suspend-to-RAM (S3) */ + cmd = virCommandNewArgList("pm-is-supported", "--suspend", NULL); + if (virCommandRun(cmd, &status) < 0) + goto cleanup; + + /* Check return code of command == 0 for success + * (i.e., the PM capability is supported) + */ + if (status == 0) + *bitmask |= 1U << VIR_HOST_PM_S3; + virCommandFree(cmd); + + /* Check support for Suspend-to-Disk (S4) */ + cmd = virCommandNewArgList("pm-is-supported", "--hibernate", NULL); + if (virCommandRun(cmd, &status) < 0) + goto cleanup; + + /* Check return code of command == 0 for success + * (i.e., the PM capability is supported) + */ + if (status == 0) + *bitmask |= 1U << VIR_HOST_PM_S4; + + ret = 0; + +cleanup: + virCommandFree(cmd); + return ret; +} diff --git a/src/util/util.h b/src/util/util.h index 3295ce8b55..5afcf58dcc 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -260,4 +260,18 @@ int virEmitXMLWarning(int fd, const char *cmd) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); void virTypedParameterArrayClear(virTypedParameterPtr params, int nparams); + +/* Power Management Capabilities of the host system */ + +enum virHostPMCapability { + VIR_HOST_PM_S3, /* Suspend-to-RAM */ + VIR_HOST_PM_S4, /* Suspend-to-Disk */ + + VIR_HOST_PM_LAST +}; + +VIR_ENUM_DECL(virHostPMCapability) + +int virGetPMCapabilities(unsigned int *); + #endif /* __VIR_UTIL_H__ */ diff --git a/src/util/virterror.c b/src/util/virterror.c index 5006fa27ed..44a276a9db 100644 --- a/src/util/virterror.c +++ b/src/util/virterror.c @@ -175,6 +175,9 @@ static const char *virErrorDomainName(virErrorDomain domain) { case VIR_FROM_HYPERV: dom = "Hyper-V "; break; + case VIR_FROM_CAPABILITIES: + dom = "Capabilities "; + break; } return(dom); } -- 2.39.5