[libvirt] [PATCH 1/2] vz: add getting job info for migration

Nikolay Shirokovskiy nshirokovskiy at virtuozzo.com
Mon Jun 20 10:08:14 UTC 2016


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 at virtuozzo.com>
---
 src/vz/vz_driver.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 src/vz/vz_sdk.c    | 31 +++++++++++++++++++++++++++++++
 src/vz/vz_utils.c  | 42 +++++++++++++++++++++++++++++++++++-------
 src/vz/vz_utils.h  | 17 +++++++++++++++--
 4 files changed, 123 insertions(+), 9 deletions(-)

diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c
index b35469a..7be2a5a 100644
--- a/src/vz/vz_driver.c
+++ b/src/vz/vz_driver.c
@@ -2539,6 +2539,7 @@ vzDomainMigratePerformStep(virDomainPtr domain,
 {
     int ret = -1;
     virDomainObjPtr dom = NULL;
+    vzDomObjPtr privdom;
     virURIPtr vzuri = NULL;
     vzConnPtr privconn = domain->conn->privateData;
     const char *miguri = NULL;
@@ -2573,6 +2574,8 @@ vzDomainMigratePerformStep(virDomainPtr domain,
     if (vzDomainObjBeginJob(dom) < 0)
         goto cleanup;
     job = true;
+    privdom = dom->privateData;
+    privdom->job.hasProgress = true;
 
     if (!vzDomainObjIsExist(dom))
         goto cleanup;
@@ -2794,6 +2797,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 */
@@ -2884,6 +2925,7 @@ static virHypervisorDriver vzHypervisorDriver = {
     .domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */
     .domainMigrateFinish3Params = vzDomainMigrateFinish3Params, /* 1.3.5 */
     .domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
+    .domainGetJobInfo = vzDomainGetJobInfo, /* 2.0.0 */
 };
 
 static virConnectDriver vzConnectDriver = {
diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c
index 8abe223..bd67b21 100644
--- a/src/vz/vz_sdk.c
+++ b/src/vz/vz_sdk.c
@@ -1885,6 +1885,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)
 {
@@ -1940,6 +1968,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);
     }
diff --git a/src/vz/vz_utils.c b/src/vz/vz_utils.c
index dc8dbf3..92af4da 100644
--- a/src/vz/vz_utils.c
+++ b/src/vz/vz_utils.c
@@ -459,7 +459,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;
@@ -482,7 +482,7 @@ vzDomObjFree(void* p)
 
     PrlHandle_Free(pdom->sdkdom);
     PrlHandle_Free(pdom->stats);
-    virCondDestroy(&pdom->jobCond);
+    virCondDestroy(&pdom->job.cond);
     VIR_FREE(pdom);
 };
 
@@ -499,12 +499,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:
@@ -522,6 +529,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;
 }
diff --git a/src/vz/vz_utils.h b/src/vz/vz_utils.h
index 548b264..c80515a 100644
--- a/src/vz/vz_utils.h
+++ b/src/vz/vz_utils.h
@@ -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;
@@ -143,3 +154,5 @@ int
 vzDomainObjBeginJob(virDomainObjPtr dom);
 void
 vzDomainObjEndJob(virDomainObjPtr dom);
+int
+vzDomainJobUpdateTime(vzDomainJobObjPtr job);
-- 
1.8.3.1




More information about the libvir-list mailing list