[libvirt] [PATCH 08/10] vz: introduce stats cache lock

Nikolay Shirokovskiy nshirokovskiy at virtuozzo.com
Thu Jun 2 11:24:29 UTC 2016


Use this lock to coordinate requests to cache and stats events
from vzsdk. Request is a series of calls of vzCountersCacheGetParam
which must be enslosed in a vzCountersCacheBegin, vzCountersCacheEnd.

Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy at virtuozzo.com>
---
 src/vz/vz_driver.c | 236 ++++++++++++++++++++++++++++++++++++++---------------
 src/vz/vz_sdk.c    | 120 ++++++++++++++++-----------
 src/vz/vz_sdk.h    |  14 +++-
 src/vz/vz_utils.h  |   2 +
 4 files changed, 256 insertions(+), 116 deletions(-)

diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c
index 95739bd..1aabfd7 100644
--- a/src/vz/vz_driver.c
+++ b/src/vz/vz_driver.c
@@ -597,15 +597,45 @@ vzDomainLookupByName(virConnectPtr conn, const char *name)
 }
 
 static int
+vzStatsGetCpuTotal(vzCountersCachePtr cache,
+                   unsigned int num,
+                   unsigned long long *total)
+{
+    int ret = -1;
+    size_t i;
+
+    if (vzCountersCacheBegin(cache) < 0)
+        return -1;
+
+    for (i = 0; i < num; ++i) {
+        unsigned long long cpu;
+
+        if (prlsdkGetVcpuStats(cache, i, &cpu) < 0) {
+            virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+                           _("cannot read cputime for domain"));
+            goto cleanup;
+        }
+        total += cpu;
+    }
+
+    ret = 0;
+
+ cleanup:
+    vzCountersCacheEnd(cache);
+
+    return ret;
+}
+
+static int
 vzDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
 {
     virDomainObjPtr dom;
+    vzDomObjPtr privdom;
     int ret = -1;
-    size_t i;
     unsigned int nvcpus;
 
     if (!(dom = vzDomObjFromDomainRef(domain)))
-        goto cleanup;
+        return -1;
 
     info->state = virDomainObjGetState(dom, NULL);
     info->memory = dom->def->mem.cur_balloon;
@@ -614,26 +644,17 @@ vzDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
     info->cpuTime = 0;
 
     if (!virDomainObjIsActive(dom)) {
-        ret = 0;
-        goto cleanup;
+        virDomainObjEndAPI(&dom);
+        return 0;
     }
 
     nvcpus = virDomainDefGetVcpus(dom->def);
 
-    for (i = 0; i < nvcpus; ++i) {
-        unsigned long long vtime;
+    virObjectUnlock(dom);
+    privdom = dom->privateData;
+    ret = vzStatsGetCpuTotal(privdom->cache, nvcpus, &info->cpuTime);
+    virObjectUnref(dom);
 
-        if (prlsdkGetVcpuStats(dom, i, &vtime) < 0) {
-            virReportError(VIR_ERR_OPERATION_FAILED, "%s",
-                           _("cannot read cputime for domain"));
-            goto cleanup;
-        }
-        info->cpuTime += vtime;
-    }
-    ret = 0;
-
- cleanup:
-    virDomainObjEndAPI(&dom);
     return ret;
 }
 
@@ -869,6 +890,33 @@ vzConnectBaselineCPU(virConnectPtr conn ATTRIBUTE_UNUSED,
     return cpuBaselineXML(xmlCPUs, ncpus, NULL, 0, flags);
 }
 
