render / rpms / libvirt

Forked from rpms/libvirt 10 months ago
Clone
032100
From 5853ac5261b2934ca300b24a7bd78cc4b377c90c Mon Sep 17 00:00:00 2001
032100
Message-Id: <5853ac5261b2934ca300b24a7bd78cc4b377c90c@dist-git>
032100
From: Michal Privoznik <mprivozn@redhat.com>
032100
Date: Thu, 7 Jul 2022 17:37:46 +0200
032100
Subject: [PATCH] qemu: Make IOThread changing more robust
032100
MIME-Version: 1.0
032100
Content-Type: text/plain; charset=UTF-8
032100
Content-Transfer-Encoding: 8bit
032100
032100
There are three APIs that allow changing IOThreads:
032100
032100
  virDomainAddIOThread()
032100
  virDomainDelIOThread()
032100
  virDomainSetIOThreadParams()
032100
032100
In case of QEMU driver these are handled by
032100
qemuDomainChgIOThread() which attempts to be versatile enough to
032100
work on both inactive and live domain definitions at the same
032100
time. However, it's a bit clumsy - when a change to live
032100
definition succeeds but fails in inactive definition then there's
032100
no rollback. And somewhat rightfully so - changes to live
032100
definition are in general harder to roll back. Therefore, do what
032100
we do elsewhere (qemuDomainAttachDeviceLiveAndConfig(),
032100
qemuDomainDetachDeviceAliasLiveAndConfig(), ...):
032100
032100
  1) do the change to inactive XML first,
032100
  2) in fact, do the change to a copy of inactive XML,
032100
  3) swap inactive XML and its copy only after everything
032100
     succeeded.
032100
032100
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
032100
Reviewed-by: Ján Tomko <jtomko@redhat.com>
032100
(cherry picked from commit 6db9c95a45d4e24cdcd5c009b7fe5da3745b5d59)
032100
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2059511
032100
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
032100
---
032100
 src/qemu/qemu_driver.c | 74 ++++++++++++++++++++++++------------------
032100
 1 file changed, 43 insertions(+), 31 deletions(-)
