[libvirt] [PATCH RESEND v5] 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 "<power_management>" is introduced in the XML under the <host> tag. Eg: When the host supports both S3 and S4, the XML looks like this: <capabilities> <host> <uuid>dc699581-48a2-11cb-b8a8-9a0265a79bbe</uuid> <cpu> <arch>i686</arch> <model>coreduo</model> <vendor>Intel</vendor> <topology sockets='1' cores='2' threads='1'/> <feature name='xtpr'/> <feature name='tm2'/> <feature name='est'/> <feature name='vmx'/> <feature name='pbe'/> <feature name='tm'/> <feature name='ht'/> <feature name='ss'/> <feature name='acpi'/> <feature name='ds'/> </cpu> <power_management> <<<=== New host power management features <S3/> <S4/> </power_management> <migration_features> <live/> <uri_transports> <uri_transport>tcp</uri_transport> </uri_transports> </migration_features> </host> . . . 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 <power_management/> 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. This was discussed in [1] and [2]. Changelog: --------- This version v5: Some redundant error messages were removed and the code was streamlined. v4: http://www.redhat.com/archives/libvir-list/2011-August/msg00316.html v3: http://www.redhat.com/archives/libvir-list/2011-August/msg00282.html v2: http://www.redhat.com/archives/libvir-list/2011-August/msg00238.html v1: http://thread.gmane.org/gmane.comp.emulators.libvirt/40886 References: ---------- [1] http://www.redhat.com/archives/libvir-list/2011-August/msg00248.html [2] http://www.redhat.com/archives/libvir-list/2011-August/msg00302.html Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> --- docs/formatcaps.html.in | 19 ++++++++++++---- docs/schemas/capability.rng | 18 +++++++++++++++ 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 | 7 ++++++ src/util/util.c | 51 ++++++++++++++++++++++++++++++++++++++++++ src/util/util.h | 14 ++++++++++++ src/util/virterror.c | 3 ++ 11 files changed, 141 insertions(+), 6 deletions(-) diff --git a/docs/formatcaps.html.in b/docs/formatcaps.html.in index a4297ce..ce6f9a6 100644 --- a/docs/formatcaps.html.in +++ b/docs/formatcaps.html.in @@ -28,6 +28,10 @@ BIOS you will see</p> <feature name='xtpr'/> ... </cpu> + <power_management> + <S3/> + <S4/> + <power_management/> </host></span> <!-- xen-3.0-x86_64 --> @@ -61,11 +65,16 @@ BIOS you will see</p> ... </capabilities></pre> <p>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).</p> +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).</p> <p>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.</p> diff --git a/docs/schemas/capability.rng b/docs/schemas/capability.rng index 0a63a1c..eac1d02 100644 --- a/docs/schemas/capability.rng +++ b/docs/schemas/capability.rng @@ -35,6 +35,9 @@ </optional> </element> <optional> + <ref name='power_management'/> + </optional> + <optional> <ref name='migration'/> </optional> <optional> @@ -105,6 +108,21 @@ </zeroOrMore> </define> + <define name='power_management'> + <element name='power_management'> + <optional> + <element name='S3'> + <empty/> + </element> + </optional> + <optional> + <element name='S4'> + <empty/> + </element> + </optional> + </element> + </define> + <define name='migration'> <element name='migration_features'> <optional> diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index a8549b7..7063ef6 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 c74b0ea..23487e3 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -493,6 +493,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 40e2976..87b60b0 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, " </cpu>\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, " <power_management>\n"); + while (pm) { + int bit = ffs(pm) - 1; + virBufferAsprintf(&xml, " <%s/>\n", + virHostPMCapabilityTypeToString(bit)); + pm &= ~(1U << bit); + } + virBufferAddLit(&xml, " </power_management>\n"); + } else { + /* The host does not support any PM feature. */ + virBufferAddLit(&xml, " <power_management/>\n"); + } + } + if (caps->host.offlineMigrate) { virBufferAddLit(&xml, " <migration_features>\n"); if (caps->host.liveMigrate) diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h index dd4a827..148c7cc 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 6a1562e..4d366d4 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1128,6 +1128,7 @@ virFormatMacAddr; virGenerateMacAddr; virGetGroupID; virGetHostname; +virGetPMCapabilities; virGetUserDirectory; virGetUserID; virGetUserName; diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 26a7f11..e1cc760 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -848,6 +848,13 @@ 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"); + 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 959c224..6f0f84a 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -2607,3 +2607,54 @@ or other application using the libvirt API.\n\ return 0; } + +/** + * 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 d8176a8..b1c4847 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -258,4 +258,18 @@ bool virIsDevMapperDevice(const char *dev_name) ATTRIBUTE_NONNULL(1); int virEmitXMLWarning(int fd, const char *name, const char *cmd) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); + +/* 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 5006fa2..44a276a 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); }

