[libvirt] [PATCHv2 3/5] qemu: Implement bulk stats API and one of the stats groups to return

Peter Krempa pkrempa at redhat.com
Tue Aug 26 14:14:51 UTC 2014


Implement the API function for virDomainListGetStats and
virConnectGetAllDomainStats in a modular way and implement the
VIR_DOMAIN_STATS_STATE group of statistics.
---
 src/qemu/qemu_driver.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 175 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index ad75bd9..7ec2751 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -17112,6 +17112,180 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
 }


+static int
+qemuDomainGetStatsState(virDomainObjPtr dom,
+                        virDomainStatsRecordPtr record,
+                        int *maxparams,
+                        unsigned int privflags ATTRIBUTE_UNUSED)
+{
+    if (virTypedParamsAddInt(&record->params,
+                             &record->nparams,
+                             maxparams,
+                             "state.state",
+                             dom->state.state) < 0)
+        return -1;
+
+    if (virTypedParamsAddInt(&record->params,
+                             &record->nparams,
+                             maxparams,
+                             "state.reason",
+                             dom->state.reason) < 0)
+        return -1;
+
+
+    return 0;
+}
+
+
+typedef int
+(*virDomainGetStatsFunc)(virDomainObjPtr dom,
+                         virDomainStatsRecordPtr record,
+                         int *maxparams,
+                         unsigned int flags);
+
+struct virDomainGetStatsWorker {
+    virDomainGetStatsFunc func;
+    unsigned int stats;
+};
+
+static struct virDomainGetStatsWorker virDomainGetStatsWorkers[] = {
+    { qemuDomainGetStatsState, VIR_DOMAIN_STATS_STATE},
+    { NULL, 0 }
+};
+
+
+static int
+virDomainGetStats(virConnectPtr conn,
+                  virDomainObjPtr dom,
+                  unsigned int stats,
+                  virDomainStatsRecordPtr *record,
+                  unsigned int flags)
+{
+    int maxparams = 0;
+    virDomainStatsRecordPtr tmp;
+    size_t i;
+    int ret = -1;
+
+    if (VIR_ALLOC(tmp) < 0)
+        goto cleanup;
+
+    for (i = 0; virDomainGetStatsWorkers[i].func; i++) {
+        if (stats & VIR_DOMAIN_STATS_ALL ||
+            stats & virDomainGetStatsWorkers[i].stats) {
+            if (virDomainGetStatsWorkers[i].func(dom, tmp, &maxparams,
+                                                 flags) < 0)
+                goto cleanup;
+
+            if (stats & virDomainGetStatsWorkers[i].stats)
+                stats &= ~(stats & virDomainGetStatsWorkers[i].stats);
+        }
+    }
+
+    if (stats & ~VIR_DOMAIN_STATS_ALL) {
+        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED,
+                       _("Stats types bits 0x%x are not supported by this daemon"),
+                       stats);
+        goto cleanup;
+    }
+
+    /* domain obj construction has to be last so that we don't
+     * need to free it on error as freeing func clears the error code */
+    if (!(tmp->dom = virGetDomain(conn, dom->def->name, dom->def->uuid)))
+        goto cleanup;
+
+    *record = tmp;
+    tmp = NULL;
+    ret = 0;
+
+ cleanup:
+    if (tmp) {
+        virTypedParamsFree(tmp->params, tmp->nparams);
+        VIR_FREE(tmp);
+    }
+
+    return ret;
+}
+
+
+static int
+qemuDomainListGetStats(virConnectPtr conn,
+                       virDomainPtr *doms,
+                       unsigned int ndoms,
+                       unsigned int stats,
+                       virDomainStatsRecordPtr **retStats,
+                       unsigned int flags)
+{
+    virQEMUDriverPtr driver = conn->privateData;
+    virDomainPtr *domlist = NULL;
+    virDomainObjPtr dom = NULL;
+    virDomainStatsRecordPtr *tmpstats = NULL;
+    int ntempdoms;
+    int nstats = 0;
+    size_t i;
+    int ret = -1;
+
+    virCheckFlags(0, -1);
+
+    if (!ndoms) {
+        if ((ntempdoms = virDomainObjListExport(driver->domains,
+                                                conn,
+                                                &domlist,
+                                                NULL,
+                                                0)) < 0)
+            goto cleanup;
+
+        ndoms = ntempdoms;
+        doms = domlist;
+    }
+
+    if (VIR_ALLOC_N(tmpstats, ndoms + 1) < 0)
+        goto cleanup;
+
+    for (i = 0; i < ndoms; i++) {
+        virDomainStatsRecordPtr tmp = NULL;
+
+        if (!(dom = qemuDomObjFromDomain(doms[i]))) {
+            if (domlist)
+                continue;
+        }
+
+        if (!domlist &&
+            virDomainListGetStatsEnsureACL(conn, dom->def) < 0)
+            continue;
+
+        if (virDomainGetStats(conn, dom, stats, &tmp, flags) < 0)
+            goto cleanup;
+
+        if (tmp)
+            tmpstats[nstats++] = tmp;
+
+        virObjectUnlock(dom);
+        dom = NULL;
+    }
+
+    *retStats = tmpstats;
+    tmpstats = NULL;
+
+    ret = nstats;
+
+ cleanup:
+    if (dom)
+        virObjectUnlock(dom);
+
+    if (tmpstats)
+        virDomainStatsRecordListFree(tmpstats);
+
+    if (domlist) {
+        for (i = 0; i < ndoms; i++)
+            virObjectUnref(domlist[i]);
+
+        VIR_FREE(domlist);
+    }
+
+    return ret;
+}
+
+
 static virDriver qemuDriver = {
     .no = VIR_DRV_QEMU,
     .name = QEMU_DRIVER_NAME,
@@ -17308,6 +17482,7 @@ static virDriver qemuDriver = {
     .domainSetTime = qemuDomainSetTime, /* 1.2.5 */
     .nodeGetFreePages = qemuNodeGetFreePages, /* 1.2.6 */
     .connectGetDomainCapabilities = qemuConnectGetDomainCapabilities, /* 1.2.7 */
+    .domainListGetStats = qemuDomainListGetStats, /* 1.2.8 */
 };


-- 
2.0.2




More information about the libvir-list mailing list