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); }