+static int
+vzStatsGetCpuInfo(vzCountersCachePtr cache,
+                  virVcpuInfoPtr info,
+                  int num)
+
+{
+    int ret = -1;
+    size_t i;
+
+    if (vzCountersCacheBegin(cache) < 0)
+        return -1;
+
+    memset(info, 0, sizeof(*info) * num);
+    for (i = 0; i < num; i++) {
+        info[i].number = i;
+        info[i].state = VIR_VCPU_RUNNING;
+        if (prlsdkGetVcpuStats(cache, i, &info[i].cpuTime) < 0)
+            goto cleanup;
+    }
+
+    ret = num;
+
+ cleanup:
+    vzCountersCacheEnd(cache);
+
+    return ret;
+}
 
 static int
 vzDomainGetVcpus(virDomainPtr domain,
@@ -878,11 +926,12 @@ vzDomainGetVcpus(virDomainPtr domain,
                  int maplen)
 {
     virDomainObjPtr dom = NULL;
+    vzDomObjPtr privdom;
     size_t i;
     int ret = -1;
 
     if (!(dom = vzDomObjFromDomainRef(domain)))
-        goto cleanup;
+        return -1;
 
     if (!virDomainObjIsActive(dom)) {
         virReportError(VIR_ERR_OPERATION_INVALID,
@@ -905,20 +954,19 @@ vzDomainGetVcpus(virDomainPtr domain,
     }
 
     if (info != NULL) {
-        memset(info, 0, sizeof(*info) * maxinfo);
-        for (i = 0; i < maxinfo; i++) {
-            info[i].number = i;
-            info[i].state = VIR_VCPU_RUNNING;
-            if (prlsdkGetVcpuStats(dom, i, &info[i].cpuTime) < 0)
-                goto cleanup;
-        }
+        virObjectUnlock(dom);
+        privdom = dom->privateData;
+        ret = vzStatsGetCpuInfo(privdom->cache, info, maxinfo);
+        virObjectUnref(dom);
+
+        return ret;
     }
 
     ret = maxinfo;
 
  cleanup:
-    if (dom)
-        virDomainObjEndAPI(&dom);
+    virDomainObjEndAPI(&dom);
+
     return ret;
 }
 
@@ -1278,10 +1326,64 @@ vzDomainGetMaxMemory(virDomainPtr domain)
 }
 
 static int
+vzStatsGetBlockStats(vzCountersCachePtr cache,
+                     const char *disk,
+                     char **disks,
+                     int ndisks,
+                     virDomainBlockStatsPtr stats)
+{
+    int ret = -1;
+    size_t i;
+
+    if (vzCountersCacheBegin(cache) < 0)
+        return -1;
+
+    if (disk) {
+        if (prlsdkGetBlockStats(cache, disk, stats) < 0)
+            goto cleanup;
+    } else if (disks) {
+        virDomainBlockStatsStruct s;
+
+#define PARALLELS_ZERO_STATS(VAR, TYPE, NAME)      \
+        stats->VAR = 0;
+
+        PARALLELS_BLOCK_STATS_FOREACH(PARALLELS_ZERO_STATS)
+
+#undef PARALLELS_ZERO_STATS
+
+        for (i = 0; i < ndisks; i++) {
+            if (prlsdkGetBlockStats(cache, disks[i], &s) < 0)
+                goto cleanup;
+
+#define PARALLELS_SUM_STATS(VAR, TYPE, NAME)        \
+            if (s.VAR != -1)                        \
+                stats->VAR += s.VAR;
+
+            PARALLELS_BLOCK_STATS_FOREACH(PARALLELS_SUM_STATS)
+
+#undef PARALLELS_SUM_STATS
+        }
+    } else {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("one of disks or disk parameters should be set"));
+        goto cleanup;
+    }
+
+    stats->errs = -1;
+    ret = 0;
+
+ cleanup:
+    vzCountersCacheEnd(cache);
+
+    return ret;
+}
+
+static int
 vzDomainBlockStats(virDomainPtr domain, const char *path,
                    virDomainBlockStatsPtr stats)
 {
     virDomainObjPtr dom = NULL;
+    vzDomObjPtr privdom;
     int ret = -1;
     size_t i;
     int idx;
@@ -1292,59 +1394,41 @@ vzDomainBlockStats(virDomainPtr domain, const char *path,
     if (!(dom = vzDomObjFromDomainRef(domain)))
         return -1;
 
+    privdom = dom->privateData;
+
     if (*path) {
         if ((idx = virDomainDiskIndexByName(dom->def, path, false)) < 0) {
             virReportError(VIR_ERR_INVALID_ARG, _("invalid path: %s"), path);
-            goto cleanup;
+            goto error;
         }
 
         if (!(disk = prlsdkGetDiskStatName(dom->def->disks[idx])))
-            goto cleanup;
-
-        if (prlsdkGetBlockStats(dom, disk, stats) < 0)
-            goto cleanup;
+            goto error;
     } else {
-        virDomainBlockStatsStruct s;
-
-#define PARALLELS_ZERO_STATS(VAR, TYPE, NAME)      \
-        stats->VAR = 0;
-
-        PARALLELS_BLOCK_STATS_FOREACH(PARALLELS_ZERO_STATS)
-
-#undef PARALLELS_ZERO_STATS
-
         ndisks = dom->def->ndisks;
 
         if (VIR_ALLOC_N(disks, ndisks))
-            goto cleanup;
+            goto error;
 
         for (i = 0; i < ndisks; i++)
             if (!(disks[i] = prlsdkGetDiskStatName(dom->def->disks[i])))
-                goto cleanup;
-
-        for (i = 0; i < ndisks; i++) {
-            if (prlsdkGetBlockStats(dom, disk, &s) < 0)
-                goto cleanup;
-
-#define PARALLELS_SUM_STATS(VAR, TYPE, NAME)        \
-    if (s.VAR != -1)                                \
-        stats->VAR += s.VAR;
-
-        PARALLELS_BLOCK_STATS_FOREACH(PARALLELS_SUM_STATS)
-
-#undef PARALLELS_SUM_STATS
-        }
+                goto error;
     }
-    stats->errs = -1;
-    ret = 0;
+
+    virObjectUnlock(dom);
+    privdom = dom->privateData;
+    ret = vzStatsGetBlockStats(privdom->cache, disk, disks, ndisks, stats);
+    virObjectUnref(dom);
 
  cleanup:
-    if (dom)
-        virDomainObjEndAPI(&dom);
     VIR_FREE(disk);
     virStringFreeListCount(disks, ndisks);
 
     return ret;
+
+ error:
+    virDomainObjEndAPI(&dom);
+    goto cleanup;
 }
 
 static int
@@ -1403,13 +1487,25 @@ vzDomainInterfaceStats(virDomainPtr domain,
                          virDomainInterfaceStatsPtr stats)
 {
     virDomainObjPtr dom = NULL;
+    vzDomObjPtr privdom;
+    vzCountersCachePtr cache;
     int ret;
 
     if (!(dom = vzDomObjFromDomainRef(domain)))
         return -1;
 
-    ret = prlsdkGetNetStats(dom, path, stats);
-    virDomainObjEndAPI(&dom);
+    virObjectUnlock(dom);
+    privdom = dom->privateData;
+    cache = privdom->cache;
+
+    if (vzCountersCacheBegin(cache) < 0) {
+        virObjectUnref(dom);
+        return -1;
+    }
+
+    ret = prlsdkGetNetStats(cache, privdom->sdkdom, path, stats);
+    vzCountersCacheEnd(cache);
+    virObjectUnref(dom);
 
     return ret;
 }
@@ -1421,14 +1517,26 @@ vzDomainMemoryStats(virDomainPtr domain,
                     unsigned int flags)
 {
     virDomainObjPtr dom = NULL;
+    vzDomObjPtr privdom;
+    vzCountersCachePtr cache;
     int ret = -1;
 
     virCheckFlags(0, -1);
     if (!(dom = vzDomObjFromDomainRef(domain)))
         return -1;
 
-    ret = prlsdkGetMemoryStats(dom, stats, nr_stats);
-    virDomainObjEndAPI(&dom);
+    virObjectUnlock(dom);
+    privdom = dom->privateData;
+    cache = privdom->cache;
+
+    if (vzCountersCacheBegin(cache) < 0) {
+        virObjectUnref(dom);
+        return -1;
+    }
+
+    ret = prlsdkGetMemoryStats(cache, stats, nr_stats);
+    vzCountersCacheEnd(cache);
+    virObjectUnref(dom);
 
     return ret;
 }
diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c
index 5cef432..a5474dc 100644
--- a/src/vz/vz_sdk.c
+++ b/src/vz/vz_sdk.c
@@ -41,7 +41,7 @@ static int
 prlsdkUUIDParse(const char *uuidstr, unsigned char *uuid);
 
 static vzCountersCachePtr
-vzCountersCacheNew(void);
+vzCountersCacheNew(PRL_HANDLE sdkdom);
 static void
 vzCountersCacheFree(vzCountersCachePtr cache);
 
@@ -1638,7 +1638,7 @@ prlsdkLoadDomain(vzDriverPtr driver, virDomainObjPtr dom)
     }
 
     if (pdom->sdkdom == PRL_INVALID_HANDLE) {
-        if (!(pdom->cache = vzCountersCacheNew()))
+        if (!(pdom->cache = vzCountersCacheNew(sdkdom)))
             goto error;
         pdom->sdkdom = sdkdom;
     } else {
@@ -1876,47 +1876,52 @@ prlsdkHandleVmRemovedEvent(vzDriverPtr driver,
 
 #define PARALLELS_STATISTICS_DROP_COUNT 3
 
-static PRL_RESULT
+static void
 prlsdkHandlePerfEvent(vzDriverPtr driver,
                       PRL_HANDLE event,
                       unsigned char *uuid)
 {
-    virDomainObjPtr dom = NULL;
+    virDomainObjPtr dom;
     vzDomObjPtr privdom = NULL;
     PRL_HANDLE job = PRL_INVALID_HANDLE;
+    vzCountersCachePtr cache;
 
-    dom = virDomainObjListFindByUUID(driver->domains, uuid);
-    if (dom == NULL)
-        goto cleanup;
+    dom = virDomainObjListFindByUUIDRef(driver->domains, uuid);
+    if (dom == NULL) {
+        PrlHandle_Free(event);
+        return;
+    }
+
+    virObjectUnlock(dom);
     privdom = dom->privateData;
+    cache = privdom->cache;
+    virMutexLock(&cache->lock);
 
     /* delayed event after unsubscribe */
-    if (privdom->cache->count == -1)
+    if (cache->count == -1)
         goto cleanup;
 
-    PrlHandle_Free(privdom->cache->stats);
-    privdom->cache->stats = PRL_INVALID_HANDLE;
+    PrlHandle_Free(cache->stats);
+    cache->stats = PRL_INVALID_HANDLE;
 
-    if (privdom->cache->count > PARALLELS_STATISTICS_DROP_COUNT) {
-        job = PrlVm_UnsubscribeFromPerfStats(privdom->sdkdom);
+    if (cache->count > PARALLELS_STATISTICS_DROP_COUNT) {
+        job = PrlVm_UnsubscribeFromPerfStats(cache->sdkdom);
         if (PRL_FAILED(waitJob(job)))
             goto cleanup;
         /* change state to unsubscribed */
-        privdom->cache->count = -1;
+        cache->count = -1;
     } else {
-        ++privdom->cache->count;
-        privdom->cache->stats = event;
+        ++cache->count;
+        cache->stats = event;
         /* thus we get own of event handle */
         event = PRL_INVALID_HANDLE;
-        virCondSignal(&privdom->cache->cond);
+        virCondSignal(&cache->cond);
     }
 
  cleanup:
     PrlHandle_Free(event);
-    if (dom)
-        virObjectUnlock(dom);
-
-    return PRL_ERR_SUCCESS;
+    virMutexUnlock(&cache->lock);
+    virObjectUnref(dom);
 }
 
 static PRL_RESULT
@@ -4004,14 +4009,14 @@ prlsdkDomainManagedSaveRemove(virDomainObjPtr dom)
 }
 
 static int
-prlsdkExtractStatsParam(PRL_HANDLE sdkstats, const char *name, long long *val)
+vzCountersCacheGetParam(vzCountersCachePtr cache, const char *name, long long *val)
 {
     PRL_HANDLE param = PRL_INVALID_HANDLE;
     PRL_RESULT pret;
     PRL_INT64 pval = 0;
     int ret = -1;
 
-    pret = PrlEvent_GetParamByName(sdkstats, name, &param);
+    pret = PrlEvent_GetParamByName(cache->stats, name, &param);
     if (pret == PRL_ERR_NO_DATA) {
         *val = -1;
         ret = 0;
@@ -4033,36 +4038,37 @@ prlsdkExtractStatsParam(PRL_HANDLE sdkstats, const char *name, long long *val)
 
 #define PARALLELS_STATISTICS_TIMEOUT (60 * 1000)
 
-static int
-prlsdkGetStatsParam(virDomainObjPtr dom, const char *name, long long *val)
+int
+vzCountersCacheBegin(vzCountersCachePtr cache)
 {
-    vzDomObjPtr privdom = dom->privateData;
     PRL_HANDLE job = PRL_INVALID_HANDLE;
     unsigned long long now;
 
-    if (privdom->cache->stats != PRL_INVALID_HANDLE) {
+    virMutexLock(&cache->lock);
+
+    if (cache->stats != PRL_INVALID_HANDLE) {
         /* reset count to keep subscribtion */
-        privdom->cache->count = 0;
-        return prlsdkExtractStatsParam(privdom->cache->stats, name, val);
+        cache->count = 0;
+        return 0;
     }
 
-    if (privdom->cache->count == -1) {
-        job = PrlVm_SubscribeToPerfStats(privdom->sdkdom, NULL);
+    if (cache->count == -1) {
+        job = PrlVm_SubscribeToPerfStats(cache->sdkdom, NULL);
         if (PRL_FAILED(waitJob(job)))
             goto error;
     }
 
     /* change state to subscribed in case of unsubscribed
        or reset count so we stop unsubscribe attempts */
-    privdom->cache->count = 0;
+    cache->count = 0;
 
     if (virTimeMillisNow(&now) < 0) {
         virReportSystemError(errno, "%s", _("Unable to get current time"));
         goto error;
     }
 
-    while (privdom->cache->stats == PRL_INVALID_HANDLE) {
-        if (virCondWaitUntil(&privdom->cache->cond, &dom->parent.lock,
+    while (cache->stats == PRL_INVALID_HANDLE) {
+        if (virCondWaitUntil(&cache->cond, &cache->lock,
                              now + PARALLELS_STATISTICS_TIMEOUT) < 0) {
             if (errno == ETIMEDOUT) {
                 virReportError(VIR_ERR_OPERATION_TIMEOUT, "%s",
@@ -4076,11 +4082,20 @@ prlsdkGetStatsParam(virDomainObjPtr dom, const char *name, long long *val)
         }
     }
 
-    return prlsdkExtractStatsParam(privdom->cache->stats, name, val);
+    return 0;
+
  error:
+    virMutexUnlock(&cache->lock);
+
     return -1;
 }
 
+void
+vzCountersCacheEnd(vzCountersCachePtr cache)
+{
+    virMutexUnlock(&cache->lock);
+}
+
 static void
 vzCountersCacheFree(vzCountersCachePtr cache)
 {
@@ -4089,11 +4104,12 @@ vzCountersCacheFree(vzCountersCachePtr cache)
 
     PrlHandle_Free(cache->stats);
     virCondDestroy(&cache->cond);
+    virMutexDestroy(&cache->lock);
     VIR_FREE(cache);
 }
 
 static vzCountersCachePtr
-vzCountersCacheNew(void)
+vzCountersCacheNew(PRL_HANDLE sdkdom)
 {
     vzCountersCachePtr cache = NULL;
 
@@ -4104,8 +4120,14 @@ vzCountersCacheNew(void)
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot initialize condition"));
         goto error;
     }
+    if (virMutexInit(&cache->lock) < 0) {
+        virCondDestroy(&cache->cond);
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot initialize mutex"));
+        goto error;
+    }
     cache->stats = PRL_INVALID_HANDLE;
     cache->count = -1;
+    cache->sdkdom = sdkdom;
 
     return cache;
 
@@ -4114,6 +4136,7 @@ vzCountersCacheNew(void)
 
     return NULL;
 }
+
 char* prlsdkGetDiskStatName(virDomainDiskDefPtr disk)
 {
     virDomainDeviceDriveAddressPtr address;
@@ -4148,7 +4171,7 @@ char* prlsdkGetDiskStatName(virDomainDiskDefPtr disk)
 }
 
 int
-prlsdkGetBlockStats(virDomainObjPtr dom,
+prlsdkGetBlockStats(vzCountersCachePtr cache,
                     const char *disk,
                     virDomainBlockStatsPtr stats)
 {
@@ -4158,7 +4181,7 @@ prlsdkGetBlockStats(virDomainObjPtr dom,
 #define PRLSDK_GET_STAT_PARAM(VAL, TYPE, NAME)                          \
     if (virAsprintf(&name, "devices.%s.%s", disk, NAME) < 0)            \
         goto cleanup;                                                   \
-    if (prlsdkGetStatsParam(dom, name, &stats->VAL) < 0)                \
+    if (vzCountersCacheGetParam(cache, name, &stats->VAL) < 0)          \
         goto cleanup;                                                   \
     VIR_FREE(name);
 
@@ -4176,20 +4199,19 @@ prlsdkGetBlockStats(virDomainObjPtr dom,
 
 
 static PRL_HANDLE
-prlsdkFindNetByPath(virDomainObjPtr dom, const char *path)
+prlsdkFindNetByPath(PRL_HANDLE sdkdom, const char *path)
 {
     PRL_UINT32 count = 0;
-    vzDomObjPtr privdom = dom->privateData;
     PRL_RESULT pret;
     size_t i;
     char *name = NULL;
     PRL_HANDLE net = PRL_INVALID_HANDLE;
 
-    pret = PrlVmCfg_GetNetAdaptersCount(privdom->sdkdom, &count);
+    pret = PrlVmCfg_GetNetAdaptersCount(sdkdom, &count);
     prlsdkCheckRetGoto(pret, error);
 
     for (i = 0; i < count; ++i) {
-        pret = PrlVmCfg_GetNetAdapter(privdom->sdkdom, i, &net);
+        pret = PrlVmCfg_GetNetAdapter(sdkdom, i, &net);
         prlsdkCheckRetGoto(pret, error);
 
         if (!(name = prlsdkGetStringParamVar(PrlVmDevNet_GetHostInterfaceName,
@@ -4216,7 +4238,9 @@ prlsdkFindNetByPath(virDomainObjPtr dom, const char *path)
 }
 
 int
-prlsdkGetNetStats(virDomainObjPtr dom, const char *path,
+prlsdkGetNetStats(vzCountersCachePtr cache,
+                  PRL_HANDLE sdkdom,
+                  const char *path,
                   virDomainInterfaceStatsPtr stats)
 {
     int ret = -1;
@@ -4225,7 +4249,7 @@ prlsdkGetNetStats(virDomainObjPtr dom, const char *path,
     PRL_RESULT pret;
     PRL_HANDLE net = PRL_INVALID_HANDLE;
 
-    net = prlsdkFindNetByPath(dom, path);
+    net = prlsdkFindNetByPath(sdkdom, path);
     if (net == PRL_INVALID_HANDLE)
        goto cleanup;
 
@@ -4235,7 +4259,7 @@ prlsdkGetNetStats(virDomainObjPtr dom, const char *path,
 #define PRLSDK_GET_NET_COUNTER(VAL, NAME)                           \
     if (virAsprintf(&name, "net.nic%d.%s", net_index, NAME) < 0)    \
         goto cleanup;                                               \
-    if (prlsdkGetStatsParam(dom, name, &stats->VAL) < 0)            \
+    if (vzCountersCacheGetParam(cache, name, &stats->VAL) < 0)      \
         goto cleanup;                                               \
     VIR_FREE(name);
 
@@ -4259,7 +4283,7 @@ prlsdkGetNetStats(virDomainObjPtr dom, const char *path,
 }
 
 int
-prlsdkGetVcpuStats(virDomainObjPtr dom, int idx, unsigned long long *vtime)
+prlsdkGetVcpuStats(vzCountersCachePtr cache, int idx, unsigned long long *vtime)
 {
     char *name = NULL;
     long long ptime = 0;
@@ -4267,7 +4291,7 @@ prlsdkGetVcpuStats(virDomainObjPtr dom, int idx, unsigned long long *vtime)
 
     if (virAsprintf(&name, "guest.vcpu%u.time", (unsigned int)idx) < 0)
         goto cleanup;
-    if (prlsdkGetStatsParam(dom, name, &ptime) < 0)
+    if (vzCountersCacheGetParam(cache, name, &ptime) < 0)
         goto cleanup;
     *vtime = ptime == -1 ? 0 : ptime;
     ret = 0;
@@ -4278,7 +4302,7 @@ prlsdkGetVcpuStats(virDomainObjPtr dom, int idx, unsigned long long *vtime)
 }
 
 int
-prlsdkGetMemoryStats(virDomainObjPtr dom,
+prlsdkGetMemoryStats(vzCountersCachePtr cache,
                      virDomainMemoryStatPtr stats,
                      unsigned int nr_stats)
 {
@@ -4287,7 +4311,7 @@ prlsdkGetMemoryStats(virDomainObjPtr dom,
     size_t i = 0;
 
 #define PRLSDK_GET_COUNTER(NAME, VALUE)                             \
-    if (prlsdkGetStatsParam(dom, NAME, &VALUE) < 0)                 \
+    if (vzCountersCacheGetParam(cache, NAME, &VALUE) < 0)           \
         goto cleanup;                                               \
 
 #define PRLSDK_MEMORY_STAT_SET(TAG, VALUE)                          \
diff --git a/src/vz/vz_sdk.h b/src/vz/vz_sdk.h
index 033a3fe..87466e7 100644
--- a/src/vz/vz_sdk.h
+++ b/src/vz/vz_sdk.h
@@ -68,17 +68,20 @@ int
 prlsdkDetachVolume(virDomainObjPtr dom, virDomainDiskDefPtr disk);
 char* prlsdkGetDiskStatName(virDomainDiskDefPtr disk);
 int
-prlsdkGetBlockStats(virDomainObjPtr dom, const char *disk, virDomainBlockStatsPtr stats);
+prlsdkGetBlockStats(vzCountersCachePtr cache, const char *disk, virDomainBlockStatsPtr stats);
 int
 prlsdkAttachNet(vzDriverPtr driver, virDomainObjPtr dom, virDomainNetDefPtr net);
 int
 prlsdkDetachNet(vzDriverPtr driver, virDomainObjPtr dom, virDomainNetDefPtr net);
 int
-prlsdkGetNetStats(virDomainObjPtr dom, const char *path, virDomainInterfaceStatsPtr stats);
+prlsdkGetNetStats(vzCountersCachePtr cache,
+                  PRL_HANDLE sdkdom,
+                  const char *path,
+                  virDomainInterfaceStatsPtr stats);
 int
-prlsdkGetVcpuStats(virDomainObjPtr dom, int idx, unsigned long long *time);
+prlsdkGetVcpuStats(vzCountersCachePtr cache, int idx, unsigned long long *time);
 int
-prlsdkGetMemoryStats(virDomainObjPtr dom, virDomainMemoryStatPtr stats, unsigned int nr_stats);
+prlsdkGetMemoryStats(vzCountersCachePtr cache, virDomainMemoryStatPtr stats, unsigned int nr_stats);
 void
 prlsdkDomObjFreePrivate(void *p);
 /* memsize is in MiB */
@@ -94,3 +97,6 @@ prlsdkMigrate(virDomainObjPtr dom,
               const char unsigned *session_uuid,
               const char *dname,
               unsigned int flags);
+
+int vzCountersCacheBegin(vzCountersCachePtr cache);
+void vzCountersCacheEnd(vzCountersCachePtr cache);
diff --git a/src/vz/vz_utils.h b/src/vz/vz_utils.h
index 43d46ca..a3ff152 100644
--- a/src/vz/vz_utils.h
+++ b/src/vz/vz_utils.h
@@ -95,7 +95,9 @@ typedef struct _vzConn *vzConnPtr;
 
 
 struct _vzCountersCache {
+    PRL_HANDLE sdkdom; /* unreferenced */
     PRL_HANDLE stats;
+    virMutex lock;
     virCond cond;
     /* = -1 - unsubscribed
        > -1 - subscribed */
-- 
1.8.3.1




More information about the libvir-list mailing list