mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-23 20:02:21 +00:00
qemu: monitor: Kill qemuMonitorGetBlockStats(Info,ParamsNumber)
The functions and their QMP and HMP implementations are no longer needed since everything is now done via the *AllStats functions.
This commit is contained in:
parent
3a83dcf43e
commit
d3534a43e6
@ -1808,45 +1808,6 @@ qemuMonitorBlockInfoLookup(virHashTablePtr blockInfo,
|
||||
return info;
|
||||
}
|
||||
|
||||
int qemuMonitorGetBlockStatsInfo(qemuMonitorPtr mon,
|
||||
const char *dev_name,
|
||||
long long *rd_req,
|
||||
long long *rd_bytes,
|
||||
long long *rd_total_times,
|
||||
long long *wr_req,
|
||||
long long *wr_bytes,
|
||||
long long *wr_total_times,
|
||||
long long *flush_req,
|
||||
long long *flush_total_times)
|
||||
{
|
||||
int ret;
|
||||
VIR_DEBUG("mon=%p dev=%s", mon, dev_name);
|
||||
|
||||
if (!mon) {
|
||||
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
||||
_("monitor must not be NULL"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mon->json)
|
||||
ret = qemuMonitorJSONGetBlockStatsInfo(mon, dev_name,
|
||||
rd_req, rd_bytes,
|
||||
rd_total_times,
|
||||
wr_req, wr_bytes,
|
||||
wr_total_times,
|
||||
flush_req,
|
||||
flush_total_times);
|
||||
else
|
||||
ret = qemuMonitorTextGetBlockStatsInfo(mon, dev_name,
|
||||
rd_req, rd_bytes,
|
||||
rd_total_times,
|
||||
wr_req, wr_bytes,
|
||||
wr_total_times,
|
||||
flush_req,
|
||||
flush_total_times);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* qemuMonitorGetAllBlockStatsInfo:
|
||||
@ -1921,29 +1882,6 @@ qemuMonitorBlockStatsUpdateCapacity(qemuMonitorPtr mon,
|
||||
}
|
||||
|
||||
|
||||
/* Return 0 and update @nparams with the number of block stats
|
||||
* QEMU supports if success. Return -1 if failure.
|
||||
*/
|
||||
int qemuMonitorGetBlockStatsParamsNumber(qemuMonitorPtr mon,
|
||||
int *nparams)
|
||||
{
|
||||
int ret;
|
||||
VIR_DEBUG("mon=%p nparams=%p", mon, nparams);
|
||||
|
||||
if (!mon) {
|
||||
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
||||
_("monitor must not be NULL"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mon->json)
|
||||
ret = qemuMonitorJSONGetBlockStatsParamsNumber(mon, nparams);
|
||||
else
|
||||
ret = qemuMonitorTextGetBlockStatsParamsNumber(mon, nparams);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qemuMonitorGetBlockExtent(qemuMonitorPtr mon,
|
||||
const char *dev_name,
|
||||
unsigned long long *extent)
|
||||
|
@ -357,17 +357,6 @@ struct qemuDomainDiskInfo *
|
||||
qemuMonitorBlockInfoLookup(virHashTablePtr blockInfo,
|
||||
const char *dev_name);
|
||||
|
||||
int qemuMonitorGetBlockStatsInfo(qemuMonitorPtr mon,
|
||||
const char *dev_name,
|
||||
long long *rd_req,
|
||||
long long *rd_bytes,
|
||||
long long *rd_total_times,
|
||||
long long *wr_req,
|
||||
long long *wr_bytes,
|
||||
long long *wr_total_times,
|
||||
long long *flush_req,
|
||||
long long *flush_total_times);
|
||||
|
||||
typedef struct _qemuBlockStats qemuBlockStats;
|
||||
typedef qemuBlockStats *qemuBlockStatsPtr;
|
||||
struct _qemuBlockStats {
|
||||
@ -394,9 +383,6 @@ int qemuMonitorBlockStatsUpdateCapacity(qemuMonitorPtr mon,
|
||||
bool backingChain)
|
||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||
|
||||
int qemuMonitorGetBlockStatsParamsNumber(qemuMonitorPtr mon,
|
||||
int *nparams);
|
||||
|
||||
int qemuMonitorGetBlockExtent(qemuMonitorPtr mon,
|
||||
const char *dev_name,
|
||||
unsigned long long *extent);
|
||||
|
@ -1668,67 +1668,6 @@ int qemuMonitorJSONGetBlockInfo(qemuMonitorPtr mon,
|
||||
}
|
||||
|
||||
|
||||
int qemuMonitorJSONGetBlockStatsInfo(qemuMonitorPtr mon,
|
||||
const char *dev_name,
|
||||
long long *rd_req,
|
||||
long long *rd_bytes,
|
||||
long long *rd_total_times,
|
||||
long long *wr_req,
|
||||
long long *wr_bytes,
|
||||
long long *wr_total_times,
|
||||
long long *flush_req,
|
||||
long long *flush_total_times)
|
||||
{
|
||||
qemuBlockStats *stats;
|
||||
virHashTablePtr blockstats = NULL;
|
||||
int ret = -1;
|
||||
|
||||
*rd_req = *rd_bytes = -1;
|
||||
*wr_req = *wr_bytes = -1;
|
||||
|
||||
if (rd_total_times)
|
||||
*rd_total_times = -1;
|
||||
if (wr_total_times)
|
||||
*wr_total_times = -1;
|
||||
if (flush_req)
|
||||
*flush_req = -1;
|
||||
if (flush_total_times)
|
||||
*flush_total_times = -1;
|
||||
|
||||
if (!(blockstats = virHashCreate(10, virHashValueFree)))
|
||||
goto cleanup;
|
||||
|
||||
if (qemuMonitorJSONGetAllBlockStatsInfo(mon, blockstats, false) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (!(stats = virHashLookup(blockstats, dev_name))) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("cannot find statistics for device '%s'"), dev_name);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
*rd_req = stats->rd_req;
|
||||
*rd_bytes = stats->rd_bytes;
|
||||
*wr_req = stats->wr_req;
|
||||
*wr_bytes = stats->wr_bytes;
|
||||
|
||||
if (rd_total_times)
|
||||
*rd_total_times = stats->rd_total_times;
|
||||
if (wr_total_times)
|
||||
*wr_total_times = stats->wr_total_times;
|
||||
if (flush_req)
|
||||
*flush_req = stats->flush_req;
|
||||
if (flush_total_times)
|
||||
*flush_total_times = stats->flush_total_times;
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
virHashFree(blockstats);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
typedef enum {
|
||||
QEMU_MONITOR_BLOCK_EXTENT_ERROR_OK,
|
||||
QEMU_MONITOR_BLOCK_EXTENT_ERROR_NOPARENT,
|
||||
@ -2013,80 +1952,6 @@ qemuMonitorJSONBlockStatsUpdateCapacity(qemuMonitorPtr mon,
|
||||
}
|
||||
|
||||
|
||||
int qemuMonitorJSONGetBlockStatsParamsNumber(qemuMonitorPtr mon,
|
||||
int *nparams)
|
||||
{
|
||||
int ret, num = 0;
|
||||
size_t i;
|
||||
virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("query-blockstats",
|
||||
NULL);
|
||||
virJSONValuePtr reply = NULL;
|
||||
virJSONValuePtr devices = NULL;
|
||||
virJSONValuePtr dev = NULL;
|
||||
virJSONValuePtr stats = NULL;
|
||||
|
||||
if (!cmd)
|
||||
return -1;
|
||||
|
||||
ret = qemuMonitorJSONCommand(mon, cmd, &reply);
|
||||
|
||||
if (ret == 0)
|
||||
ret = qemuMonitorJSONCheckError(cmd, reply);
|
||||
if (ret < 0)
|
||||
goto cleanup;
|
||||
ret = -1;
|
||||
|
||||
devices = virJSONValueObjectGet(reply, "return");
|
||||
if (!devices || devices->type != VIR_JSON_TYPE_ARRAY) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("blockstats reply was missing device list"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
dev = virJSONValueArrayGet(devices, 0);
|
||||
|
||||
if (!dev || dev->type != VIR_JSON_TYPE_OBJECT) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("blockstats device entry was not in expected format"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((stats = virJSONValueObjectGet(dev, "stats")) == NULL ||
|
||||
stats->type != VIR_JSON_TYPE_OBJECT) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("blockstats stats entry was not in expected format"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (i = 0; i < stats->data.object.npairs; i++) {
|
||||
const char *key = stats->data.object.pairs[i].key;
|
||||
|
||||
if (STREQ(key, "rd_bytes") ||
|
||||
STREQ(key, "rd_operations") ||
|
||||
STREQ(key, "rd_total_time_ns") ||
|
||||
STREQ(key, "wr_bytes") ||
|
||||
STREQ(key, "wr_operations") ||
|
||||
STREQ(key, "wr_total_time_ns") ||
|
||||
STREQ(key, "flush_operations") ||
|
||||
STREQ(key, "flush_total_time_ns")) {
|
||||
num++;
|
||||
} else {
|
||||
/* wr_highest_offset is parsed by qemuMonitorJSONGetBlockExtent. */
|
||||
if (STRNEQ(key, "wr_highest_offset"))
|
||||
VIR_DEBUG("Missed block stat: %s", key);
|
||||
}
|
||||
}
|
||||
|
||||
*nparams = num;
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
virJSONValueFree(cmd);
|
||||
virJSONValueFree(reply);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuMonitorJSONReportBlockExtentError(qemuMonitorBlockExtentError error)
|
||||
{
|
||||
|
@ -71,24 +71,12 @@ int qemuMonitorJSONSetMemoryStatsPeriod(qemuMonitorPtr mon,
|
||||
int period);
|
||||
int qemuMonitorJSONGetBlockInfo(qemuMonitorPtr mon,
|
||||
virHashTablePtr table);
|
||||
int qemuMonitorJSONGetBlockStatsInfo(qemuMonitorPtr mon,
|
||||
const char *dev_name,
|
||||
long long *rd_req,
|
||||
long long *rd_bytes,
|
||||
long long *rd_total_times,
|
||||
long long *wr_req,
|
||||
long long *wr_bytes,
|
||||
long long *wr_total_times,
|
||||
long long *flush_req,
|
||||
long long *flush_total_times);
|
||||
int qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon,
|
||||
virHashTablePtr hash,
|
||||
bool backingChain);
|
||||
int qemuMonitorJSONBlockStatsUpdateCapacity(qemuMonitorPtr mon,
|
||||
virHashTablePtr stats,
|
||||
bool backingChain);
|
||||
int qemuMonitorJSONGetBlockStatsParamsNumber(qemuMonitorPtr mon,
|
||||
int *nparams);
|
||||
int qemuMonitorJSONGetBlockExtent(qemuMonitorPtr mon,
|
||||
const char *dev_name,
|
||||
unsigned long long *extent);
|
||||
|
@ -975,204 +975,6 @@ qemuMonitorTextGetAllBlockStatsInfo(qemuMonitorPtr mon,
|
||||
}
|
||||
|
||||
|
||||
int qemuMonitorTextGetBlockStatsInfo(qemuMonitorPtr mon,
|
||||
const char *dev_name,
|
||||
long long *rd_req,
|
||||
long long *rd_bytes,
|
||||
long long *rd_total_times,
|
||||
long long *wr_req,
|
||||
long long *wr_bytes,
|
||||
long long *wr_total_times,
|
||||
long long *flush_req,
|
||||
long long *flush_total_times)
|
||||
{
|
||||
char *info = NULL;
|
||||
int ret = -1;
|
||||
char *dummy;
|
||||
const char *p, *eol;
|
||||
int devnamelen = strlen(dev_name);
|
||||
|
||||
if (qemuMonitorHMPCommand(mon, "info blockstats", &info) < 0)
|
||||
goto cleanup;
|
||||
|
||||
/* If the command isn't supported then qemu prints the supported
|
||||
* info commands, so the output starts "info ". Since this is
|
||||
* unlikely to be the name of a block device, we can use this
|
||||
* to detect if qemu supports the command.
|
||||
*/
|
||||
if (strstr(info, "\ninfo ")) {
|
||||
virReportError(VIR_ERR_OPERATION_INVALID,
|
||||
"%s",
|
||||
_("'info blockstats' not supported by this qemu"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
*rd_req = *rd_bytes = -1;
|
||||
*wr_req = *wr_bytes = -1;
|
||||
|
||||
if (rd_total_times)
|
||||
*rd_total_times = -1;
|
||||
if (wr_total_times)
|
||||
*wr_total_times = -1;
|
||||
if (flush_req)
|
||||
*flush_req = -1;
|
||||
if (flush_total_times)
|
||||
*flush_total_times = -1;
|
||||
|
||||
/* The output format for both qemu & KVM is:
|
||||
* blockdevice: rd_bytes=% wr_bytes=% rd_operations=% wr_operations=%
|
||||
* (repeated for each block device)
|
||||
* where '%' is a 64 bit number.
|
||||
*/
|
||||
p = info;
|
||||
|
||||
while (*p) {
|
||||
/* New QEMU has separate names for host & guest side of the disk
|
||||
* and libvirt gives the host side a 'drive-' prefix. The passed
|
||||
* in dev_name is the guest side though
|
||||
*/
|
||||
if (STRPREFIX(p, QEMU_DRIVE_HOST_PREFIX))
|
||||
p += strlen(QEMU_DRIVE_HOST_PREFIX);
|
||||
|
||||
if (STREQLEN(p, dev_name, devnamelen)
|
||||
&& p[devnamelen] == ':' && p[devnamelen+1] == ' ') {
|
||||
|
||||
eol = strchr(p, '\n');
|
||||
if (!eol)
|
||||
eol = p + strlen(p);
|
||||
|
||||
p += devnamelen+2; /* Skip to first label. */
|
||||
|
||||
while (*p) {
|
||||
if (STRPREFIX(p, "rd_bytes=")) {
|
||||
p += strlen("rd_bytes=");
|
||||
if (virStrToLong_ll(p, &dummy, 10, rd_bytes) == -1)
|
||||
VIR_DEBUG("error reading rd_bytes: %s", p);
|
||||
} else if (STRPREFIX(p, "wr_bytes=")) {
|
||||
p += strlen("wr_bytes=");
|
||||
if (virStrToLong_ll(p, &dummy, 10, wr_bytes) == -1)
|
||||
VIR_DEBUG("error reading wr_bytes: %s", p);
|
||||
} else if (STRPREFIX(p, "rd_operations=")) {
|
||||
p += strlen("rd_operations=");
|
||||
if (virStrToLong_ll(p, &dummy, 10, rd_req) == -1)
|
||||
VIR_DEBUG("error reading rd_req: %s", p);
|
||||
} else if (STRPREFIX(p, "wr_operations=")) {
|
||||
p += strlen("wr_operations=");
|
||||
if (virStrToLong_ll(p, &dummy, 10, wr_req) == -1)
|
||||
VIR_DEBUG("error reading wr_req: %s", p);
|
||||
} else if (rd_total_times &&
|
||||
STRPREFIX(p, "rd_total_time_ns=")) {
|
||||
p += strlen("rd_total_time_ns=");
|
||||
if (virStrToLong_ll(p, &dummy, 10, rd_total_times) == -1)
|
||||
VIR_DEBUG("error reading rd_total_times: %s", p);
|
||||
} else if (wr_total_times &&
|
||||
STRPREFIX(p, "wr_total_time_ns=")) {
|
||||
p += strlen("wr_total_time_ns=");
|
||||
if (virStrToLong_ll(p, &dummy, 10, wr_total_times) == -1)
|
||||
VIR_DEBUG("error reading wr_total_times: %s", p);
|
||||
} else if (flush_req &&
|
||||
STRPREFIX(p, "flush_operations=")) {
|
||||
p += strlen("flush_operations=");
|
||||
if (virStrToLong_ll(p, &dummy, 10, flush_req) == -1)
|
||||
VIR_DEBUG("error reading flush_req: %s", p);
|
||||
} else if (flush_total_times &&
|
||||
STRPREFIX(p, "flush_total_time_ns=")) {
|
||||
p += strlen("flush_total_time_ns=");
|
||||
if (virStrToLong_ll(p, &dummy, 10, flush_total_times) == -1)
|
||||
VIR_DEBUG("error reading flush_total_times: %s", p);
|
||||
} else {
|
||||
VIR_DEBUG("unknown block stat near %s", p);
|
||||
}
|
||||
|
||||
/* Skip to next label. */
|
||||
p = strchr(p, ' ');
|
||||
if (!p || p >= eol) break;
|
||||
p++;
|
||||
}
|
||||
ret = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Skip to next line. */
|
||||
p = strchr(p, '\n');
|
||||
if (!p) break;
|
||||
p++;
|
||||
}
|
||||
|
||||
/* If we reach here then the device was not found. */
|
||||
virReportError(VIR_ERR_INVALID_ARG,
|
||||
_("no stats found for device %s"), dev_name);
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(info);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qemuMonitorTextGetBlockStatsParamsNumber(qemuMonitorPtr mon,
|
||||
int *nparams)
|
||||
{
|
||||
char *info = NULL;
|
||||
int ret = -1;
|
||||
int num = 0;
|
||||
const char *p, *eol;
|
||||
|
||||
if (qemuMonitorHMPCommand(mon, "info blockstats", &info) < 0)
|
||||
goto cleanup;
|
||||
|
||||
/* If the command isn't supported then qemu prints the supported
|
||||
* info commands, so the output starts "info ". Since this is
|
||||
* unlikely to be the name of a block device, we can use this
|
||||
* to detect if qemu supports the command.
|
||||
*/
|
||||
if (strstr(info, "\ninfo ")) {
|
||||
virReportError(VIR_ERR_OPERATION_INVALID,
|
||||
"%s",
|
||||
_("'info blockstats' not supported by this qemu"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* The output format for both qemu & KVM is:
|
||||
* blockdevice: rd_bytes=% wr_bytes=% rd_operations=% wr_operations=%
|
||||
* (repeated for each block device)
|
||||
* where '%' is a 64 bit number.
|
||||
*/
|
||||
p = info;
|
||||
|
||||
eol = strchr(p, '\n');
|
||||
if (!eol)
|
||||
eol = p + strlen(p);
|
||||
|
||||
/* Skip the device name and following ":", and spaces (e.g.
|
||||
* "floppy0: ")
|
||||
*/
|
||||
p = strchr(p, ' ');
|
||||
|
||||
while (p && p < eol) {
|
||||
if (STRPREFIX(p, " rd_bytes=") ||
|
||||
STRPREFIX(p, " wr_bytes=") ||
|
||||
STRPREFIX(p, " rd_operations=") ||
|
||||
STRPREFIX(p, " wr_operations=") ||
|
||||
STRPREFIX(p, " rd_total_time_ns=") ||
|
||||
STRPREFIX(p, " wr_total_time_ns=") ||
|
||||
STRPREFIX(p, " flush_operations=") ||
|
||||
STRPREFIX(p, " flush_total_time_ns=")) {
|
||||
num++;
|
||||
} else {
|
||||
VIR_DEBUG("unknown block stat near %s", p);
|
||||
}
|
||||
|
||||
/* Skip to next label. */
|
||||
p = strchr(p + 1, ' ');
|
||||
}
|
||||
|
||||
*nparams = num;
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(info);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qemuMonitorTextGetBlockExtent(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
||||
const char *dev_name ATTRIBUTE_UNUSED,
|
||||
unsigned long long *extent ATTRIBUTE_UNUSED)
|
||||
|
@ -63,18 +63,6 @@ int qemuMonitorTextGetBlockInfo(qemuMonitorPtr mon,
|
||||
|
||||
int qemuMonitorTextGetAllBlockStatsInfo(qemuMonitorPtr mon,
|
||||
virHashTablePtr hash);
|
||||
int qemuMonitorTextGetBlockStatsInfo(qemuMonitorPtr mon,
|
||||
const char *dev_name,
|
||||
long long *rd_req,
|
||||
long long *rd_bytes,
|
||||
long long *rd_total_times,
|
||||
long long *wr_req,
|
||||
long long *wr_bytes,
|
||||
long long *wr_total_times,
|
||||
long long *flush_req,
|
||||
long long *flush_total_times);
|
||||
int qemuMonitorTextGetBlockStatsParamsNumber(qemuMonitorPtr mon,
|
||||
int *nparams);
|
||||
int qemuMonitorTextGetBlockExtent(qemuMonitorPtr mon,
|
||||
const char *dev_name,
|
||||
unsigned long long *extent);
|
||||
|
Loading…
x
Reference in New Issue
Block a user