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(a)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, ¶m);
+ 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