libvirt-10.10.0-6.el9

- build: Bump minimum glib2 version to 2.66.0 (RHEL-77884)
- qemuProcessHandleIOError: Refactor to extract 'priv' instead of 'driver' (RHEL-77884)
- qemu: Handle quirks of 'device' field of BLOCK_IO_ERROR event in monitor code (RHEL-77884)
- qemu: Rename 'diskAlias' to 'device' in qemu IO error event handling (RHEL-77884)
- qemuProcessHandleIOError: Rename local variables (RHEL-77884)
- qemuMonitorJSONHandleIOError: Do not munge 'reason' field of IO error event (RHEL-77884)
- qemuProcessHandleIOError: Prefer lookup by node name (RHEL-77884)
- qemuMonitorJSONHandleIOError: Propagate new 'qom-path' field (RHEL-77884)
- virStorageSource: Add fields for storing last I/O error message (RHEL-77884)
- qemuProcessHandleIOError: Populate I/O error reason to virStorageSource (RHEL-77884)
- qemuProcessHandleIOError: Log IO errors in the VM log file (RHEL-77884)
- libxlDomainGetMessages: Add existing flags to 'virCheckFlags' (RHEL-77884)
- virDomainObjGetMessages: Refactor using GPtrArray (RHEL-77884)
- virDomainGetMessages: Introduce VIR_DOMAIN_MESSAGE_IOERRORS (RHEL-77884)
- include: libvirt-domain: Reword documentation for @reason of VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON (RHEL-77884)
- include: libvirt-domain: Add 'message' @reason of VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON (RHEL-77884)
- qemuSnapshotForEachQcow2: Don't initialize 'nrollback' (RHEL-73315)
- qemu: process: Export qemuPrepareNVRAM for use in snapshot code (RHEL-73315)
- qemu: snapshot: Ensure that NVRAM image exists when taking inactive internal snapshot (RHEL-73315)
- qemuxmlconftest: Allow testing of the 'writable' flag for passed FDs for disks (RHEL-37519)
- qemuxmlconftest: Add testing of FDs with 'writable' flag in 'disk-source-fd' (RHEL-37519)
- qemu: domain: Initialize FD passthrough for a virStorageSource before using it (RHEL-37519)

Resolves: RHEL-37519, RHEL-73315, RHEL-77884
This commit is contained in:
Jiri Denemark 2025-02-07 15:56:31 +01:00
parent c2bfdf96a6
commit 26e17db3c8
23 changed files with 2237 additions and 2 deletions

View File

