]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
virDomainGetMessages: Introduce VIR_DOMAIN_MESSAGE_IOERRORS
authorPeter Krempa <pkrempa@redhat.com>
Mon, 27 Jan 2025 18:13:43 +0000 (19:13 +0100)
committerPeter Krempa <pkrempa@redhat.com>
Tue, 4 Feb 2025 13:40:55 +0000 (14:40 +0100)
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>
include/libvirt/libvirt-domain.h
src/conf/domain_conf.c
src/conf/domain_conf.h
src/libvirt_private.syms
src/libxl/libxl_driver.c
src/qemu/qemu_driver.c
src/test/test_driver.c

index 74016c6c46beed6e10eb24e6ac1e6db4249952c9..9e9016cfe7966de80fa5db969a07f5aa47e89cbe 100644 (file)
@@ -6520,6 +6520,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,
index 00d486e774a9e9512358b90697bf47b1f36cd57e..2ef18b77fcd15d06678b4f9943fc7f0760e7e1f2 100644 (file)
@@ -31682,6 +31682,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
@@ -31710,6 +31751,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
index e996d3c0de9295590ad20f695fdd99a5e787d977..e51c74b6d18e1b811709eb9eb26f4e8879f8df55 100644 (file)
@@ -4588,6 +4588,11 @@ bool
 virHostdevIsPCIDevice(const virDomainHostdevDef *hostdev)
     ATTRIBUTE_NONNULL(1);
 
+void
+virDomainObjGetMessagesIOErrorsChain(virStorageSource *src,
+                                     const char *diskdst,
+                                     GPtrArray *m);
+
 void
 virDomainObjGetMessages(virDomainObj *vm,
                         GPtrArray *m,
index 2fe0a079442796405ba25e548c0f3c64cfaf310d..406e6583a3e982ea2732b9f0ccdf0261cc3d28c5 100644 (file)
@@ -592,6 +592,7 @@ virDomainObjEndAPI;
 virDomainObjFormat;
 virDomainObjGetDefs;
 virDomainObjGetMessages;
+virDomainObjGetMessagesIOErrorsChain;
 virDomainObjGetMetadata;
 virDomainObjGetOneDef;
 virDomainObjGetOneDefState;
index 426c2b42781f24ce064636cafa1ff72e1cfea88f..a76545c9ffb5bb9ca7716e1198b1598347634f49 100644 (file)
@@ -6580,7 +6580,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;
index 72dd471b6e190e29ff7e0392feb15c3a9068fa77..1b5ac883b5e2c161faf9ba8be4605e8718618a3c 100644 (file)
@@ -19837,9 +19837,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;
@@ -19847,8 +19849,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);
index a10ec3bc41be120c4ce54e5d1d31b4bdf8a30622..6f18b2b2c820f5d0610a62ac7797d2651a83f3ab 100644 (file)
@@ -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;