This flag can be used to sync the domain's time right after
domain CPUs are started. It's basically backing call of two
subsequent APIs into one:
1) virDomainResume(dom)
2) virDomainSetTime(dom, 0, 0, VIR_DOMAIN_TIME_SYNC)
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
include/libvirt/libvirt-domain.h | 7 +++++++
src/libvirt-domain.c | 18 ++++++++++++------
src/qemu/qemu_driver.c | 20 +++++++++++++++++++-
3 files changed, 38 insertions(+), 7 deletions(-)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 1795dd3..faafee4 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -867,6 +867,13 @@ int virDomainFree (virDomainPtr
domain);
/*
* Domain suspend/resume
*/
+typedef enum {
+ VIR_DOMAIN_RESUME_SYNC_TIME = 1 << 0, /* On resume sync domain time from
+ its RTC. Depending on underlying
+ hypervisor it may require guest
+ agent. */
+} virDomainResumeFlagsValues;
+
int virDomainSuspend (virDomainPtr domain);
int virDomainResume (virDomainPtr domain);
int virDomainResumeFlags (virDomainPtr domain,
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 7d21d77..7c8ccd8 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -695,13 +695,19 @@ virDomainResume(virDomainPtr domain)
/**
* virDomainResumeFlags:
* @domain: a domain object
- * @flags: extra flags; not used yet, so callers should always pass 0
+ * @flags: bitwise-OR of virDomainResumeFlagsValues
*
- * Resume a suspended domain, the process is restarted from the state where
- * it was frozen by calling virDomainSuspend().
- * This function may require privileged access
- * Moreover, resume may not be supported if domain is in some
- * special state like VIR_DOMAIN_PMSUSPENDED.
+ * Resume a suspended domain, the process is restarted from the
+ * state where it was frozen by calling virDomainSuspend(). This
+ * function may require privileged access Moreover, resume may
+ * not be supported if domain is in some special state like
+ * VIR_DOMAIN_PMSUSPENDED. If VIR_DOMAIN_RESUME_SYNC_TIME flag
+ * is specified the domain's time is synced once its vCPUs are
+ * started. Depending on driver, this flag may require guest
+ * agent. However, due to nature of things in such drivers, vCPUs
+ * may have executed some instructions prior the time is set.
+ * Moreover, if time synchronisation fails, domain remains
+ * resumed, so you should check the domain state on error.
*
* Returns 0 in case of success and -1 in case of failure.
*/
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 7065999..342d630 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1933,7 +1933,7 @@ qemuDomainResumeFlags(virDomainPtr dom,
virQEMUDriverConfigPtr cfg = NULL;
virCapsPtr caps = NULL;
- virCheckFlags(0, -1);
+ virCheckFlags(VIR_DOMAIN_RESUME_SYNC_TIME, -1);
if (!(vm = qemuDomObjFromDomain(dom)))
return -1;
@@ -1974,6 +1974,24 @@ qemuDomainResumeFlags(virDomainPtr dom,
goto endjob;
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
goto endjob;
+
+ if (flags & VIR_DOMAIN_RESUME_SYNC_TIME) {
+ if (!virDomainObjIsActive(vm)) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto endjob;
+ }
+
+ if (qemuDomainSetTimeImpl(driver, vm, 0, 0, true) < 0) {
+ /* Intentionally overwrite the error, to make it
+ * obvious that guest is running. */
+ virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+ _("domain resumed, but time "
+ "synchronization failed!"));
+ goto endjob;
+ }
+ }
+
ret = 0;
endjob:
--
2.0.4