@ -0,0 +1,286 @@
From 5e88ca84d3988e7943cace7b53cd1a249c55a99b Mon Sep 17 00:00:00 2001
Message-ID: <5e88ca84d3988e7943cace7b53cd1a249c55a99b.1738940190.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
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 <pkrempa@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
(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

View File

@ -0,0 +1,69 @@
From ebe771353b9511ec5850a1415b82399a53fa2c71 Mon Sep 17 00:00:00 2001
Message-ID: <ebe771353b9511ec5850a1415b82399a53fa2c71.1738940191.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 24 Jan 2025 16:26:54 +0100
Subject: [PATCH] include: libvirt-domain: Add 'message' @reason of
VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In case when the hypervisor does report the reason for the I/O error as
an unstable string to display to users we can add a @reason possibility
for the I/O error event noting that the error is available.
Add 'message' as a reason enumeration value and document it
to instruct users to look at the logs or virDomainGetMessages().
The resulting event looks like:
event 'io-error' for domain 'cd': /dev/mapper/errdev0 (virtio-disk0) report due to message
Users then can look at the virDomainGetMessages() API:
I/O error: disk='vda', index='1', path='/dev/mapper/errdev0', timestamp='2025-01-28 15:47:52.776+0000', message='Input/output error'
Or in the VM log file:
2025-01-28 15:47:52.776+0000: IO error device='virtio-disk0' node-name='libvirt-1-storage' reason='Input/output error'
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 97c47333cbdc2531260f7b11b1fa9ba828878343)
https://issues.redhat.com/browse/RHEL-77884
---
include/libvirt/libvirt-domain.h | 4 ++++
src/qemu/qemu_process.c | 2 ++
2 files changed, 6 insertions(+)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 1dc7b417c9..f026ce197c 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -4782,6 +4782,10 @@ typedef void (*virConnectDomainEventIOErrorCallback)(virConnectPtr conn,
* - "enospc": The I/O error is known to be caused by an ENOSPC condition in
* the host. Resizing the disk source to be larger will allow the
* guest to be resumed as if nothing happened.
+ * - "message": The hypervisor reported a string description of the
+ * I/O error. The errors are usually logged into the
+ * domain log file or the last instance of the error
+ * string can be queried via virDomainGetMessages().
*
* Since: 0.8.1
*/
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 409734d948..b9d69649ca 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -862,6 +862,8 @@ qemuProcessHandleIOError(qemuMonitor *mon G_GNUC_UNUSED,
if (nospace)
eventReason = "enospc";
+ else if (reason)
+ eventReason = "message";
ioErrorEvent = virDomainEventIOErrorNewFromObj(vm, eventPath, eventAlias, action);
ioErrorEvent2 = virDomainEventIOErrorReasonNewFromObj(vm, eventPath, eventAlias, action, eventReason);
--
2.48.1

View File

@ -0,0 +1,47 @@
From 5def2eb78e1152a78533e27647eda2352f1dbc4b Mon Sep 17 00:00:00 2001
Message-ID: <5def2eb78e1152a78533e27647eda2352f1dbc4b.1738940191.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 27 Jan 2025 15:50:34 +0100
Subject: [PATCH] include: libvirt-domain: Reword documentation for @reason of
VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Emphasise that it's an enumeration and convert the possibilities to a
list of values with explanation.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 3a3c5616eb2c50a58896f99f30d887937dab297a)
https://issues.redhat.com/browse/RHEL-77884
---
include/libvirt/libvirt-domain.h | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 92a32f1cde..1dc7b417c9 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -4775,11 +4775,13 @@ typedef void (*virConnectDomainEventIOErrorCallback)(virConnectPtr conn,
* The callback signature to use when registering for an event of type
* VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON with virConnectDomainEventRegisterAny()
*
- * If the I/O error is known to be caused by an ENOSPC condition in
- * the host (where resizing the disk to be larger will allow the guest
- * to be resumed as if nothing happened), @reason will be "enospc".
- * Otherwise, @reason will be "", although future strings may be added
- * if determination of other error types becomes possible.
+ * Although @reason is a string, it is considered to be an enumeration of the
+ * following values:
+ *
+ * - "" (empty string): unknown I/O error reason
+ * - "enospc": The I/O error is known to be caused by an ENOSPC condition in
+ * the host. Resizing the disk source to be larger will allow the
+ * guest to be resumed as if nothing happened.
*
* Since: 0.8.1
*/
--
2.48.1

View File

@ -0,0 +1,37 @@
From c417e164d2b225ea401093e33a853d827d8bd8ca Mon Sep 17 00:00:00 2001
Message-ID: <c417e164d2b225ea401093e33a853d827d8bd8ca.1738940191.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Tue, 28 Jan 2025 14:06:16 +0100
Subject: [PATCH] libxlDomainGetMessages: Add existing flags to 'virCheckFlags'
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The two VIR_DOMAIN_MESSAGE_* flags were not listed in the virCheckFlags
check in 'libxl' but were present in 'test' and 'qemu' driver impls.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 042ea8630b1b35ce6d325df52fefa84bad94d027)
https://issues.redhat.com/browse/RHEL-77884
---
src/libxl/libxl_driver.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index e72553603d..26d22550ae 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -6575,7 +6575,8 @@ libxlDomainGetMessages(virDomainPtr dom,
virDomainObj *vm = NULL;
int ret = -1;
- virCheckFlags(0, -1);
+ virCheckFlags(VIR_DOMAIN_MESSAGE_DEPRECATION |
+ VIR_DOMAIN_MESSAGE_TAINTING, -1);
if (!(vm = libxlDomObjFromDomain(dom)))
return -1;
--
2.48.1

View File

@ -0,0 +1,66 @@
From 62e633d298639fd7b7e9c12e6b9d095872c8e6a3 Mon Sep 17 00:00:00 2001
Message-ID: <62e633d298639fd7b7e9c12e6b9d095872c8e6a3.1738940191.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 27 Jan 2025 13:03:58 +0100
Subject: [PATCH] qemu: Handle quirks of 'device' field of BLOCK_IO_ERROR event
in monitor code
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
BLOCK_IO_ERROR's 'device' field is an empty string in case when it isn't
applicable as it was originally mandatory in the qemu API docs.
Move the logic that convert's empty string back to NULL from
'qemuProcessHandleIOError()' to 'qemuMonitorJSONHandleIOError()'
This also fixes a hypothetical NULL-dereference if qemu would indeed
report an IO error without the 'device' field present.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 2f8359f827ce92e0b454eca55640a928367131fd)
https://issues.redhat.com/browse/RHEL-77884
---
src/qemu/qemu_monitor_json.c | 9 ++++++++-
src/qemu/qemu_process.c | 3 ---
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 1b4288b744..345e9383e3 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -708,8 +708,15 @@ qemuMonitorJSONHandleIOError(qemuMonitor *mon, virJSONValue *data)
action = "ignore";
}
- if ((device = virJSONValueObjectGetString(data, "device")) == NULL)
+ if ((device = virJSONValueObjectGetString(data, "device")) == NULL) {
VIR_WARN("missing device in disk io error event");
+ } else {
+ /* 'device' was documented as mandatory in the qemu event, but later became
+ * optional, in which case an empty string is sent by qemu. Convert it back
+ * to NULL */
+ if (*device == '\0')
+ device = NULL;
+ }
nodename = virJSONValueObjectGetString(data, "node-name");
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index c618fbf69c..b4f6d358f3 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -840,9 +840,6 @@ qemuProcessHandleIOError(qemuMonitor *mon G_GNUC_UNUSED,
virObjectLock(vm);
priv = QEMU_DOMAIN_PRIVATE(vm);
- if (*diskAlias == '\0')
- diskAlias = NULL;
-
if (diskAlias)
disk = qemuProcessFindDomainDiskByAliasOrQOM(vm, diskAlias, NULL);
else if (nodename)
--
2.48.1

View File

@ -0,0 +1,93 @@
From 88fab9d6fe37abb85c3c4b51c046b49e1601b5da Mon Sep 17 00:00:00 2001
Message-ID: <88fab9d6fe37abb85c3c4b51c046b49e1601b5da.1738940191.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 27 Jan 2025 13:42:36 +0100
Subject: [PATCH] qemu: Rename 'diskAlias' to 'device' in qemu IO error event
handling
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The field is named 'device' in the event so unify our naming.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 2d6bd6f05fc57839093850ebfc06c9b4e02b4f67)
https://issues.redhat.com/browse/RHEL-77884
---
src/qemu/qemu_monitor.c | 4 ++--
src/qemu/qemu_monitor.h | 4 ++--
src/qemu/qemu_process.c | 6 +++---
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 79bd91b539..e98da5fbff 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1127,7 +1127,7 @@ qemuMonitorEmitWatchdog(qemuMonitor *mon, int action)
void
qemuMonitorEmitIOError(qemuMonitor *mon,
- const char *diskAlias,
+ const char *device,
const char *nodename,
int action,
const char *reason)
@@ -1135,7 +1135,7 @@ qemuMonitorEmitIOError(qemuMonitor *mon,
VIR_DEBUG("mon=%p", mon);
QEMU_MONITOR_CALLBACK(mon, domainIOError, mon->vm,
- diskAlias, nodename, action, reason);
+ device, nodename, action, reason);
}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 89a59dfd27..0ab60f286d 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -206,7 +206,7 @@ typedef void (*qemuMonitorDomainWatchdogCallback)(qemuMonitor *mon,
int action);
typedef void (*qemuMonitorDomainIOErrorCallback)(qemuMonitor *mon,
virDomainObj *vm,
- const char *diskAlias,
+ const char *device,
const char *nodename,
int action,
const char *reason);
@@ -450,7 +450,7 @@ void qemuMonitorEmitResume(qemuMonitor *mon);
void qemuMonitorEmitRTCChange(qemuMonitor *mon, long long offset);
void qemuMonitorEmitWatchdog(qemuMonitor *mon, int action);
void qemuMonitorEmitIOError(qemuMonitor *mon,
- const char *diskAlias,
+ const char *device,
const char *nodename,
int action,
const char *reason);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index b4f6d358f3..3861d91228 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -824,7 +824,7 @@ qemuProcessHandleWatchdog(qemuMonitor *mon G_GNUC_UNUSED,
static void
qemuProcessHandleIOError(qemuMonitor *mon G_GNUC_UNUSED,
virDomainObj *vm,
- const char *diskAlias,
+ const char *device,
const char *nodename,
int action,
const char *reason)
@@ -840,8 +840,8 @@ qemuProcessHandleIOError(qemuMonitor *mon G_GNUC_UNUSED,
virObjectLock(vm);
priv = QEMU_DOMAIN_PRIVATE(vm);
- if (diskAlias)
- disk = qemuProcessFindDomainDiskByAliasOrQOM(vm, diskAlias, NULL);
+ if (device)
+ disk = qemuProcessFindDomainDiskByAliasOrQOM(vm, device, NULL);
else if (nodename)
disk = qemuDomainDiskLookupByNodename(vm->def, NULL, nodename, NULL);
else
--
2.48.1

View File

@ -0,0 +1,85 @@
From 763d97401abc5d656b13967b811c04688061e760 Mon Sep 17 00:00:00 2001
Message-ID: <763d97401abc5d656b13967b811c04688061e760.1738940191.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 6 Feb 2025 16:20:45 +0100
Subject: [PATCH] qemu: domain: Initialize FD passthrough for a
virStorageSource before using it
The call to 'qemuBlockStorageSourceNeedsFormatLayer()' bases the
decision also on the state of the passed FD, so we must initialize the
passthrough data via 'qemuDomainPrepareStorageSourceFDs()' before the
aforementioned call.
In the test change it's visible that we didn't add the necessary 'raw'
driver which allows the 'protocol' blockdev to be opened in 'rw' mode so
that qemu picks the proper file descriptior while keeping the device
read-only.
Resolves: https://issues.redhat.com/browse/RHEL-37519
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 5830e564bbeb798cccce2988094d1218f6dc5a60)
https://issues.redhat.com/browse/RHEL-37519
---
src/qemu/qemu_domain.c | 6 +++---
.../qemuxmlconfdata/disk-source-fd.x86_64-latest.args | 10 ++++++----
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 1fc4e2f33f..92035dd281 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -9677,6 +9677,9 @@ qemuDomainPrepareStorageSourceBlockdevNodename(virDomainDiskDef *disk,
/* qemuBlockStorageSourceSetStorageNodename steals 'nodestorage' */
qemuBlockStorageSourceSetStorageNodename(src, nodestorage);
+ if (qemuDomainPrepareStorageSourceFDs(src, priv) < 0)
+ return -1;
+
if (qemuBlockStorageSourceNeedsFormatLayer(src, priv->qemuCaps)) {
char *nodeformat = g_strdup_printf("%s-format", nodenameprefix);
@@ -9717,9 +9720,6 @@ qemuDomainPrepareStorageSourceBlockdevNodename(virDomainDiskDef *disk,
if (qemuDomainPrepareStorageSourceNFS(src) < 0)
return -1;
- if (qemuDomainPrepareStorageSourceFDs(src, priv) < 0)
- return -1;
-
return 0;
}
diff --git a/tests/qemuxmlconfdata/disk-source-fd.x86_64-latest.args b/tests/qemuxmlconfdata/disk-source-fd.x86_64-latest.args
index d77b3ca505..27d852cf32 100644
--- a/tests/qemuxmlconfdata/disk-source-fd.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/disk-source-fd.x86_64-latest.args
@@ -33,11 +33,12 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-blockdev '{"node-name":"libvirt-6-format","read-only":false,"driver":"qcow2","file":"libvirt-6-storage"}' \
-device '{"driver":"virtio-blk-pci","bus":"pci.0","addr":"0x2","drive":"libvirt-6-format","id":"virtio-disk4","bootindex":1}' \
-add-fd set=4,fd=209,opaque=libvirt-5-storage0 \
--blockdev '{"driver":"file","filename":"/dev/fdset/4","node-name":"libvirt-5-storage","read-only":true}' \
+-blockdev '{"driver":"file","filename":"/dev/fdset/4","node-name":"libvirt-5-storage","read-only":false,"discard":"unmap"}' \
+-blockdev '{"node-name":"libvirt-5-format","read-only":true,"driver":"raw","file":"libvirt-5-storage"}' \
-add-fd set=3,fd=247,opaque=libvirt-4-storage0 \
-add-fd set=3,fd=248,opaque=libvirt-4-storage1 \
-blockdev '{"driver":"file","filename":"/dev/fdset/3","node-name":"libvirt-4-storage","auto-read-only":true,"discard":"unmap"}' \
--blockdev '{"node-name":"libvirt-4-format","read-only":true,"driver":"qcow2","file":"libvirt-4-storage","backing":"libvirt-5-storage"}' \
+-blockdev '{"node-name":"libvirt-4-format","read-only":true,"driver":"qcow2","file":"libvirt-4-storage","backing":"libvirt-5-format"}' \
-add-fd set=2,fd=204,opaque=libvirt-3-storage0 \
-blockdev '{"driver":"file","filename":"/dev/fdset/2","node-name":"libvirt-3-storage","read-only":false,"discard":"unmap"}' \
-blockdev '{"node-name":"libvirt-3-format","read-only":false,"driver":"qcow2","file":"libvirt-3-storage","backing":"libvirt-4-format"}' \
@@ -46,8 +47,9 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-blockdev '{"driver":"file","filename":"/dev/fdset/1","node-name":"libvirt-2-storage","read-only":true}' \
-device '{"driver":"ide-cd","bus":"ide.0","unit":0,"drive":"libvirt-2-storage","id":"ide0-0-0"}' \
-add-fd set=0,fd=208,opaque=libvirt-1-storage0 \
--blockdev '{"driver":"file","filename":"/dev/fdset/0","node-name":"libvirt-1-storage","read-only":true}' \
--device '{"driver":"ide-cd","bus":"ide.0","unit":1,"drive":"libvirt-1-storage","id":"ide0-0-1"}' \
+-blockdev '{"driver":"file","filename":"/dev/fdset/0","node-name":"libvirt-1-storage","read-only":false,"discard":"unmap"}' \
+-blockdev '{"node-name":"libvirt-1-format","read-only":true,"driver":"raw","file":"libvirt-1-storage"}' \
+-device '{"driver":"ide-cd","bus":"ide.0","unit":1,"drive":"libvirt-1-format","id":"ide0-0-1"}' \
-audiodev '{"id":"audio1","driver":"none"}' \
-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x4"}' \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
--
2.48.1

View File

@ -0,0 +1,109 @@
From 556d3cac6b834a7f5630e31bac2f4f594392bde6 Mon Sep 17 00:00:00 2001
Message-ID: <556d3cac6b834a7f5630e31bac2f4f594392bde6.1738940191.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 3 Feb 2025 17:48:05 +0100
Subject: [PATCH] qemu: process: Export qemuPrepareNVRAM for use in snapshot
code
Export qemuPrepareNVRAM so that it doesn't require the VM object. The
snapshot code needs in the corner case of creating a snapshot of a
freshly defined VM ensure that the nvram image exists in order to
snapshot it.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
(cherry picked from commit a377404ed912e8d17e88ef3eb8e71143eff88f7d)
https://issues.redhat.com/browse/RHEL-73315
---
src/qemu/qemu_process.c | 26 ++++++++++++++------------
src/qemu/qemu_process.h | 4 ++++
2 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index b9d69649ca..1866c8f4e1 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4627,10 +4627,9 @@ qemuPrepareNVRAMHelper(int dstFD,
static int
-qemuPrepareNVRAMBlock(virDomainObj *vm,
+qemuPrepareNVRAMBlock(virDomainLoaderDef *loader,
bool reset_nvram)
{
- virDomainLoaderDef *loader = vm->def->os.loader;
g_autoptr(virCommand) qemuimg = NULL;
const char *templateFormatStr = "raw";
@@ -4691,13 +4690,12 @@ qemuPrepareNVRAMBlock(virDomainObj *vm,
static int
-qemuPrepareNVRAMFile(virDomainObj *vm,
+qemuPrepareNVRAMFile(virQEMUDriver *driver,
+ virDomainLoaderDef *loader,
bool reset_nvram)
{
- qemuDomainObjPrivate *priv = vm->privateData;
- g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(priv->driver);
+ g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
VIR_AUTOCLOSE srcFD = -1;
- virDomainLoaderDef *loader = vm->def->os.loader;
struct qemuPrepareNVRAMHelperData data;
if (virFileExists(loader->nvram->path) && !reset_nvram)
@@ -4739,21 +4737,24 @@ qemuPrepareNVRAMFile(virDomainObj *vm,
}
-static int
-qemuPrepareNVRAM(virDomainObj *vm,
+int
+qemuPrepareNVRAM(virQEMUDriver *driver,
+ virDomainDef *def,
bool reset_nvram)
{
- virDomainLoaderDef *loader = vm->def->os.loader;
+ virDomainLoaderDef *loader = def->os.loader;
if (!loader || !loader->nvram)
return 0;
+ VIR_DEBUG("nvram='%s'", NULLSTR(loader->nvram->path));
+
switch (virStorageSourceGetActualType(loader->nvram)) {
case VIR_STORAGE_TYPE_FILE:
- return qemuPrepareNVRAMFile(vm, reset_nvram);
+ return qemuPrepareNVRAMFile(driver, loader, reset_nvram);
case VIR_STORAGE_TYPE_BLOCK:
- return qemuPrepareNVRAMBlock(vm, reset_nvram);
+ return qemuPrepareNVRAMBlock(loader, reset_nvram);
case VIR_STORAGE_TYPE_DIR:
case VIR_STORAGE_TYPE_NETWORK:
@@ -7408,7 +7409,8 @@ qemuProcessPrepareHost(virQEMUDriver *driver,
qemuProcessMakeDir(driver, vm, priv->channelTargetDir) < 0)
return -1;
- if (qemuPrepareNVRAM(vm, !!(flags & VIR_QEMU_PROCESS_START_RESET_NVRAM)) < 0)
+ if (qemuPrepareNVRAM(driver, vm->def,
+ !!(flags & VIR_QEMU_PROCESS_START_RESET_NVRAM)) < 0)
return -1;
if (vm->def->vsock) {
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 12781673c5..fee00ce53b 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -258,3 +258,7 @@ int qemuProcessSetupEmulator(virDomainObj *vm);
void qemuProcessHandleNbdkitExit(qemuNbdkitProcess *nbdkit,
virDomainObj *vm);
+
+int qemuPrepareNVRAM(virQEMUDriver *driver,
+ virDomainDef *def,
+ bool reset_nvram);
--
2.48.1

View File

@ -0,0 +1,94 @@
From 45fe2375b04f05ff9f9cb0f84dd3c5408718353f Mon Sep 17 00:00:00 2001
Message-ID: <45fe2375b04f05ff9f9cb0f84dd3c5408718353f.1738940191.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 3 Feb 2025 17:52:50 +0100
Subject: [PATCH] qemu: snapshot: Ensure that NVRAM image exists when taking
inactive internal snapshot
Attempting to take an internal snapshot of a freshly defined VM with
qcow2 backed NVRAM results in failure as the NVRAM image doesn't get
populated until the VM is started for the first time.
Fix this by invoking qemuPrepareNVRAM() when qcow2 nvram is defined.
Resolves: https://issues.redhat.com/browse/RHEL-73315
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
(cherry picked from commit 650e6fb7ebf905fe7dc992610ef9e932328460b7)
https://issues.redhat.com/browse/RHEL-73315
---
src/qemu/qemu_snapshot.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
index 7c998afe6f..b1f4ebb995 100644
--- a/src/qemu/qemu_snapshot.c
+++ b/src/qemu/qemu_snapshot.c
@@ -269,6 +269,7 @@ qemuSnapshotForEachQcow2One(virStorageSource *src,
/**
* qemuSnapshotForEachQcow2:
*
+ * @driver: qemu driver configuration
* @def: domain definition
* @snap: snapshot object
* @op: 'qemu-img snapshot' operation flag, one of "-c", "-d", "-a"
@@ -282,7 +283,8 @@ qemuSnapshotForEachQcow2One(virStorageSource *src,
* permissive modes.
*/
static int
-qemuSnapshotForEachQcow2(virDomainDef *def,
+qemuSnapshotForEachQcow2(virQEMUDriver *driver,
+ virDomainDef *def,
virDomainMomentObj *snap,
const char *op)
{
@@ -352,6 +354,16 @@ qemuSnapshotForEachQcow2(virDomainDef *def,
if (virStorageSourceIsLocalStorage(nvram) &&
nvram->format == VIR_STORAGE_FILE_QCOW2) {
+ if (create) {
+ /* Ensure that the NVRAM image exists; e.g. when snapshotting
+ * a VM directly after defining it */
+ if (qemuPrepareNVRAM(driver, def, false) < 0) {
+ nrollback = def->ndisks;
+ virErrorPreserveLast(&orig_err);
+ goto rollback;
+ }
+ }
+
if (qemuSnapshotForEachQcow2One(nvram, op, snap->def->name) < 0) {
if (create) {
nrollback = def->ndisks;
@@ -392,7 +404,8 @@ static int
qemuSnapshotCreateInactiveInternal(virDomainObj *vm,
virDomainMomentObj *snap)
{
- return qemuSnapshotForEachQcow2(vm->def, snap, "-c");
+ return qemuSnapshotForEachQcow2(QEMU_DOMAIN_PRIVATE(vm)->driver,
+ vm->def, snap, "-c");
}
@@ -2696,7 +2709,8 @@ qemuSnapshotInternalRevertInactive(virDomainObj *vm,
}
/* Try all disks, but report failure if we skipped any. */
- if (qemuSnapshotForEachQcow2(def, snap, "-a") != 0)
+ if (qemuSnapshotForEachQcow2(QEMU_DOMAIN_PRIVATE(vm)->driver,
+ def, snap, "-a") != 0)
return -1;
return 0;
@@ -4064,7 +4078,8 @@ qemuSnapshotDiscardImpl(virDomainObj *vm,
if (qemuSnapshotDiscardExternal(vm, snap, externalData) < 0)
return -1;
} else {
- if (qemuSnapshotForEachQcow2(def, snap, "-d") < 0)
+ if (qemuSnapshotForEachQcow2(QEMU_DOMAIN_PRIVATE(vm)->driver,
+ def, snap, "-d") < 0)
return -1;
}
} else {
--
2.48.1

View File

@ -0,0 +1,139 @@
From 321a694cb6e4c401f9b2ea130ebae046a3f0c88b Mon Sep 17 00:00:00 2001
Message-ID: <321a694cb6e4c401f9b2ea130ebae046a3f0c88b.1738940191.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 27 Jan 2025 13:53:36 +0100
Subject: [PATCH] qemuMonitorJSONHandleIOError: Do not munge 'reason' field of
IO error event
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Leave the interpretation of the event to 'qemuProcessHandleIOError()'
which will create it's own variant of the messages for the user-facing
libvirt events. qemuMonitorJSONHandleIOError() will pass through the raw
data it got from qemu.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit f8f8d5a253633aaae93b04d92bdcbed5b954149f)
https://issues.redhat.com/browse/RHEL-77884
---
src/qemu/qemu_monitor.c | 3 ++-
src/qemu/qemu_monitor.h | 2 ++
src/qemu/qemu_monitor_json.c | 12 ++++++------
src/qemu/qemu_process.c | 9 +++++++--
4 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index e98da5fbff..e0161b8e23 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1130,12 +1130,13 @@ qemuMonitorEmitIOError(qemuMonitor *mon,
const char *device,
const char *nodename,
int action,
+ bool nospace,
const char *reason)
{
VIR_DEBUG("mon=%p", mon);
QEMU_MONITOR_CALLBACK(mon, domainIOError, mon->vm,
- device, nodename, action, reason);
+ device, nodename, action, nospace, reason);
}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 0ab60f286d..0655802dcc 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -209,6 +209,7 @@ typedef void (*qemuMonitorDomainIOErrorCallback)(qemuMonitor *mon,
const char *device,
const char *nodename,
int action,
+ bool nospace,
const char *reason);
typedef void (*qemuMonitorDomainGraphicsCallback)(qemuMonitor *mon,
virDomainObj *vm,
@@ -453,6 +454,7 @@ void qemuMonitorEmitIOError(qemuMonitor *mon,
const char *device,
const char *nodename,
int action,
+ bool nospace,
const char *reason);
void qemuMonitorEmitGraphics(qemuMonitor *mon,
int phase,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 345e9383e3..7d202133f7 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -695,8 +695,8 @@ qemuMonitorJSONHandleIOError(qemuMonitor *mon, virJSONValue *data)
const char *device;
const char *nodename;
const char *action;
- const char *reason = "";
- bool nospc = false;
+ const char *reason;
+ bool nospace = false;
int actionID;
/* Throughout here we try our best to carry on upon errors,
@@ -719,16 +719,16 @@ qemuMonitorJSONHandleIOError(qemuMonitor *mon, virJSONValue *data)
}
nodename = virJSONValueObjectGetString(data, "node-name");
-
- if (virJSONValueObjectGetBoolean(data, "nospace", &nospc) == 0 && nospc)
- reason = "enospc";
+ reason = virJSONValueObjectGetString(data, "reason");
+ /* 'nospace' flag is relevant only when true */
+ ignore_value(virJSONValueObjectGetBoolean(data, "nospace", &nospace));
if ((actionID = qemuMonitorIOErrorActionTypeFromString(action)) < 0) {
VIR_WARN("unknown disk io error action '%s'", action);
actionID = VIR_DOMAIN_EVENT_IO_ERROR_NONE;
}
- qemuMonitorEmitIOError(mon, device, nodename, actionID, reason);
+ qemuMonitorEmitIOError(mon, device, nodename, actionID, nospace, reason);
}
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 4083188af4..9ae39c0379 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -827,7 +827,8 @@ qemuProcessHandleIOError(qemuMonitor *mon G_GNUC_UNUSED,
const char *device,
const char *nodename,
int action,
- const char *reason)
+ bool nospace,
+ const char *reason G_GNUC_UNUSED)
{
qemuDomainObjPrivate *priv;
virObjectEvent *ioErrorEvent = NULL;
@@ -835,6 +836,7 @@ qemuProcessHandleIOError(qemuMonitor *mon G_GNUC_UNUSED,
virObjectEvent *lifecycleEvent = NULL;
const char *eventPath = "";
const char *eventAlias = "";
+ const char *eventReason = "";
virDomainDiskDef *disk;
virObjectLock(vm);
@@ -852,8 +854,11 @@ qemuProcessHandleIOError(qemuMonitor *mon G_GNUC_UNUSED,
eventAlias = disk->info.alias;
}
+ if (nospace)
+ eventReason = "enospc";
+
ioErrorEvent = virDomainEventIOErrorNewFromObj(vm, eventPath, eventAlias, action);
- ioErrorEvent2 = virDomainEventIOErrorReasonNewFromObj(vm, eventPath, eventAlias, action, reason);
+ ioErrorEvent2 = virDomainEventIOErrorReasonNewFromObj(vm, eventPath, eventAlias, action, eventReason);
if (action == VIR_DOMAIN_EVENT_IO_ERROR_PAUSE &&
virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
--
2.48.1

View File

@ -0,0 +1,118 @@
From c987c88930aa84b0b96d06bbd84287a7e62cc812 Mon Sep 17 00:00:00 2001
Message-ID: <c987c88930aa84b0b96d06bbd84287a7e62cc812.1738940191.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Tue, 28 Jan 2025 10:39:52 +0100
Subject: [PATCH] qemuMonitorJSONHandleIOError: Propagate new 'qom-path' field
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
QEMU commit v9.1.0-1065-ge67b7aef7c added 'qom-path' as an optional
field for the BLOCK_IO_ERROR event. Extract and propagate it as an
alternative to lookup via 'node-name' and 'device' (alias).
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 0525323175253b1fe1a161181e58bd348d9c605b)
https://issues.redhat.com/browse/RHEL-77884
---
src/qemu/qemu_monitor.c | 3 ++-
src/qemu/qemu_monitor.h | 2 ++
src/qemu/qemu_monitor_json.c | 4 +++-
src/qemu/qemu_process.c | 3 ++-
4 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index e0161b8e23..79ff4e2e87 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1128,6 +1128,7 @@ qemuMonitorEmitWatchdog(qemuMonitor *mon, int action)
void
qemuMonitorEmitIOError(qemuMonitor *mon,
const char *device,
+ const char *qompath,
const char *nodename,
int action,
bool nospace,
@@ -1136,7 +1137,7 @@ qemuMonitorEmitIOError(qemuMonitor *mon,
VIR_DEBUG("mon=%p", mon);
QEMU_MONITOR_CALLBACK(mon, domainIOError, mon->vm,
- device, nodename, action, nospace, reason);
+ device, qompath, nodename, action, nospace, reason);
}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 0655802dcc..a4818a6aa1 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -207,6 +207,7 @@ typedef void (*qemuMonitorDomainWatchdogCallback)(qemuMonitor *mon,
typedef void (*qemuMonitorDomainIOErrorCallback)(qemuMonitor *mon,
virDomainObj *vm,
const char *device,
+ const char *qompath,
const char *nodename,
int action,
bool nospace,
@@ -452,6 +453,7 @@ void qemuMonitorEmitRTCChange(qemuMonitor *mon, long long offset);
void qemuMonitorEmitWatchdog(qemuMonitor *mon, int action);
void qemuMonitorEmitIOError(qemuMonitor *mon,
const char *device,
+ const char *qompath,
const char *nodename,
int action,
bool nospace,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 7d202133f7..53648dea8b 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -693,6 +693,7 @@ static void
qemuMonitorJSONHandleIOError(qemuMonitor *mon, virJSONValue *data)
{
const char *device;
+ const char *qompath;
const char *nodename;
const char *action;
const char *reason;
@@ -718,6 +719,7 @@ qemuMonitorJSONHandleIOError(qemuMonitor *mon, virJSONValue *data)
device = NULL;
}
+ qompath = virJSONValueObjectGetString(data, "qom-path");
nodename = virJSONValueObjectGetString(data, "node-name");
reason = virJSONValueObjectGetString(data, "reason");
/* 'nospace' flag is relevant only when true */
@@ -728,7 +730,7 @@ qemuMonitorJSONHandleIOError(qemuMonitor *mon, virJSONValue *data)
actionID = VIR_DOMAIN_EVENT_IO_ERROR_NONE;
}
- qemuMonitorEmitIOError(mon, device, nodename, actionID, nospace, reason);
+ qemuMonitorEmitIOError(mon, device, qompath, nodename, actionID, nospace, reason);
}
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index b0a20328d4..c95b1ecd82 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -825,6 +825,7 @@ static void
qemuProcessHandleIOError(qemuMonitor *mon G_GNUC_UNUSED,
virDomainObj *vm,
const char *device,
+ const char *qompath,
const char *nodename,
int action,
bool nospace,
@@ -847,7 +848,7 @@ qemuProcessHandleIOError(qemuMonitor *mon G_GNUC_UNUSED,
disk = qemuDomainDiskLookupByNodename(vm->def, priv->backup, nodename, &src);
if (!disk)
- disk = qemuProcessFindDomainDiskByAliasOrQOM(vm, device, NULL);
+ disk = qemuProcessFindDomainDiskByAliasOrQOM(vm, device, qompath);
if (!src && disk)
src = disk->src;
--
2.48.1

View File

@ -0,0 +1,48 @@
From 0ad096e3448a2b6e366995220f4266af34dd9010 Mon Sep 17 00:00:00 2001
Message-ID: <0ad096e3448a2b6e366995220f4266af34dd9010.1738940191.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 24 Jan 2025 17:01:34 +0100
Subject: [PATCH] qemuProcessHandleIOError: Log IO errors in the VM log file
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add a log entry to the VM log file for every time we receive an IO error
event from qemu. The log entry is as follows:
2025-01-24 16:03:28.928+0000: IO error device='virtio-disk0' node-name='libvirt-1-storage' reason='other: Input/output error'
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 18f8d572be4caaa0c55a8d68a4048ef2360a03c5)
https://issues.redhat.com/browse/RHEL-77884
---
src/qemu/qemu_process.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 6b8a2af4ed..409734d948 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -829,7 +829,7 @@ qemuProcessHandleIOError(qemuMonitor *mon G_GNUC_UNUSED,
const char *nodename,
int action,
bool nospace,
- const char *reason G_GNUC_UNUSED)
+ const char *reason)
{
qemuDomainObjPrivate *priv;
virObjectEvent *ioErrorEvent = NULL;
@@ -867,6 +867,9 @@ qemuProcessHandleIOError(qemuMonitor *mon G_GNUC_UNUSED,
ioErrorEvent2 = virDomainEventIOErrorReasonNewFromObj(vm, eventPath, eventAlias, action, eventReason);
if ((timestamp = virTimeStringNow()) != NULL) {
+ qemuDomainLogAppendMessage(priv->driver, vm, "%s: IO error device='%s' node-name='%s' reason='%s'\n",
+ timestamp, NULLSTR(eventAlias), NULLSTR(nodename), NULLSTR(reason));
+
if (src) {
g_free(src->ioerror_timestamp);
g_free(src->ioerror_message);
--
2.48.1

View File

@ -0,0 +1,55 @@
From d67189b0a37a76b60bab7d9e1f527bf4d984be16 Mon Sep 17 00:00:00 2001
Message-ID: <d67189b0a37a76b60bab7d9e1f527bf4d984be16.1738940191.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 27 Jan 2025 19:17:16 +0100
Subject: [PATCH] qemuProcessHandleIOError: Populate I/O error reason to
virStorageSource
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Record the last I/O error reason and timestamp which happened with the
corresponding virStorageSource struct.
This will later allow querying the last error e.g. via the
virDomainGetMessages() API.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 300f7e9bd4ee4e043cac1a84059fe4a60b101cf1)
https://issues.redhat.com/browse/RHEL-77884
---
src/qemu/qemu_process.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index c95b1ecd82..6b8a2af4ed 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -840,6 +840,7 @@ qemuProcessHandleIOError(qemuMonitor *mon G_GNUC_UNUSED,
const char *eventReason = "";
virDomainDiskDef *disk = NULL;
virStorageSource *src = NULL;
+ g_autofree char *timestamp = NULL;
virObjectLock(vm);
priv = QEMU_DOMAIN_PRIVATE(vm);
@@ -865,6 +866,15 @@ qemuProcessHandleIOError(qemuMonitor *mon G_GNUC_UNUSED,
ioErrorEvent = virDomainEventIOErrorNewFromObj(vm, eventPath, eventAlias, action);
ioErrorEvent2 = virDomainEventIOErrorReasonNewFromObj(vm, eventPath, eventAlias, action, eventReason);
+ if ((timestamp = virTimeStringNow()) != NULL) {
+ if (src) {
+ g_free(src->ioerror_timestamp);
+ g_free(src->ioerror_message);
+ src->ioerror_timestamp = g_steal_pointer(&timestamp);
+ src->ioerror_message = g_strdup(reason);
+ }
+ }
+
if (action == VIR_DOMAIN_EVENT_IO_ERROR_PAUSE &&
virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
VIR_WARN("Transitioned guest %s to paused state due to IO error", vm->def->name);
--
2.48.1

View File

@ -0,0 +1,64 @@
From 56a472de55c45c97fd5f201073327c2d7c6d43c3 Mon Sep 17 00:00:00 2001
Message-ID: <56a472de55c45c97fd5f201073327c2d7c6d43c3.1738940191.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 24 Jan 2025 17:17:51 +0100
Subject: [PATCH] qemuProcessHandleIOError: Prefer lookup by node name
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When qemu reports a node name for an I/O error we should prefer the
lookup by node name instead as it gives us the path to the specific
image which caused the error instead of the top level image path.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 784538a470fe346cb1ab85786b8ece85cbe7ff9f)
https://issues.redhat.com/browse/RHEL-77884
---
src/qemu/qemu_process.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 9ae39c0379..b0a20328d4 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -837,22 +837,26 @@ qemuProcessHandleIOError(qemuMonitor *mon G_GNUC_UNUSED,
const char *eventPath = "";
const char *eventAlias = "";
const char *eventReason = "";
- virDomainDiskDef *disk;
+ virDomainDiskDef *disk = NULL;
+ virStorageSource *src = NULL;
virObjectLock(vm);
priv = QEMU_DOMAIN_PRIVATE(vm);
- if (device)
+ if (nodename)
+ disk = qemuDomainDiskLookupByNodename(vm->def, priv->backup, nodename, &src);
+
+ if (!disk)
disk = qemuProcessFindDomainDiskByAliasOrQOM(vm, device, NULL);
- else if (nodename)
- disk = qemuDomainDiskLookupByNodename(vm->def, NULL, nodename, NULL);
- else
- disk = NULL;
- if (disk) {
- eventPath = virDomainDiskGetSource(disk);
+ if (!src && disk)
+ src = disk->src;
+
+ if (disk)
eventAlias = disk->info.alias;
- }
+
+ if (src && src->path)
+ eventPath = src->path;
if (nospace)
eventReason = "enospc";
--
2.48.1

View File

@ -0,0 +1,76 @@
From 8ae4a9c8e3f66dd7a94cfa4f12614c7ba3e3b1c3 Mon Sep 17 00:00:00 2001
Message-ID: <8ae4a9c8e3f66dd7a94cfa4f12614c7ba3e3b1c3.1738940190.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 24 Jan 2025 17:16:35 +0100
Subject: [PATCH] qemuProcessHandleIOError: Refactor to extract 'priv' instead
of 'driver'
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The VM private data will be used in a sub-sequent patch. To minimize
churn, refactor the function before changing the logic.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 72142dcde34dd7e1dfb3ea0d841f567badd80539)
https://issues.redhat.com/browse/RHEL-77884
---
src/qemu/qemu_process.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 7297263d33..c618fbf69c 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -829,7 +829,7 @@ qemuProcessHandleIOError(qemuMonitor *mon G_GNUC_UNUSED,
int action,
const char *reason)
{
- virQEMUDriver *driver;
+ qemuDomainObjPrivate *priv;
virObjectEvent *ioErrorEvent = NULL;
virObjectEvent *ioErrorEvent2 = NULL;
virObjectEvent *lifecycleEvent = NULL;
@@ -838,7 +838,7 @@ qemuProcessHandleIOError(qemuMonitor *mon G_GNUC_UNUSED,
virDomainDiskDef *disk;
virObjectLock(vm);
- driver = QEMU_DOMAIN_PRIVATE(vm)->driver;
+ priv = QEMU_DOMAIN_PRIVATE(vm);
if (*diskAlias == '\0')
diskAlias = NULL;
@@ -863,7 +863,6 @@ qemuProcessHandleIOError(qemuMonitor *mon G_GNUC_UNUSED,
if (action == VIR_DOMAIN_EVENT_IO_ERROR_PAUSE &&
virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
- qemuDomainObjPrivate *priv = vm->privateData;
VIR_WARN("Transitioned guest %s to paused state due to IO error", vm->def->name);
if (priv->signalIOError)
@@ -875,7 +874,7 @@ qemuProcessHandleIOError(qemuMonitor *mon G_GNUC_UNUSED,
VIR_DOMAIN_EVENT_SUSPENDED_IOERROR);
VIR_FREE(priv->lockState);
- if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0)
+ if (virDomainLockProcessPause(priv->driver->lockManager, vm, &priv->lockState) < 0)
VIR_WARN("Unable to release lease on %s", vm->def->name);
VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState));
@@ -883,9 +882,9 @@ qemuProcessHandleIOError(qemuMonitor *mon G_GNUC_UNUSED,
}
virObjectUnlock(vm);
- virObjectEventStateQueue(driver->domainEventState, ioErrorEvent);
- virObjectEventStateQueue(driver->domainEventState, ioErrorEvent2);
- virObjectEventStateQueue(driver->domainEventState, lifecycleEvent);
+ virObjectEventStateQueue(priv->driver->domainEventState, ioErrorEvent);
+ virObjectEventStateQueue(priv->driver->domainEventState, ioErrorEvent2);
+ virObjectEventStateQueue(priv->driver->domainEventState, lifecycleEvent);
}
--
2.48.1

View File

@ -0,0 +1,59 @@
From 8a4acd4ce68b416a9de21b3ad7ca976cfc3b01ee Mon Sep 17 00:00:00 2001
Message-ID: <8a4acd4ce68b416a9de21b3ad7ca976cfc3b01ee.1738940191.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 27 Jan 2025 13:07:24 +0100
Subject: [PATCH] qemuProcessHandleIOError: Rename local variables
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Prefix the helper variables used to supply data to the event by
'event'. Declare them with the default value of an empty string rather
than doing it later.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 590a5765c190230ab3df87e7eda42f621766347b)
https://issues.redhat.com/browse/RHEL-77884
---
src/qemu/qemu_process.c | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 3861d91228..4083188af4 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -833,8 +833,8 @@ qemuProcessHandleIOError(qemuMonitor *mon G_GNUC_UNUSED,
virObjectEvent *ioErrorEvent = NULL;
virObjectEvent *ioErrorEvent2 = NULL;
virObjectEvent *lifecycleEvent = NULL;
- const char *srcPath;
- const char *devAlias;
+ const char *eventPath = "";
+ const char *eventAlias = "";
virDomainDiskDef *disk;
virObjectLock(vm);
@@ -848,15 +848,12 @@ qemuProcessHandleIOError(qemuMonitor *mon G_GNUC_UNUSED,
disk = NULL;
if (disk) {
- srcPath = virDomainDiskGetSource(disk);
- devAlias = disk->info.alias;
- } else {
- srcPath = "";
- devAlias = "";
+ eventPath = virDomainDiskGetSource(disk);
+ eventAlias = disk->info.alias;
}
- ioErrorEvent = virDomainEventIOErrorNewFromObj(vm, srcPath, devAlias, action);
- ioErrorEvent2 = virDomainEventIOErrorReasonNewFromObj(vm, srcPath, devAlias, action, reason);
+ ioErrorEvent = virDomainEventIOErrorNewFromObj(vm, eventPath, eventAlias, action);
+ ioErrorEvent2 = virDomainEventIOErrorReasonNewFromObj(vm, eventPath, eventAlias, action, reason);
if (action == VIR_DOMAIN_EVENT_IO_ERROR_PAUSE &&
virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
--
2.48.1

View File

@ -0,0 +1,36 @@
From b6efc51ef60d5aa4ee94a85ad7211ab51034407e Mon Sep 17 00:00:00 2001
Message-ID: <b6efc51ef60d5aa4ee94a85ad7211ab51034407e.1738940191.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 3 Feb 2025 18:23:29 +0100
Subject: [PATCH] qemuSnapshotForEachQcow2: Don't initialize 'nrollback'
The variable holds the amount of disks to roll back the snapshot for.
The value must be set before the code jumps to the 'rollback:' label so
the best situation is to not initialize it and let the compiler catch
errors rather than initialize the unsigned variable to -1 and let it
crash.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
(cherry picked from commit d15eff63041ace067fa0ea9687c482a0f1dd140f)
https://issues.redhat.com/browse/RHEL-73315
---
src/qemu/qemu_snapshot.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
index 80cd54bf33..7c998afe6f 100644
--- a/src/qemu/qemu_snapshot.c
+++ b/src/qemu/qemu_snapshot.c
@@ -290,7 +290,7 @@ qemuSnapshotForEachQcow2(virDomainDef *def,
size_t i;
bool skipped = false;
bool create = STREQ(op, "-c");
- size_t nrollback = -1;
+ size_t nrollback;
virErrorPtr orig_err;
/* pre-checks */
--
2.48.1

View File

@ -0,0 +1,164 @@
From 12e160e847dac7ef71a0eb09f862b544cb49f76f Mon Sep 17 00:00:00 2001
Message-ID: <12e160e847dac7ef71a0eb09f862b544cb49f76f.1738940191.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 6 Feb 2025 15:55:37 +0100
Subject: [PATCH] qemuxmlconftest: Add testing of FDs with 'writable' flag in
'disk-source-fd'
Add few examples of fd groups with the 'writable' flag set, when passing
a single FD. Notably as a top level image of a readonly disk (even when
that doesn't make much sense) and also as a base image of a chain.
Note that this documents a status quo of a bug fixed in upcoming patch.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 7a119483a361a3ab814e4e07ccac7b13b0cbfbf7)
https://issues.redhat.com/browse/RHEL-37519
---
.../disk-source-fd.x86_64-latest.args | 36 +++++++++++--------
.../disk-source-fd.x86_64-latest.xml | 21 +++++++++--
tests/qemuxmlconfdata/disk-source-fd.xml | 16 +++++++--
tests/qemuxmlconftest.c | 3 ++
4 files changed, 57 insertions(+), 19 deletions(-)
diff --git a/tests/qemuxmlconfdata/disk-source-fd.x86_64-latest.args b/tests/qemuxmlconfdata/disk-source-fd.x86_64-latest.args
index 1341b7d032..d77b3ca505 100644
--- a/tests/qemuxmlconfdata/disk-source-fd.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/disk-source-fd.x86_64-latest.args
@@ -27,21 +27,27 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-no-shutdown \
-boot strict=on \
-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \
--add-fd set=2,fd=200,opaque=libvirt-4-storage0 \
--add-fd set=2,fd=205,opaque=libvirt-4-storage1 \
--blockdev '{"driver":"file","filename":"/dev/fdset/2","node-name":"libvirt-4-storage","auto-read-only":true,"discard":"unmap"}' \
--blockdev '{"node-name":"libvirt-4-format","read-only":false,"driver":"qcow2","file":"libvirt-4-storage"}' \
--device '{"driver":"virtio-blk-pci","bus":"pci.0","addr":"0x2","drive":"libvirt-4-format","id":"virtio-disk4","bootindex":1}' \
--blockdev '{"driver":"file","filename":"/var/lib/libvirt/images/rhel7.1484071876","node-name":"libvirt-3-storage","auto-read-only":true,"discard":"unmap"}' \
--blockdev '{"node-name":"libvirt-3-format","read-only":true,"driver":"qcow2","file":"libvirt-3-storage","backing":null}' \
--add-fd set=1,fd=247,opaque=libvirt-2-storage0 \
--add-fd set=1,fd=248,opaque=libvirt-2-storage1 \
--blockdev '{"driver":"file","filename":"/dev/fdset/1","node-name":"libvirt-2-storage","auto-read-only":true,"discard":"unmap"}' \
--blockdev '{"node-name":"libvirt-2-format","read-only":true,"driver":"qcow2","file":"libvirt-2-storage","backing":"libvirt-3-format"}' \
--add-fd set=0,fd=204,opaque=libvirt-1-storage0 \
--blockdev '{"driver":"file","filename":"/dev/fdset/0","node-name":"libvirt-1-storage","read-only":false,"discard":"unmap"}' \
--blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"qcow2","file":"libvirt-1-storage","backing":"libvirt-2-format"}' \
--device '{"driver":"virtio-blk-pci","bus":"pci.0","addr":"0x3","drive":"libvirt-1-format","id":"virtio-disk5"}' \
+-add-fd set=5,fd=200,opaque=libvirt-6-storage0 \
+-add-fd set=5,fd=205,opaque=libvirt-6-storage1 \
+-blockdev '{"driver":"file","filename":"/dev/fdset/5","node-name":"libvirt-6-storage","auto-read-only":true,"discard":"unmap"}' \
+-blockdev '{"node-name":"libvirt-6-format","read-only":false,"driver":"qcow2","file":"libvirt-6-storage"}' \
+-device '{"driver":"virtio-blk-pci","bus":"pci.0","addr":"0x2","drive":"libvirt-6-format","id":"virtio-disk4","bootindex":1}' \
+-add-fd set=4,fd=209,opaque=libvirt-5-storage0 \
+-blockdev '{"driver":"file","filename":"/dev/fdset/4","node-name":"libvirt-5-storage","read-only":true}' \
+-add-fd set=3,fd=247,opaque=libvirt-4-storage0 \
+-add-fd set=3,fd=248,opaque=libvirt-4-storage1 \
+-blockdev '{"driver":"file","filename":"/dev/fdset/3","node-name":"libvirt-4-storage","auto-read-only":true,"discard":"unmap"}' \
+-blockdev '{"node-name":"libvirt-4-format","read-only":true,"driver":"qcow2","file":"libvirt-4-storage","backing":"libvirt-5-storage"}' \
+-add-fd set=2,fd=204,opaque=libvirt-3-storage0 \
+-blockdev '{"driver":"file","filename":"/dev/fdset/2","node-name":"libvirt-3-storage","read-only":false,"discard":"unmap"}' \
+-blockdev '{"node-name":"libvirt-3-format","read-only":false,"driver":"qcow2","file":"libvirt-3-storage","backing":"libvirt-4-format"}' \
+-device '{"driver":"virtio-blk-pci","bus":"pci.0","addr":"0x3","drive":"libvirt-3-format","id":"virtio-disk5"}' \
+-add-fd set=1,fd=207,opaque=libvirt-2-storage0 \
+-blockdev '{"driver":"file","filename":"/dev/fdset/1","node-name":"libvirt-2-storage","read-only":true}' \
+-device '{"driver":"ide-cd","bus":"ide.0","unit":0,"drive":"libvirt-2-storage","id":"ide0-0-0"}' \
+-add-fd set=0,fd=208,opaque=libvirt-1-storage0 \
+-blockdev '{"driver":"file","filename":"/dev/fdset/0","node-name":"libvirt-1-storage","read-only":true}' \
+-device '{"driver":"ide-cd","bus":"ide.0","unit":1,"drive":"libvirt-1-storage","id":"ide0-0-1"}' \
-audiodev '{"id":"audio1","driver":"none"}' \
-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x4"}' \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
diff --git a/tests/qemuxmlconfdata/disk-source-fd.x86_64-latest.xml b/tests/qemuxmlconfdata/disk-source-fd.x86_64-latest.xml
index 9ab5e9443f..d9917c7d53 100644
--- a/tests/qemuxmlconfdata/disk-source-fd.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/disk-source-fd.x86_64-latest.xml
@@ -30,18 +30,35 @@
<format type='qcow2'/>
<source file='/var/lib/libvirt/images/rhel7.1484071877' fdgroup='testgroup6'/>
<backingStore type='file'>
- <format type='qcow2'/>
- <source file='/var/lib/libvirt/images/rhel7.1484071876'/>
+ <format type='raw'/>
+ <source file='/var/lib/libvirt/images/rhel7.1484071876' fdgroup='raw-rw-base'/>
<backingStore/>
</backingStore>
</backingStore>
<target dev='vdf' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</disk>
+ <disk type='file' device='cdrom'>
+ <driver name='qemu' type='raw'/>
+ <source file='/path/to/cdimage-ro' fdgroup='cdimage-ro'/>
+ <target dev='hda' bus='ide'/>
+ <readonly/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <disk type='file' device='cdrom'>
+ <driver name='qemu' type='raw'/>
+ <source file='/path/to/cdimage-rw' fdgroup='cdimage-rw'/>
+ <target dev='hdb' bus='ide'/>
+ <readonly/>
+ <address type='drive' controller='0' bus='0' target='0' unit='1'/>
+ </disk>
<controller type='usb' index='0' model='piix3-uhci'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
</controller>
<controller type='pci' index='0' model='pci-root'/>
+ <controller type='ide' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+ </controller>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<audio id='1' type='none'/>
diff --git a/tests/qemuxmlconfdata/disk-source-fd.xml b/tests/qemuxmlconfdata/disk-source-fd.xml
index d8c47fa364..93a3fcfbf7 100644
--- a/tests/qemuxmlconfdata/disk-source-fd.xml
+++ b/tests/qemuxmlconfdata/disk-source-fd.xml
@@ -19,6 +19,18 @@
<source file='/path/to/blah' fdgroup='testgroup2'/>
<target dev='vde' bus='virtio'/>
</disk>
+ <disk type='file' device='cdrom'>
+ <driver name='qemu' type='raw'/>
+ <source file='/path/to/cdimage-ro' fdgroup='cdimage-ro'/>
+ <readonly/>
+ <target dev='hda' bus='ide'/>
+ </disk>
+ <disk type='file' device='cdrom'>
+ <driver name='qemu' type='raw'/>
+ <source file='/path/to/cdimage-rw' fdgroup='cdimage-rw'/>
+ <readonly/>
+ <target dev='hdb' bus='ide'/>
+ </disk>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/var/lib/libvirt/images/rhel7.1484071880' fdgroup='testgroup5'/>
@@ -26,8 +38,8 @@
<format type='qcow2'/>
<source file='/var/lib/libvirt/images/rhel7.1484071877' fdgroup='testgroup6'/>
<backingStore type='file'>
- <format type='qcow2'/>
- <source file='/var/lib/libvirt/images/rhel7.1484071876'/>
+ <format type='raw'/>
+ <source file='/var/lib/libvirt/images/rhel7.1484071876' fdgroup='raw-rw-base'/>
<backingStore/>
</backingStore>
</backingStore>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index 7da622e9be..821d9b1048 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -1655,6 +1655,9 @@ mymain(void)
DO_TEST_CAPS_ARCH_LATEST_FULL("disk-source-fd", "x86_64",
ARG_FD_GROUP, "testgroup2", false, 2, 200, 205,
ARG_FD_GROUP, "testgroup5", false, 1, 204,
+ ARG_FD_GROUP, "cdimage-ro", false, 1, 207,
+ ARG_FD_GROUP, "cdimage-rw", true, 1, 208,
+ ARG_FD_GROUP, "raw-rw-base", true, 1, 209,
ARG_FD_GROUP, "testgroup6", false, 2, 247, 248);
DO_TEST_CAPS_LATEST("disk-slices");
--
2.48.1

View File

@ -0,0 +1,71 @@
From 81ccb43343bfd63358b610ef5a44082e2c5081f4 Mon Sep 17 00:00:00 2001
Message-ID: <81ccb43343bfd63358b610ef5a44082e2c5081f4.1738940191.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 6 Feb 2025 15:50:35 +0100
Subject: [PATCH] qemuxmlconftest: Allow testing of the 'writable' flag for
passed FDs for disks
Pass also the 'writable' state to the fake passed FDs so that we can
test it.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 500d985a130ff7910ca6cdeac42046d7301da43f)
https://issues.redhat.com/browse/RHEL-37519
---
tests/qemuxmlconftest.c | 6 +++---
tests/testutilsqemu.c | 2 ++
tests/testutilsqemu.h | 2 +-
3 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index 53a0237a42..7da622e9be 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -1653,9 +1653,9 @@ mymain(void)
DO_TEST_CAPS_LATEST("disk-backing-chains-noindex");
DO_TEST_CAPS_LATEST("disk-qcow2-datafile-store");
DO_TEST_CAPS_ARCH_LATEST_FULL("disk-source-fd", "x86_64",
- ARG_FD_GROUP, "testgroup2", 2, 200, 205,
- ARG_FD_GROUP, "testgroup5", 1, 204,
- ARG_FD_GROUP, "testgroup6", 2, 247, 248);
+ ARG_FD_GROUP, "testgroup2", false, 2, 200, 205,
+ ARG_FD_GROUP, "testgroup5", false, 1, 204,
+ ARG_FD_GROUP, "testgroup6", false, 2, 247, 248);
DO_TEST_CAPS_LATEST("disk-slices");
DO_TEST_CAPS_LATEST("disk-rotation");
diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c
index 5caccbc6b4..d395a1e61b 100644
--- a/tests/testutilsqemu.c
+++ b/tests/testutilsqemu.c
@@ -705,11 +705,13 @@ testQemuInfoSetArgs(testQemuInfo *info,
virStorageSourceFDTuple *new = virStorageSourceFDTupleNew();
const char *fdname = va_arg(argptr, char *);
VIR_AUTOCLOSE fakefd = open("/dev/zero", O_RDWR);
+ bool writable = va_arg(argptr, int);
size_t i;
new->nfds = va_arg(argptr, unsigned int);
new->fds = g_new0(int, new->nfds);
new->testfds = g_new0(int, new->nfds);
+ new->writable = writable;
for (i = 0; i < new->nfds; i++) {
new->testfds[i] = va_arg(argptr, unsigned int);
diff --git a/tests/testutilsqemu.h b/tests/testutilsqemu.h
index 74e307d653..20135b8390 100644
--- a/tests/testutilsqemu.h
+++ b/tests/testutilsqemu.h
@@ -49,7 +49,7 @@ typedef enum {
ARG_CAPS_VER,
ARG_CAPS_VARIANT,
ARG_CAPS_HOST_CPU_MODEL,
- ARG_FD_GROUP, /* name, nfds, fd[0], ... fd[n-1] */
+ ARG_FD_GROUP, /* name, writable, nfds, fd[0], ... fd[n-1] */
ARG_VDPA_FD, /* vdpadev, fd */
ARG_NBDKIT_CAPS,
ARG_END,
--
2.48.1

View File

@ -0,0 +1,210 @@
From b4154f389e688beafc9cbfae7e868fa406c8448d Mon Sep 17 00:00:00 2001
Message-ID: <b4154f389e688beafc9cbfae7e868fa406c8448d.1738940191.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 27 Jan 2025 19:13:43 +0100
Subject: [PATCH] virDomainGetMessages: Introduce VIR_DOMAIN_MESSAGE_IOERRORS
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Report any stored I/O error messages reported by the hypervisor when
reporting messages of a domain. As the I/O error may be already stale we
report also the timestamp when it was recorded.
Example message:
I/O error: disk='vda', index='1', path='/dev/mapper/errdev0', timestamp='2025-01-28 15:47:52.776+0000', message='Input/output error'
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 666219f5f166ac3cebe4854bcefddd449a98ad04)
https://issues.redhat.com/browse/RHEL-77884
---
include/libvirt/libvirt-domain.h | 3 ++
src/conf/domain_conf.c | 50 ++++++++++++++++++++++++++++++++
src/conf/domain_conf.h | 5 ++++
src/libvirt_private.syms | 1 +
src/libxl/libxl_driver.c | 3 +-
src/qemu/qemu_driver.c | 16 +++++++++-
src/test/test_driver.c | 3 +-
7 files changed, 78 insertions(+), 3 deletions(-)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index d4f1573954..92a32f1cde 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -6490,6 +6490,9 @@ int virDomainAuthorizedSSHKeysSet(virDomainPtr domain,
typedef enum {
VIR_DOMAIN_MESSAGE_DEPRECATION = (1 << 0), /* (Since: 7.1.0) */
VIR_DOMAIN_MESSAGE_TAINTING = (1 << 1), /* (Since: 7.1.0) */
+ VIR_DOMAIN_MESSAGE_IOERRORS = (1 << 2), /* Report available stored I/O
+ errors messages for disk images
+ (Since: 11.1.0) */
} virDomainMessageType;
int virDomainGetMessages(virDomainPtr domain,
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 8cd0fb83b6..d83f1ba240 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -31643,6 +31643,47 @@ virHostdevIsPCIDevice(const virDomainHostdevDef *hostdev)
}
+static void
+virDomainObjGetMessagesIOErrorsSrc(virStorageSource *src,
+ const char *diskdst,
+ GPtrArray *m)
+{
+ if (!src ||
+ !src->ioerror_message)
+ return;
+
+ g_ptr_array_add(m, g_strdup_printf(_("I/O error: disk='%1$s', index='%2$d', path='%3$s', timestamp='%4$s', message='%5$s'"),
+ NULLSTR_MINUS(diskdst),
+ src->id,
+ NULLSTR_MINUS(src->path),
+ src->ioerror_timestamp,
+ src->ioerror_message));
+}
+
+
+void
+virDomainObjGetMessagesIOErrorsChain(virStorageSource *src,
+ const char *diskdst,
+ GPtrArray *m)
+{
+ virStorageSource *n;
+
+ for (n = src; n; n = n->backingStore) {
+ virDomainObjGetMessagesIOErrorsSrc(n, diskdst, m);
+ virDomainObjGetMessagesIOErrorsSrc(n->dataFileStore, diskdst, m);
+ }
+}
+
+
+static void
+virDomainObjGetMessagesIOErrorsDisk(virDomainDiskDef *disk,
+ GPtrArray *m)
+{
+ virDomainObjGetMessagesIOErrorsChain(disk->src, disk->dst, m);
+ virDomainObjGetMessagesIOErrorsChain(disk->mirror, disk->dst, m);
+}
+
+
/**
* virDomainObjGetMessages:
* @vm: domain object
@@ -31671,6 +31712,15 @@ virDomainObjGetMessages(virDomainObj *vm,
vm->deprecations[i]));
}
}
+
+ if (!flags || (flags & VIR_DOMAIN_MESSAGE_IOERRORS)) {
+ if (vm->def->os.loader)
+ virDomainObjGetMessagesIOErrorsChain(vm->def->os.loader->nvram, NULL, m);
+
+ for (i = 0; i < vm->def->ndisks; i++)
+ virDomainObjGetMessagesIOErrorsDisk(vm->def->disks[i], m);
+ }
+
}
bool
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 7058203e67..5237046196 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -4576,6 +4576,11 @@ bool
virHostdevIsPCIDevice(const virDomainHostdevDef *hostdev)
ATTRIBUTE_NONNULL(1);
+void
+virDomainObjGetMessagesIOErrorsChain(virStorageSource *src,
+ const char *diskdst,
+ GPtrArray *m);
+
void
virDomainObjGetMessages(virDomainObj *vm,
GPtrArray *m,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 43e2dfb9cd..7d404fdbf5 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -590,6 +590,7 @@ virDomainObjEndAPI;
virDomainObjFormat;
virDomainObjGetDefs;
virDomainObjGetMessages;
+virDomainObjGetMessagesIOErrorsChain;
virDomainObjGetMetadata;
virDomainObjGetOneDef;
virDomainObjGetOneDefState;
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 545d67de52..29dcee3cfc 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -6577,7 +6577,8 @@ libxlDomainGetMessages(virDomainPtr dom,
int ret = -1;
virCheckFlags(VIR_DOMAIN_MESSAGE_DEPRECATION |
- VIR_DOMAIN_MESSAGE_TAINTING, -1);
+ VIR_DOMAIN_MESSAGE_TAINTING |
+ VIR_DOMAIN_MESSAGE_IOERRORS, -1);
if (!(vm = libxlDomObjFromDomain(dom)))
return -1;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 276a7caded..9a69574f31 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19814,9 +19814,11 @@ qemuDomainGetMessages(virDomainPtr dom,
g_autoptr(GPtrArray) m = g_ptr_array_new_with_free_func(g_free);
virDomainObj *vm = NULL;
int rv = -1;
+ qemuDomainObjPrivate *priv;
virCheckFlags(VIR_DOMAIN_MESSAGE_DEPRECATION |
- VIR_DOMAIN_MESSAGE_TAINTING, -1);
+ VIR_DOMAIN_MESSAGE_TAINTING |
+ VIR_DOMAIN_MESSAGE_IOERRORS, -1);
if (!(vm = qemuDomainObjFromDomain(dom)))
return -1;
@@ -19824,8 +19826,20 @@ qemuDomainGetMessages(virDomainPtr dom,
if (virDomainGetMessagesEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
+ priv = vm->privateData;
+
virDomainObjGetMessages(vm, m, flags);
+ if (priv->backup &&
+ (!flags || (flags & VIR_DOMAIN_MESSAGE_IOERRORS))) {
+ size_t i;
+
+ for (i = 0; i < priv->backup->ndisks; i++)
+ virDomainObjGetMessagesIOErrorsChain(priv->backup->disks[i].store,
+ priv->backup->disks[i].name,
+ m);
+ }
+
rv = m->len;
if (m->len > 0) {
g_ptr_array_add(m, NULL);
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index a10ec3bc41..6f18b2b2c8 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -9527,7 +9527,8 @@ testDomainGetMessages(virDomainPtr dom,
int rv = -1;
virCheckFlags(VIR_DOMAIN_MESSAGE_DEPRECATION |
- VIR_DOMAIN_MESSAGE_TAINTING, -1);
+ VIR_DOMAIN_MESSAGE_TAINTING |
+ VIR_DOMAIN_MESSAGE_IOERRORS, -1);
if (!(vm = testDomObjFromDomain(dom)))
return -1;
--
2.48.1

View File

@ -0,0 +1,191 @@
From d3ebbc9040b3f58dcf790a6d53f09c2eb5119bfd Mon Sep 17 00:00:00 2001
Message-ID: <d3ebbc9040b3f58dcf790a6d53f09c2eb5119bfd.1738940191.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 27 Jan 2025 17:38:51 +0100
Subject: [PATCH] virDomainObjGetMessages: Refactor using GPtrArray
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Simplify the function especially by rewriting it using GPtrArray to
construct the string list, especially for the upcoming case when the
number of added elements will not be known beforehand and when
hypervisor specific data will be added.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 1a02760cc6d79422dc4dd17b943915cd0ac15987)
https://issues.redhat.com/browse/RHEL-77884
---
src/conf/domain_conf.c | 36 +++++++-----------------------------
src/conf/domain_conf.h | 4 ++--
src/libxl/libxl_driver.c | 9 ++++++++-
src/qemu/qemu_driver.c | 9 ++++++++-
src/test/test_driver.c | 9 ++++++++-
5 files changed, 33 insertions(+), 34 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index d3f30b08dc..8cd0fb83b6 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -31646,53 +31646,31 @@ virHostdevIsPCIDevice(const virDomainHostdevDef *hostdev)
/**
* virDomainObjGetMessages:
* @vm: domain object
- * @msgs: pointer to a variable to store messages
+ * @m: GPtrArray to be filled with messages
* @flags: zero or more virDomainMessageType flags
- *
- * Returns number of messages stored in @msgs, -1 otherwise.
*/
-int
+void
virDomainObjGetMessages(virDomainObj *vm,
- char ***msgs,
+ GPtrArray *m,
unsigned int flags)
{
size_t i = 0;
- size_t n = 0;
- int nmsgs = 0;
- int rv = -1;
-
- *msgs = NULL;
if (!flags || (flags & VIR_DOMAIN_MESSAGE_TAINTING)) {
- nmsgs += __builtin_popcount(vm->taint);
- *msgs = g_renew(char *, *msgs, nmsgs+1);
-
for (i = 0; i < VIR_DOMAIN_TAINT_LAST; i++) {
if (vm->taint & (1 << i)) {
- (*msgs)[n++] = g_strdup_printf(
- _("tainted: %1$s"),
- _(virDomainTaintMessageTypeToString(i)));
+ g_ptr_array_add(m, g_strdup_printf(_("tainted: %1$s"),
+ _(virDomainTaintMessageTypeToString(i))));
}
}
}
if (!flags || (flags & VIR_DOMAIN_MESSAGE_DEPRECATION)) {
- nmsgs += vm->ndeprecations;
- *msgs = g_renew(char *, *msgs, nmsgs+1);
-
for (i = 0; i < vm->ndeprecations; i++) {
- (*msgs)[n++] = g_strdup_printf(
- _("deprecated configuration: %1$s"),
- vm->deprecations[i]);
+ g_ptr_array_add(m, g_strdup_printf(_("deprecated configuration: %1$s"),
+ vm->deprecations[i]));
}
}
-
- if (*msgs)
- (*msgs)[nmsgs] = NULL;
-
- rv = nmsgs;
-
- return rv;
}
bool
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 9f7c28343f..7058203e67 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -4576,9 +4576,9 @@ bool
virHostdevIsPCIDevice(const virDomainHostdevDef *hostdev)
ATTRIBUTE_NONNULL(1);
-int
+void
virDomainObjGetMessages(virDomainObj *vm,
- char ***msgs,
+ GPtrArray *m,
unsigned int flags);
bool
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 26d22550ae..545d67de52 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -6572,6 +6572,7 @@ libxlDomainGetMessages(virDomainPtr dom,
char ***msgs,
unsigned int flags)
{
+ g_autoptr(GPtrArray) m = g_ptr_array_new_with_free_func(g_free);
virDomainObj *vm = NULL;
int ret = -1;
@@ -6584,7 +6585,13 @@ libxlDomainGetMessages(virDomainPtr dom,
if (virDomainGetMessagesEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
- ret = virDomainObjGetMessages(vm, msgs, flags);
+ virDomainObjGetMessages(vm, m, flags);
+
+ ret = m->len;
+ if (m->len > 0) {
+ g_ptr_array_add(m, NULL);
+ *msgs = (char **) g_ptr_array_steal(m, NULL);
+ }
cleanup:
virDomainObjEndAPI(&vm);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 09f7edda7d..276a7caded 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19811,6 +19811,7 @@ qemuDomainGetMessages(virDomainPtr dom,
char ***msgs,
unsigned int flags)
{
+ g_autoptr(GPtrArray) m = g_ptr_array_new_with_free_func(g_free);
virDomainObj *vm = NULL;
int rv = -1;
@@ -19823,7 +19824,13 @@ qemuDomainGetMessages(virDomainPtr dom,
if (virDomainGetMessagesEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
- rv = virDomainObjGetMessages(vm, msgs, flags);
+ virDomainObjGetMessages(vm, m, flags);
+
+ rv = m->len;
+ if (m->len > 0) {
+ g_ptr_array_add(m, NULL);
+ *msgs = (char **) g_ptr_array_steal(m, NULL);
+ }
cleanup:
virDomainObjEndAPI(&vm);
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index f1cefb5c50..a10ec3bc41 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -9522,6 +9522,7 @@ testDomainGetMessages(virDomainPtr dom,
char ***msgs,
unsigned int flags)
{
+ g_autoptr(GPtrArray) m = g_ptr_array_new_with_free_func(g_free);
virDomainObj *vm = NULL;
int rv = -1;
@@ -9531,7 +9532,13 @@ testDomainGetMessages(virDomainPtr dom,
if (!(vm = testDomObjFromDomain(dom)))
return -1;
- rv = virDomainObjGetMessages(vm, msgs, flags);
+ virDomainObjGetMessages(vm, m, flags);
+
+ rv = m->len;
+ if (m->len > 0) {
+ g_ptr_array_add(m, NULL);
+ *msgs = (char **) g_ptr_array_steal(m, NULL);
+ }
virDomainObjEndAPI(&vm);
return rv;
--
2.48.1

View File

@ -0,0 +1,72 @@
From 1e47a795e7a06152cfd8b6d7c80692875d2e00b9 Mon Sep 17 00:00:00 2001
Message-ID: <1e47a795e7a06152cfd8b6d7c80692875d2e00b9.1738940191.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 27 Jan 2025 16:20:43 +0100
Subject: [PATCH] virStorageSource: Add fields for storing last I/O error
message
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Hypervisors may report a I/O error message (unstable; for human use)
to libvirt. In order to store it with the appropriate virStorageSource
so that it can be later queried we need to add fields to
virStorageSource to store the timestamp and message.
The message is deliberately not copied via virStorageSourceCopy.
The messages are also not serialized to the status XML as losing them on
a daemon restart as they're likely to be stale anyways.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 2f6c9fa4f6f4c0a36ffc2b24892eee78e1e4cf53)
https://issues.redhat.com/browse/RHEL-77884
---
src/conf/storage_source_conf.c | 5 +++++
src/conf/storage_source_conf.h | 6 ++++++
2 files changed, 11 insertions(+)
diff --git a/src/conf/storage_source_conf.c b/src/conf/storage_source_conf.c
index 2b658dd485..ca956a1b7c 100644
--- a/src/conf/storage_source_conf.c
+++ b/src/conf/storage_source_conf.c
@@ -917,6 +917,8 @@ virStorageSourceCopy(const virStorageSource *src,
def->nfs_uid = src->nfs_uid;
def->nfs_gid = src->nfs_gid;
+ /* 'ioerror_timestamp' and 'ioerror_message' are deliberately not copied */
+
return g_steal_pointer(&def);
}
@@ -1203,6 +1205,9 @@ virStorageSourceClear(virStorageSource *def)
g_clear_pointer(&def->fdtuple, g_object_unref);
+ VIR_FREE(def->ioerror_timestamp);
+ VIR_FREE(def->ioerror_message);
+
/* clear everything except the class header as the object APIs
* will break otherwise */
memset((char *) def + sizeof(def->parent), 0,
diff --git a/src/conf/storage_source_conf.h b/src/conf/storage_source_conf.h
index 9463722518..e6cbb93c06 100644
--- a/src/conf/storage_source_conf.h
+++ b/src/conf/storage_source_conf.h
@@ -445,6 +445,12 @@ struct _virStorageSource {
* to do this decision.
*/
bool seclabelSkipRemember;
+
+ /* Last instance of hypervisor originated I/O error message and timestamp.
+ * The error stored here is not designed to be stable. The message
+ * is also not copied via virStorageSourceCopy */
+ char *ioerror_timestamp;
+ char *ioerror_message;
};
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virStorageSource, virObjectUnref);
--
2.48.1

View File

@ -289,7 +289,7 @@
Summary: Library providing a simple virtualization API
Name: libvirt
Version: 10.10.0
Release: 5%{?dist}%{?extra_release}
Release: 6%{?dist}%{?extra_release}
License: GPL-2.0-or-later AND LGPL-2.1-only AND LGPL-2.1-or-later AND OFL-1.1
URL: https://libvirt.org/
@ -338,6 +338,28 @@ Patch38: libvirt-qemu-snapshot-delete-disk-image-only-if-parent-snapshot-is-exte
Patch39: libvirt-storage_file-de-modularize-the-local-file-backend.patch
Patch40: libvirt-qemu-re-use-existing-ActualNetDef-for-more-interface-types-during-update-device.patch
Patch41: libvirt-tools-ssh-proxy-Check-for-domain-status-before-parsing-its-CID.patch
Patch42: libvirt-build-Bump-minimum-glib2-version-to-2.66.0.patch
Patch43: libvirt-qemuProcessHandleIOError-Refactor-to-extract-priv-instead-of-driver.patch
Patch44: libvirt-qemu-Handle-quirks-of-device-field-of-BLOCK_IO_ERROR-event-in-monitor-code.patch
Patch45: libvirt-qemu-Rename-diskAlias-to-device-in-qemu-IO-error-event-handling.patch
Patch46: libvirt-qemuProcessHandleIOError-Rename-local-variables.patch
Patch47: libvirt-qemuMonitorJSONHandleIOError-Do-not-munge-reason-field-of-IO-error-event.patch
Patch48: libvirt-qemuProcessHandleIOError-Prefer-lookup-by-node-name.patch
Patch49: libvirt-qemuMonitorJSONHandleIOError-Propagate-new-qom-path-field.patch
Patch50: libvirt-virStorageSource-Add-fields-for-storing-last-I-O-error-message.patch
Patch51: libvirt-qemuProcessHandleIOError-Populate-I-O-error-reason-to-virStorageSource.patch
Patch52: libvirt-qemuProcessHandleIOError-Log-IO-errors-in-the-VM-log-file.patch
Patch53: libvirt-libxlDomainGetMessages-Add-existing-flags-to-virCheckFlags.patch
Patch54: libvirt-virDomainObjGetMessages-Refactor-using-GPtrArray.patch
Patch55: libvirt-virDomainGetMessages-Introduce-VIR_DOMAIN_MESSAGE_IOERRORS.patch
Patch56: libvirt-include-libvirt-domain-Reword-documentation-for-reason-of-VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON.patch
Patch57: libvirt-include-libvirt-domain-Add-message-reason-of-VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON.patch
Patch58: libvirt-qemuSnapshotForEachQcow2-Don-t-initialize-nrollback.patch
Patch59: libvirt-qemu-process-Export-qemuPrepareNVRAM-for-use-in-snapshot-code.patch
Patch60: libvirt-qemu-snapshot-Ensure-that-NVRAM-image-exists-when-taking-inactive-internal-snapshot.patch
Patch61: libvirt-qemuxmlconftest-Allow-testing-of-the-writable-flag-for-passed-FDs-for-disks.patch
Patch62: libvirt-qemuxmlconftest-Add-testing-of-FDs-with-writable-flag-in-disk-source-fd.patch
Patch63: libvirt-qemu-domain-Initialize-FD-passthrough-for-a-virStorageSource-before-using-it.patch
Requires: libvirt-daemon = %{version}-%{release}
@ -390,7 +412,7 @@ BuildRequires: gcc
%if %{with_libxl}
BuildRequires: xen-devel
%endif
BuildRequires: glib2-devel >= 2.58
BuildRequires: glib2-devel >= 2.66
BuildRequires: libxml2-devel
BuildRequires: readline-devel
BuildRequires: pkgconfig(bash-completion) >= 2.0
@ -2662,6 +2684,30 @@ exit 0
%endif
%changelog
* Fri Feb 7 2025 Jiri Denemark <jdenemar@redhat.com> - 10.10.0-6
- build: Bump minimum glib2 version to 2.66.0 (RHEL-77884)
- qemuProcessHandleIOError: Refactor to extract 'priv' instead of 'driver' (RHEL-77884)
- qemu: Handle quirks of 'device' field of BLOCK_IO_ERROR event in monitor code (RHEL-77884)
- qemu: Rename 'diskAlias' to 'device' in qemu IO error event handling (RHEL-77884)
- qemuProcessHandleIOError: Rename local variables (RHEL-77884)
- qemuMonitorJSONHandleIOError: Do not munge 'reason' field of IO error event (RHEL-77884)
- qemuProcessHandleIOError: Prefer lookup by node name (RHEL-77884)
- qemuMonitorJSONHandleIOError: Propagate new 'qom-path' field (RHEL-77884)
- virStorageSource: Add fields for storing last I/O error message (RHEL-77884)
- qemuProcessHandleIOError: Populate I/O error reason to virStorageSource (RHEL-77884)
- qemuProcessHandleIOError: Log IO errors in the VM log file (RHEL-77884)
- libxlDomainGetMessages: Add existing flags to 'virCheckFlags' (RHEL-77884)
- virDomainObjGetMessages: Refactor using GPtrArray (RHEL-77884)
- virDomainGetMessages: Introduce VIR_DOMAIN_MESSAGE_IOERRORS (RHEL-77884)
- include: libvirt-domain: Reword documentation for @reason of VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON (RHEL-77884)
- include: libvirt-domain: Add 'message' @reason of VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON (RHEL-77884)
- qemuSnapshotForEachQcow2: Don't initialize 'nrollback' (RHEL-73315)
- qemu: process: Export qemuPrepareNVRAM for use in snapshot code (RHEL-73315)
- qemu: snapshot: Ensure that NVRAM image exists when taking inactive internal snapshot (RHEL-73315)
- qemuxmlconftest: Allow testing of the 'writable' flag for passed FDs for disks (RHEL-37519)
- qemuxmlconftest: Add testing of FDs with 'writable' flag in 'disk-source-fd' (RHEL-37519)
- qemu: domain: Initialize FD passthrough for a virStorageSource before using it (RHEL-37519)
* Fri Jan 24 2025 Jiri Denemark <jdenemar@redhat.com> - 10.10.0-5
- qemu: allow migration of guest with mdev vGPU to VF vGPU (RHEL-68064)
- storage_file: Refuse qcow2 images with empty string as 'data_file' (RHEL-73504)