[libvirt] [PATCH 11/12] qemu: implement virDomainModIOThreadParams API

Pavel Hrdina phrdina at redhat.com
Tue Feb 21 12:15:07 UTC 2017


Signed-off-by: Pavel Hrdina <phrdina at redhat.com>
---
 src/conf/domain_conf.c       |  26 ++++++++
 src/conf/domain_conf.h       |   8 +++
 src/libvirt_private.syms     |   1 +
 src/qemu/qemu_driver.c       | 150 +++++++++++++++++++++++++++++++++++++++++--
 src/qemu/qemu_monitor.c      |  19 ++++++
 src/qemu/qemu_monitor.h      |   3 +
 src/qemu/qemu_monitor_json.c |  32 +++++++++
 src/qemu/qemu_monitor_json.h |   4 ++
 8 files changed, 236 insertions(+), 7 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 64303a6790..cc1be373ca 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -20370,6 +20370,32 @@ virDomainIOThreadIDAdd(virDomainDefPtr def,
 
 
 void
+virDomainIOThreadIDMod(virDomainIOThreadIDDefPtr old_iothread,
+                       virDomainIOThreadIDDefPtr new_iothread)
+{
+    old_iothread->poll_enabled = new_iothread->poll_enabled;
+
+    switch (new_iothread->poll_enabled) {
+    case VIR_TRISTATE_BOOL_YES:
+        old_iothread->poll_max_ns = new_iothread->poll_max_ns;
+        old_iothread->poll_grow = new_iothread->poll_grow;
+        old_iothread->poll_shrink = new_iothread->poll_shrink;
+        break;
+
+    case VIR_TRISTATE_BOOL_ABSENT:
+    case VIR_TRISTATE_BOOL_NO:
+        old_iothread->poll_max_ns = 0;
+        old_iothread->poll_grow = 0;
+        old_iothread->poll_shrink = 0;
+        break;
+
+    case VIR_TRISTATE_BOOL_LAST:
+        break;
+    }
+}
+
+
+void
 virDomainIOThreadIDDel(virDomainDefPtr def,
                        unsigned int iothread_id)
 {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 5f8c745d8a..6f7edb3bfa 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2065,6 +2065,12 @@ struct _virDomainHugePage {
 
 # define VIR_DOMAIN_CPUMASK_LEN 1024
 
+typedef enum {
+    VIR_DOMAIN_IOTHREAD_ACTION_ADD,
+    VIR_DOMAIN_IOTHREAD_ACTION_DEL,
+    VIR_DOMAIN_IOTHREAD_ACTION_MOD,
+} virDomainIOThreadAction;
+
 typedef struct _virDomainIOThreadIDDef virDomainIOThreadIDDef;
 typedef virDomainIOThreadIDDef *virDomainIOThreadIDDefPtr;
 
@@ -2792,6 +2798,8 @@ virDomainIOThreadIDDefPtr virDomainIOThreadIDFind(const virDomainDef *def,
                                                   unsigned int iothread_id);
 virDomainIOThreadIDDefPtr virDomainIOThreadIDAdd(virDomainDefPtr def,
                                                  virDomainIOThreadIDDef iothread);
+void virDomainIOThreadIDMod(virDomainIOThreadIDDefPtr old_iothread,
+                            virDomainIOThreadIDDefPtr new_iothread);
 void virDomainIOThreadIDDel(virDomainDefPtr def, unsigned int iothread_id);
 
 unsigned int virDomainDefFormatConvertXMLFlags(unsigned int flags);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 97aee9c0e3..b9f0ac0c9f 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -376,6 +376,7 @@ virDomainIOThreadIDAdd;
 virDomainIOThreadIDDefFree;
 virDomainIOThreadIDDel;
 virDomainIOThreadIDFind;
+virDomainIOThreadIDMod;
 virDomainKeyWrapCipherNameTypeFromString;
 virDomainKeyWrapCipherNameTypeToString;
 virDomainLeaseDefFree;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 96c8b2b8bc..46dc4a5ffb 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5662,6 +5662,55 @@ qemuDomainHotplugAddIOThread(virQEMUDriverPtr driver,
     goto cleanup;
 }
 
+
+static int
+qemuDomainHotplugModIOThread(virQEMUDriverPtr driver,
+                             virDomainObjPtr vm,
+                             virDomainIOThreadIDDef iothread,
+                             virDomainIOThreadIDDefPtr old_iothread)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuMonitorIOThreadInfo iothread_info = {0};
+    int rc;
+
+    iothread_info.iothread_id = old_iothread->iothread_id;
+
+    switch (iothread.poll_enabled) {
+    case VIR_TRISTATE_BOOL_ABSENT:
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("IOThread polling must be specified for "
+                         "live update"));
+        return -1;
+
+    case VIR_TRISTATE_BOOL_YES:
+        iothread_info.poll_max_ns = iothread.poll_max_ns;
+        iothread_info.poll_grow = iothread.poll_grow;
+        iothread_info.poll_shrink = iothread.poll_shrink;
+        break;
+
+    case VIR_TRISTATE_BOOL_NO:
+        /* No need to do anything because iothread_info has all members
+         * initialized to 0 which will disable polling. */
+    case VIR_TRISTATE_BOOL_LAST:
+        break;
+    }
+
+    qemuDomainObjEnterMonitor(driver, vm);
+
+    rc = qemuMonitorSetIOThread(priv->mon, &iothread_info);
+
+    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        return -1;
+
+    if (rc < 0)
+        return -1;
+
+    virDomainIOThreadIDMod(old_iothread, &iothread);
+
+    return 0;
+}
+
+
 static int
 qemuDomainHotplugDelIOThread(virQEMUDriverPtr driver,
                              virDomainObjPtr vm,
@@ -5742,6 +5791,21 @@ qemuDomainAddIOThreadCheck(virDomainDefPtr def,
 }
 
 
+static virDomainIOThreadIDDefPtr
+qemuDomainModIOThreadGet(virDomainDefPtr def,
+                         unsigned int iothread_id)
+{
+    virDomainIOThreadIDDefPtr ret = NULL;
+
+    if (!(ret = virDomainIOThreadIDFind(def, iothread_id)))
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("cannot find IOThread '%u' in iothreadids list"),
+                       iothread_id);
+
+    return ret;
+}
+
+
 static int
 qemuDomainDelIOThreadCheck(virDomainDefPtr def,
                            unsigned int iothread_id)
@@ -5845,13 +5909,14 @@ static int
 qemuDomainChgIOThread(virQEMUDriverPtr driver,
                       virDomainObjPtr vm,
                       virDomainIOThreadIDDef iothread,
-                      bool add,
+                      virDomainIOThreadAction action,
                       unsigned int flags)
 {
     virQEMUDriverConfigPtr cfg = NULL;
     qemuDomainObjPrivatePtr priv;
     virDomainDefPtr def;
     virDomainDefPtr persistentDef;
+    virDomainIOThreadIDDefPtr old_iothread = NULL;
     int ret = -1;
 
     cfg = virQEMUDriverGetConfig(driver);
@@ -5871,19 +5936,34 @@ qemuDomainChgIOThread(virQEMUDriverPtr driver,
             goto endjob;
         }
 
-        if (add) {
+        switch (action) {
+        case VIR_DOMAIN_IOTHREAD_ACTION_ADD:
             if (qemuDomainAddIOThreadCheck(def, iothread.iothread_id) < 0)
                 goto endjob;
 
             if (qemuDomainHotplugAddIOThread(driver, vm, iothread) < 0)
                 goto endjob;
-        } else {
+            break;
+
+        case VIR_DOMAIN_IOTHREAD_ACTION_DEL:
             if (qemuDomainDelIOThreadCheck(def, iothread.iothread_id) < 0)
                 goto endjob;
 
             if (qemuDomainHotplugDelIOThread(driver, vm,
                                              iothread.iothread_id) < 0)
                 goto endjob;
+            break;
+
+        case VIR_DOMAIN_IOTHREAD_ACTION_MOD:
+            if (!(old_iothread = qemuDomainModIOThreadGet(def,
+                                                          iothread.iothread_id)))
+                goto endjob;
+
+            if (qemuDomainHotplugModIOThread(driver, vm, iothread,
+                                             old_iothread) < 0)
+                goto endjob;
+
+            break;
         }
 
         if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm,
@@ -5892,19 +5972,30 @@ qemuDomainChgIOThread(virQEMUDriverPtr driver,
     }
 
     if (persistentDef) {
-        if (add) {
+        switch (action) {
+        case VIR_DOMAIN_IOTHREAD_ACTION_ADD:
             if (qemuDomainAddIOThreadCheck(persistentDef,
                                            iothread.iothread_id) < 0)
                 goto endjob;
 
             if (!virDomainIOThreadIDAdd(persistentDef, iothread))
                 goto endjob;
-        } else {
+            break;
+
+        case VIR_DOMAIN_IOTHREAD_ACTION_DEL:
             if (qemuDomainDelIOThreadCheck(persistentDef,
                                            iothread.iothread_id) < 0)
                 goto endjob;
 
             virDomainIOThreadIDDel(persistentDef, iothread.iothread_id);
+
+        case VIR_DOMAIN_IOTHREAD_ACTION_MOD:
+            if (!(old_iothread = qemuDomainModIOThreadGet(persistentDef,
+                                                          iothread.iothread_id)))
+                goto endjob;
+
+            virDomainIOThreadIDMod(old_iothread, &iothread);
+            break;
         }
 
         if (virDomainSaveConfig(cfg->configDir, driver->caps,
@@ -5955,7 +6046,8 @@ qemuDomainAddIOThreadParams(virDomainPtr dom,
     if (virDomainAddIOThreadParamsEnsureACL(dom->conn, vm->def, flags) < 0)
         goto cleanup;
 
-    ret = qemuDomainChgIOThread(driver, vm, iothread, true, flags);
+    ret = qemuDomainChgIOThread(driver, vm, iothread,
+                                VIR_DOMAIN_IOTHREAD_ACTION_ADD, flags);
 
  cleanup:
     virDomainObjEndAPI(&vm);
@@ -5973,6 +6065,48 @@ qemuDomainAddIOThread(virDomainPtr dom,
 
 
 static int
+qemuDomainModIOThreadParams(virDomainPtr dom,
+                            unsigned int iothread_id,
+                            virTypedParameterPtr params,
+                            int nparams,
+                            unsigned int flags)
+{
+    virQEMUDriverPtr driver = dom->conn->privateData;
+    virDomainObjPtr vm = NULL;
+    virDomainIOThreadIDDef iothread = {0};
+    int ret = -1;
+
+    virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
+                  VIR_DOMAIN_AFFECT_CONFIG, -1);
+
+    if (iothread_id == 0) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("invalid value of 0 for iothread_id"));
+        goto cleanup;
+    }
+
+    iothread.iothread_id = iothread_id;
+
+    if (!(vm = qemuDomObjFromDomain(dom)))
+        goto cleanup;
+
+    if (qemuDomainIOThreadParseParams(params, nparams, vm->privateData,
+                                      &iothread) < 0)
+        goto cleanup;
+
+    if (virDomainModIOThreadParamsEnsureACL(dom->conn, vm->def, flags) < 0)
+        goto cleanup;
+
+    ret = qemuDomainChgIOThread(driver, vm, iothread,
+                                VIR_DOMAIN_IOTHREAD_ACTION_MOD, flags);
+
+ cleanup:
+    virDomainObjEndAPI(&vm);
+    return ret;
+}
+
+
+static int
 qemuDomainDelIOThread(virDomainPtr dom,
                       unsigned int iothread_id,
                       unsigned int flags)
@@ -5998,7 +6132,8 @@ qemuDomainDelIOThread(virDomainPtr dom,
     if (virDomainDelIOThreadEnsureACL(dom->conn, vm->def, flags) < 0)
            goto cleanup;
 
-    ret = qemuDomainChgIOThread(driver, vm, iothread, false, flags);
+    ret = qemuDomainChgIOThread(driver, vm, iothread,
+                                VIR_DOMAIN_IOTHREAD_ACTION_DEL, flags);
 
  cleanup:
     virDomainObjEndAPI(&vm);
@@ -20366,6 +20501,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
     .domainPinIOThread = qemuDomainPinIOThread, /* 1.2.14 */
     .domainAddIOThread = qemuDomainAddIOThread, /* 1.2.15 */
     .domainAddIOThreadParams = qemuDomainAddIOThreadParams, /* 3.1.0 */
+    .domainModIOThreadParams = qemuDomainModIOThreadParams, /* 3.1.0 */
     .domainDelIOThread = qemuDomainDelIOThread, /* 1.2.15 */
     .domainGetSecurityLabel = qemuDomainGetSecurityLabel, /* 0.6.1 */
     .domainGetSecurityLabelList = qemuDomainGetSecurityLabelList, /* 0.10.0 */
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 7633e6fc07..19be1bbf2e 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -4054,6 +4054,25 @@ qemuMonitorGetIOThreads(qemuMonitorPtr mon,
 
 
 /**
+ * qemuMonitorSetIOThread:
+ * @mon: Pointer to the monitor
+ * @iothreadInfo: filled IOThread info with data
+ *
+ *
+ */
+int
+qemuMonitorSetIOThread(qemuMonitorPtr mon,
+                       qemuMonitorIOThreadInfoPtr iothreadInfo)
+{
+    VIR_DEBUG("iothread=%p", iothreadInfo);
+
+    QEMU_CHECK_MONITOR_JSON(mon);
+
+    return qemuMonitorJSONSetIOThread(mon, iothreadInfo);
+}
+
+
+/**
  * qemuMonitorGetMemoryDeviceInfo:
  * @mon: pointer to the monitor
  * @info: Location to return the hash of qemuMonitorMemoryDeviceInfo
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index eeae18e5b0..09c1dbc882 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1013,6 +1013,9 @@ int qemuMonitorGetIOThreads(qemuMonitorPtr mon,
                             qemuMonitorIOThreadInfoPtr **iothreads,
                             bool supportPolling);
 
+int qemuMonitorSetIOThread(qemuMonitorPtr mon,
+                           qemuMonitorIOThreadInfoPtr iothreadInfo);
+
 typedef struct _qemuMonitorMemoryDeviceInfo qemuMonitorMemoryDeviceInfo;
 typedef qemuMonitorMemoryDeviceInfo *qemuMonitorMemoryDeviceInfoPtr;
 
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index ab73f7aaf6..93e2920d79 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -6840,6 +6840,38 @@ qemuMonitorJSONGetIOThreads(qemuMonitorPtr mon,
 
 
 int
+qemuMonitorJSONSetIOThread(qemuMonitorPtr mon,
+                           qemuMonitorIOThreadInfoPtr iothreadInfo)
+{
+    int ret = -1;
+    char *path = NULL;
+    qemuMonitorJSONObjectProperty prop;
+
+    if (virAsprintf(&path, "/objects/iothread%u", iothreadInfo->iothread_id) < 0)
+        goto cleanup;
+
+#define VIR_IOTHREAD_SET_PROP(propName, propVal)                            \
+    memset(&prop, 0, sizeof(qemuMonitorJSONObjectProperty));                \
+    prop.type = QEMU_MONITOR_OBJECT_PROPERTY_INT;                           \
+    prop.val.iv = propVal;                                                  \
+    if (qemuMonitorJSONSetObjectProperty(mon, path, propName, &prop) < 0)   \
+        goto cleanup;
+
+    VIR_IOTHREAD_SET_PROP("poll-max-ns", iothreadInfo->poll_max_ns)
+    VIR_IOTHREAD_SET_PROP("poll-grow", iothreadInfo->poll_grow)
+    VIR_IOTHREAD_SET_PROP("poll-shrink", iothreadInfo->poll_shrink)
+
+#undef VIR_IOTHREAD_SET_PROP
+
+    ret = 0;
+
+ cleanup:
+    VIR_FREE(path);
+    return ret;
+}
+
+
+int
 qemuMonitorJSONGetMemoryDeviceInfo(qemuMonitorPtr mon,
                                    virHashTablePtr info)
 {
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 0f557a2991..1614ff5860 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -484,6 +484,10 @@ int qemuMonitorJSONGetIOThreads(qemuMonitorPtr mon,
                                 bool supportPolling)
     ATTRIBUTE_NONNULL(2);
 
+int qemuMonitorJSONSetIOThread(qemuMonitorPtr mon,
+                               qemuMonitorIOThreadInfoPtr iothreadInfo)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
 int qemuMonitorJSONGetMemoryDeviceInfo(qemuMonitorPtr mon,
                                        virHashTablePtr info)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
-- 
2.11.1




More information about the libvir-list mailing list