032100
032100
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
032100
index 3b5c3db67c..2c627396f1 100644
032100
--- a/src/qemu/qemu_driver.c
032100
+++ b/src/qemu/qemu_driver.c
032100
@@ -5594,6 +5594,7 @@ qemuDomainChgIOThread(virQEMUDriver *driver,
032100
 {
032100
     g_autoptr(virQEMUDriverConfig) cfg = NULL;
032100
     qemuDomainObjPrivate *priv;
032100
+    g_autoptr(virDomainDef) defcopy = NULL;
032100
     virDomainDef *def;
032100
     virDomainDef *persistentDef;
032100
     virDomainIOThreadIDDef *iothreaddef = NULL;
032100
@@ -5609,34 +5610,34 @@ qemuDomainChgIOThread(virQEMUDriver *driver,
032100
     if (virDomainObjGetDefs(vm, flags, &def, &persistentDef) < 0)
032100
         goto endjob;
032100
 
032100
-    if (def) {
032100
-        if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_OBJECT_IOTHREAD)) {
032100
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
032100
-                           _("IOThreads not supported with this binary"));
032100
-            goto endjob;
032100
-        }
032100
+    if (persistentDef) {
032100
+        /* Make a copy of persistent definition and do all the changes there.
032100
+         * Swap the definitions only after changes to live definition
032100
+         * succeeded. */
032100
+        if (!(defcopy = virDomainObjCopyPersistentDef(vm, driver->xmlopt,
032100
+                                                      priv->qemuCaps)))
032100
+            return -1;
032100
 
032100
         switch (action) {
032100
         case VIR_DOMAIN_IOTHREAD_ACTION_ADD:
032100
-            if (virDomainDriverAddIOThreadCheck(def, iothread.iothread_id) < 0)
032100
+            if (virDomainDriverAddIOThreadCheck(defcopy, iothread.iothread_id) < 0)
032100
                 goto endjob;
032100
 
032100
-            if (qemuDomainHotplugAddIOThread(driver, vm, iothread.iothread_id) < 0)
032100
+            if (!virDomainIOThreadIDAdd(defcopy, iothread.iothread_id))
032100
                 goto endjob;
032100
 
032100
             break;
032100
 
032100
         case VIR_DOMAIN_IOTHREAD_ACTION_DEL:
032100
-            if (virDomainDriverDelIOThreadCheck(def, iothread.iothread_id) < 0)
032100
+            if (virDomainDriverDelIOThreadCheck(defcopy, iothread.iothread_id) < 0)
032100
                 goto endjob;
032100
 
032100
-            if (qemuDomainHotplugDelIOThread(driver, vm, iothread.iothread_id) < 0)
032100
-                goto endjob;
032100
+            virDomainIOThreadIDDel(defcopy, iothread.iothread_id);
032100
 
032100
             break;
032100
 
032100
         case VIR_DOMAIN_IOTHREAD_ACTION_MOD:
032100
-            iothreaddef = virDomainIOThreadIDFind(def, iothread.iothread_id);
032100
+            iothreaddef = virDomainIOThreadIDFind(defcopy, iothread.iothread_id);
032100
 
032100
             if (!iothreaddef) {
032100
                 virReportError(VIR_ERR_INVALID_ARG,
032100
@@ -5645,41 +5646,47 @@ qemuDomainChgIOThread(virQEMUDriver *driver,
032100
                 goto endjob;
032100
             }
032100
 
032100
-            if (qemuDomainIOThreadValidate(iothreaddef, iothread, true) < 0)
032100
+            if (qemuDomainIOThreadValidate(iothreaddef, iothread, false) < 0)
032100
                 goto endjob;
032100
 
032100
-            if (qemuDomainHotplugModIOThread(driver, vm, iothread) < 0)
032100
+            if (qemuDomainHotplugModIOThreadIDDef(iothreaddef, iothread) < 0) {
032100
+                virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
032100
+                               _("configuring persistent polling values is not supported"));
032100
                 goto endjob;
032100
+            }
032100
 
032100
-            qemuDomainHotplugModIOThreadIDDef(iothreaddef, iothread);
032100
             break;
032100
-
032100
         }
032100
-
032100
-        qemuDomainSaveStatus(vm);
032100
     }
032100
 
032100
-    if (persistentDef) {
032100
+    if (def) {
032100
+        if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_OBJECT_IOTHREAD)) {
032100
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
032100
+                           _("IOThreads not supported with this binary"));
032100
+            goto endjob;
032100
+        }
032100
+
032100
         switch (action) {
032100
         case VIR_DOMAIN_IOTHREAD_ACTION_ADD:
032100
-            if (virDomainDriverAddIOThreadCheck(persistentDef, iothread.iothread_id) < 0)
032100
+            if (virDomainDriverAddIOThreadCheck(def, iothread.iothread_id) < 0)
032100
                 goto endjob;
032100
 
032100
-            if (!virDomainIOThreadIDAdd(persistentDef, iothread.iothread_id))
032100
+            if (qemuDomainHotplugAddIOThread(driver, vm, iothread.iothread_id) < 0)
032100
                 goto endjob;
032100
 
032100
             break;
032100
 
032100
         case VIR_DOMAIN_IOTHREAD_ACTION_DEL:
032100
-            if (virDomainDriverDelIOThreadCheck(persistentDef, iothread.iothread_id) < 0)
032100
+            if (virDomainDriverDelIOThreadCheck(def, iothread.iothread_id) < 0)
032100
                 goto endjob;
032100
 
032100
-            virDomainIOThreadIDDel(persistentDef, iothread.iothread_id);
032100
+            if (qemuDomainHotplugDelIOThread(driver, vm, iothread.iothread_id) < 0)
032100
+                goto endjob;
032100
 
032100
             break;
032100
 
032100
         case VIR_DOMAIN_IOTHREAD_ACTION_MOD:
032100
-            iothreaddef = virDomainIOThreadIDFind(persistentDef, iothread.iothread_id);
032100
+            iothreaddef = virDomainIOThreadIDFind(def, iothread.iothread_id);
032100
 
032100
             if (!iothreaddef) {
032100
                 virReportError(VIR_ERR_INVALID_ARG,
032100
@@ -5688,21 +5695,26 @@ qemuDomainChgIOThread(virQEMUDriver *driver,
032100
                 goto endjob;
032100
             }
032100
 
032100
-            if (qemuDomainIOThreadValidate(iothreaddef, iothread, false) < 0)
032100
+            if (qemuDomainIOThreadValidate(iothreaddef, iothread, true) < 0)
032100
                 goto endjob;
032100
 
032100
-            if (qemuDomainHotplugModIOThreadIDDef(iothreaddef, iothread) < 0) {
032100
-                virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
032100
-                               _("configuring persistent polling values is not supported"));
032100
+            if (qemuDomainHotplugModIOThread(driver, vm, iothread) < 0)
032100
                 goto endjob;
032100
-            }
032100
 
032100
+            qemuDomainHotplugModIOThreadIDDef(iothreaddef, iothread);
032100
             break;
032100
+
032100
         }
032100
 
032100
-        if (virDomainDefSave(persistentDef, driver->xmlopt,
032100
-                             cfg->configDir) < 0)
032100
+        qemuDomainSaveStatus(vm);
032100
+    }
032100
+
032100
+    /* Finally, if no error until here, we can save config. */
032100
+    if (defcopy) {
032100
+        if (virDomainDefSave(defcopy, driver->xmlopt, cfg->configDir) < 0)
032100
             goto endjob;
032100
+
032100
+        virDomainObjAssignDef(vm, &defcopy, false, NULL);
032100
     }
032100
 
032100
     ret = 0;
032100
-- 
032100
2.35.1
032100