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