]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: Wire up new virDomainSetIOThreadParams parameters
authorMichal Privoznik <mprivozn@redhat.com>
Wed, 11 May 2022 11:32:26 +0000 (13:32 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 10 Jun 2022 12:00:44 +0000 (14:00 +0200)
Introduced in previous commit, QEMU driver needs to be taught how
to set VIR_DOMAIN_IOTHREAD_THREAD_POOL_MIN and
VIR_DOMAIN_IOTHREAD_THREAD_POOL_MAX parameters on given IOThread.
Fortunately, this is fairly trivial to do and since these two
parameters are exposed in domain XML too the update of inactive
XML can be wired up too.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
src/qemu/qemu_driver.c
src/qemu/qemu_monitor.h
src/qemu/qemu_monitor_json.c

index ee1adb030002b612c3392786577ff2d11d854b0e..ded34e97cd81d1d0d268454059755303f7feda4a 100644 (file)
@@ -5323,6 +5323,26 @@ qemuDomainHotplugModIOThread(virQEMUDriver *driver,
 }
 
 
+static int
+qemuDomainHotplugModIOThreadIDDef(virDomainIOThreadIDDef *def,
+                                  qemuMonitorIOThreadInfo mondef)
+{
+    /* These have no representation in domain XML */
+    if (mondef.set_poll_grow ||
+        mondef.set_poll_max_ns ||
+        mondef.set_poll_shrink)
+        return -1;
+
+    if (mondef.set_thread_pool_min)
+        def->thread_pool_min = mondef.thread_pool_min;
+
+    if (mondef.set_thread_pool_max)
+        def->thread_pool_max = mondef.thread_pool_max;
+
+    return 0;
+}
+
+
 static int
 qemuDomainHotplugDelIOThread(virQEMUDriver *driver,
                              virDomainObj *vm,
@@ -5430,6 +5450,10 @@ qemuDomainIOThreadParseParams(virTypedParameterPtr params,
                                VIR_TYPED_PARAM_UINT,
                                VIR_DOMAIN_IOTHREAD_POLL_SHRINK,
                                VIR_TYPED_PARAM_UINT,
+                               VIR_DOMAIN_IOTHREAD_THREAD_POOL_MIN,
+                               VIR_TYPED_PARAM_INT,
+                               VIR_DOMAIN_IOTHREAD_THREAD_POOL_MAX,
+                               VIR_TYPED_PARAM_INT,
                                NULL) < 0)
         return -1;
 
@@ -5454,6 +5478,20 @@ qemuDomainIOThreadParseParams(virTypedParameterPtr params,
     if (rc == 1)
         iothread->set_poll_shrink = true;
 
+    if ((rc = virTypedParamsGetInt(params, nparams,
+                                   VIR_DOMAIN_IOTHREAD_THREAD_POOL_MIN,
+                                   &iothread->thread_pool_min)) < 0)
+        return -1;
+    if (rc == 1)
+        iothread->set_thread_pool_min = true;
+
+    if ((rc = virTypedParamsGetInt(params, nparams,
+                                   VIR_DOMAIN_IOTHREAD_THREAD_POOL_MAX,
+                                   &iothread->thread_pool_max)) < 0)
+        return -1;
+    if (rc == 1)
+        iothread->set_thread_pool_max = true;
+
     if (iothread->set_poll_max_ns && iothread->poll_max_ns > INT_MAX) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("poll-max-ns (%llu) must be less than or equal to %d"),
@@ -5475,6 +5513,78 @@ qemuDomainIOThreadParseParams(virTypedParameterPtr params,
         return -1;
     }
 
+    if (iothread->set_thread_pool_min && iothread->thread_pool_min < -1) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("thread_pool_min (%d) must be equal to or greater than -1"),
+                       iothread->thread_pool_min);
+        return -1;
+    }
+
+    if (iothread->set_thread_pool_max &&
+        (iothread->thread_pool_max < -1 || iothread->thread_pool_max == 0)) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("thread_pool_max (%d) must be a positive number or -1"),
+                       iothread->thread_pool_max);
+        return -1;
+    }
+
+    return 0;
+}
+
+
+/**
+ * qemuDomainIOThreadValidate:
+ * iothreaddef: IOThread definition in domain XML
+ * iothread: new values to set
+ * live: whether this is update of active domain
+ *
+ * Validate that changes to be made to an IOThread (as expressed by @iothread)
+ * are consistent with the current state of the IOThread (@iothreaddef).
+ * For instance, that thread_pool_min won't end up greater than thread_pool_max.
+ *
+ * Returns: 0 on success,
+ *         -1 on error, with error message reported.
+ */
+static int
+qemuDomainIOThreadValidate(virDomainIOThreadIDDef *iothreaddef,
+                           qemuMonitorIOThreadInfo iothread,
+                           bool live)
+{
+    int thread_pool_min = iothreaddef->thread_pool_min;
+    int thread_pool_max = iothreaddef->thread_pool_max;
+
+    /* For live change we don't have a way to let QEMU return to its
+     * defaults. Therefore, deny setting -1. */
+
+    if (iothread.set_thread_pool_min) {
+        if (live && iothread.thread_pool_min < 0) {
+            virReportError(VIR_ERR_OPERATION_INVALID,
+                           _("thread_pool_min (%d) must be equal to or greater than 0 for live change"),
+                           iothread.thread_pool_min);
+            return -1;
+        }
+
+        thread_pool_min = iothread.thread_pool_min;
+    }
+
+    if (iothread.set_thread_pool_max) {
+        if (live && iothread.thread_pool_max < 0) {
+            virReportError(VIR_ERR_OPERATION_INVALID,
+                           _("thread_pool_max (%d) must be equal to or greater than 0 for live change"),
+                           iothread.thread_pool_max);
+            return -1;
+        }
+
+        thread_pool_max = iothread.thread_pool_max;
+    }
+
+    if (thread_pool_min > thread_pool_max) {
+        virReportError(VIR_ERR_OPERATION_INVALID,
+                       _("thread_pool_min (%d) can't be greater than thread_pool_max (%d)"),
+                       thread_pool_min, thread_pool_max);
+        return -1;
+    }
+
     return 0;
 }
 
