9119d9
From 5f9e238175a43da530e2bfc7946cd81659bad915 Mon Sep 17 00:00:00 2001
9119d9
Message-Id: <5f9e238175a43da530e2bfc7946cd81659bad915@dist-git>
9119d9
From: Francesco Romani <fromani@redhat.com>
9119d9
Date: Wed, 1 Oct 2014 11:20:11 +0200
9119d9
Subject: [PATCH] qemu: bulk stats: extend internal collection API
9119d9
9119d9
https://bugzilla.redhat.com/show_bug.cgi?id=1113116
9119d9
9119d9
Future patches which will implement more bulk stats groups for QEMU will
9119d9
need to access the connection object.
9119d9
9119d9
To accommodate that, a few changes are needed:
9119d9
9119d9
* enrich internal prototype to pass qemu driver object
9119d9
9119d9
* add per-group flag to mark if one collector needs monitor access or not
9119d9
9119d9
* If at least one collector of the requested stats needs monitor access
9119d9
  we must start a query job for each domain.  The specific collectors
9119d9
  will run nested monitor jobs inside that.
9119d9
9119d9
* If the job can't be acquired we pass flags to the collector so
9119d9
  specific collectors that need monitor access can be skipped in order
9119d9
  to gather as much data as is possible.
9119d9
9119d9
Signed-off-by: Francesco Romani <fromani@redhat.com>
9119d9
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
9119d9
(cherry picked from commit 1f4831ee6ecc17d0f2008d7db15bfd9bc3b1d685)
9119d9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
9119d9
---
9119d9
 src/qemu/qemu_driver.c | 63 +++++++++++++++++++++++++++++++++++++++++++-------
9119d9
 1 file changed, 55 insertions(+), 8 deletions(-)
9119d9
9119d9
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
9119d9
index 08f0142..1d94330 100644
9119d9
--- a/src/qemu/qemu_driver.c
9119d9
+++ b/src/qemu/qemu_driver.c
9119d9
@@ -17412,7 +17412,8 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
9119d9
 
9119d9
 
9119d9
 static int
