
On Thu, Feb 18, 2010 at 03:56:10PM +0000, Daniel P. Berrange wrote:
Introduce support for virDomainGetJobInfo in the QEMU driver. This allows for monitoring of any API that uses the 'info migrate' monitor command. ie virDomainMigrate, virDomainSave and virDomainCoreDump
Unfortunately QEMU does not provide a way to monitor incoming migration so we can't wire up virDomainRestore yet.
The virsh tool gets a new command 'domjobinfo' to query status
* src/qemu/qemu_driver.c: Record virDomainJobInfo and start time in qemuDomainObjPrivatePtr objects. Add generic shared handler for calling 'info migrate' with all migration based APIs. * src/qemu/qemu_monitor_text.c: Fix parsing of 'info migration' reply * tools/virsh.c: add new 'domjobinfo' command to query progress --- src/qemu/qemu_driver.c | 208 +++++++++++++++++++++++++++++++++++------- src/qemu/qemu_monitor_text.c | 7 +- tools/virsh.c | 129 ++++++++++++++++++++++---- 3 files changed, 288 insertions(+), 56 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index a6dc4f9..b245eb2 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -87,6 +87,8 @@ struct _qemuDomainObjPrivate { int jobActive; /* Non-zero if a job is active. Only 1 job is allowed at any time * A job includes *all* monitor commands, even those just querying * information, not merely actions */ + virDomainJobInfo jobInfo; + unsigned long long jobStart;
qemuMonitorPtr mon; virDomainChrDefPtr monConfig; @@ -329,6 +331,8 @@ static int qemuDomainObjBeginJob(virDomainObjPtr obj) } } priv->jobActive = 1; + priv->jobStart = (now.tv_sec * 1000ull) + (now.tv_usec / 1000); + memset(&priv->jobInfo, 0, sizeof(priv->jobInfo));
return 0; } @@ -373,6 +377,8 @@ static int qemuDomainObjBeginJobWithDriver(struct qemud_driver *driver, } } priv->jobActive = 1; + priv->jobStart = (now.tv_sec * 1000ull) + (now.tv_usec / 1000); + memset(&priv->jobInfo, 0, sizeof(priv->jobInfo));
Hum, I though the time was measured in second in the job strcture, why keep a millisecond timestamp here ? Maybe seconds are too coarse in the API anyway
virDomainObjUnlock(obj); qemuDriverLock(driver); @@ -395,6 +401,8 @@ static int ATTRIBUTE_RETURN_CHECK qemuDomainObjEndJob(virDomainObjPtr obj) qemuDomainObjPrivatePtr priv = obj->privateData;
priv->jobActive = 0; + priv->jobStart = 0; + memset(&priv->jobInfo, 0, sizeof(priv->jobInfo)); virCondSignal(&priv->jobCond);
return virDomainObjUnref(obj); @@ -3919,6 +3927,96 @@ cleanup: }
+static int +qemuDomainWaitForMigrationComplete(struct qemud_driver *driver, virDomainObjPtr vm) +{ + int ret = -1; + int status; + unsigned long long memProcessed; + unsigned long long memRemaining; + unsigned long long memTotal; + qemuDomainObjPrivatePtr priv = vm->privateData; + + priv->jobInfo.type = VIR_DOMAIN_JOB_UNBOUNDED; + + while (priv->jobInfo.type == VIR_DOMAIN_JOB_UNBOUNDED) { + /* Poll every 1/2 second for progress & to allow cancellation */
that's way larger than an human perception window so from an UI perspective the user will percieve the time between the request and when it takes effect, probably not a big deal but could be refined in the future.
+ struct timespec ts = { .tv_sec = 0, .tv_nsec = 500 * 1000ull }; + struct timeval now; + int rc; + + qemuDomainObjEnterMonitorWithDriver(driver, vm);
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/