]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
qemu: monitor: Count block stats fields in qemuMonitorGetAllBlockStatsInfo
authorPeter Krempa <pkrempa@redhat.com>
Tue, 10 Mar 2015 13:40:58 +0000 (14:40 +0100)
committerPeter Krempa <pkrempa@redhat.com>
Wed, 11 Mar 2015 10:28:04 +0000 (11:28 +0100)
Our virDomainBlockStatsFlags API uses the old approach where, when it's
called without the typed parameter array, returns the count of parameters
supported by qemu.

The supported parameter count is obtained via separate monitor calls
which is a waste since we can calculate it when gathering the data.

This patch adds code to the qemuMonitorGetAllBlockStatsInfo workers that
allows to track the count of supported fields reported by qemu and will
allow to remove the old duplicate code.

src/qemu/qemu_monitor.c
src/qemu/qemu_monitor_json.c
src/qemu/qemu_monitor_text.c

index 149e7431d9ec7633af8d3af54c37ca2a5b171d5a..851a1859d03424f6d2e9c28b2e85fb616316df6d 100644 (file)
@@ -1848,14 +1848,24 @@ int qemuMonitorGetBlockStatsInfo(qemuMonitorPtr mon,
 }
 
 
-/* Creates a hash table in 'ret_stats' with all block stats.
- * Returns <0 on error, 0 on success.
+/**
+ * qemuMonitorGetAllBlockStatsInfo:
+ * @mon: monitor object
+ * @ret_stats: pointer that is filled with a hash table containing the stats
+ * @backingChain: recurse into the backing chain of devices
+ *
+ * Creates a hash table in @ret_stats with block stats of all devices. In case
+ * @backingChain is true @ret_stats will additionally contain stats for
+ * backing chain members of block devices.
+ *
+ * Returns < 0 on error, count of supported block stats fields on success.
  */
 int
 qemuMonitorGetAllBlockStatsInfo(qemuMonitorPtr mon,
                                 virHashTablePtr *ret_stats,
                                 bool backingChain)
 {
+    int ret = -1;
     VIR_DEBUG("mon=%p ret_stats=%p, backing=%d", mon, ret_stats, backingChain);
 
     if (!mon->json) {
@@ -1868,8 +1878,8 @@ qemuMonitorGetAllBlockStatsInfo(qemuMonitorPtr mon,
         goto error;
 
     if (mon->json) {
-        if (qemuMonitorJSONGetAllBlockStatsInfo(mon, *ret_stats, backingChain) < 0)
-            goto error;
+        ret = qemuMonitorJSONGetAllBlockStatsInfo(mon, *ret_stats,
+                                                  backingChain);
     } else {
          if (backingChain) {
              virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
@@ -1878,11 +1888,13 @@ qemuMonitorGetAllBlockStatsInfo(qemuMonitorPtr mon,
              goto error;
          }
 
-         if (qemuMonitorTextGetAllBlockStatsInfo(mon, *ret_stats) < 0)
-             goto error;
+         ret = qemuMonitorTextGetAllBlockStatsInfo(mon, *ret_stats);
     }
 
-    return 0;
+    if (ret < 0)
+        goto error;
+
+    return ret;
 
  error:
     virHashFree(*ret_stats);
index 931b86584932a73b17fa1c819a9b847c02d228a4..530df96f5469c945a661362d4aac8a26026c5209 100644 (file)
@@ -1773,6 +1773,7 @@ qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev,
     qemuBlockStatsPtr bstats = NULL;
     virJSONValuePtr stats;
     int ret = -1;
+    int nstats = 0;
     char *entry_name = qemuDomainStorageAlias(dev_name, depth);
     virJSONValuePtr backing;
 
@@ -1791,6 +1792,7 @@ qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev,
 
 #define QEMU_MONITOR_BLOCK_STAT_GET(NAME, VAR, MANDATORY)                      \
     if (MANDATORY || virJSONValueObjectHasKey(stats, NAME)) {                  \
+        nstats++;                                                              \
         if (virJSONValueObjectGetNumberLong(stats, NAME, &VAR) < 0) {          \
             virReportError(VIR_ERR_INTERNAL_ERROR,                             \
                            _("cannot read %s statistic"), NAME);               \
@@ -1820,7 +1822,7 @@ qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev,
                                             hash, true) < 0)
         goto cleanup;
 
-    ret = 0;
+    ret = nstats;
  cleanup:
     VIR_FREE(bstats);
     VIR_FREE(entry_name);
@@ -1834,6 +1836,7 @@ qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
                                     bool backingChain)
 {
     int ret = -1;
+    int nstats = 0;
     int rc;
     size_t i;
     virJSONValuePtr cmd;
@@ -1874,13 +1877,17 @@ qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
             goto cleanup;
         }
 
-        if (qemuMonitorJSONGetOneBlockStatsInfo(dev, dev_name, 0, hash,
-                                                backingChain) < 0)
+        rc = qemuMonitorJSONGetOneBlockStatsInfo(dev, dev_name, 0, hash,
+                                                 backingChain);
+
+        if (rc < 0)
             goto cleanup;
 
+        if (rc > nstats)
+            nstats = rc;
     }
 
-    ret = 0;
+    ret = nstats;
 
  cleanup:
     virJSONValueFree(cmd);
index 8b2ef90ee8edb2c85e5236c47230b208d6302c62..203859cc9c459b32872162172aed9a6fae0743bf 100644 (file)
@@ -854,6 +854,8 @@ qemuMonitorTextGetAllBlockStatsInfo(qemuMonitorPtr mon,
     size_t i;
     size_t j;
     int ret = -1;
+    int nstats;
+    int maxstats = 0;
 
     if (qemuMonitorHMPCommand(mon, "info blockstats", &info) < 0)
         goto cleanup;
@@ -911,6 +913,8 @@ qemuMonitorTextGetAllBlockStatsInfo(qemuMonitorPtr mon,
         if (!(values = virStringSplit(line, " ", 0)))
             goto cleanup;
 
+        nstats = 0;
+
         for (j = 0; values[j] && *values[j]; j++) {
             key = values[j];
 
@@ -925,6 +929,7 @@ qemuMonitorTextGetAllBlockStatsInfo(qemuMonitorPtr mon,
 
 #define QEMU_MONITOR_TEXT_READ_BLOCK_STAT(NAME, VAR)                           \
             if (STREQ(key, NAME)) {                                            \
+                nstats++;                                                      \
                 if (virStrToLong_ll(value, NULL, 10, &VAR) < 0) {              \
                     virReportError(VIR_ERR_INTERNAL_ERROR,                     \
                                    _("'info blockstats' contains malformed "   \
@@ -948,6 +953,9 @@ qemuMonitorTextGetAllBlockStatsInfo(qemuMonitorPtr mon,
             VIR_DEBUG("unknown block stat field '%s'", key);
         }
 
+        if (nstats > maxstats)
+            maxstats = nstats;
+
         if (virHashAddEntry(hash, dev_name, stats) < 0)
             goto cleanup;
         stats = NULL;
@@ -956,7 +964,7 @@ qemuMonitorTextGetAllBlockStatsInfo(qemuMonitorPtr mon,
         values = NULL;
     }
 
-    ret = 0;
+    ret = maxstats;
 
  cleanup:
     virStringFreeList(lines);