]> xenbits.xensource.com Git - libvirt.git/commitdiff
vz: add getting job info for migration
authorNikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
Mon, 20 Jun 2016 10:08:14 +0000 (13:08 +0300)
committerMaxim Nestratov <mnestratov@virtuozzo.com>
Sat, 6 Aug 2016 19:01:02 +0000 (22:01 +0300)
Unfortunately vz sdk do not provide detail information on migration
progress, only progress percentage. Thus vz driver provides percents
instead of bytes in data fields of virDomainJobInfoPtr.

Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
src/vz/vz_driver.c
src/vz/vz_sdk.c
src/vz/vz_utils.c
src/vz/vz_utils.h

index 343145510ab62aafb47c9c7e335aedcf21af0797..5f8e0c0ad54e8e41bf45affbcfbd998b9005d701 100644 (file)
@@ -2545,6 +2545,7 @@ vzDomainMigratePerformStep(virDomainPtr domain,
 {
     int ret = -1;
     virDomainObjPtr dom = NULL;
+    vzDomObjPtr privdom;
     virURIPtr vzuri = NULL;
     vzConnPtr privconn = domain->conn->privateData;
     const char *miguri = NULL;
@@ -2579,6 +2580,8 @@ vzDomainMigratePerformStep(virDomainPtr domain,
     if (vzDomainObjBeginJob(dom) < 0)
         goto cleanup;
     job = true;
+    privdom = dom->privateData;
+    privdom->job.hasProgress = true;
 
     if (vzEnsureDomainExists(dom) < 0)
         goto cleanup;
@@ -2784,6 +2787,44 @@ vzDomainMigrateConfirm3Params(virDomainPtr domain ATTRIBUTE_UNUSED,
     return 0;
 }
 
+static int
+vzDomainGetJobInfoImpl(virDomainObjPtr dom, virDomainJobInfoPtr info)
+{
+    vzDomObjPtr privdom = dom->privateData;
+    vzDomainJobObjPtr job = &privdom->job;
+
+    memset(info, 0, sizeof(*info));
+
+    if (!job->active || !job->hasProgress)
+        return 0;
+
+    if (vzDomainJobUpdateTime(job) < 0)
+        return -1;
+
+    info->type = VIR_DOMAIN_JOB_UNBOUNDED;
+    info->dataTotal = 100;
+    info->dataProcessed = job->progress;
+    info->dataRemaining = 100 - job->progress;
+    info->timeElapsed = job->elapsed;
+
+    return 0;
+}
+
+static int
+vzDomainGetJobInfo(virDomainPtr domain, virDomainJobInfoPtr info)
+{
+    virDomainObjPtr dom;
+    int ret;
+
+    if (!(dom = vzDomObjFromDomain(domain)))
+        return -1;
+
+    ret = vzDomainGetJobInfoImpl(dom, info);
+
+    virObjectUnlock(dom);
+    return ret;
+}
+
 static virHypervisorDriver vzHypervisorDriver = {
     .name = "vz",
     .connectOpen = vzConnectOpen,            /* 0.10.0 */
@@ -2875,6 +2916,7 @@ static virHypervisorDriver vzHypervisorDriver = {
     .domainMigrateFinish3Params = vzDomainMigrateFinish3Params, /* 1.3.5 */
     .domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
     .domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
+    .domainGetJobInfo = vzDomainGetJobInfo, /* 2.2.0 */
 };
 
 static virConnectDriver vzConnectDriver = {
index 38254c05e2df1d91e0d62825cf66338bbb629b4d..f81b32007ba1db7651d56fad8ab2a949766e7275 100644 (file)
@@ -2140,6 +2140,34 @@ prlsdkHandlePerfEvent(vzDriverPtr driver,
     virObjectUnlock(dom);
 }
 
+static void
+prlsdkHandleMigrationProgress(vzDriverPtr driver,
+                              PRL_HANDLE event,
+                              unsigned char *uuid)
+{
+    virDomainObjPtr dom = NULL;
+    vzDomObjPtr privdom = NULL;
+    PRL_UINT32 progress;
+    PRL_HANDLE param = PRL_INVALID_HANDLE;
+    PRL_RESULT pret;
+
+    if (!(dom = virDomainObjListFindByUUID(driver->domains, uuid)))
+        return;
+
+    pret = PrlEvent_GetParam(event, 0, &param);
+    prlsdkCheckRetGoto(pret, cleanup);
+
+    pret = PrlEvtPrm_ToUint32(param, &progress);
+    prlsdkCheckRetGoto(pret, cleanup);
+
+    privdom = dom->privateData;
+    privdom->job.progress = progress;
+
+ cleanup:
+    PrlHandle_Free(param);
+    virObjectUnlock(dom);
+}
+
 static PRL_RESULT
 prlsdkEventsHandler(PRL_HANDLE prlEvent, PRL_VOID_PTR opaque)
 {
@@ -2195,6 +2223,9 @@ prlsdkEventsHandler(PRL_HANDLE prlEvent, PRL_VOID_PTR opaque)
     case PET_DSP_EVT_DISP_CONNECTION_CLOSED:
         vzDestroyDriverConnection();
         break;
+    case PET_DSP_EVT_VM_MIGRATE_PROGRESS_CHANGED:
+        prlsdkHandleMigrationProgress(driver, prlEvent, uuid);
+        break;
     default:
         VIR_DEBUG("Skipping event of type %d", prlEventType);
     }
index 3aea7a55bd6ee8719e5ac1f6c9b20cfed6496ad5..312355d9b64ea936115bcb303078d718ffb91e71 100644 (file)
@@ -588,7 +588,7 @@ vzDomObjAlloc(void)
     if (VIR_ALLOC(pdom) < 0)
         return NULL;
 
-    if (virCondInit(&pdom->jobCond) < 0)
+    if (virCondInit(&pdom->job.cond) < 0)
         goto error;
 
     pdom->stats = PRL_INVALID_HANDLE;
@@ -611,7 +611,7 @@ vzDomObjFree(void* p)
 
     PrlHandle_Free(pdom->sdkdom);
     PrlHandle_Free(pdom->stats);
-    virCondDestroy(&pdom->jobCond);
+    virCondDestroy(&pdom->job.cond);
     VIR_FREE(pdom);
 };
 
@@ -628,12 +628,19 @@ vzDomainObjBeginJob(virDomainObjPtr dom)
         return -1;
     then = now + VZ_JOB_WAIT_TIME;
 
-    while (pdom->job) {
-        if (virCondWaitUntil(&pdom->jobCond, &dom->parent.lock, then) < 0)
+    while (pdom->job.active) {
+        if (virCondWaitUntil(&pdom->job.cond, &dom->parent.lock, then) < 0)
             goto error;
     }
 
-    pdom->job = true;
+    if (virTimeMillisNow(&now) < 0)
+        return -1;
+
+    pdom->job.active = true;
+    pdom->job.started = now;
+    pdom->job.elapsed = 0;
+    pdom->job.progress = 0;
+    pdom->job.hasProgress = false;
     return 0;
 
  error:
@@ -651,6 +658,27 @@ vzDomainObjEndJob(virDomainObjPtr dom)
 {
     vzDomObjPtr pdom = dom->privateData;
 
-    pdom->job = false;
-    virCondSignal(&pdom->jobCond);
+    pdom->job.active = false;
+    virCondSignal(&pdom->job.cond);
+}
+
+int
+vzDomainJobUpdateTime(vzDomainJobObjPtr job)
+{
+    unsigned long long now;
+
+    if (!job->started)
+        return 0;
+
+    if (virTimeMillisNow(&now) < 0)
+        return -1;
+
+    if (now < job->started) {
+        VIR_WARN("Async job starts in the future");
+        job->started = 0;
+        return 0;
+    }
+
+    job->elapsed = now - job->started;
+    return 0;
 }
index 3f6b62011f68de830ecadbc3ea9312b2bd7f3d5b..d033f943a2f3d8eacdae2f5efe34fa8523651b62 100644 (file)
@@ -93,13 +93,24 @@ struct _vzConn {
 typedef struct _vzConn vzConn;
 typedef struct _vzConn *vzConnPtr;
 
+struct _vzDomainJobObj {
+    virCond cond;
+    bool active;
+    /* when the job started, zeroed on time discontinuities */
+    unsigned long long started;
+    unsigned long long elapsed;
+    bool hasProgress;
+    int progress; /* percents */
+};
+
+typedef struct _vzDomainJobObj vzDomainJobObj;
+typedef struct _vzDomainJobObj *vzDomainJobObjPtr;
 
 struct vzDomObj {
     int id;
     PRL_HANDLE sdkdom;
     PRL_HANDLE stats;
-    bool job;
-    virCond jobCond;
+    vzDomainJobObj job;
 };
 
 typedef struct vzDomObj *vzDomObjPtr;
@@ -146,3 +157,5 @@ int
 vzDomainObjBeginJob(virDomainObjPtr dom);
 void
 vzDomainObjEndJob(virDomainObjPtr dom);
+int
+vzDomainJobUpdateTime(vzDomainJobObjPtr job);