提交 bdc05128 编写于 作者: P Peter Krempa

qemu: monitor: Count block stats fields in qemuMonitorGetAllBlockStatsInfo

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.
上级 4d8ebb7a
...@@ -1848,14 +1848,24 @@ int qemuMonitorGetBlockStatsInfo(qemuMonitorPtr mon, ...@@ -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 int
qemuMonitorGetAllBlockStatsInfo(qemuMonitorPtr mon, qemuMonitorGetAllBlockStatsInfo(qemuMonitorPtr mon,
virHashTablePtr *ret_stats, virHashTablePtr *ret_stats,
bool backingChain) bool backingChain)
{ {
int ret = -1;
VIR_DEBUG("mon=%p ret_stats=%p, backing=%d", mon, ret_stats, backingChain); VIR_DEBUG("mon=%p ret_stats=%p, backing=%d", mon, ret_stats, backingChain);
if (!mon->json) { if (!mon->json) {
...@@ -1868,8 +1878,8 @@ qemuMonitorGetAllBlockStatsInfo(qemuMonitorPtr mon, ...@@ -1868,8 +1878,8 @@ qemuMonitorGetAllBlockStatsInfo(qemuMonitorPtr mon,
goto error; goto error;
if (mon->json) { if (mon->json) {
if (qemuMonitorJSONGetAllBlockStatsInfo(mon, *ret_stats, backingChain) < 0) ret = qemuMonitorJSONGetAllBlockStatsInfo(mon, *ret_stats,
goto error; backingChain);
} else { } else {
if (backingChain) { if (backingChain) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
...@@ -1878,11 +1888,13 @@ qemuMonitorGetAllBlockStatsInfo(qemuMonitorPtr mon, ...@@ -1878,11 +1888,13 @@ qemuMonitorGetAllBlockStatsInfo(qemuMonitorPtr mon,
goto error; goto error;
} }
if (qemuMonitorTextGetAllBlockStatsInfo(mon, *ret_stats) < 0) ret = qemuMonitorTextGetAllBlockStatsInfo(mon, *ret_stats);
goto error;
} }
return 0; if (ret < 0)
goto error;
return ret;
error: error:
virHashFree(*ret_stats); virHashFree(*ret_stats);
......
...@@ -1773,6 +1773,7 @@ qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev, ...@@ -1773,6 +1773,7 @@ qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev,
qemuBlockStatsPtr bstats = NULL; qemuBlockStatsPtr bstats = NULL;
virJSONValuePtr stats; virJSONValuePtr stats;
int ret = -1; int ret = -1;
int nstats = 0;
char *entry_name = qemuDomainStorageAlias(dev_name, depth); char *entry_name = qemuDomainStorageAlias(dev_name, depth);
virJSONValuePtr backing; virJSONValuePtr backing;
...@@ -1791,6 +1792,7 @@ qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev, ...@@ -1791,6 +1792,7 @@ qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev,
#define QEMU_MONITOR_BLOCK_STAT_GET(NAME, VAR, MANDATORY) \ #define QEMU_MONITOR_BLOCK_STAT_GET(NAME, VAR, MANDATORY) \
if (MANDATORY || virJSONValueObjectHasKey(stats, NAME)) { \ if (MANDATORY || virJSONValueObjectHasKey(stats, NAME)) { \
nstats++; \
if (virJSONValueObjectGetNumberLong(stats, NAME, &VAR) < 0) { \ if (virJSONValueObjectGetNumberLong(stats, NAME, &VAR) < 0) { \
virReportError(VIR_ERR_INTERNAL_ERROR, \ virReportError(VIR_ERR_INTERNAL_ERROR, \
_("cannot read %s statistic"), NAME); \ _("cannot read %s statistic"), NAME); \
...@@ -1820,7 +1822,7 @@ qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev, ...@@ -1820,7 +1822,7 @@ qemuMonitorJSONGetOneBlockStatsInfo(virJSONValuePtr dev,
hash, true) < 0) hash, true) < 0)
goto cleanup; goto cleanup;
ret = 0; ret = nstats;
cleanup: cleanup:
VIR_FREE(bstats); VIR_FREE(bstats);
VIR_FREE(entry_name); VIR_FREE(entry_name);
...@@ -1834,6 +1836,7 @@ qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon, ...@@ -1834,6 +1836,7 @@ qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
bool backingChain) bool backingChain)
{ {
int ret = -1; int ret = -1;
int nstats = 0;
int rc; int rc;
size_t i; size_t i;
virJSONValuePtr cmd; virJSONValuePtr cmd;
...@@ -1874,13 +1877,17 @@ qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon, ...@@ -1874,13 +1877,17 @@ qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
goto cleanup; goto cleanup;
} }
if (qemuMonitorJSONGetOneBlockStatsInfo(dev, dev_name, 0, hash, rc = qemuMonitorJSONGetOneBlockStatsInfo(dev, dev_name, 0, hash,
backingChain) < 0) backingChain);
if (rc < 0)
goto cleanup; goto cleanup;
if (rc > nstats)
nstats = rc;
} }
ret = 0; ret = nstats;
cleanup: cleanup:
virJSONValueFree(cmd); virJSONValueFree(cmd);
......
...@@ -854,6 +854,8 @@ qemuMonitorTextGetAllBlockStatsInfo(qemuMonitorPtr mon, ...@@ -854,6 +854,8 @@ qemuMonitorTextGetAllBlockStatsInfo(qemuMonitorPtr mon,
size_t i; size_t i;
size_t j; size_t j;
int ret = -1; int ret = -1;
int nstats;
int maxstats = 0;
if (qemuMonitorHMPCommand(mon, "info blockstats", &info) < 0) if (qemuMonitorHMPCommand(mon, "info blockstats", &info) < 0)
goto cleanup; goto cleanup;
...@@ -911,6 +913,8 @@ qemuMonitorTextGetAllBlockStatsInfo(qemuMonitorPtr mon, ...@@ -911,6 +913,8 @@ qemuMonitorTextGetAllBlockStatsInfo(qemuMonitorPtr mon,
if (!(values = virStringSplit(line, " ", 0))) if (!(values = virStringSplit(line, " ", 0)))
goto cleanup; goto cleanup;
nstats = 0;
for (j = 0; values[j] && *values[j]; j++) { for (j = 0; values[j] && *values[j]; j++) {
key = values[j]; key = values[j];
...@@ -925,6 +929,7 @@ qemuMonitorTextGetAllBlockStatsInfo(qemuMonitorPtr mon, ...@@ -925,6 +929,7 @@ qemuMonitorTextGetAllBlockStatsInfo(qemuMonitorPtr mon,
#define QEMU_MONITOR_TEXT_READ_BLOCK_STAT(NAME, VAR) \ #define QEMU_MONITOR_TEXT_READ_BLOCK_STAT(NAME, VAR) \
if (STREQ(key, NAME)) { \ if (STREQ(key, NAME)) { \
nstats++; \
if (virStrToLong_ll(value, NULL, 10, &VAR) < 0) { \ if (virStrToLong_ll(value, NULL, 10, &VAR) < 0) { \
virReportError(VIR_ERR_INTERNAL_ERROR, \ virReportError(VIR_ERR_INTERNAL_ERROR, \
_("'info blockstats' contains malformed " \ _("'info blockstats' contains malformed " \
...@@ -948,6 +953,9 @@ qemuMonitorTextGetAllBlockStatsInfo(qemuMonitorPtr mon, ...@@ -948,6 +953,9 @@ qemuMonitorTextGetAllBlockStatsInfo(qemuMonitorPtr mon,
VIR_DEBUG("unknown block stat field '%s'", key); VIR_DEBUG("unknown block stat field '%s'", key);
} }
if (nstats > maxstats)
maxstats = nstats;
if (virHashAddEntry(hash, dev_name, stats) < 0) if (virHashAddEntry(hash, dev_name, stats) < 0)
goto cleanup; goto cleanup;
stats = NULL; stats = NULL;
...@@ -956,7 +964,7 @@ qemuMonitorTextGetAllBlockStatsInfo(qemuMonitorPtr mon, ...@@ -956,7 +964,7 @@ qemuMonitorTextGetAllBlockStatsInfo(qemuMonitorPtr mon,
values = NULL; values = NULL;
} }
ret = 0; ret = maxstats;
cleanup: cleanup:
virStringFreeList(lines); virStringFreeList(lines);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册