[libvirt] [PATCH 1/5] vz: provide block stats for all domain stats

Nikolay Shirokovskiy nshirokovskiy at virtuozzo.com
Mon Dec 12 07:56:34 UTC 2016


---
 src/vz/vz_driver.c | 189 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/vz/vz_sdk.c    |   8 +++
 2 files changed, 197 insertions(+)

diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c
index 08f7961..6d173ef 100644
--- a/src/vz/vz_driver.c
+++ b/src/vz/vz_driver.c
@@ -3508,6 +3508,194 @@ vzDomainGetJobStats(virDomainPtr domain,
     return ret;
 }
 
+#define VZ_ADD_STAT_PARAM_UUL(group, field, counter)            \
+do {                                                            \
+    if (stat.field != -1) {                                     \
+        snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,      \
+                 group ".%zu." counter, i);                     \
+        if (virTypedParamsAddULLong(&record->params,            \
+                                    &record->nparams,           \
+                                    maxparams,                  \
+                                    param_name,                 \
+                                    stat.field) < 0)            \
+            return -1;                                          \
+    }                                                           \
+} while (0)
+
+static int
+vzDomainGetBlockStats(virDomainObjPtr dom,
+                      virDomainStatsRecordPtr record,
+                      int *maxparams)
+{
+    vzDomObjPtr privdom = dom->privateData;
+    size_t i;
+    char param_name[VIR_TYPED_PARAM_FIELD_LENGTH];
+
+    if (virTypedParamsAddUInt(&record->params,
+                              &record->nparams,
+                              maxparams,
+                              "block.count",
+                              dom->def->ndisks) < 0)
+        return -1;
+
+    for (i = 0; i < dom->def->ndisks; i++) {
+        virDomainBlockStatsStruct stat;
+        virDomainDiskDefPtr disk = dom->def->disks[i];
+
+        if (prlsdkGetBlockStats(privdom->stats, disk, &stat) < 0)
+            return -1;
+
+        snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
+                 "block.%zu.name", i);
+        if (virTypedParamsAddString(&record->params,
+                                    &record->nparams,
+                                    maxparams,
+                                    param_name,
+                                    disk->dst) < 0)
+            return -1;
+
+        if (virStorageSourceIsLocalStorage(disk->src) && disk->src->path) {
+            snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
+                     "block.%zu.path", i);
+            if (virTypedParamsAddString(&record->params,
+                                        &record->nparams,
+                                        maxparams,
+                                        param_name,
+                                        disk->src->path) < 0)
+                return -1;
+        }
+
+        VZ_ADD_STAT_PARAM_UUL("block", rd_req, "rd.reqs");
+        VZ_ADD_STAT_PARAM_UUL("block", rd_bytes, "rd.bytes");
+        VZ_ADD_STAT_PARAM_UUL("block", wr_req, "wr.reqs");
+        VZ_ADD_STAT_PARAM_UUL("block", wr_bytes, "wr.bytes");
+
+        if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
+            snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
+                     "block.%zu.capacity", i);
+            if (virTypedParamsAddULLong(&record->params,
+                                        &record->nparams,
+                                        maxparams,
+                                        param_name,
+                                        disk->src->capacity) < 0)
+                return -1;
+        }
+
+    }
+
+    return 0;
+}
+
+static virDomainStatsRecordPtr
+vzDomainGetAllStats(virConnectPtr conn,
+                    virDomainObjPtr dom)
+{
+    virDomainStatsRecordPtr stat;
+    int maxparams = 0;
+
+    if (VIR_ALLOC(stat) < 0)
+        return NULL;
+
+    if (vzDomainGetBlockStats(dom, stat, &maxparams) < 0)
+        goto error;
+
+    if (!(stat->dom = virGetDomain(conn, dom->def->name, dom->def->uuid)))
+        goto error;
+
+    return stat;
+
+ error:
+    virTypedParamsFree(stat->params, stat->nparams);
+    virObjectUnref(stat->dom);
+    VIR_FREE(stat);
+    return NULL;
+}
+
+static int
+vzConnectGetAllDomainStats(virConnectPtr conn,
+                           virDomainPtr *domains,
+                           unsigned int ndomains,
+                           unsigned int stats,
+                           virDomainStatsRecordPtr **retStats,
+                           unsigned int flags)
+{
+    vzConnPtr privconn = conn->privateData;
+    vzDriverPtr driver = privconn->driver;
+    unsigned int lflags = flags & (VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE |
+                                   VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT |
+                                   VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE);
+    unsigned int supported = VIR_DOMAIN_STATS_STATE |
+                             VIR_DOMAIN_STATS_VCPU |
+                             VIR_DOMAIN_STATS_INTERFACE |
+                             VIR_DOMAIN_STATS_BALLOON |
+                             VIR_DOMAIN_STATS_BLOCK;
+    virDomainObjPtr *doms = NULL;
+    size_t ndoms;
+    virDomainStatsRecordPtr *tmpstats = NULL;
+    int nstats = 0;
+    int ret = -1;
+    size_t i;
+
+    virCheckFlags(VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE |
+                  VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT |
+                  VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE |
+                  VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS, -1);
+
+    if (virConnectGetAllDomainStatsEnsureACL(conn) < 0)
+        return -1;
+
+    if (!stats) {
+        stats = supported;
+    } else if ((flags & VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS) &&
+               (stats & ~supported)) {
+        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED,
+                       _("Stats types bits 0x%x are not supported by this daemon"),
+                       stats & ~supported);
+        return -1;
+    }
+
+    if (ndomains) {
+        if (virDomainObjListConvert(driver->domains, conn, domains, ndomains, &doms,
+                                    &ndoms, virConnectGetAllDomainStatsCheckACL,
+                                    lflags, true) < 0)
+            return -1;
+    } else {
+        if (virDomainObjListCollect(driver->domains, conn, &doms, &ndoms,
+                                    virConnectGetAllDomainStatsCheckACL,
+                                    lflags) < 0)
+            return -1;
+    }
+
+    if (VIR_ALLOC_N(tmpstats, ndoms + 1) < 0)
+        goto cleanup;
+
+    for (i = 0; i < ndoms; i++) {
+        virDomainStatsRecordPtr tmp;
+        virDomainObjPtr dom = doms[i];
+
+        virObjectLock(dom);
+        tmp = vzDomainGetAllStats(conn, dom);
+        virObjectUnlock(dom);
+
+        if (!tmp)
+            goto cleanup;
+
+        tmpstats[nstats++] = tmp;
+    }
+
+    *retStats = tmpstats;
+    tmpstats = NULL;
+    ret = nstats;
+
+ cleanup:
+    virDomainStatsRecordListFree(tmpstats);
+    virObjectListFreeCount(doms, ndoms);
+
+    return ret;
+}
+
+#undef VZ_ADD_STAT_PARAM_UUL
+
 static virHypervisorDriver vzHypervisorDriver = {
     .name = "vz",
     .connectOpen = vzConnectOpen,            /* 0.10.0 */
@@ -3603,6 +3791,7 @@ static virHypervisorDriver vzHypervisorDriver = {
     .domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
     .domainGetJobInfo = vzDomainGetJobInfo, /* 2.2.0 */
     .domainGetJobStats = vzDomainGetJobStats, /* 2.2.0 */
+    .connectGetAllDomainStats = vzConnectGetAllDomainStats, /* 3.0.0 */
 };
 
 static virConnectDriver vzConnectDriver = {
diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c
index d13c86a..9566daf 100644
--- a/src/vz/vz_sdk.c
+++ b/src/vz/vz_sdk.c
@@ -592,6 +592,7 @@ prlsdkGetDiskInfo(vzDriverPtr driver,
     char *buf = NULL;
     PRL_RESULT pret;
     PRL_UINT32 emulatedType;
+    PRL_UINT32 size;
     virDomainDeviceDriveAddressPtr address;
     int busIdx, devIdx;
     int ret = -1;
@@ -650,6 +651,13 @@ prlsdkGetDiskInfo(vzDriverPtr driver,
     if (virDomainDiskSetDriver(disk, "vz") < 0)
         goto cleanup;
 
+    if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
+        pret = PrlVmDevHd_GetDiskSize(prldisk, &size);
+        prlsdkCheckRetGoto(pret, cleanup);
+        /* from MiB to bytes */
+        disk->src->capacity = ((unsigned long long)size) << 20;
+    }
+
     ret = 0;
 
  cleanup:
-- 
1.8.3.1




More information about the libvir-list mailing list