This API allows a domain to be put into one of S# ACPI states.
Currently, S3 and S4 are supported. These states are shared
with virNodeSuspendForDuration.
However, for now we don't support any duration other than zero.
The same apply for flags.
---
include/libvirt/libvirt.h.in | 5 +++-
src/driver.h | 6 ++++
src/libvirt.c | 58 ++++++++++++++++++++++++++++++++++++++++++
src/libvirt_public.syms | 1 +
src/remote/remote_driver.c | 1 +
src/remote/remote_protocol.x | 11 +++++++-
src/remote_protocol-structs | 7 +++++
7 files changed, 87 insertions(+), 2 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index e99cd00..0117333 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1232,7 +1232,10 @@ int virDomainFree (virDomainPtr
domain);
*/
int virDomainSuspend (virDomainPtr domain);
int virDomainResume (virDomainPtr domain);
-
+int virDomainSuspendForDuration (virDomainPtr domain,
+ unsigned int target,
+ unsigned long long duration,
+ unsigned int flags);
/*
* Domain save/restore
*/
diff --git a/src/driver.h b/src/driver.h
index df2aa60..a39b228 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -120,6 +120,11 @@ typedef int
typedef int
(*virDrvDomainResume) (virDomainPtr domain);
typedef int
+ (*virDrvDomainSuspendForDuration) (virDomainPtr,
+ unsigned int target,
+ unsigned long long duration,
+ unsigned int flags);
+typedef int
(*virDrvDomainShutdown) (virDomainPtr domain);
typedef int
(*virDrvDomainReboot) (virDomainPtr domain,
@@ -831,6 +836,7 @@ struct _virDriver {
virDrvDomainLookupByUUID domainLookupByUUID;
virDrvDomainLookupByName domainLookupByName;
virDrvDomainSuspend domainSuspend;
+ virDrvDomainSuspendForDuration domainSuspendForDuration;
virDrvDomainResume domainResume;
virDrvDomainShutdown domainShutdown;
virDrvDomainShutdownFlags domainShutdownFlags;
diff --git a/src/libvirt.c b/src/libvirt.c
index e9d638b..886776f 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -2433,6 +2433,64 @@ error:
}
/**
+ * virDomainSuspendForDuration:
+ * @dom: a domain object
+ * @target: an OR'ed set of virNodeSuspendTarget
+ * @duration: currently unused, pass 0
+ * @flags: ditto
+ *
+ * Attempt to suspend given domain. However, more
+ * states are supported than in virDomainSuspend.
+ *
+ * Dependent on hypervisor used, this may require
+ * guest agent to be available, e.g. QEMU.
+ *
+ * Returns: 0 on success,
+ * -1 on failure.
+ */
+int
+virDomainSuspendForDuration(virDomainPtr dom,
+ unsigned int target,
+ unsigned long long duration,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(dom, "target=%u duration=%llu flags=%x",
+ target, duration, flags);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
+ virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ virDispatchError(NULL);
+ return -1;
+ }
+
+ if (dom->conn->flags & VIR_CONNECT_RO) {
+ virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ conn = dom->conn;
+
+ if (conn->driver->domainSuspendForDuration) {
+ int ret;
+ ret = conn->driver->domainSuspendForDuration(dom, target,
+ duration, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ virDispatchError(conn);
+ return -1;
+}
+
+/**
* virDomainSave:
* @domain: a domain object
* @to: path for the output file
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 1340b0c..ef17ffc 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -520,6 +520,7 @@ LIBVIRT_0.9.10 {
global:
virDomainShutdownFlags;
virStorageVolWipePattern;
+ virDomainSuspendForDuration;
} LIBVIRT_0.9.9;
# .... define new API here using predicted next version number ....
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index f79f53e..fca4319 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -4616,6 +4616,7 @@ static virDriver remote_driver = {
.domainLookupByName = remoteDomainLookupByName, /* 0.3.0 */
.domainSuspend = remoteDomainSuspend, /* 0.3.0 */
.domainResume = remoteDomainResume, /* 0.3.0 */
+ .domainSuspendForDuration = remoteDomainSuspendForDuration, /* 0.9.10 */
.domainShutdown = remoteDomainShutdown, /* 0.3.0 */
.domainShutdownFlags = remoteDomainShutdownFlags, /* 0.9.10 */
.domainReboot = remoteDomainReboot, /* 0.3.0 */
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 0f354bb..c0d0979 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -732,6 +732,13 @@ struct remote_domain_suspend_args {
remote_nonnull_domain dom;
};
+struct remote_domain_suspend_for_duration_args {
+ remote_nonnull_domain dom;
+ unsigned int target;
+ unsigned hyper duration;
+ unsigned int flags;
+};
+
struct remote_domain_resume_args {
remote_nonnull_domain dom;
};
@@ -2667,7 +2674,9 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_SET_INTERFACE_PARAMETERS = 256, /* autogen autogen */
REMOTE_PROC_DOMAIN_GET_INTERFACE_PARAMETERS = 257, /* skipgen skipgen */
REMOTE_PROC_DOMAIN_SHUTDOWN_FLAGS = 258, /* autogen autogen */
- REMOTE_PROC_STORAGE_VOL_WIPE_PATTERN = 259 /* autogen autogen */
+ REMOTE_PROC_STORAGE_VOL_WIPE_PATTERN = 259, /* autogen autogen */
+
+ REMOTE_PROC_DOMAIN_SUSPEND_FOR_DURATION = 260 /* autogen autogen */
/*
* Notice how the entries are grouped in sets of 10 ?
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index de85862..e70dfd0 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -440,6 +440,12 @@ struct remote_domain_lookup_by_name_ret {
struct remote_domain_suspend_args {
remote_nonnull_domain dom;
};
+struct remote_domain_suspend_for_duration_args {
+ remote_nonnull_domain dom;
+ u_int target;
+ uint64_t duration;
+ u_int flags;
+};
struct remote_domain_resume_args {
remote_nonnull_domain dom;
};
@@ -2101,4 +2107,5 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_GET_INTERFACE_PARAMETERS = 257,
REMOTE_PROC_DOMAIN_SHUTDOWN_FLAGS = 258,
REMOTE_PROC_STORAGE_VOL_WIPE_PATTERN = 259,
+ REMOTE_PROC_DOMAIN_SUSPEND_FOR_DURATION = 260,
};
--
1.7.3.4