On 11/09/2011 04:38 PM, Srivatsa S. Bhat wrote:
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 "<power_management>" is introduced in the XML under the <host> tag.
Eg: When the host supports both S3 and S4, the XML looks like this:
<capabilities>
<host> <uuid>dc699581-48a2-11cb-b8a8-9a0265a79bbe</uuid> <cpu> <arch>i686</arch> <model>coreduo</model> <vendor>Intel</vendor> <topology sockets='1' cores='2' threads='1'/> <feature name='xtpr'/> <feature name='tm2'/> <feature name='est'/> <feature name='vmx'/> <feature name='pbe'/> <feature name='tm'/> <feature name='ht'/> <feature name='ss'/> <feature name='acpi'/> <feature name='ds'/> </cpu> <power_management> <<<=== New host power management features <S3/> <S4/> </power_management> <migration_features> <live/> <uri_transports> <uri_transport>tcp</uri_transport> </uri_transports> </migration_features> </host> . . .
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 <power_management/> 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. This was discussed in [1] and [2].
Changelog: --------- This version v5: Some redundant error messages were removed and the code was streamlined.
v4: http://www.redhat.com/archives/libvir-list/2011-August/msg00316.html v3: http://www.redhat.com/archives/libvir-list/2011-August/msg00282.html v2: http://www.redhat.com/archives/libvir-list/2011-August/msg00238.html v1: http://thread.gmane.org/gmane.comp.emulators.libvirt/40886
References: ---------- [1] http://www.redhat.com/archives/libvir-list/2011-August/msg00248.html [2] http://www.redhat.com/archives/libvir-list/2011-August/msg00302.html
Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Any suggestions/comments on this patch? As suggested in one of the earlier versions, I have posted the follow-on patchset to add libvirt APIs to invoke suspend/resume in-band, here: http://www.redhat.com/archives/libvir-list/2011-November/msg00381.html Thanks, Srivatsa S. Bhat
---
docs/formatcaps.html.in | 19 ++++++++++++---- docs/schemas/capability.rng | 18 +++++++++++++++ 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 | 7 ++++++ src/util/util.c | 51 ++++++++++++++++++++++++++++++++++++++++++ src/util/util.h | 14 ++++++++++++ src/util/virterror.c | 3 ++ 11 files changed, 141 insertions(+), 6 deletions(-)
diff --git a/docs/formatcaps.html.in b/docs/formatcaps.html.in index a4297ce..ce6f9a6 100644 --- a/docs/formatcaps.html.in +++ b/docs/formatcaps.html.in @@ -28,6 +28,10 @@ BIOS you will see</p> <feature name='xtpr'/> ... </cpu> + <power_management> + <S3/> + <S4/> + <power_management/> </host></span>
<!-- xen-3.0-x86_64 --> @@ -61,11 +65,16 @@ BIOS you will see</p> ... </capabilities></pre> <p>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).</p> +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).</p> <p>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.</p> diff --git a/docs/schemas/capability.rng b/docs/schemas/capability.rng index 0a63a1c..eac1d02 100644 --- a/docs/schemas/capability.rng +++ b/docs/schemas/capability.rng @@ -35,6 +35,9 @@ </optional> </element> <optional> + <ref name='power_management'/> + </optional> + <optional> <ref name='migration'/> </optional> <optional> @@ -105,6 +108,21 @@ </zeroOrMore> </define>
+ <define name='power_management'> + <element name='power_management'> + <optional> + <element name='S3'> + <empty/> + </element> + </optional> + <optional> + <element name='S4'> + <empty/> + </element> + </optional> + </element> + </define> + <define name='migration'> <element name='migration_features'> <optional> diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index a8549b7..7063ef6 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 c74b0ea..23487e3 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -493,6 +493,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 40e2976..87b60b0 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, " </cpu>\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, " <power_management>\n"); + while (pm) { + int bit = ffs(pm) - 1; + virBufferAsprintf(&xml, " <%s/>\n", + virHostPMCapabilityTypeToString(bit)); + pm &= ~(1U << bit); + } + virBufferAddLit(&xml, " </power_management>\n"); + } else { + /* The host does not support any PM feature. */ + virBufferAddLit(&xml, " <power_management/>\n"); + } + } + if (caps->host.offlineMigrate) { virBufferAddLit(&xml, " <migration_features>\n"); if (caps->host.liveMigrate) diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h index dd4a827..148c7cc 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 6a1562e..4d366d4 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1128,6 +1128,7 @@ virFormatMacAddr; virGenerateMacAddr; virGetGroupID; virGetHostname; +virGetPMCapabilities; virGetUserDirectory; virGetUserID; virGetUserName; diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 26a7f11..e1cc760 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -848,6 +848,13 @@ 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"); + 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 959c224..6f0f84a 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -2607,3 +2607,54 @@ or other application using the libvirt API.\n\
return 0; } + +/** + * 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 d8176a8..b1c4847 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -258,4 +258,18 @@ bool virIsDevMapperDevice(const char *dev_name) ATTRIBUTE_NONNULL(1); int virEmitXMLWarning(int fd, const char *name, const char *cmd) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); + +/* 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 5006fa2..44a276a 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); }

On 11/13/2011 10:29 PM, Srivatsa S. Bhat wrote:
On 11/09/2011 04:38 PM, Srivatsa S. Bhat wrote:
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.
Changelog: --------- This version v5: Some redundant error messages were removed and the code was streamlined.
v4: http://www.redhat.com/archives/libvir-list/2011-August/msg00316.html v3: http://www.redhat.com/archives/libvir-list/2011-August/msg00282.html v2: http://www.redhat.com/archives/libvir-list/2011-August/msg00238.html v1: http://thread.gmane.org/gmane.comp.emulators.libvirt/40886
References: ---------- [1] http://www.redhat.com/archives/libvir-list/2011-August/msg00248.html [2] http://www.redhat.com/archives/libvir-list/2011-August/msg00302.html
Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Any suggestions/comments on this patch? As suggested in one of the earlier versions, I have posted the follow-on patchset to add libvirt APIs to invoke suspend/resume in-band, here: http://www.redhat.com/archives/libvir-list/2011-November/msg00381.html
Apologies for the delays, but I'm finally getting around to reviewing this series, along with the v3 series to expose an API to control power management on the host. I promise to either apply both series as a unit in time for 0.9.8, or give further feedback on how to improve them in the next revision, but I think we're converging on a useful design to make it worth exposing this information. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 11/22/2011 05:53 AM, Eric Blake wrote:
On 11/13/2011 10:29 PM, Srivatsa S. Bhat wrote:
On 11/09/2011 04:38 PM, Srivatsa S. Bhat wrote:
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.
Changelog: --------- This version v5: Some redundant error messages were removed and the code was streamlined.
v4: http://www.redhat.com/archives/libvir-list/2011-August/msg00316.html v3: http://www.redhat.com/archives/libvir-list/2011-August/msg00282.html v2: http://www.redhat.com/archives/libvir-list/2011-August/msg00238.html v1: http://thread.gmane.org/gmane.comp.emulators.libvirt/40886
References: ---------- [1] http://www.redhat.com/archives/libvir-list/2011-August/msg00248.html [2] http://www.redhat.com/archives/libvir-list/2011-August/msg00302.html
Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Any suggestions/comments on this patch? As suggested in one of the earlier versions, I have posted the follow-on patchset to add libvirt APIs to invoke suspend/resume in-band, here: http://www.redhat.com/archives/libvir-list/2011-November/msg00381.html
Apologies for the delays, but I'm finally getting around to reviewing this series, along with the v3 series to expose an API to control power management on the host. I promise to either apply both series as a unit in time for 0.9.8, or give further feedback on how to improve them in the next revision, but I think we're converging on a useful design to make it worth exposing this information.
Hi Eric, Thanks a lot for your time and for reviving this thread with your reviews and also for your reviews in the previous iterations of this patch! Regards, Srivatsa S. Bhat IBM Linux Technology Center

On Wed, Nov 09, 2011 at 04:38:02PM +0530, Srivatsa S. Bhat wrote:
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 "<power_management>" is introduced in the XML under the <host> tag.
Eg: When the host supports both S3 and S4, the XML looks like this:
<capabilities>
<host> <uuid>dc699581-48a2-11cb-b8a8-9a0265a79bbe</uuid> <cpu> <arch>i686</arch> <model>coreduo</model> <vendor>Intel</vendor> <topology sockets='1' cores='2' threads='1'/> <feature name='xtpr'/> <feature name='tm2'/> <feature name='est'/> <feature name='vmx'/> <feature name='pbe'/> <feature name='tm'/> <feature name='ht'/> <feature name='ss'/> <feature name='acpi'/> <feature name='ds'/> </cpu> <power_management> <<<=== New host power management features <S3/> <S4/> </power_management> <migration_features> <live/> <uri_transports> <uri_transport>tcp</uri_transport> </uri_transports> </migration_features> </host> . . .
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 <power_management/> 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. This was discussed in [1] and [2].
Changelog: --------- This version v5: Some redundant error messages were removed and the code was streamlined.
v4: http://www.redhat.com/archives/libvir-list/2011-August/msg00316.html v3: http://www.redhat.com/archives/libvir-list/2011-August/msg00282.html v2: http://www.redhat.com/archives/libvir-list/2011-August/msg00238.html v1: http://thread.gmane.org/gmane.comp.emulators.libvirt/40886
References: ---------- [1] http://www.redhat.com/archives/libvir-list/2011-August/msg00248.html [2] http://www.redhat.com/archives/libvir-list/2011-August/msg00302.html
Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> [...] index 0a63a1c..eac1d02 100644 --- a/docs/schemas/capability.rng +++ b/docs/schemas/capability.rng @@ -35,6 +35,9 @@ </optional> </element> <optional> + <ref name='power_management'/> + </optional> + <optional> <ref name='migration'/> </optional> <optional> @@ -105,6 +108,21 @@ </zeroOrMore> </define>
+ <define name='power_management'> + <element name='power_management'>
Seems to me you don't care about S3 and S4 order so <interleave>
+ <optional> + <element name='S3'> + <empty/> + </element> + </optional> + <optional> + <element name='S4'> + <empty/> + </element> + </optional>
</interleave> should be added, but that's minor.
+ </element> + </define> + [...] diff --git a/libvirt.spec.in b/libvirt.spec.in index c74b0ea..23487e3 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -493,6 +493,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
Okay that seems present even on RHEL-5
%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 40e2976..87b60b0 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, " </cpu>\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, " <power_management>\n"); + while (pm) { + int bit = ffs(pm) - 1; + virBufferAsprintf(&xml, " <%s/>\n", + virHostPMCapabilityTypeToString(bit)); + pm &= ~(1U << bit); + } + virBufferAddLit(&xml, " </power_management>\n"); + } else { + /* The host does not support any PM feature. */ + virBufferAddLit(&xml, " <power_management/>\n"); + } + } + if (caps->host.offlineMigrate) { virBufferAddLit(&xml, " <migration_features>\n"); if (caps->host.liveMigrate) diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h index dd4a827..148c7cc 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 6a1562e..4d366d4 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1128,6 +1128,7 @@ virFormatMacAddr; virGenerateMacAddr; virGetGroupID; virGetHostname; +virGetPMCapabilities; virGetUserDirectory; virGetUserID; virGetUserName; diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 26a7f11..e1cc760 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -848,6 +848,13 @@ 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"); + else + caps->host.powerMgmt_valid = true; /* The PM query succeeded. */ + virCapabilitiesAddHostMigrateTransport(caps, "tcp");
I would probably explicitely set caps->host.powerMgmt_valid to false if that failed instead of relying on "false" being 0 ...
diff --git a/src/util/util.c b/src/util/util.c index 959c224..6f0f84a 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -2607,3 +2607,54 @@ or other application using the libvirt API.\n\
return 0; } + +/** + * 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 d8176a8..b1c4847 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -258,4 +258,18 @@ bool virIsDevMapperDevice(const char *dev_name) ATTRIBUTE_NONNULL(1); int virEmitXMLWarning(int fd, const char *name, const char *cmd) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); + +/* 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 5006fa2..44a276a 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); }
ACK, I made the couple of modifications above, cleaned up "make syntax-check" and fixed a small issue in applying the patch to util.h, then commited it, thanks a lot ! Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On 11/22/2011 08:59 AM, Daniel Veillard wrote:
On Wed, Nov 09, 2011 at 04:38:02PM +0530, Srivatsa S. Bhat wrote:
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 "<power_management>" is introduced in the XML under the <host> tag.
Eg: When the host supports both S3 and S4, the XML looks like this:
[...]
ACK, I made the couple of modifications above, cleaned up "make syntax-check" and fixed a small issue in applying the patch to util.h, then commited it,
thanks a lot !
Hi Daniel, Thank you for your review, ACK and for pushing the patch! Regards, Srivatsa S. Bhat IBM Linux Technology Center
participants (3)
-
Daniel Veillard
-
Eric Blake
-
Srivatsa S. Bhat