Signed-off-by: Pavel Hrdina <phrdina@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list