diff --git a/.gitignore b/.gitignore index 3f04786..eb9aad1 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/libvirt-10.10.0.tar.xz +SOURCES/libvirt-11.10.0.tar.xz diff --git a/.libvirt.metadata b/.libvirt.metadata index 954575b..85fa0db 100644 --- a/.libvirt.metadata +++ b/.libvirt.metadata @@ -1 +1 @@ -7e76874bdcd1b220d90619c1ce7a876b6c9a8d78 SOURCES/libvirt-10.10.0.tar.xz +f36316de87378f52ae9c237d936c28b0f3210253 SOURCES/libvirt-11.10.0.tar.xz diff --git a/SOURCES/libvirt-Add-load-average-information-type-into-virDomainGetGuestInfo.patch b/SOURCES/libvirt-Add-load-average-information-type-into-virDomainGetGuestInfo.patch deleted file mode 100644 index 224dd74..0000000 --- a/SOURCES/libvirt-Add-load-average-information-type-into-virDomainGetGuestInfo.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 9874072fc9396d609f1a0213bb06fa7e9a2fa019 Mon Sep 17 00:00:00 2001 -Message-ID: <9874072fc9396d609f1a0213bb06fa7e9a2fa019.1747908717.git.jdenemar@redhat.com> -From: Martin Kletzander -Date: Tue, 25 Feb 2025 15:36:03 +0100 -Subject: [PATCH] Add load average information type into virDomainGetGuestInfo - -The public API part. - -Signed-off-by: Martin Kletzander -Reviewed-by: Peter Krempa -(cherry picked from commit c52c449fd40c7263896d5f17129207b815c3a09c) - -https://issues.redhat.com/browse/RHEL-88447 - -Signed-off-by: Martin Kletzander ---- - include/libvirt/libvirt-domain.h | 1 + - src/libvirt-domain.c | 8 ++++++++ - 2 files changed, 9 insertions(+) - -diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h -index f026ce197c..c04b696f03 100644 ---- a/include/libvirt/libvirt-domain.h -+++ b/include/libvirt/libvirt-domain.h -@@ -6425,6 +6425,7 @@ typedef enum { - VIR_DOMAIN_GUEST_INFO_FILESYSTEM = (1 << 4), /* return filesystem information (Since: 5.7.0) */ - VIR_DOMAIN_GUEST_INFO_DISKS = (1 << 5), /* return disks information (Since: 7.0.0) */ - VIR_DOMAIN_GUEST_INFO_INTERFACES = (1 << 6), /* return interfaces information (Since: 7.10.0) */ -+ VIR_DOMAIN_GUEST_INFO_LOAD = (1 << 7), /* return load averages (Since: 11.2.0) */ - } virDomainGuestInfoTypes; - - int virDomainGetGuestInfo(virDomainPtr domain, -diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c -index 7c6b93963c..24752a9888 100644 ---- a/src/libvirt-domain.c -+++ b/src/libvirt-domain.c -@@ -13292,6 +13292,14 @@ virDomainSetVcpu(virDomainPtr domain, - * "if..addr..addr" - the IP address of addr - * "if..addr..prefix" - the prefix of IP address of addr - * -+ * VIR_DOMAIN_GUEST_INFO_LOAD: -+ * Returns load (the number of processes in the runqueue or waiting for disk -+ * I/O) as double values: -+ * -+ * "load.1m" - load averaged over 1 minute -+ * "load.5m" - load averaged over 5 minutes -+ * "load.15m" - load averaged over 15 minutes -+ * - * Using 0 for @types returns all information groups supported by the given - * hypervisor. - * --- -2.49.0 diff --git a/SOURCES/libvirt-Expose-latency-histograms-via-virConnectGetAllDomainStats.patch b/SOURCES/libvirt-Expose-latency-histograms-via-virConnectGetAllDomainStats.patch new file mode 100644 index 0000000..696d10b --- /dev/null +++ b/SOURCES/libvirt-Expose-latency-histograms-via-virConnectGetAllDomainStats.patch @@ -0,0 +1,248 @@ +From d3031b230cc8300541a3ec39bf80b78d11ac15d6 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Peter Krempa +Date: Thu, 29 Jan 2026 18:10:26 +0100 +Subject: [PATCH] Expose latency histograms via 'virConnectGetAllDomainStats' + +Add documentation and constants for constructing the stats field names +for latency histograms and expose them in the qemu driver: + +Example: + + block.1.latency_histogram.read.bin.count=9 + block.1.latency_histogram.read.bin.0.start=0 + block.1.latency_histogram.read.bin.0.value=0 + block.1.latency_histogram.read.bin.1.start=10 + block.1.latency_histogram.read.bin.1.value=0 + block.1.latency_histogram.read.bin.2.start=100 + block.1.latency_histogram.read.bin.2.value=0 + block.1.latency_histogram.read.bin.3.start=1000 + block.1.latency_histogram.read.bin.3.value=1047 + block.1.latency_histogram.read.bin.4.start=10000 + block.1.latency_histogram.read.bin.4.value=2131 + block.1.latency_histogram.read.bin.5.start=100000 + block.1.latency_histogram.read.bin.5.value=0 + block.1.latency_histogram.read.bin.6.start=1000000 + block.1.latency_histogram.read.bin.6.value=0 + block.1.latency_histogram.read.bin.7.start=10000000 + block.1.latency_histogram.read.bin.7.value=0 + block.1.latency_histogram.read.bin.8.start=100000000 + block.1.latency_histogram.read.bin.8.value=0 + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit 237e49127a9390f054e33e689ba9db1587cdc9f1) + +https://issues.redhat.com/browse/RHEL-147866 [rhel-9.8] +https://issues.redhat.com/browse/RHEL-131335 [rhel-10.2] +--- + docs/manpages/virsh.rst | 7 ++ + include/libvirt/libvirt-domain.h | 113 +++++++++++++++++++++++++++++++ + src/qemu/qemu_driver.c | 43 ++++++++++++ + 3 files changed, 163 insertions(+) + +diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst +index a9d691824e..ff0cf1a715 100644 +--- a/docs/manpages/virsh.rst ++++ b/docs/manpages/virsh.rst +@@ -2811,6 +2811,13 @@ Information listed includes: + pending write operations in the defined interval + * ``block..timed_group..zone_append_queue_depth_avg`` - average number + of pending zone append operations in the defined interval ++* ``block..latency_histogram..bin.count`` - number of bins in ++ latency histogram. is one of ``read``, ``write``, ``zone_append``, or ++ ``flush`` ++* ``block..latency_histogram..bin..start`` start boundary of ++ a latency histogram bin in nanoseconds of given operation duration ++* ``block..latency_histogram..bin..value`` current number of ++ events corresponding to the given bin and type + + + *--iothread* returns information about IOThreads on the running guest +diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h +index 16fac6b085..8e62bd23d4 100644 +--- a/include/libvirt/libvirt-domain.h ++++ b/include/libvirt/libvirt-domain.h +@@ -3815,6 +3815,119 @@ struct _virDomainStatsRecord { + */ + # define VIR_DOMAIN_STATS_BLOCK_SUFFIX_TIMED_GROUP_SUFFIX_ZONE_APPEND_QUEUE_DEPTH_AVG ".zone_append_queue_depth_avg" + ++/** ++ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_READ_PREFIX: ++ * ++ * The parameter name prefix to access 'read' latency histograms. Concatenate ++ * the prefix with either: ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_COUNT ++ * to get the number of bins in given histogram ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_PREFIX and ++ * entry number formatted as an unsigned integer and one of the latency ++ * histogram suffix parameters to compelte a full bin parameter name ++ * ++ * Since: 12.1.0 ++ */ ++# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_READ_PREFIX ".latency_histogram.read." ++ ++/** ++ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_WRITE_PREFIX: ++ * ++ * The parameter name prefix to access 'write' latency histograms. Concatenate ++ * the prefix with either: ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_COUNT ++ * to get the number of bins in given histogram ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_PREFIX and ++ * entry number formatted as an unsigned integer and one of the latency ++ * histogram suffix parameters to compelte a full bin parameter name ++ * ++ * Since: 12.1.0 ++ */ ++# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_WRITE_PREFIX ".latency_histogram.write." ++ ++/** ++ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_ZONE_APPEND_PREFIX: ++ * ++ * The parameter name prefix to access 'zone_append' latency histograms. Concatenate ++ * the prefix with either: ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_COUNT ++ * to get the number of bins in given histogram ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_PREFIX and ++ * entry number formatted as an unsigned integer and one of the latency ++ * histogram suffix parameters to compelte a full bin parameter name ++ * ++ * Since: 12.1.0 ++ */ ++# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_ZONE_APPEND_PREFIX ".latency_histogram.zone_append." ++ ++/** ++ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_FLUSH_PREFIX: ++ * ++ * The parameter name prefix to access 'flush' latency histograms. Concatenate ++ * the prefix with either: ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_COUNT ++ * to get the number of bins in given histogram ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_PREFIX and ++ * entry number formatted as an unsigned integer and one of the latency ++ * histogram suffix parameters to compelte a full bin parameter name ++ * ++ * Since: 12.1.0 ++ */ ++# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_FLUSH_PREFIX ".latency_histogram.flush." ++ ++/** ++ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_COUNT: ++ * ++ * The parameter name suffix to access number of bins in one of the following ++ * latency histogram types: ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_READ_PREFIX ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_WRITE_PREFIX ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_ZONE_APPEND_PREFIX ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_FLUSH_PREFIX ++ * ++ * Number of bins in latency histogram as unsigned long long. ++ * ++ * Since: 12.1.0 ++ */ ++# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_COUNT "bin.count" ++ ++/** ++ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_PREFIX: ++ * ++ * The parameter name suffix to access a latency histogram bin in one of the ++ * following latency histogram types: ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_READ_PREFIX ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_WRITE_PREFIX ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_ZONE_APPEND_PREFIX ++ * - VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_FLUSH_PREFIX ++ * ++ * Concatenate with a bin number as unsigned int and one of the other field ++ * suffixes to access bin parameters. ++ * ++ * Since: 12.1.0 ++ */ ++# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_PREFIX "bin." ++ ++/** ++ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_SUFFIX_START: ++ * ++ * Start of the current latency histogram bin in nanoseconds as unsigned long long. ++ * ++ * Since: 12.1.0 ++ */ ++# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_SUFFIX_START ".start" ++ ++/** ++ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_SUFFIX_VALUE: ++ * ++ * Current value of the number of occurences of the latency within this bin ++ * as unsigned long long. ++ * ++ * Since: 12.1.0 ++ */ ++# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_SUFFIX_VALUE ".value" ++ ++ + /** + * VIR_DOMAIN_STATS_PERF_CMT: + * +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 08a547c546..f3e7410f9e 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -17597,6 +17597,36 @@ qemuDomainGetStatsBlockExportBackendStorage(const char *entryname, + } + + ++static void ++qemuDomainGetStatsBlockExportFrontendLatencyHistogram(struct qemuBlockStatsLatencyHistogram *h, ++ size_t disk_idx, ++ const char *prefix_hist, ++ virTypedParamList *par) ++{ ++ size_t i; ++ ++ if (!h) ++ return; ++ ++ virTypedParamListAddULLong(par, h->nbins, ++ VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu%s" VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_COUNT, ++ disk_idx, prefix_hist); ++ ++ for (i = 0; i < h->nbins; i++) { ++ virTypedParamListAddULLong(par, h->bins[i].start, ++ VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu%s" ++ VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_PREFIX "%zu" ++ VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_SUFFIX_START, ++ disk_idx, prefix_hist, i); ++ virTypedParamListAddULLong(par, h->bins[i].value, ++ VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu%s" ++ VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_PREFIX "%zu" ++ VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_SUFFIX_BIN_SUFFIX_VALUE, ++ disk_idx, prefix_hist, i); ++ } ++} ++ ++ + static void + qemuDomainGetStatsBlockExportFrontend(const char *frontendname, + GHashTable *stats, +@@ -17721,6 +17751,19 @@ qemuDomainGetStatsBlockExportFrontend(const char *frontendname, + idx, i); + } + } ++ ++ qemuDomainGetStatsBlockExportFrontendLatencyHistogram(en->histogram_read, idx, ++ VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_READ_PREFIX, ++ par); ++ qemuDomainGetStatsBlockExportFrontendLatencyHistogram(en->histogram_write, idx, ++ VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_WRITE_PREFIX, ++ par); ++ qemuDomainGetStatsBlockExportFrontendLatencyHistogram(en->histogram_zone, idx, ++ VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_ZONE_APPEND_PREFIX, ++ par); ++ qemuDomainGetStatsBlockExportFrontendLatencyHistogram(en->histogram_flush, idx, ++ VIR_DOMAIN_STATS_BLOCK_SUFFIX_LATENCY_HISTOGRAM_FLUSH_PREFIX, ++ par); + } + + +-- +2.53.0 diff --git a/SOURCES/libvirt-Introduce-support-for-disk-operation-latency-histogram-collection.patch b/SOURCES/libvirt-Introduce-support-for-disk-operation-latency-histogram-collection.patch new file mode 100644 index 0000000..8a95bf4 --- /dev/null +++ b/SOURCES/libvirt-Introduce-support-for-disk-operation-latency-histogram-collection.patch @@ -0,0 +1,422 @@ +From a26ff56a6bc216751ea6995d63396dfa634407c1 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Peter Krempa +Date: Fri, 23 Jan 2026 17:09:27 +0100 +Subject: [PATCH] Introduce support for disk operation latency histogram + collection + +Add config and docs allowing enabling latency histogram collection for +block device operations. + +This patch sets up the docs, schema and XML infrastructure. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit b874c944bd8c4ffa6c51394557587c8c203f1656) + +https://issues.redhat.com/browse/RHEL-147866 [rhel-9.8] +https://issues.redhat.com/browse/RHEL-131335 [rhel-10.2] +--- + docs/formatdomain.rst | 41 ++++++ + src/conf/domain_conf.c | 133 +++++++++++++++++- + src/conf/domain_conf.h | 7 + + src/conf/schemas/domaincommon.rng | 37 ++++- + ...isk-statistics-intervals.x86_64-latest.xml | 29 ++++ + .../disk-statistics-intervals.xml | 25 ++++ + 6 files changed, 262 insertions(+), 10 deletions(-) + +diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst +index 70882c6820..31232deb3c 100644 +--- a/docs/formatdomain.rst ++++ b/docs/formatdomain.rst +@@ -3628,6 +3628,47 @@ paravirtualized driver is specified via the ``disk`` element. + + :since:`Since 11.9.0 (QEMU 10.2, virtio, ide, scsi disks only)`. + ++ Block operation latency histogram collection can be configured using ++ ```` sub-element. The histogram is collected for ++ the whole runtime of the VM, but can be re-started or reconfigured using ++ the `virDomainUpdateDeviceFlags `__ ++ API. Using the same config re-starts histogram collection. ++ ++ The optional ``type`` attribute configures specific operation to collect ++ the histogram for. Supported types are ``read``, ``write``, ``zone``, and ++ ``flush``. If the ``type`` attribute is omitted the histogram collection ++ bins bins apply to all of the aforementioned types, which can be overriden ++ with specific config. ++ ++ The ```` has multiple mandatory ```` sub-elements ++ with mandatory ``start`` attribute configuring the starting boundary of ++ the histogram bin configured in nanosecods of the operation duration and ++ the intervals must be properly ordered and non-duplicate. ++ ++ Example:: ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ [or for specific operation types] ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ :since:`Since 12.1.0`. ++ + - 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 f5c4d135a9..83c58ab5ff 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -2445,6 +2445,11 @@ virDomainDiskDefFree(virDomainDiskDef *def) + virObjectUnref(def->privateData); + g_slist_free_full(def->iothreads, (GDestroyNotify) virDomainIothreadMappingDefFree); + g_free(def->statistics); ++ g_free(def->histogram_boundaries); ++ g_free(def->histogram_boundaries_read); ++ g_free(def->histogram_boundaries_write); ++ g_free(def->histogram_boundaries_zone); ++ g_free(def->histogram_boundaries_flush); + + if (def->throttlefilters) { + size_t i; +@@ -8307,6 +8312,91 @@ virDomainIothreadMappingDefParse(xmlNodePtr driverNode, + } + + ++static int ++virDomainDiskDefDriverParseXMLHistogramOne(virDomainDiskDef *def, ++ xmlNodePtr cur) ++{ ++ g_autofree char *histogram_type = NULL; ++ unsigned int **histogram_config = NULL; ++ g_autoptr(GPtrArray) binNodes = virXMLNodeGetSubelementList(cur, "bin"); ++ size_t nbins = 0; ++ size_t i; ++ ++ if ((histogram_type = virXMLPropString(cur, "type"))) { ++ if (STREQ(histogram_type, "read")) { ++ histogram_config = &def->histogram_boundaries_read; ++ } else if (STREQ(histogram_type, "write")) { ++ histogram_config = &def->histogram_boundaries_write; ++ } else if (STREQ(histogram_type, "zone")) { ++ histogram_config = &def->histogram_boundaries_zone; ++ } else if (STREQ(histogram_type, "flush")) { ++ histogram_config = &def->histogram_boundaries_flush; ++ } else { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("unknown latency_histogram type '%1$s'"), ++ histogram_type); ++ return -1; ++ } ++ } else { ++ histogram_config = &def->histogram_boundaries; ++ } ++ ++ if (*histogram_config) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("only one latency-histogram of a given type is supported")); ++ return -1; ++ } ++ ++ if (binNodes->len == 0) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("missing 'bin' elements for 'latency-histogram'")); ++ return -1; ++ } ++ ++ *histogram_config = g_new0(unsigned int, binNodes->len + 1); ++ ++ for (i = 0; i < binNodes->len; i++) { ++ unsigned int val; ++ ++ if (virXMLPropUInt(g_ptr_array_index(binNodes, i), ++ "start", 10, ++ VIR_XML_PROP_REQUIRED, ++ &val) < 0) ++ return -1; ++ ++ if (nbins > 0 && ++ (val == 0 || ++ val <= (*histogram_config)[nbins-1])) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("the values of 'start' attribute of a 'latency-histogram' 'bin' configuration must be sorted and non-overlapping")); ++ return -1; ++ } ++ ++ if (val > 0) ++ (*histogram_config)[nbins++] = val; ++ } ++ ++ return 0; ++} ++ ++ ++static int ++virDomainDiskDefDriverParseXMLHistograms(virDomainDiskDef *def, ++ xmlNodePtr cur) ++{ ++ g_autoptr(GPtrArray) histogramNodes = virXMLNodeGetSubelementList(cur, "latency-histogram"); ++ size_t i; ++ ++ for (i = 0; i < histogramNodes->len; i++) { ++ if (virDomainDiskDefDriverParseXMLHistogramOne(def, ++ g_ptr_array_index(histogramNodes, i)) < 0) ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ + static int + virDomainDiskDefDriverParseXML(virDomainDiskDef *def, + xmlNodePtr cur) +@@ -8380,6 +8470,9 @@ virDomainDiskDefDriverParseXML(virDomainDiskDef *def, + return -1; + } + } ++ ++ if (virDomainDiskDefDriverParseXMLHistograms(def, statisticsNode) < 0) ++ return -1; + } + + if (virXMLPropEnum(cur, "detect_zeroes", +@@ -23961,12 +24054,37 @@ virDomainDiskDefFormatThrottleFilters(virBuffer *buf, + } + + ++static void ++virDomainDiskDefFormatDriverHistogram(virBuffer *buf, ++ const char *type, ++ unsigned int *bins) ++{ ++ g_auto(virBuffer) histogramAttrBuf = VIR_BUFFER_INITIALIZER; ++ g_auto(virBuffer) histogramChildBuf = VIR_BUFFER_INIT_CHILD(buf); ++ ++ if (!bins || bins[0] == 0) ++ return; ++ ++ if (type) ++ virBufferAsprintf(&histogramAttrBuf, " type='%s'", type); ++ ++ /* we dont store the start boundary of the first bin but it's always there */ ++ virBufferAddLit(&histogramChildBuf, "\n"); ++ ++ for (; *bins > 0; bins++) ++ virBufferAsprintf(&histogramChildBuf, "\n", *bins); ++ ++ virXMLFormatElement(buf, "latency-histogram", &histogramAttrBuf, &histogramChildBuf); ++} ++ ++ + static void + virDomainDiskDefFormatDriver(virBuffer *buf, + virDomainDiskDef *disk) + { + g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER; + g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf); ++ g_auto(virBuffer) statisticsChildBuf = VIR_BUFFER_INIT_CHILD(&childBuf); + + virBufferEscapeString(&attrBuf, " name='%s'", virDomainDiskGetDriver(disk)); + +@@ -24038,16 +24156,25 @@ 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); + } + ++ virDomainDiskDefFormatDriverHistogram(&statisticsChildBuf, NULL, ++ disk->histogram_boundaries); ++ virDomainDiskDefFormatDriverHistogram(&statisticsChildBuf, "read", ++ disk->histogram_boundaries_read); ++ virDomainDiskDefFormatDriverHistogram(&statisticsChildBuf, "write", ++ disk->histogram_boundaries_write); ++ virDomainDiskDefFormatDriverHistogram(&statisticsChildBuf, "zone", ++ disk->histogram_boundaries_zone); ++ virDomainDiskDefFormatDriverHistogram(&statisticsChildBuf, "flush", ++ disk->histogram_boundaries_flush); ++ ++ 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 8f53ed96c0..b120d4a68e 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -596,6 +596,13 @@ struct _virDomainDiskDef { + GSList *iothreads; /* List of virDomainIothreadMappingDef */ + unsigned int *statistics; /* Optional, zero terminated list of intervals to + collect statistics for */ ++ /* optional zero terminated lists of bin boundaries for latency histograms */ ++ unsigned int *histogram_boundaries; ++ unsigned int *histogram_boundaries_read; ++ unsigned int *histogram_boundaries_write; ++ unsigned int *histogram_boundaries_zone; ++ unsigned int *histogram_boundaries_flush; ++ + 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 1f9ac102a0..441328a08e 100644 +--- a/src/conf/schemas/domaincommon.rng ++++ b/src/conf/schemas/domaincommon.rng +@@ -2728,13 +2728,36 @@ + + + +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ read ++ write ++ zone ++ flush ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +diff --git a/tests/qemuxmlconfdata/disk-statistics-intervals.x86_64-latest.xml b/tests/qemuxmlconfdata/disk-statistics-intervals.x86_64-latest.xml +index 4c55c50ef5..d02f954073 100644 +--- a/tests/qemuxmlconfdata/disk-statistics-intervals.x86_64-latest.xml ++++ b/tests/qemuxmlconfdata/disk-statistics-intervals.x86_64-latest.xml +@@ -22,6 +22,11 @@ + + + ++ ++ ++ ++ ++ + + + +@@ -33,6 +38,30 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +diff --git a/tests/qemuxmlconfdata/disk-statistics-intervals.xml b/tests/qemuxmlconfdata/disk-statistics-intervals.xml +index f5e801f5a8..5f9e9470d7 100644 +--- a/tests/qemuxmlconfdata/disk-statistics-intervals.xml ++++ b/tests/qemuxmlconfdata/disk-statistics-intervals.xml +@@ -19,6 +19,11 @@ + + + ++ ++ ++ ++ ++ + + + +@@ -29,6 +34,26 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +-- +2.53.0 diff --git a/SOURCES/libvirt-RHEL-ONLY-backport-test-data-for-migrate-pr-capability-of-scsi-block.patch b/SOURCES/libvirt-RHEL-ONLY-backport-test-data-for-migrate-pr-capability-of-scsi-block.patch new file mode 100644 index 0000000..6f8b0dc --- /dev/null +++ b/SOURCES/libvirt-RHEL-ONLY-backport-test-data-for-migrate-pr-capability-of-scsi-block.patch @@ -0,0 +1,125 @@ +From 91aa454341b6cf9a901405b8e12d4c15a233e05a Mon Sep 17 00:00:00 2001 +Message-ID: <91aa454341b6cf9a901405b8e12d4c15a233e05a.1771336751.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Mon, 16 Feb 2026 15:08:54 +0100 +Subject: [PATCH] RHEL-ONLY: backport test data for 'migrate-pr' capability of + 'scsi-block' + +In upstream qemu the capability is present starting with qemu-11.0. We +don't have the test data downstream and backporting them would be too +invasive. Backport the relevant capability detection as a +downstream-only fix. + +https://issues.redhat.com/browse/RHEL-140614 [rhel-9.8] +https://issues.redhat.com/browse/RHEL-135115 [rhel-10.2] + +Signed-off-by: Peter Krempa +--- + .../caps_10.2.0_x86_64.replies | 79 ++++++++++++++++++- + .../caps_10.2.0_x86_64.xml | 1 + + 2 files changed, 76 insertions(+), 4 deletions(-) + +diff --git a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.replies b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.replies +index cb4abb4533..10db9baca1 100644 +--- a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.replies ++++ b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.replies +@@ -33081,10 +33081,81 @@ + } + + { +- "error": { +- "class": "DeviceNotFound", +- "desc": "The libvirt device dump was not collected for this version+device tuple" +- }, ++ "return": [ ++ { ++ "default-value": 4294967295, ++ "name": "scsi-id", ++ "type": "uint32" ++ }, ++ { ++ "default-value": 4294967295, ++ "name": "lun", ++ "type": "uint32" ++ }, ++ { ++ "default-value": 0, ++ "name": "channel", ++ "type": "uint32" ++ }, ++ { ++ "default-value": "auto", ++ "name": "rerror", ++ "description": "Error handling policy (report/ignore/enospc/stop/auto)", ++ "type": "BlockdevOnError" ++ }, ++ { ++ "default-value": 2147483647, ++ "name": "max_io_size", ++ "type": "uint64" ++ }, ++ { ++ "default-value": false, ++ "name": "share-rw", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "default-value": true, ++ "name": "migrate-pr", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "default-value": "auto", ++ "name": "werror", ++ "description": "Error handling policy (report/ignore/enospc/stop/auto)", ++ "type": "BlockdevOnError" ++ }, ++ { ++ "default-value": 1073741824, ++ "name": "max_unmap_size", ++ "type": "uint64" ++ }, ++ { ++ "default-value": -1, ++ "name": "scsi_version", ++ "type": "int32" ++ }, ++ { ++ "default-value": 0, ++ "name": "rotation_rate", ++ "type": "uint16" ++ }, ++ { ++ "name": "drive", ++ "description": "Node name or ID of a block device to use as a backend", ++ "type": "str" ++ }, ++ { ++ "default-value": 30, ++ "name": "io_timeout", ++ "type": "uint32" ++ }, ++ { ++ "name": "bootindex", ++ "type": "int32" ++ } ++ ], + "id": "libvirt-37" + } + +diff --git a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml +index 7cff2c2291..7d5a75ce88 100644 +--- a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.xml +@@ -215,6 +215,7 @@ + + + ++ + 10001091 + 43100287 + v10.2.0-rc1-38-gfb241d0a1f +-- +2.53.0 diff --git a/SOURCES/libvirt-build-Bump-minimum-glib2-version-to-2.66.0.patch b/SOURCES/libvirt-build-Bump-minimum-glib2-version-to-2.66.0.patch deleted file mode 100644 index d1f76c1..0000000 --- a/SOURCES/libvirt-build-Bump-minimum-glib2-version-to-2.66.0.patch +++ /dev/null @@ -1,286 +0,0 @@ -From 5e88ca84d3988e7943cace7b53cd1a249c55a99b Mon Sep 17 00:00:00 2001 -Message-ID: <5e88ca84d3988e7943cace7b53cd1a249c55a99b.1738940190.git.jdenemar@redhat.com> -From: Peter Krempa -Date: Mon, 27 Jan 2025 17:42:34 +0100 -Subject: [PATCH] build: Bump minimum glib2 version to 2.66.0 - -Per our supported platforms the minimum available versions are: - - CentOS Stream 9: 2.68.4 - Debian 11: 2.66.8 - Fedora 39: 2.78.6 - openSUSE Leap 15.6: 2.78.6 - Ubuntu 22.04: 2.72.4 - FreeBSD ports: 2.80.5 - macOS homebrew: 2.82.4 - macOS macports: 2.78.4 - -Bump to 2.66 which is limited by Debian 11. While ideally we'd bump to -2.68 which would give us 'g_strv_builder' and friends 2.66 is enough for -g_ptr_array_steal() which can be used to emulate the former with almost -no extra code. - -Signed-off-by: Peter Krempa -Reviewed-by: Pavel Hrdina -(cherry picked from commit 420c39d6bd66ccf4841878882f5a3e9e47103ebb) - -https://issues.redhat.com/browse/RHEL-77884 ---- - libvirt.spec.in | 2 +- - meson.build | 2 +- - src/libvirt_private.syms | 4 -- - src/qemu/qemu_agent.c | 2 +- - src/qemu/qemu_monitor.c | 2 +- - src/util/glibcompat.c | 94 ---------------------------------------- - src/util/glibcompat.h | 18 -------- - src/util/vireventglib.c | 12 ++--- - 8 files changed, 10 insertions(+), 126 deletions(-) - -diff --git a/meson.build b/meson.build -index 89ac1594cb..d3e2c939ea 100644 ---- a/meson.build -+++ b/meson.build -@@ -998,7 +998,7 @@ else - endif - endif - --glib_version = '2.58.0' -+glib_version = '2.66.0' - glib_dep = dependency('glib-2.0', version: '>=' + glib_version) - gobject_dep = dependency('gobject-2.0', version: '>=' + glib_version) - if host_machine.system() == 'windows' -diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms -index c931003fad..43e2dfb9cd 100644 ---- a/src/libvirt_private.syms -+++ b/src/libvirt_private.syms -@@ -1871,10 +1871,6 @@ virStorageSourceUpdatePhysicalSize; - - - # util/glibcompat.h --vir_g_fsync; --vir_g_source_unref; --vir_g_strdup_printf; --vir_g_strdup_vprintf; - vir_g_string_replace; - - -diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c -index 22359f8518..43fca86f10 100644 ---- a/src/qemu/qemu_agent.c -+++ b/src/qemu/qemu_agent.c -@@ -448,7 +448,7 @@ qemuAgentUnregister(qemuAgent *agent) - { - if (agent->watch) { - g_source_destroy(agent->watch); -- vir_g_source_unref(agent->watch, agent->context); -+ g_source_unref(agent->watch); - agent->watch = NULL; - } - } -diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c -index 73f37d26eb..79bd91b539 100644 ---- a/src/qemu/qemu_monitor.c -+++ b/src/qemu/qemu_monitor.c -@@ -745,7 +745,7 @@ qemuMonitorUnregister(qemuMonitor *mon) - { - if (mon->watch) { - g_source_destroy(mon->watch); -- vir_g_source_unref(mon->watch, mon->context); -+ g_source_unref(mon->watch); - mon->watch = NULL; - } - } -diff --git a/src/util/glibcompat.c b/src/util/glibcompat.c -index 98dcfab389..bcb666992a 100644 ---- a/src/util/glibcompat.c -+++ b/src/util/glibcompat.c -@@ -63,100 +63,6 @@ - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wdeprecated-declarations" - --#undef g_fsync --#undef g_strdup_printf --#undef g_strdup_vprintf -- -- --/* Drop when min glib >= 2.63.0 */ --gint --vir_g_fsync(gint fd) --{ --#ifdef G_OS_WIN32 -- return _commit(fd); --#else -- return fsync(fd); --#endif --} -- -- --/* Due to a bug in glib, g_strdup_printf() nor g_strdup_vprintf() -- * abort on OOM. It's fixed in glib's upstream. Provide our own -- * implementation until the fix gets distributed. */ --char * --vir_g_strdup_printf(const char *msg, ...) --{ -- va_list args; -- char *ret; -- va_start(args, msg); -- ret = g_strdup_vprintf(msg, args); -- if (!ret) -- abort(); -- va_end(args); -- return ret; --} -- -- --char * --vir_g_strdup_vprintf(const char *msg, va_list args) --{ -- char *ret; -- ret = g_strdup_vprintf(msg, args); -- if (!ret) -- abort(); -- return ret; --} -- -- --/* -- * If the last reference to a GSource is released in a non-main -- * thread we're exposed to a race condition that causes a -- * crash: -- * -- * https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1358 -- * -- * Thus we're using an idle func to release our ref... -- * -- * ...but this imposes a significant performance penalty on -- * I/O intensive workloads which are sensitive to the iterations -- * of the event loop, so avoid the workaround if we know we have -- * new enough glib. -- * -- * The function below is used from a header file definition. -- * -- * Drop when min glib >= 2.64.0 -- */ --#if GLIB_CHECK_VERSION(2, 64, 0) --void vir_g_source_unref(GSource *src, GMainContext *ctx G_GNUC_UNUSED) --{ -- g_source_unref(src); --} --#else -- --static gboolean --virEventGLibSourceUnrefIdle(gpointer data) --{ -- GSource *src = data; -- -- g_source_unref(src); -- -- return FALSE; --} -- --void vir_g_source_unref(GSource *src, GMainContext *ctx) --{ -- GSource *idle = g_idle_source_new(); -- -- g_source_set_callback(idle, virEventGLibSourceUnrefIdle, src, NULL); -- -- g_source_attach(idle, ctx); -- -- g_source_unref(idle); --} -- --#endif -- -- - /** - * Adapted (to pass syntax check) from 'g_string_replace' from - * glib-2.81.1. Drop once minimum glib is bumped to 2.68. -diff --git a/src/util/glibcompat.h b/src/util/glibcompat.h -index 474ff95bc5..a3d01089e6 100644 ---- a/src/util/glibcompat.h -+++ b/src/util/glibcompat.h -@@ -42,24 +42,6 @@ - - #endif /* GLib < 2.67.0 */ - -- --gint vir_g_fsync(gint fd); --char *vir_g_strdup_printf(const char *msg, ...) -- G_GNUC_PRINTF(1, 2); --char *vir_g_strdup_vprintf(const char *msg, va_list args) -- G_GNUC_PRINTF(1, 0); -- --#if !GLIB_CHECK_VERSION(2, 64, 0) --# define g_strdup_printf vir_g_strdup_printf --# define g_strdup_vprintf vir_g_strdup_vprintf --#endif -- --#undef g_fsync --#define g_fsync vir_g_fsync -- --void vir_g_source_unref(GSource *src, GMainContext *ctx); -- -- - /* Drop once we require glib-2.68 at minimum */ - guint - vir_g_string_replace(GString *string, -diff --git a/src/util/vireventglib.c b/src/util/vireventglib.c -index 023dc37445..6c54f62123 100644 ---- a/src/util/vireventglib.c -+++ b/src/util/vireventglib.c -@@ -213,7 +213,7 @@ virEventGLibHandleUpdate(int watch, - if (data->source != NULL) { - VIR_DEBUG("Removed old handle source=%p", data->source); - g_source_destroy(data->source); -- vir_g_source_unref(data->source, NULL); -+ g_source_unref(data->source); - } - - data->source = virEventGLibAddSocketWatch( -@@ -227,7 +227,7 @@ virEventGLibHandleUpdate(int watch, - - VIR_DEBUG("Removed old handle source=%p", data->source); - g_source_destroy(data->source); -- vir_g_source_unref(data->source, NULL); -+ g_source_unref(data->source); - data->source = NULL; - data->events = 0; - } -@@ -276,7 +276,7 @@ virEventGLibHandleRemove(int watch) - - if (data->source != NULL) { - g_source_destroy(data->source); -- vir_g_source_unref(data->source, NULL); -+ g_source_unref(data->source); - data->source = NULL; - data->events = 0; - } -@@ -409,7 +409,7 @@ virEventGLibTimeoutUpdate(int timer, - if (interval >= 0) { - if (data->source != NULL) { - g_source_destroy(data->source); -- vir_g_source_unref(data->source, NULL); -+ g_source_unref(data->source); - } - - data->interval = interval; -@@ -419,7 +419,7 @@ virEventGLibTimeoutUpdate(int timer, - goto cleanup; - - g_source_destroy(data->source); -- vir_g_source_unref(data->source, NULL); -+ g_source_unref(data->source); - data->source = NULL; - } - -@@ -468,7 +468,7 @@ virEventGLibTimeoutRemove(int timer) - - if (data->source != NULL) { - g_source_destroy(data->source); -- vir_g_source_unref(data->source, NULL); -+ g_source_unref(data->source); - data->source = NULL; - } - --- -2.48.1 diff --git a/SOURCES/libvirt-conf-Adjust-hyperv-tlbflush-formatting.patch b/SOURCES/libvirt-conf-Adjust-hyperv-tlbflush-formatting.patch deleted file mode 100644 index e2fc32d..0000000 --- a/SOURCES/libvirt-conf-Adjust-hyperv-tlbflush-formatting.patch +++ /dev/null @@ -1,72 +0,0 @@ -From e34ac564b018b166a7d6f955f2abe80a9e62f07e Mon Sep 17 00:00:00 2001 -Message-ID: -From: Martin Kletzander -Date: Mon, 6 Jan 2025 16:11:01 +0100 -Subject: [PATCH] conf: Adjust hyperv tlbflush formatting -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Commit 247357cc292a added support for direct and extended modes for -tlbflush, but forgot to do the formatting as well. - -Signed-off-by: Martin Kletzander -Signed-off-by: Ján Tomko -Reviewed-by: Martin Kletzander -(cherry picked from commit 9df14f51735eeb4221a25ccd408a2dccf0a35b59) - -https://issues.redhat.com/browse/RHEL-7122 - -Signed-off-by: Martin Kletzander ---- - src/conf/domain_conf.c | 11 ++++++++++- - tests/qemuxmlconfdata/hyperv.x86_64-latest.xml | 5 ++++- - 2 files changed, 14 insertions(+), 2 deletions(-) - -diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c -index c8254d2146..1f0b67ca28 100644 ---- a/src/conf/domain_conf.c -+++ b/src/conf/domain_conf.c -@@ -27974,7 +27974,6 @@ virDomainDefFormatFeatures(virBuffer *buf, - case VIR_DOMAIN_HYPERV_RESET: - case VIR_DOMAIN_HYPERV_FREQUENCIES: - case VIR_DOMAIN_HYPERV_REENLIGHTENMENT: -- case VIR_DOMAIN_HYPERV_TLBFLUSH: - case VIR_DOMAIN_HYPERV_IPI: - case VIR_DOMAIN_HYPERV_EVMCS: - case VIR_DOMAIN_HYPERV_AVIC: -@@ -28004,6 +28003,16 @@ virDomainDefFormatFeatures(virBuffer *buf, - } - break; - -+ case VIR_DOMAIN_HYPERV_TLBFLUSH: -+ if (def->hyperv_features[j] != VIR_TRISTATE_SWITCH_ON) -+ break; -+ -+ if (def->hyperv_tlbflush_direct == VIR_TRISTATE_SWITCH_ON) -+ virBufferAddLit(&hypervChildBuf, "\n"); -+ if (def->hyperv_tlbflush_extended == VIR_TRISTATE_SWITCH_ON) -+ virBufferAddLit(&hypervChildBuf, "\n"); -+ break; -+ - case VIR_DOMAIN_HYPERV_LAST: - break; - } -diff --git a/tests/qemuxmlconfdata/hyperv.x86_64-latest.xml b/tests/qemuxmlconfdata/hyperv.x86_64-latest.xml -index 36d9161fa8..49537188af 100644 ---- a/tests/qemuxmlconfdata/hyperv.x86_64-latest.xml -+++ b/tests/qemuxmlconfdata/hyperv.x86_64-latest.xml -@@ -22,7 +22,10 @@ - - - -- -+ -+ -+ -+ - - - --- -2.47.1 diff --git a/SOURCES/libvirt-conf-Introduce-iommufd-enum-for-domaincaps.patch b/SOURCES/libvirt-conf-Introduce-iommufd-enum-for-domaincaps.patch new file mode 100644 index 0000000..99ef8a7 --- /dev/null +++ b/SOURCES/libvirt-conf-Introduce-iommufd-enum-for-domaincaps.patch @@ -0,0 +1,69 @@ +From 18aa061f3b4f2b2c2ed6f07120a990935f56d93e Mon Sep 17 00:00:00 2001 +Message-ID: <18aa061f3b4f2b2c2ed6f07120a990935f56d93e.1771423832.git.jdenemar@redhat.com> +From: Pavel Hrdina +Date: Sat, 14 Feb 2026 06:14:20 +0100 +Subject: [PATCH] conf: Introduce iommufd enum for domaincaps + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 855f8fe9e2454555ba84696750e0e1501dd5ba80) + +Resolves: https://issues.redhat.com/browse/RHEL-138544 +Signed-off-by: Pavel Hrdina +--- + docs/formatdomaincaps.rst | 7 +++++++ + src/conf/domain_capabilities.c | 1 + + src/conf/domain_capabilities.h | 1 + + 3 files changed, 9 insertions(+) + +diff --git a/docs/formatdomaincaps.rst b/docs/formatdomaincaps.rst +index 8b4f0ecff3..6ba7f84f96 100644 +--- a/docs/formatdomaincaps.rst ++++ b/docs/formatdomaincaps.rst +@@ -461,6 +461,10 @@ Well, only if the following is enabled: + vfio + xen + ++ ++ yes ++ no ++ + + + +@@ -477,6 +481,9 @@ Well, only if the following is enabled: + ``mode="capabilities"``. + ``pciBackend`` + Options for the ``name`` attribute of the element. ++``iommufd`` ++ Options for the ``iommufd`` attribute of the element. ++ :since:`Since 12.1.0` + + RNG device + ^^^^^^^^^^ +diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c +index f843124695..49179b97ab 100644 +--- a/src/conf/domain_capabilities.c ++++ b/src/conf/domain_capabilities.c +@@ -620,6 +620,7 @@ virDomainCapsDeviceHostdevFormat(virBuffer *buf, + ENUM_PROCESS(hostdev, subsysType, virDomainHostdevSubsysTypeToString); + ENUM_PROCESS(hostdev, capsType, virDomainHostdevCapsTypeToString); + ENUM_PROCESS(hostdev, pciBackend, virDeviceHostdevPCIDriverNameTypeToString); ++ ENUM_PROCESS(hostdev, iommufd, virTristateBoolTypeToString); + + FORMAT_EPILOGUE(hostdev); + } +diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h +index 437981c711..b10370db8f 100644 +--- a/src/conf/domain_capabilities.h ++++ b/src/conf/domain_capabilities.h +@@ -108,6 +108,7 @@ struct _virDomainCapsDeviceHostdev { + virDomainCapsEnum subsysType; /* Info about virDomainHostdevSubsysType */ + virDomainCapsEnum capsType; /* Info about virDomainHostdevCapsType */ + virDomainCapsEnum pciBackend; /* Info about virDomainHostdevSubsysPCIBackendType */ ++ virDomainCapsEnum iommufd; /* Info about iommufd:virTristateBool */ + /* add new fields here */ + }; + +-- +2.53.0 diff --git a/SOURCES/libvirt-conf-Introduce-virDomainDefHasPCIHostdevWithIOMMUFD.patch b/SOURCES/libvirt-conf-Introduce-virDomainDefHasPCIHostdevWithIOMMUFD.patch new file mode 100644 index 0000000..6969f7b --- /dev/null +++ b/SOURCES/libvirt-conf-Introduce-virDomainDefHasPCIHostdevWithIOMMUFD.patch @@ -0,0 +1,132 @@ +From 748c9648eb88b69e3ed0847126d59d6c7a11eda8 Mon Sep 17 00:00:00 2001 +Message-ID: <748c9648eb88b69e3ed0847126d59d6c7a11eda8.1771423832.git.jdenemar@redhat.com> +From: Pavel Hrdina +Date: Sun, 15 Feb 2026 18:19:56 +0100 +Subject: [PATCH] conf: Introduce virDomainDefHasPCIHostdevWithIOMMUFD + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 4b176cfc3877cca882d63ab4ed446794d7a05722) + +Resolves: https://issues.redhat.com/browse/RHEL-150353 +Signed-off-by: Pavel Hrdina +--- + src/conf/domain_conf.c | 14 ++++++++++++++ + src/conf/domain_conf.h | 3 +++ + src/libvirt_private.syms | 1 + + src/qemu/qemu_command.c | 42 ++++++++++++---------------------------- + 4 files changed, 30 insertions(+), 30 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 9ae48e9abc..cb047e5a3e 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -32482,6 +32482,20 @@ virDomainDefHasPCIHostdev(const virDomainDef *def) + } + + ++bool ++virDomainDefHasPCIHostdevWithIOMMUFD(const virDomainDef *def) ++{ ++ size_t i; ++ ++ for (i = 0; i < def->nhostdevs; i++) { ++ if (virHostdevIsPCIDeviceWithIOMMUFD(def->hostdevs[i])) ++ return true; ++ } ++ ++ return false; ++} ++ ++ + bool + virDomainDefHasMdevHostdev(const virDomainDef *def) + { +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index d958ed04f9..69a8e79c6d 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -4655,6 +4655,9 @@ virDomainDefHasNVMeDisk(const virDomainDef *def); + bool + virDomainDefHasPCIHostdev(const virDomainDef *def); + ++bool ++virDomainDefHasPCIHostdevWithIOMMUFD(const virDomainDef *def); ++ + bool + virDomainDefHasMdevHostdev(const virDomainDef *def); + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 863e50ec4f..effe44fe57 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -348,6 +348,7 @@ virDomainDefHasNVMeDisk; + virDomainDefHasOldStyleROUEFI; + virDomainDefHasOldStyleUEFI; + virDomainDefHasPCIHostdev; ++virDomainDefHasPCIHostdevWithIOMMUFD; + virDomainDefHasTimer; + virDomainDefHasUSB; + virDomainDefHasVcpusOffline; +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 1718097b63..482f8d8ca2 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -5349,43 +5349,25 @@ qemuBuildIOMMUFDCommandLine(virCommand *cmd, + const virDomainDef *def, + virDomainObj *vm) + { +- size_t i; + qemuDomainObjPrivate *priv = vm->privateData; + g_autofree char *fdstr = g_strdup_printf("%d", priv->iommufd); ++ g_autoptr(virJSONValue) props = NULL; + ++ if (!virDomainDefHasPCIHostdevWithIOMMUFD(def)) ++ return 0; + +- for (i = 0; i < def->nhostdevs; i++) { +- virDomainHostdevDef *hostdev = def->hostdevs[i]; +- virDomainHostdevSubsys *subsys = &hostdev->source.subsys; +- g_autoptr(virJSONValue) props = NULL; ++ virCommandPassFD(cmd, priv->iommufd, VIR_COMMAND_PASS_FD_CLOSE_PARENT); + +- if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) +- continue; ++ priv->iommufd = -1; + +- if (subsys->type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) +- continue; ++ if (qemuMonitorCreateObjectProps(&props, "iommufd", ++ "iommufd0", ++ "S:fd", fdstr, ++ NULL) < 0) ++ return -1; + +- if (hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_UNASSIGNED) +- continue; +- +- if (subsys->u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) +- continue; +- +- virCommandPassFD(cmd, priv->iommufd, VIR_COMMAND_PASS_FD_CLOSE_PARENT); +- +- priv->iommufd = -1; +- +- if (qemuMonitorCreateObjectProps(&props, "iommufd", +- "iommufd0", +- "S:fd", fdstr, +- NULL) < 0) +- return -1; +- +- if (qemuBuildObjectCommandlineFromJSON(cmd, props) < 0) +- return -1; +- +- break; +- } ++ if (qemuBuildObjectCommandlineFromJSON(cmd, props) < 0) ++ return -1; + + return 0; + } +-- +2.53.0 diff --git a/SOURCES/libvirt-conf-Introduce-virHostdevIsPCIDeviceWithIOMMUFD.patch b/SOURCES/libvirt-conf-Introduce-virHostdevIsPCIDeviceWithIOMMUFD.patch new file mode 100644 index 0000000..615615d --- /dev/null +++ b/SOURCES/libvirt-conf-Introduce-virHostdevIsPCIDeviceWithIOMMUFD.patch @@ -0,0 +1,89 @@ +From 3864161a4d28f0ef71d435f2ae1e52e92afaac15 Mon Sep 17 00:00:00 2001 +Message-ID: <3864161a4d28f0ef71d435f2ae1e52e92afaac15.1771423832.git.jdenemar@redhat.com> +From: Pavel Hrdina +Date: Sun, 15 Feb 2026 18:19:23 +0100 +Subject: [PATCH] conf: Introduce virHostdevIsPCIDeviceWithIOMMUFD + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 97eed30948e980be8b7552fff637e828768854e4) + +Resolves: https://issues.redhat.com/browse/RHEL-150353 +Signed-off-by: Pavel Hrdina +--- + src/conf/domain_conf.c | 15 +++++++++++++++ + src/conf/domain_conf.h | 3 +++ + src/libvirt_private.syms | 1 + + src/qemu/qemu_process.c | 5 +---- + 4 files changed, 20 insertions(+), 4 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 83c58ab5ff..9ae48e9abc 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -32758,6 +32758,21 @@ virHostdevIsPCIDevice(const virDomainHostdevDef *hostdev) + } + + ++/** ++ * virHostdevIsPCIDeviceWithIOMMUFD: ++ * @hostdev: host device to check ++ * ++ * Returns true if @hostdev is a PCI device with IOMMUFD enabled, false otherwise. ++ */ ++bool ++virHostdevIsPCIDeviceWithIOMMUFD(const virDomainHostdevDef *hostdev) ++{ ++ return virHostdevIsPCIDevice(hostdev) && ++ hostdev->source.subsys.u.pci.driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO && ++ hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES; ++} ++ ++ + static void + virDomainObjGetMessagesIOErrorsSrc(virStorageSource *src, + const char *diskdst, +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index b120d4a68e..d958ed04f9 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -4713,6 +4713,9 @@ virHostdevIsMdevDevice(const virDomainHostdevDef *hostdev) + bool + virHostdevIsPCIDevice(const virDomainHostdevDef *hostdev) + ATTRIBUTE_NONNULL(1); ++bool ++virHostdevIsPCIDeviceWithIOMMUFD(const virDomainHostdevDef *hostdev) ++ ATTRIBUTE_NONNULL(1); + + void + virDomainObjGetMessagesIOErrorsChain(virStorageSource *src, +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 9ae44e31b8..863e50ec4f 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -812,6 +812,7 @@ virDomainQemuMonitorEventNew; + virDomainQemuMonitorEventStateRegisterID; + virHostdevIsMdevDevice; + virHostdevIsPCIDevice; ++virHostdevIsPCIDeviceWithIOMMUFD; + virHostdevIsSCSIDevice; + + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 7e32325fa0..3bd81c55b3 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -7732,10 +7732,7 @@ qemuProcessOpenVfioFds(virDomainObj *vm) + for (i = 0; i < vm->def->nhostdevs; i++) { + virDomainHostdevDef *hostdev = vm->def->hostdevs[i]; + +- if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && +- hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && +- hostdev->source.subsys.u.pci.driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO && +- hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES) { ++ if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) { + /* Open VFIO device FD */ + if (qemuProcessOpenVfioDeviceFd(hostdev) < 0) + return -1; +-- +2.53.0 diff --git a/SOURCES/libvirt-conf-add-deprecated_features-attribute.patch b/SOURCES/libvirt-conf-add-deprecated_features-attribute.patch deleted file mode 100644 index 11fdd08..0000000 --- a/SOURCES/libvirt-conf-add-deprecated_features-attribute.patch +++ /dev/null @@ -1,280 +0,0 @@ -From 4c66a653f02c8259fdcf72fdcd801b594f73183e Mon Sep 17 00:00:00 2001 -Message-ID: <4c66a653f02c8259fdcf72fdcd801b594f73183e.1749039441.git.jdenemar@redhat.com> -From: Collin Walling -Date: Mon, 16 Dec 2024 18:03:58 -0500 -Subject: [PATCH] conf: add deprecated_features attribute - -Add a new a attribute, deprecated_features='on|off' to the -element. This is used to toggle features flagged as deprecated on the -CPU model on or off. When this attribute is paired with 'on', -deprecated features will not be filtered. When paired with 'off', any -CPU features that are flagged as deprecated will be listed under the -CPU model with the 'disable' policy. - -Example: - - - -The absence of this attribute is equivalent to the 'on' option. - -The deprecated features that will populate the domain XML are the same -features that result in the virsh domcapabilities command with the ---disable-deprecated-features argument present. - -It is recommended to define a domain XML with this attribute set to -'off' to ensure migration to machines that may outright drop these -features in the future. - -Signed-off-by: Collin Walling -Reviewed-by: Jiri Denemark -(cherry picked from commit 62658bbf060784c757f96c9de3935f27885834aa) -JIRA: https://issues.redhat.com/browse/RHEL-89415 -Signed-off-by: Thomas Huth ---- - src/conf/cpu_conf.c | 11 +++++++ - src/conf/cpu_conf.h | 1 + - src/conf/schemas/cputypes.rng | 5 +++ - src/qemu/qemu_process.c | 11 +++++++ - ...el-deprecated-features-off.s390x-8.2.0.err | 1 + - ...el-deprecated-features-off.s390x-8.2.0.xml | 25 +++++++++++++++ - ...-deprecated-features-off.s390x-latest.args | 32 +++++++++++++++++++ - ...l-deprecated-features-off.s390x-latest.xml | 25 +++++++++++++++ - .../cpu-model-deprecated-features-off.xml | 15 +++++++++ - tests/qemuxmlconftest.c | 3 ++ - 10 files changed, 129 insertions(+) - create mode 100644 tests/qemuxmlconfdata/cpu-model-deprecated-features-off.s390x-8.2.0.err - create mode 100644 tests/qemuxmlconfdata/cpu-model-deprecated-features-off.s390x-8.2.0.xml - create mode 100644 tests/qemuxmlconfdata/cpu-model-deprecated-features-off.s390x-latest.args - create mode 100644 tests/qemuxmlconfdata/cpu-model-deprecated-features-off.s390x-latest.xml - create mode 100644 tests/qemuxmlconfdata/cpu-model-deprecated-features-off.xml - -diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c -index dcc164d165..31425783ba 100644 ---- a/src/conf/cpu_conf.c -+++ b/src/conf/cpu_conf.c -@@ -238,6 +238,7 @@ virCPUDefCopyWithoutModel(const virCPUDef *cpu) - copy->mode = cpu->mode; - copy->match = cpu->match; - copy->check = cpu->check; -+ copy->deprecated_feats = cpu->deprecated_feats; - copy->fallback = cpu->fallback; - copy->sockets = cpu->sockets; - copy->dies = cpu->dies; -@@ -450,6 +451,11 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt, - if (virXMLPropEnum(ctxt->node, "check", virCPUCheckTypeFromString, - VIR_XML_PROP_NONE, &def->check) < 0) - return -1; -+ -+ if (virXMLPropTristateSwitch(ctxt->node, "deprecated_features", -+ VIR_XML_PROP_NONE, -+ &def->deprecated_feats) < 0) -+ return -1; - } - - if (def->type == VIR_CPU_TYPE_HOST) { -@@ -748,6 +754,11 @@ virCPUDefFormatBufFull(virBuffer *buf, - virBufferAsprintf(&attributeBuf, " migratable='%s'", - virTristateSwitchTypeToString(def->migratable)); - } -+ -+ if (def->deprecated_feats) { -+ virBufferAsprintf(&attributeBuf, " deprecated_features='%s'", -+ virTristateSwitchTypeToString(def->deprecated_feats)); -+ } - } - - /* Format children */ -diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h -index f71d942ce6..28e26303ef 100644 ---- a/src/conf/cpu_conf.h -+++ b/src/conf/cpu_conf.h -@@ -161,6 +161,7 @@ struct _virCPUDef { - virCPUMaxPhysAddrDef *addr; - virHostCPUTscInfo *tsc; - virTristateSwitch migratable; /* for host-passthrough mode */ -+ virTristateSwitch deprecated_feats; - }; - - virCPUDef *virCPUDefNew(void); -diff --git a/src/conf/schemas/cputypes.rng b/src/conf/schemas/cputypes.rng -index 3a8910e09f..8edf1d14e3 100644 ---- a/src/conf/schemas/cputypes.rng -+++ b/src/conf/schemas/cputypes.rng -@@ -439,6 +439,11 @@ - - - -+ -+ -+ -+ -+ - - - -diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c -index c1ae324ad4..64683ecfe0 100644 ---- a/src/qemu/qemu_process.c -+++ b/src/qemu/qemu_process.c -@@ -6429,6 +6429,17 @@ qemuProcessUpdateGuestCPU(virDomainDef *def, - &def->os.arch) < 0) - return -1; - -+ if (def->cpu->deprecated_feats && -+ !virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION_DEPRECATED_PROPS)) { -+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", -+ _("toggling deprecated features for CPU model is unsupported")); -+ return -1; -+ } -+ -+ if (def->cpu->deprecated_feats == VIR_TRISTATE_SWITCH_OFF) { -+ virQEMUCapsUpdateCPUDeprecatedFeatures(qemuCaps, def->virtType, def->cpu); -+ } -+ - return 0; - } - -diff --git a/tests/qemuxmlconfdata/cpu-model-deprecated-features-off.s390x-8.2.0.err b/tests/qemuxmlconfdata/cpu-model-deprecated-features-off.s390x-8.2.0.err -new file mode 100644 -index 0000000000..936d1d5a46 ---- /dev/null -+++ b/tests/qemuxmlconfdata/cpu-model-deprecated-features-off.s390x-8.2.0.err -@@ -0,0 +1 @@ -+unsupported configuration: toggling deprecated features for CPU model is unsupported -diff --git a/tests/qemuxmlconfdata/cpu-model-deprecated-features-off.s390x-8.2.0.xml b/tests/qemuxmlconfdata/cpu-model-deprecated-features-off.s390x-8.2.0.xml -new file mode 100644 -index 0000000000..e1f7ba3857 ---- /dev/null -+++ b/tests/qemuxmlconfdata/cpu-model-deprecated-features-off.s390x-8.2.0.xml -@@ -0,0 +1,25 @@ -+ -+ guest -+ 22782664-6b93-46bf-9595-317220dd2d1c -+ 219100 -+ 219100 -+ 1 -+ -+ hvm -+ -+ -+ -+ -+ destroy -+ restart -+ destroy -+ -+ /usr/bin/qemu-system-s390x -+ -+