[libvirt] [PATCH v2 0/5] test_driver: implement IOThread related APIs

Changes since v1: - Use vm-private data for storing iothread parameters and implement virDomainSetIOThreadParams Ilias Stamatis (5): test_driver: implement virDomainAddIOThread test_driver: implement virDomainDelIOThread test_driver: implement virDomainPinIOThread test_driver: implement virDomainGetIOThreadInfo test_driver: implement virDomainSetIOThreadParams src/test/test_driver.c | 362 +++++++++++++++++++++++++++++++++++++++++ src/test/test_driver.h | 11 ++ 2 files changed, 373 insertions(+) -- 2.22.0

Signed-off-by: Ilias Stamatis <stamatis.iliass@gmail.com> --- src/test/test_driver.c | 67 ++++++++++++++++++++++++++++++++++++++++++ src/test/test_driver.h | 11 +++++++ 2 files changed, 78 insertions(+) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 5f5c512571..7acde811ef 100755 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -396,6 +396,10 @@ struct _testDomainObjPrivate { /* used by get/set time APIs */ long long seconds; unsigned int nseconds; + + /* used by IOThread APIs */ + size_t num_iothreads; + testIOThreadInfoPtr *iothreads; }; @@ -413,6 +417,9 @@ testDomainObjPrivateAlloc(void *opaque) priv->seconds = 627319920; priv->nseconds = 0; + priv->num_iothreads = 0; + priv->iothreads = NULL; + return priv; } @@ -2897,6 +2904,65 @@ testDomainSetVcpusFlags(virDomainPtr domain, unsigned int nrCpus, } +static int +testDomainAddIOThread(virDomainPtr dom, + unsigned int iothread_id, + unsigned int flags) +{ + virDomainObjPtr vm = NULL; + virDomainDefPtr def = NULL; + virDomainIOThreadIDDefPtr iothrid = NULL; + testDomainObjPrivatePtr priv; + testIOThreadInfoPtr info; + 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")); + return -1; + } + + if (!(vm = testDomObjFromDomain(dom))) + goto cleanup; + + if (!(def = virDomainObjGetOneDef(vm, flags))) + goto cleanup; + + if (virDomainIOThreadIDFind(def, iothread_id)) { + virReportError(VIR_ERR_INVALID_ARG, + _("an IOThread is already using iothread_id '%u'"), + iothread_id); + goto cleanup; + } + + if (!virDomainIOThreadIDAdd(def, iothread_id)) + goto cleanup; + + priv = vm->privateData; + + if (VIR_ALLOC(info) < 0) + goto cleanup; + + info->id = iothread_id; + info->poll_max_ns = 32768; + + if (VIR_APPEND_ELEMENT(priv->iothreads, priv->num_iothreads, info) < 0) + goto cleanup; + + ret = 0; + cleanup: + if (ret < 0) { + virDomainIOThreadIDDefFree(iothrid); + VIR_FREE(info); + } + virDomainObjEndAPI(&vm); + return ret; +} + + static int testDomainSetUserPassword(virDomainPtr dom, const char *user ATTRIBUTE_UNUSED, @@ -9351,6 +9417,7 @@ static virHypervisorDriver testHypervisorDriver = { .domainSaveImageGetXMLDesc = testDomainSaveImageGetXMLDesc, /* 5.5.0 */ .domainCoreDump = testDomainCoreDump, /* 0.3.2 */ .domainCoreDumpWithFormat = testDomainCoreDumpWithFormat, /* 1.2.3 */ + .domainAddIOThread = testDomainAddIOThread, /* 5.7.0 */ .domainSetUserPassword = testDomainSetUserPassword, /* 5.6.0 */ .domainPinEmulator = testDomainPinEmulator, /* 5.6.0 */ .domainGetEmulatorPinInfo = testDomainGetEmulatorPinInfo, /* 5.6.0 */ diff --git a/src/test/test_driver.h b/src/test/test_driver.h index 8c8a462db7..0ef913fdd3 100644 --- a/src/test/test_driver.h +++ b/src/test/test_driver.h @@ -23,4 +23,15 @@ #include "internal.h" + +typedef struct _testIOThreadInfo testIOThreadInfo; +typedef testIOThreadInfo *testIOThreadInfoPtr; + +struct _testIOThreadInfo { + unsigned int id; + unsigned long long poll_max_ns; + unsigned int poll_grow; + unsigned int poll_shrink; +}; + int testRegister(void); -- 2.22.0

Signed-off-by: Ilias Stamatis <stamatis.iliass@gmail.com> --- src/test/test_driver.c | 85 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 7acde811ef..b4a883cb54 100755 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -2963,6 +2963,90 @@ testDomainAddIOThread(virDomainPtr dom, } +static int +testDomainDelIOThread(virDomainPtr dom, + unsigned int iothread_id, + unsigned int flags) +{ + virDomainObjPtr vm = NULL; + virDomainDefPtr def = NULL; + testDomainObjPrivatePtr priv; + size_t i, j; + 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")); + return -1; + } + + if (!(vm = testDomObjFromDomain(dom))) + goto cleanup; + + if (!(def = virDomainObjGetOneDef(vm, flags))) + goto cleanup; + + if (!virDomainIOThreadIDFind(def, iothread_id)) { + virReportError(VIR_ERR_INVALID_ARG, + _("cannot find IOThread '%u' in iothreadids list"), + iothread_id); + goto cleanup; + } + + for (i = 0; i < def->ndisks; i++) { + if (def->disks[i]->iothread == iothread_id) { + virReportError(VIR_ERR_INVALID_ARG, + _("cannot remove IOThread %u since it " + "is being used by disk '%s'"), + iothread_id, def->disks[i]->dst); + goto cleanup; + } + } + + for (i = 0; i < def->ncontrollers; i++) { + if (def->controllers[i]->iothread == iothread_id) { + virReportError(VIR_ERR_INVALID_ARG, + _("cannot remove IOThread '%u' since it " + "is being used by controller"), + iothread_id); + goto cleanup; + } + } + + for (i = 0; i < def->niothreadids; i++) { + if (def->iothreadids[i]->iothread_id == iothread_id) { + for (j = i + 1; j < def->niothreadids; j++) + def->iothreadids[j]->autofill = false; + + virDomainIOThreadIDDefFree(def->iothreadids[i]); + VIR_DELETE_ELEMENT(def->iothreadids, i, def->niothreadids); + + break; + } + } + + /* We have already deleted the iothread from the domain definition, now + * let's delete the info structure too from the domain-private data. */ + + priv = vm->privateData; + + for (i = 0; i < priv->num_iothreads; i++) { + if (iothread_id == priv->iothreads[i]->id) { + VIR_DELETE_ELEMENT(priv->iothreads, i, priv->num_iothreads); + break; + } + } + + ret = 0; + cleanup: + virDomainObjEndAPI(&vm); + return ret; +} + + static int testDomainSetUserPassword(virDomainPtr dom, const char *user ATTRIBUTE_UNUSED, @@ -9418,6 +9502,7 @@ static virHypervisorDriver testHypervisorDriver = { .domainCoreDump = testDomainCoreDump, /* 0.3.2 */ .domainCoreDumpWithFormat = testDomainCoreDumpWithFormat, /* 1.2.3 */ .domainAddIOThread = testDomainAddIOThread, /* 5.7.0 */ + .domainDelIOThread = testDomainDelIOThread, /* 5.7.0 */ .domainSetUserPassword = testDomainSetUserPassword, /* 5.6.0 */ .domainPinEmulator = testDomainPinEmulator, /* 5.6.0 */ .domainGetEmulatorPinInfo = testDomainGetEmulatorPinInfo, /* 5.6.0 */ -- 2.22.0

Signed-off-by: Ilias Stamatis <stamatis.iliass@gmail.com> Reviewed-by: Erik Skultety <eskultet@redhat.com> --- src/test/test_driver.c | 51 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index b4a883cb54..60d611245d 100755 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -3047,6 +3047,56 @@ testDomainDelIOThread(virDomainPtr dom, } +static int +testDomainPinIOThread(virDomainPtr dom, + unsigned int iothread_id, + unsigned char *cpumap, + int maplen, + unsigned int flags) +{ + int ret = -1; + virDomainObjPtr vm = NULL; + virDomainDefPtr def = NULL; + virDomainIOThreadIDDefPtr iothrid = NULL; + virBitmapPtr cpumask = NULL; + + virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | + VIR_DOMAIN_AFFECT_CONFIG, -1); + + if (!(vm = testDomObjFromDomain(dom))) + goto cleanup; + + if (!(def = virDomainObjGetOneDef(vm, flags))) + goto cleanup; + + if (!(cpumask = virBitmapNewData(cpumap, maplen))) + goto cleanup; + + if (virBitmapIsAllClear(cpumask)) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("Empty iothread cpumap list for pinning")); + goto cleanup; + } + + if (!(iothrid = virDomainIOThreadIDFind(def, iothread_id))) { + virReportError(VIR_ERR_INVALID_ARG, + _("iothreadid %d not found"), iothread_id); + goto cleanup; + } + + virBitmapFree(iothrid->cpumask); + iothrid->cpumask = cpumask; + iothrid->autofill = false; + + ret = 0; + cleanup: + if (ret < 0) + virBitmapFree(cpumask); + virDomainObjEndAPI(&vm); + return ret; +} + + static int testDomainSetUserPassword(virDomainPtr dom, const char *user ATTRIBUTE_UNUSED, @@ -9503,6 +9553,7 @@ static virHypervisorDriver testHypervisorDriver = { .domainCoreDumpWithFormat = testDomainCoreDumpWithFormat, /* 1.2.3 */ .domainAddIOThread = testDomainAddIOThread, /* 5.7.0 */ .domainDelIOThread = testDomainDelIOThread, /* 5.7.0 */ + .domainPinIOThread = testDomainPinIOThread, /* 5.7.0 */ .domainSetUserPassword = testDomainSetUserPassword, /* 5.6.0 */ .domainPinEmulator = testDomainPinEmulator, /* 5.6.0 */ .domainGetEmulatorPinInfo = testDomainGetEmulatorPinInfo, /* 5.6.0 */ -- 2.22.0

Signed-off-by: Ilias Stamatis <stamatis.iliass@gmail.com> Reviewed-by: Erik Skultety <eskultet@redhat.com> --- src/test/test_driver.c | 74 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 60d611245d..7eef54bb05 100755 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -3097,6 +3097,79 @@ testDomainPinIOThread(virDomainPtr dom, } +static int +testDomainGetIOThreadInfo(virDomainPtr dom, + virDomainIOThreadInfoPtr **info, + unsigned int flags) +{ + virDomainObjPtr vm = NULL; + virDomainDefPtr def = NULL; + virBitmapPtr cpumask = NULL; + virBitmapPtr bitmap = NULL; + virDomainIOThreadInfoPtr *info_ret = NULL; + size_t i; + int hostcpus; + int ret = -1; + + virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | + VIR_DOMAIN_AFFECT_CONFIG, -1); + + if (!(vm = testDomObjFromDomain(dom))) + goto cleanup; + + if (!(def = virDomainObjGetOneDef(vm, flags))) + goto cleanup; + + if (def->niothreadids == 0) + goto cleanup; + + if ((hostcpus = virHostCPUGetCount()) < 0) + goto cleanup; + + if (VIR_ALLOC_N(info_ret, def->niothreadids) < 0) + goto cleanup; + + for (i = 0; i < def->niothreadids; i++) { + if (VIR_ALLOC(info_ret[i]) < 0) + goto cleanup; + + info_ret[i]->iothread_id = def->iothreadids[i]->iothread_id; + + cpumask = def->iothreadids[i]->cpumask; + if (!cpumask) { + if (def->cpumask) { + cpumask = def->cpumask; + } else { + if (!(bitmap = virBitmapNew(hostcpus))) + goto cleanup; + virBitmapSetAll(bitmap); + cpumask = bitmap; + } + } + + if (virBitmapToData(cpumask, &info_ret[i]->cpumap, + &info_ret[i]->cpumaplen) < 0) + goto cleanup; + + virBitmapFree(bitmap); + bitmap = NULL; + } + + VIR_STEAL_PTR(*info, info_ret); + ret = def->niothreadids; + + cleanup: + if (info_ret) { + for (i = 0; i < def->niothreadids; i++) + virDomainIOThreadInfoFree(info_ret[i]); + VIR_FREE(info_ret); + } + virBitmapFree(bitmap); + virDomainObjEndAPI(&vm); + return ret; +} + + static int testDomainSetUserPassword(virDomainPtr dom, const char *user ATTRIBUTE_UNUSED, @@ -9554,6 +9627,7 @@ static virHypervisorDriver testHypervisorDriver = { .domainAddIOThread = testDomainAddIOThread, /* 5.7.0 */ .domainDelIOThread = testDomainDelIOThread, /* 5.7.0 */ .domainPinIOThread = testDomainPinIOThread, /* 5.7.0 */ + .domainGetIOThreadInfo = testDomainGetIOThreadInfo, /* 5.7.0 */ .domainSetUserPassword = testDomainSetUserPassword, /* 5.6.0 */ .domainPinEmulator = testDomainPinEmulator, /* 5.6.0 */ .domainGetEmulatorPinInfo = testDomainGetEmulatorPinInfo, /* 5.6.0 */ -- 2.22.0

Signed-off-by: Ilias Stamatis <stamatis.iliass@gmail.com> --- src/test/test_driver.c | 85 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 7eef54bb05..6274d5bf0f 100755 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -3170,6 +3170,90 @@ testDomainGetIOThreadInfo(virDomainPtr dom, } +static int +testDomainSetIOThreadParams(virDomainPtr dom, + unsigned int iothread_id, + virTypedParameterPtr params, + int nparams, + unsigned int flags) +{ + virDomainObjPtr vm = NULL; + virDomainDefPtr def = NULL; + testDomainObjPrivatePtr priv; + testIOThreadInfo info_copy; + testIOThreadInfoPtr infop = NULL; + size_t i; + 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")); + return -1; + } + + if (!(vm = testDomObjFromDomain(dom))) + goto cleanup; + + if (!(def = virDomainObjGetOneDef(vm, flags))) + goto cleanup; + + if (!virDomainIOThreadIDFind(def, iothread_id)) { + virReportError(VIR_ERR_INVALID_ARG, + _("cannot find IOThread '%u' in iothreadids list"), + iothread_id); + goto cleanup; + } + + if (virTypedParamsValidate(params, nparams, + VIR_DOMAIN_IOTHREAD_POLL_MAX_NS, + VIR_TYPED_PARAM_ULLONG, + VIR_DOMAIN_IOTHREAD_POLL_GROW, + VIR_TYPED_PARAM_UINT, + VIR_DOMAIN_IOTHREAD_POLL_SHRINK, + VIR_TYPED_PARAM_UINT, + NULL) < 0) + goto cleanup; + + priv = vm->privateData; + + for (i = 0; i < priv->num_iothreads; i++) { + if (iothread_id == priv->iothreads[i]->id) { + infop = priv->iothreads[i]; + break; + } + } + + if (!infop) + goto cleanup; + + memcpy(&info_copy, infop, sizeof(testIOThreadInfo)); + + if (virTypedParamsGetULLong(params, nparams, + VIR_DOMAIN_IOTHREAD_POLL_MAX_NS, + &info_copy.poll_max_ns) < 0) + goto cleanup; + + if (virTypedParamsGetUInt(params, nparams, + VIR_DOMAIN_IOTHREAD_POLL_GROW, + &info_copy.poll_grow) < 0) + goto cleanup; + + if (virTypedParamsGetUInt(params, nparams, + VIR_DOMAIN_IOTHREAD_POLL_SHRINK, + &info_copy.poll_shrink) < 0) + goto cleanup; + + memcpy(infop, &info_copy, sizeof(testIOThreadInfo)); + + ret = 0; + cleanup: + virDomainObjEndAPI(&vm); + return ret; +} + static int testDomainSetUserPassword(virDomainPtr dom, const char *user ATTRIBUTE_UNUSED, @@ -9628,6 +9712,7 @@ static virHypervisorDriver testHypervisorDriver = { .domainDelIOThread = testDomainDelIOThread, /* 5.7.0 */ .domainPinIOThread = testDomainPinIOThread, /* 5.7.0 */ .domainGetIOThreadInfo = testDomainGetIOThreadInfo, /* 5.7.0 */ + .domainSetIOThreadParams = testDomainSetIOThreadParams, /* 5.7.0 */ .domainSetUserPassword = testDomainSetUserPassword, /* 5.6.0 */ .domainPinEmulator = testDomainPinEmulator, /* 5.6.0 */ .domainGetEmulatorPinInfo = testDomainGetEmulatorPinInfo, /* 5.6.0 */ -- 2.22.0
participants (1)
-
Ilias Stamatis