9119d9
-qemuDomainGetStatsState(virDomainObjPtr dom,
9119d9
+qemuDomainGetStatsState(virQEMUDriverPtr driver ATTRIBUTE_UNUSED,
9119d9
+                        virDomainObjPtr dom,
9119d9
                         virDomainStatsRecordPtr record,
9119d9
                         int *maxparams,
9119d9
                         unsigned int privflags ATTRIBUTE_UNUSED)
9119d9
@@ -17435,8 +17436,18 @@ qemuDomainGetStatsState(virDomainObjPtr dom,
9119d9
 }
9119d9
 
9119d9
 
9119d9
+typedef enum {
9119d9
+    QEMU_DOMAIN_STATS_HAVE_JOB = (1 << 0), /* job is entered, monitor can be
9119d9
+                                              accessed */
9119d9
+} qemuDomainStatsFlags;
9119d9
+
9119d9
+
9119d9
+#define HAVE_JOB(flags) ((flags) & QEMU_DOMAIN_STATS_HAVE_JOB)
9119d9
+
9119d9
+
9119d9
 typedef int
9119d9
-(*qemuDomainGetStatsFunc)(virDomainObjPtr dom,
9119d9
+(*qemuDomainGetStatsFunc)(virQEMUDriverPtr driver,
9119d9
+                          virDomainObjPtr dom,
9119d9
                           virDomainStatsRecordPtr record,
9119d9
                           int *maxparams,
9119d9
                           unsigned int flags);
9119d9
@@ -17444,11 +17455,12 @@ typedef int
9119d9
 struct qemuDomainGetStatsWorker {
9119d9
     qemuDomainGetStatsFunc func;
9119d9
     unsigned int stats;
9119d9
+    bool monitor;
9119d9
 };
9119d9
 
9119d9
 static struct qemuDomainGetStatsWorker qemuDomainGetStatsWorkers[] = {
9119d9
-    { qemuDomainGetStatsState, VIR_DOMAIN_STATS_STATE},
9119d9
-    { NULL, 0 }
9119d9
+    { qemuDomainGetStatsState, VIR_DOMAIN_STATS_STATE, false },
9119d9
+    { NULL, 0, false }
9119d9
 };
9119d9
 
9119d9
 
9119d9
@@ -17480,6 +17492,20 @@ qemuDomainGetStatsCheckSupport(unsigned int *stats,
9119d9
 }
9119d9
 
9119d9
 
9119d9
+static bool
9119d9
+qemuDomainGetStatsNeedMonitor(unsigned int stats)
9119d9
+{
9119d9
+    size_t i;
9119d9
+
9119d9
+    for (i = 0; qemuDomainGetStatsWorkers[i].func; i++)
9119d9
+        if (stats & qemuDomainGetStatsWorkers[i].stats &&
9119d9
+            qemuDomainGetStatsWorkers[i].monitor)
9119d9
+            return true;
9119d9
+
9119d9
+    return false;
9119d9
+}
9119d9
+
9119d9
+
9119d9
 static int
9119d9
 qemuDomainGetStats(virConnectPtr conn,
9119d9
                    virDomainObjPtr dom,
9119d9
@@ -17497,8 +17523,8 @@ qemuDomainGetStats(virConnectPtr conn,
9119d9
 
9119d9
     for (i = 0; qemuDomainGetStatsWorkers[i].func; i++) {
9119d9
         if (stats & qemuDomainGetStatsWorkers[i].stats) {
9119d9
-            if (qemuDomainGetStatsWorkers[i].func(dom, tmp, &maxparams,
9119d9
-                                                  flags) < 0)
9119d9
+            if (qemuDomainGetStatsWorkers[i].func(conn->privateData, dom, tmp,
9119d9
+                                                  &maxparams, flags) < 0)
9119d9
                 goto cleanup;
9119d9
         }
9119d9
     }
9119d9
@@ -17537,6 +17563,8 @@ qemuConnectGetAllDomainStats(virConnectPtr conn,
9119d9
     int nstats = 0;
9119d9
     size_t i;
9119d9
     int ret = -1;
9119d9
+    unsigned int privflags = 0;
9119d9
+    unsigned int domflags = 0;
9119d9
 
9119d9
     if (ndoms)
9119d9
         virCheckFlags(VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS, -1);
9119d9
@@ -17571,7 +17599,11 @@ qemuConnectGetAllDomainStats(virConnectPtr conn,
9119d9
     if (VIR_ALLOC_N(tmpstats, ndoms + 1) < 0)
9119d9
         goto cleanup;
9119d9
 
9119d9
+    if (qemuDomainGetStatsNeedMonitor(stats))
9119d9
+        privflags |= QEMU_DOMAIN_STATS_HAVE_JOB;
9119d9
+
9119d9
     for (i = 0; i < ndoms; i++) {
9119d9
+        domflags = privflags;
9119d9
         virDomainStatsRecordPtr tmp = NULL;
9119d9
 
9119d9
         if (!(dom = qemuDomObjFromDomain(doms[i])))
9119d9
@@ -17581,12 +17613,22 @@ qemuConnectGetAllDomainStats(virConnectPtr conn,
9119d9
             !virConnectGetAllDomainStatsCheckACL(conn, dom->def))
9119d9
             continue;
9119d9
 
9119d9
-        if (qemuDomainGetStats(conn, dom, stats, &tmp, flags) < 0)
9119d9
-            goto cleanup;
9119d9
+        if (HAVE_JOB(domflags) &&
9119d9
+            qemuDomainObjBeginJob(driver, dom, QEMU_JOB_QUERY) < 0)
9119d9
+            /* As it was never requested. Gather as much as possible anyway. */
9119d9
+            domflags &= ~QEMU_DOMAIN_STATS_HAVE_JOB;
9119d9
+
9119d9
+        if (qemuDomainGetStats(conn, dom, stats, &tmp, domflags) < 0)
9119d9
+            goto endjob;
9119d9
 
9119d9
         if (tmp)
9119d9
             tmpstats[nstats++] = tmp;
9119d9
 
9119d9
+        if (HAVE_JOB(domflags) && !qemuDomainObjEndJob(driver, dom)) {
9119d9
+            dom = NULL;
9119d9
+            continue;
9119d9
+        }
9119d9
+
9119d9
         virObjectUnlock(dom);
9119d9
         dom = NULL;
9119d9
     }
9119d9
@@ -17596,6 +17638,11 @@ qemuConnectGetAllDomainStats(virConnectPtr conn,
9119d9
 
9119d9
     ret = nstats;
9119d9
 
9119d9
+ endjob:
9119d9
+    if (HAVE_JOB(domflags) && dom)
9119d9
+        if (!qemuDomainObjEndJob(driver, dom))
9119d9
+            dom = NULL;
9119d9
+
9119d9
  cleanup:
9119d9
     if (dom)
9119d9
         virObjectUnlock(dom);
9119d9
-- 
9119d9
2.1.2
9119d9