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@xxxxxxxxxxxxxxxxxx> 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); > } > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list