From 19fc614d531fb75877abb59baaf33bc1add4d483 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Mon, 6 Oct 2025 17:32:28 +0200 Subject: [PATCH] conf: Add configuration option for timed disk statistics collection QEMU supports collection of disk statistics in configurable time windows. Add support for enabling this feature to the conf parser. Signed-off-by: Peter Krempa Reviewed-by: Michal Privoznik --- docs/formatdomain.rst | 17 ++++++++++++++++ src/conf/domain_conf.c | 34 +++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 2 ++ src/conf/schemas/domaincommon.rng | 11 ++++++++++ 4 files changed, 64 insertions(+) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 34dc9c3af7..4c245f41a9 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -3597,6 +3597,23 @@ paravirtualized driver is specified via the ``disk`` element. + - The optional ``statistics`` sub-element allows configuring statistics + collection in configurable intervals for the given disk. Intervals are + configured by ```` sub-elements with ``interval`` attribute + configuring the collection window duration in seconds. The statistics + are available via the bulk statistics API. + + Example:: + + + + + + + + + :since:`Since 11.9.0 (QEMU 10.2, virtio, ide, scsi disks only)`. + - The optional ``queues`` attribute specifies the number of virt queues for virtio-blk ( :since:`Since 3.9.0` ) or vhost-user-blk ( :since:`Since 7.1.0` ) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 1e84c93841..c749d505bf 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -8297,6 +8297,8 @@ static int virDomainDiskDefDriverParseXML(virDomainDiskDef *def, xmlNodePtr cur) { + xmlNodePtr statisticsNode; + def->driverName = virXMLPropString(cur, "name"); if (virXMLPropEnum(cur, "cache", virDomainDiskCacheTypeFromString, @@ -8346,6 +8348,26 @@ virDomainDiskDefDriverParseXML(virDomainDiskDef *def, if (virDomainIothreadMappingDefParse(cur, &def->iothreads) < 0) return -1; + if ((statisticsNode = virXMLNodeGetSubelement(cur, "statistics"))) { + g_autoptr(GPtrArray) statisticNodes = NULL; + + statisticNodes = virXMLNodeGetSubelementList(statisticsNode, "statistic"); + + if (statisticNodes->len > 0) { + size_t i; + + def->statistics = g_new0(unsigned int, statisticNodes->len + 1); + + for (i = 0; i < statisticNodes->len; i++) { + if (virXMLPropUInt(g_ptr_array_index(statisticNodes, i), + "interval", 10, + VIR_XML_PROP_REQUIRED | VIR_XML_PROP_NONZERO, + def->statistics + i) < 0) + return -1; + } + } + } + if (virXMLPropEnum(cur, "detect_zeroes", virDomainDiskDetectZeroesTypeFromString, VIR_XML_PROP_NONZERO, &def->detect_zeroes) < 0) @@ -23864,6 +23886,18 @@ virDomainDiskDefFormatDriver(virBuffer *buf, virDomainIothreadMappingDefFormat(&childBuf, disk->iothreads); + if (disk->statistics) { + g_auto(virBuffer) statisticsChildBuf = VIR_BUFFER_INIT_CHILD(&childBuf); + size_t i; + + for (i = 0; disk->statistics[i] > 0; i++) + virBufferAsprintf(&statisticsChildBuf, "\n", + disk->statistics[i]); + + virXMLFormatElement(&childBuf, "statistics", NULL, &statisticsChildBuf); + } + + virXMLFormatElement(buf, "driver", &attrBuf, &childBuf); } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index b265bf224b..81e735993d 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -592,6 +592,8 @@ struct _virDomainDiskDef { virDomainDiskDiscard discard; unsigned int iothread; /* unused = 0, > 0 specific thread # */ GSList *iothreads; /* List of virDomainIothreadMappingDef */ + unsigned int *statistics; /* Optional, zero terminated list of intervals to + collect statistics for */ virDomainDiskDetectZeroes detect_zeroes; virTristateSwitch discard_no_unref; char *domain_name; /* backend domain name */ diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index 110f6cbc69..75b5124c33 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -2742,6 +2742,17 @@ + + + + + + + + + + + -- 2.47.3