]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: monitor: Retrieve blockstats also by qdev and node-names
authorPeter Krempa <pkrempa@redhat.com>
Fri, 3 Aug 2018 14:22:19 +0000 (16:22 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Tue, 21 Aug 2018 13:46:06 +0000 (15:46 +0200)
For use with -blockdev we need to be able to retrieve the stats by
'qdev' for the frontend device stats since 'device' will be empty. Note
that for non-blockdev case qdev and 'device' with 'drive-' skipped would
be the same.

Additionally so that we can report the highest written offset we need to
also be able to access them by node-name for backing chain purposes.

In cases when 'device' is empty it does not make sense to gather them.

Allow arranging the stats simultaneously in all the above dimensions.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/qemu/qemu_monitor_json.c

index 502a740fd3324d21792bcefbdc6faf44ee311bf3..d4ff9ff97b57c914c8e8ba281abbe5efe1049796 100644 (file)
@@ -2332,6 +2332,28 @@ qemuMonitorJSONBlockStatsCollectData(virJSONValuePtr dev,
 }
 
 
+static int
+qemuMonitorJSONAddOneBlockStatsInfo(qemuBlockStatsPtr bstats,
+                                    const char *name,
+                                    virHashTablePtr stats)
+{
+    qemuBlockStatsPtr copy = NULL;
+
+    if (VIR_ALLOC(copy) < 0)
+        return -1;
+
+    if (bstats)
+        *copy = *bstats;
+
+    if (virHashAddEntry(stats, name, copy) < 0) {
+        VIR_FREE(copy);
+        return -1;
+    }
+
+    return 0;
+}
+
+
 static int
 qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev,
                                     const char *dev_name,
@@ -2342,18 +2364,38 @@ qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev,
     qemuBlockStatsPtr bstats = NULL;
     int ret = -1;
     int nstats = 0;
-    char *entry_name = qemuDomainStorageAlias(dev_name, depth);
+    const char *qdevname = NULL;
+    const char *nodename = NULL;
+    char *devicename = NULL;
     virJSONValuePtr backing;
 
-    if (!entry_name)
+    if (dev_name &&
+        !(devicename = qemuDomainStorageAlias(dev_name, depth)))
         goto cleanup;
 
+    qdevname = virJSONValueObjectGetString(dev, "qdev");
+    nodename = virJSONValueObjectGetString(dev, "node-name");
+
+    if (!devicename && !qdevname && !nodename) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("blockstats device entry was not in expected format"));
+        goto cleanup;
+    }
+
     if (!(bstats = qemuMonitorJSONBlockStatsCollectData(dev, &nstats)))
         goto cleanup;
 
-    if (virHashAddEntry(hash, entry_name, bstats) < 0)
+    if (devicename &&
+        qemuMonitorJSONAddOneBlockStatsInfo(bstats, devicename, hash) < 0)
+        goto cleanup;
+
+    if (qdevname && STRNEQ_NULLABLE(qdevname, devicename) &&
+        qemuMonitorJSONAddOneBlockStatsInfo(bstats, qdevname, hash) < 0)
+        goto cleanup;
+
+    if (nodename &&
+        qemuMonitorJSONAddOneBlockStatsInfo(bstats, nodename, hash) < 0)
         goto cleanup;
-    bstats = NULL;
 
     if (backingChain &&
         (backing = virJSONValueObjectGetObject(dev, "backing")) &&
@@ -2364,7 +2406,7 @@ qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev,
     ret = nstats;
  cleanup:
     VIR_FREE(bstats);
-    VIR_FREE(entry_name);
+    VIR_FREE(devicename);
     return ret;
 }
 
@@ -2426,6 +2468,9 @@ qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
             goto cleanup;
         }
 
+        if (*dev_name == '\0')
+            dev_name = NULL;
+
         rc = qemuMonitorJSONGetOneBlockStatsInfo(dev, dev_name, 0, hash,
                                                  backingChain);