These APIs allow users to get or set time in a domain, which may come
handy if the domain has been resumed just recently and NTP is not
configured or hasn't kicked in yet and the guest is running
something time critical. In addition, NTP may refuse to re-set the clock
if the skew is too big.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
include/libvirt/libvirt.h.in | 24 +++++++++++
src/driver.h | 14 +++++++
src/libvirt.c | 96 ++++++++++++++++++++++++++++++++++++++++++++
src/libvirt_public.syms | 6 +++
4 files changed, 140 insertions(+)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 930b7e8..93393fd 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -5278,6 +5278,30 @@ int virDomainFSTrim(virDomainPtr dom,
unsigned int flags);
/**
+ * VIR_DOMAIN_TIME_SECONDS:
+ *
+ * Macro for the virDomainGetTime and virDomainSetTime. It
+ * represents the time in guest in form of the number of seconds
+ * since the UNIX Epoch of 1970-01-01 UTC. The corresponding type
+ * is long long.
+ */
+#define VIR_DOMAIN_TIME_SECONDS "time_seconds"
+
+int virDomainGetTime(virDomainPtr dom,
+ virTypedParameterPtr *params,
+ int *nparams,
+ unsigned int flags);
+
+typedef enum {
+ VIR_DOMAIN_TIME_SYNC = (1 << 0), /* Re-sync domain time from domain's RTC
*/
+} virDomainSetTimeFlags;
+
+int virDomainSetTime(virDomainPtr dom,
+ virTypedParameterPtr params,
+ int nparams,
+ unsigned int flags);
+
+/**
* virSchedParameterType:
*
* A scheduler parameter field type. Provided for backwards
diff --git a/src/driver.h b/src/driver.h
index e66fc7a..bde98c9 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -1084,6 +1084,18 @@ typedef int
unsigned int flags);
typedef int
+(*virDrvDomainGetTime)(virDomainPtr dom,
+ virTypedParameterPtr *params,
+ int *nparams,
+ unsigned int flags);
+
+typedef int
+(*virDrvDomainSetTime)(virDomainPtr dom,
+ virTypedParameterPtr params,
+ int nparams,
+ unsigned int flags);
+
+typedef int
(*virDrvDomainLxcOpenNamespace)(virDomainPtr dom,
int **fdlist,
unsigned int flags);
@@ -1354,6 +1366,8 @@ struct _virDriver {
virDrvNodeSetMemoryParameters nodeSetMemoryParameters;
virDrvNodeGetCPUMap nodeGetCPUMap;
virDrvDomainFSTrim domainFSTrim;
+ virDrvDomainGetTime domainGetTime;
+ virDrvDomainSetTime domainSetTime;
virDrvDomainSendProcessSignal domainSendProcessSignal;
virDrvDomainLxcOpenNamespace domainLxcOpenNamespace;
virDrvDomainMigrateBegin3Params domainMigrateBegin3Params;
diff --git a/src/libvirt.c b/src/libvirt.c
index 4454829..3befd2d 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -20658,3 +20658,99 @@ virDomainFSTrim(virDomainPtr dom,
virDispatchError(dom->conn);
return -1;
}
+
+/**
+ * virDomainGetTime:
+ * @dom: a domain object
+ * @params: where to store time
+ * @nparams: numnber of items in @params
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Extract information about guest time and store it into
+ * @params. The return value is a superset of virDomainTimeType
+ * items.
+ *
+ * Please note that some hypervisors may require guest agent to
+ * be configured and running in order to run this API.
+ *
+ * Returns 0 on success, -1 otherwise.
+ */
+int
+virDomainGetTime(virDomainPtr dom,
+ virTypedParameterPtr *params,
+ int *nparams,
+ unsigned int flags)
+{
+ VIR_DOMAIN_DEBUG(dom, "params=%p, nparams=%d, flags=%x",
+ params, nparams ? *nparams : -1, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ virCheckNonNullArgGoto(params, error);
+ virCheckNonNullArgGoto(nparams, error);
+
+ if (dom->conn->driver->domainGetTime) {
+ int ret = dom->conn->driver->domainGetTime(dom, params,
+ nparams, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+/**
+ * virDomainSetTime:
+ * @dom: a domain object,
+ * @params: pointer to array of virDomainTimeType items
+ * @nparams: the size of @params
+ * @flags: bitwise-OR of virDomainSetTimeFlags
+ *
+ * When a domain is suspended or restored from a file the
+ * domain's OS has no idea that there was a big gap in the time.
+ * Depending on how long the gap was, NTP might not be able to
+ * resynchronize the guest.
+ *
+ * This API tries to set guest time to the given value.
+ *
+ * Please note that some hypervisors may require guest agent to
+ * be configured and running in order to be able to run this API.
+ *
+ * Returns 0 on success, -1 otherwise.
+ */
+int
+virDomainSetTime(virDomainPtr dom,
+ virTypedParameterPtr params,
+ int nparams,
+ unsigned int flags)
+{
+ VIR_DOMAIN_DEBUG(dom, "params=%p, nparams=%d, flags=%x",
+ params, nparams, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+
+ if (virTypedParameterValidateSet(dom->conn, params, nparams) < 0)
+ goto error;
+
+ if (dom->conn->driver->domainSetTime) {
+ int ret = dom->conn->driver->domainSetTime(dom, params,
+ nparams, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 9ab0c92..bccdd47 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -650,5 +650,11 @@ LIBVIRT_1.2.3 {
virDomainCoreDumpWithFormat;
} LIBVIRT_1.2.1;
+LIBVIRT_1.2.4 {
+ global:
+ virDomainGetTime;
+ virDomainSetTime;
+} LIBVIRT_1.2.3;
+
# .... define new API here using predicted next version number ....
--
1.9.0