From dd7b0a388f529259ff130c988d38d6cec34cb862 Mon Sep 17 00:00:00 2001 From: Nikolay Shirokovskiy Date: Mon, 20 Jun 2016 13:08:14 +0300 Subject: [PATCH] vz: add getting job info for migration 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 --- 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 343145510a..5f8e0c0ad5 100644 --- a/src/vz/vz_driver.c +++ b/src/vz/vz_driver.c @@ -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 = { diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c index 38254c05e2..f81b32007b 100644 --- a/src/vz/vz_sdk.c +++ b/src/vz/vz_sdk.c @@ -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, ¶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) { @@ -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); } diff --git a/src/vz/vz_utils.c b/src/vz/vz_utils.c index 3aea7a55bd..312355d9b6 100644 --- a/src/vz/vz_utils.c +++ b/src/vz/vz_utils.c @@ -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; } diff --git a/src/vz/vz_utils.h b/src/vz/vz_utils.h index 3f6b62011f..d033f943a2 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; @@ -146,3 +157,5 @@ int vzDomainObjBeginJob(virDomainObjPtr dom); void vzDomainObjEndJob(virDomainObjPtr dom); +int +vzDomainJobUpdateTime(vzDomainJobObjPtr job); -- GitLab