@@ -5496,6 +5606,7 @@ qemuDomainChgIOThread(virQEMUDriver *driver,
     qemuDomainObjPrivate *priv;
     virDomainDef *def;
     virDomainDef *persistentDef;
+    virDomainIOThreadIDDef *iothreaddef = NULL;
     int ret = -1;
 
     cfg = virQEMUDriverGetConfig(driver);
@@ -5535,16 +5646,22 @@ qemuDomainChgIOThread(virQEMUDriver *driver,
             break;
 
         case VIR_DOMAIN_IOTHREAD_ACTION_MOD:
-            if (!(virDomainIOThreadIDFind(def, iothread.iothread_id))) {
+            iothreaddef = virDomainIOThreadIDFind(def, iothread.iothread_id);
+
+            if (!iothreaddef) {
                 virReportError(VIR_ERR_INVALID_ARG,
                                _("cannot find IOThread '%u' in iothreadids"),
                                iothread.iothread_id);
                 goto endjob;
             }
 
+            if (qemuDomainIOThreadValidate(iothreaddef, iothread, true) < 0)
+                goto endjob;
+
             if (qemuDomainHotplugModIOThread(driver, vm, iothread) < 0)
                 goto endjob;
 
+            qemuDomainHotplugModIOThreadIDDef(iothreaddef, iothread);
             break;
 
         }
@@ -5572,10 +5689,23 @@ qemuDomainChgIOThread(virQEMUDriver *driver,
             break;
 
         case VIR_DOMAIN_IOTHREAD_ACTION_MOD:
-            virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
-                           _("configuring persistent polling values is "
-                             "not supported"));
-            goto endjob;
+            iothreaddef = virDomainIOThreadIDFind(persistentDef, iothread.iothread_id);
+
+            if (!iothreaddef) {
+                virReportError(VIR_ERR_INVALID_ARG,
+                               _("cannot find IOThread '%u' in iothreadids"),
+                               iothread.iothread_id);
+                goto endjob;
+            }
+
+            if (qemuDomainIOThreadValidate(iothreaddef, iothread, false) < 0)
+                goto endjob;
+
+            if (qemuDomainHotplugModIOThreadIDDef(iothreaddef, iothread) < 0) {
+                virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+                               _("configuring persistent polling values is not supported"));
+                goto endjob;
+            }
 
             break;
         }
index 91f2d0941cf710094eebe9329686395f9a6625a9..06822d664215af33104ef1dd08f8abbb46a53be8 100644 (file)
@@ -1314,9 +1314,13 @@ struct _qemuMonitorIOThreadInfo {
     unsigned long long poll_max_ns;
     unsigned int poll_grow;
     unsigned int poll_shrink;
+    int thread_pool_min;
+    int thread_pool_max;
     bool set_poll_max_ns;
     bool set_poll_grow;
     bool set_poll_shrink;
+    bool set_thread_pool_min;
+    bool set_thread_pool_max;
 };
 int qemuMonitorGetIOThreads(qemuMonitor *mon,
                             qemuMonitorIOThreadInfo ***iothreads,
index 8b81a07429cd80829d804319c5e673c60ff5d4f8..6b3acab0d2b1279f5888df9d42cc4d0c039af618 100644 (file)
@@ -7447,6 +7447,8 @@ qemuMonitorJSONSetIOThread(qemuMonitor *mon,
     VIR_IOTHREAD_SET_PROP("poll-max-ns", poll_max_ns);
     VIR_IOTHREAD_SET_PROP("poll-grow", poll_grow);
     VIR_IOTHREAD_SET_PROP("poll-shrink", poll_shrink);
+    VIR_IOTHREAD_SET_PROP("thread-pool-min", thread_pool_min);
+    VIR_IOTHREAD_SET_PROP("thread-pool-max", thread_pool_max);
 
 #undef VIR_IOTHREAD_SET_PROP