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