[PATCH v3 00/11] Implement IOThreads related APIs for test driver

v3: - Rebase to current master branch - Fix compilation - Fix tests Luke Yue (11): domain_driver.c: Introduce and use virDomainDriverAddIOThreadCheck() test_driver: Introduce testIOThreadInfo and generate IOThread infos test_driver: Implement virDomainAddIOThread test_driver: Implement virDomainDelIOThread domain_driver.c: Introduce and use virDomainDriverGetIOThreadsConfig() test_driver: Implement virDomainGetIOThreadInfo test_driver: Implement virDomainPinIOThread test_driver: Implement testDomainSetIOThreadParams test_driver: Implement virConnectGetAllDomainStats test_driver: Introduce testDomainGetStatsIOThread tests: Test IOThread related functions for test driver examples/xml/test/testdomfc4.xml | 5 + src/hypervisor/domain_driver.c | 132 ++++++++ src/hypervisor/domain_driver.h | 10 + src/libvirt_private.syms | 3 + src/qemu/qemu_driver.c | 113 +------ src/test/meson.build | 1 + src/test/test_driver.c | 515 +++++++++++++++++++++++++++++++ tests/virshtest.c | 90 ++++++ 8 files changed, 761 insertions(+), 108 deletions(-) -- 2.32.0

The test driver can share the same code with qemu driver when implement testDomainAddIOThreadCheck and testDomainDelIOThreadCheck, so extract them for test driver to use. Signed-off-by: Luke Yue <lukedyue@gmail.com> --- src/hypervisor/domain_driver.c | 64 ++++++++++++++++++++++++++++++++++ src/hypervisor/domain_driver.h | 6 ++++ src/libvirt_private.syms | 2 ++ src/qemu/qemu_driver.c | 60 +++---------------------------- 4 files changed, 76 insertions(+), 56 deletions(-) diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c index 2969d55173..3eb2401053 100644 --- a/src/hypervisor/domain_driver.c +++ b/src/hypervisor/domain_driver.c @@ -512,3 +512,67 @@ virDomainDriverNodeDeviceDetachFlags(virNodeDevicePtr dev, return virHostdevPCINodeDeviceDetach(hostdevMgr, pci); } + +/** + * virDomainDriverAddIOThreadCheck: + * @def: domain definition + * @iothread_id: iothread id + * + * Returns -1 if an IOThread is already using the given iothread id + */ +int +virDomainDriverAddIOThreadCheck(virDomainDef *def, + unsigned int iothread_id) +{ + if (virDomainIOThreadIDFind(def, iothread_id)) { + virReportError(VIR_ERR_INVALID_ARG, + _("an IOThread is already using iothread_id '%u'"), + iothread_id); + return -1; + } + + return 0; +} + +/** + * virDomainDriverDelIOThreadCheck: + * @def: domain definition + * @iothread_id: iothread id + * + * Returns -1 if there is no IOThread using the given iothread id + */ +int +virDomainDriverDelIOThreadCheck(virDomainDef *def, + unsigned int iothread_id) +{ + size_t i; + + if (!virDomainIOThreadIDFind(def, iothread_id)) { + virReportError(VIR_ERR_INVALID_ARG, + _("cannot find IOThread '%u' in iothreadids list"), + iothread_id); + return -1; + } + + 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); + return -1; + } + } + + 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); + return -1; + } + } + + return 0; +} diff --git a/src/hypervisor/domain_driver.h b/src/hypervisor/domain_driver.h index 5970eef082..d91d21bc91 100644 --- a/src/hypervisor/domain_driver.h +++ b/src/hypervisor/domain_driver.h @@ -60,3 +60,9 @@ int virDomainDriverNodeDeviceReAttach(virNodeDevicePtr dev, int virDomainDriverNodeDeviceDetachFlags(virNodeDevicePtr dev, virHostdevManager *hostdevMgr, const char *driverName); + +int virDomainDriverAddIOThreadCheck(virDomainDef *def, + unsigned int iothread_id); + +int virDomainDriverDelIOThreadCheck(virDomainDef *def, + unsigned int iothread_id); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 51a400ba59..d74f43da73 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1533,6 +1533,8 @@ virDomainCgroupSetupMemtune; # hypervisor/domain_driver.h +virDomainDriverAddIOThreadCheck; +virDomainDriverDelIOThreadCheck; virDomainDriverGenerateMachineName; virDomainDriverGenerateRootHash; virDomainDriverMergeBlkioDevice; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index a7d76dd00f..908ad61785 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -5477,58 +5477,6 @@ qemuDomainHotplugDelIOThread(virQEMUDriver *driver, } -static int -qemuDomainAddIOThreadCheck(virDomainDef *def, - unsigned int iothread_id) -{ - if (virDomainIOThreadIDFind(def, iothread_id)) { - virReportError(VIR_ERR_INVALID_ARG, - _("an IOThread is already using iothread_id '%u'"), - iothread_id); - return -1; - } - - return 0; -} - - -static int -qemuDomainDelIOThreadCheck(virDomainDef *def, - unsigned int iothread_id) -{ - size_t i; - - if (!virDomainIOThreadIDFind(def, iothread_id)) { - virReportError(VIR_ERR_INVALID_ARG, - _("cannot find IOThread '%u' in iothreadids list"), - iothread_id); - return -1; - } - - 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); - return -1; - } - } - - 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); - return -1; - } - } - - return 0; -} - - /** * @params: Pointer to params list * @nparams: Number of params to be parsed @@ -5662,7 +5610,7 @@ qemuDomainChgIOThread(virQEMUDriver *driver, switch (action) { case VIR_DOMAIN_IOTHREAD_ACTION_ADD: - if (qemuDomainAddIOThreadCheck(def, iothread.iothread_id) < 0) + if (virDomainDriverAddIOThreadCheck(def, iothread.iothread_id) < 0) goto endjob; if (qemuDomainHotplugAddIOThread(driver, vm, iothread.iothread_id) < 0) @@ -5671,7 +5619,7 @@ qemuDomainChgIOThread(virQEMUDriver *driver, break; case VIR_DOMAIN_IOTHREAD_ACTION_DEL: - if (qemuDomainDelIOThreadCheck(def, iothread.iothread_id) < 0) + if (virDomainDriverDelIOThreadCheck(def, iothread.iothread_id) < 0) goto endjob; if (qemuDomainHotplugDelIOThread(driver, vm, iothread.iothread_id) < 0) @@ -5701,7 +5649,7 @@ qemuDomainChgIOThread(virQEMUDriver *driver, if (persistentDef) { switch (action) { case VIR_DOMAIN_IOTHREAD_ACTION_ADD: - if (qemuDomainAddIOThreadCheck(persistentDef, iothread.iothread_id) < 0) + if (virDomainDriverAddIOThreadCheck(persistentDef, iothread.iothread_id) < 0) goto endjob; if (!virDomainIOThreadIDAdd(persistentDef, iothread.iothread_id)) @@ -5710,7 +5658,7 @@ qemuDomainChgIOThread(virQEMUDriver *driver, break; case VIR_DOMAIN_IOTHREAD_ACTION_DEL: - if (qemuDomainDelIOThreadCheck(persistentDef, iothread.iothread_id) < 0) + if (virDomainDriverDelIOThreadCheck(persistentDef, iothread.iothread_id) < 0) goto endjob; virDomainIOThreadIDDel(persistentDef, iothread.iothread_id); -- 2.32.0

Introduce testIOThreadInfo to store IOThread infos: iothread_id, poll_max_ns, poll_grow and poll_shrink for future usage. Add an example of IOThread configuration to testdomfc4.xml, we also want to generate default testIOThreadInfo for the IOThread configured in the xml, so introduce testDomainGenerateIOThreadInfos, the values are taken from QEMU. Signed-off-by: Luke Yue <lukedyue@gmail.com> --- examples/xml/test/testdomfc4.xml | 5 +++++ src/test/test_driver.c | 37 ++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/examples/xml/test/testdomfc4.xml b/examples/xml/test/testdomfc4.xml index 26b7f25a06..cb4dd0cf70 100644 --- a/examples/xml/test/testdomfc4.xml +++ b/examples/xml/test/testdomfc4.xml @@ -11,6 +11,11 @@ <memory>261072</memory> <currentMemory>131072</currentMemory> <vcpu>1</vcpu> + <iothreads>2</iothreads> + <iothreadids> + <iothread id="2"/> + <iothread id="4"/> + </iothreadids> <devices> <disk type='file'> <source file='/u/fc4.img'/> diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 7c3bb70be3..5c875ae7ee 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -182,6 +182,14 @@ struct _testDomainNamespaceDef { xmlNodePtr *snap_nodes; }; +typedef struct _testIOThreadInfo testIOThreadInfo; +struct _testIOThreadInfo { + unsigned int iothread_id; + unsigned long long poll_max_ns; + unsigned int poll_grow; + unsigned int poll_shrink; +}; + static void testDomainDefNamespaceFree(void *data) { @@ -380,6 +388,9 @@ struct _testDomainObjPrivate { /* used by get/set time APIs */ long long seconds; unsigned int nseconds; + + /* used by IOThread APIs */ + GArray *iothreads; }; @@ -396,6 +407,8 @@ testDomainObjPrivateAlloc(void *opaque) priv->seconds = 627319920; priv->nseconds = 0; + priv->iothreads = g_array_new(FALSE, FALSE, sizeof(testIOThreadInfo)); + return priv; } @@ -426,6 +439,8 @@ static void testDomainObjPrivateFree(void *data) { testDomainObjPrivate *priv = data; + + g_array_free(priv->iothreads, TRUE); g_free(priv); } @@ -695,6 +710,26 @@ testDomainGenerateIfnames(virDomainDef *domdef) return 0; } +static void +testDomainGenerateIOThreadInfos(virDomainObj *obj) +{ + size_t i; + testDomainObjPrivate *priv; + + if (!obj->def->iothreadids || !obj->def->niothreadids) + return; + + priv = obj->privateData; + + for (i = 0; i < obj->def->niothreadids; i++) { + testIOThreadInfo iothread; + iothread.iothread_id = obj->def->iothreadids[i]->iothread_id; + iothread.poll_max_ns = 32768; + iothread.poll_grow = 0; + iothread.poll_shrink = 0; + g_array_append_val(priv->iothreads, iothread); + } +} static void testDomainShutdownState(virDomainPtr domain, @@ -1045,6 +1080,8 @@ testParseDomains(testDriver *privconn, testDomainObjCheckTaint(obj); + testDomainGenerateIOThreadInfos(obj); + virDomainObjEndAPI(&obj); } -- 2.32.0

Introduce testDomainChgIOThread at the same time Signed-off-by: Luke Yue <lukedyue@gmail.com> --- src/test/meson.build | 1 + src/test/test_driver.c | 77 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/src/test/meson.build b/src/test/meson.build index f54585adfd..c0174ad856 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -17,6 +17,7 @@ if conf.has('WITH_TEST') ], include_directories: [ conf_inc_dir, + hypervisor_inc_dir, ], ) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 5c875ae7ee..f3e3745442 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -40,6 +40,7 @@ #include "interface_conf.h" #include "checkpoint_conf.h" #include "domain_conf.h" +#include "domain_driver.h" #include "domain_event.h" #include "network_event.h" #include "snapshot_conf.h" @@ -9489,6 +9490,81 @@ testDomainGetMessages(virDomainPtr dom, return rv; } +typedef enum { + VIR_DOMAIN_IOTHREAD_ACTION_ADD, +} virDomainIOThreadAction; + +static int +testDomainChgIOThread(virDomainObj *vm, + unsigned int iothread_id, + virDomainIOThreadAction action, + unsigned int flags) +{ + virDomainDef *def; + int ret = -1; + + if (!(def = virDomainObjGetOneDef(vm, flags))) + return ret; + + if (def) { + switch (action) { + case VIR_DOMAIN_IOTHREAD_ACTION_ADD: + if (virDomainDriverAddIOThreadCheck(def, iothread_id) < 0) + return ret; + + if (!virDomainIOThreadIDAdd(def, iothread_id)) + return ret; + + break; + } + } + + ret = 0; + + return ret; +} + +static int +testDomainAddIOThread(virDomainPtr dom, + unsigned int iothread_id, + unsigned int flags) +{ + virDomainObj *vm = NULL; + testDomainObjPrivate *priv; + testIOThreadInfo iothread; + 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 (testDomainChgIOThread(vm, iothread_id, + VIR_DOMAIN_IOTHREAD_ACTION_ADD, flags) < 0) + goto cleanup; + + priv = vm->privateData; + + iothread.iothread_id = iothread_id; + iothread.poll_max_ns = 32768; + iothread.poll_grow = 0; + iothread.poll_shrink = 0; + + g_array_append_val(priv->iothreads, iothread); + + ret = 0; + + cleanup: + virDomainObjEndAPI(&vm); + return ret; +} /* * Test driver */ @@ -9555,6 +9631,7 @@ static virHypervisorDriver testHypervisorDriver = { .domainGetVcpus = testDomainGetVcpus, /* 0.7.3 */ .domainGetVcpuPinInfo = testDomainGetVcpuPinInfo, /* 1.2.18 */ .domainGetMaxVcpus = testDomainGetMaxVcpus, /* 0.7.3 */ + .domainAddIOThread = testDomainAddIOThread, /* 7.7.0 */ .domainGetSecurityLabel = testDomainGetSecurityLabel, /* 7.5.0 */ .nodeGetSecurityModel = testNodeGetSecurityModel, /* 7.5.0 */ .domainGetXMLDesc = testDomainGetXMLDesc, /* 0.1.4 */ -- 2.32.0

Signed-off-by: Luke Yue <lukedyue@gmail.com> --- src/test/test_driver.c | 55 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index f3e3745442..2813320939 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -9492,6 +9492,7 @@ testDomainGetMessages(virDomainPtr dom, typedef enum { VIR_DOMAIN_IOTHREAD_ACTION_ADD, + VIR_DOMAIN_IOTHREAD_ACTION_DEL, } virDomainIOThreadAction; static int @@ -9516,6 +9517,14 @@ testDomainChgIOThread(virDomainObj *vm, return ret; break; + + case VIR_DOMAIN_IOTHREAD_ACTION_DEL: + if (virDomainDriverDelIOThreadCheck(def, iothread_id) < 0) + return ret; + + virDomainIOThreadIDDel(def, iothread_id); + + break; } } @@ -9565,6 +9574,51 @@ testDomainAddIOThread(virDomainPtr dom, virDomainObjEndAPI(&vm); return ret; } + +static int +testDomainDelIOThread(virDomainPtr dom, + unsigned int iothread_id, + unsigned int flags) +{ + virDomainObj *vm = NULL; + testDomainObjPrivate *priv; + 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 (testDomainChgIOThread(vm, iothread_id, + VIR_DOMAIN_IOTHREAD_ACTION_DEL, flags) < 0) + goto cleanup; + + priv = vm->privateData; + + for (i = 0; i < priv->iothreads->len; i++) { + testIOThreadInfo iothread = g_array_index(priv->iothreads, + testIOThreadInfo, i); + if (iothread.iothread_id == iothread_id) { + g_array_remove_index(priv->iothreads, i); + break; + } + } + + ret = 0; + + cleanup: + virDomainObjEndAPI(&vm); + return ret; +} + /* * Test driver */ @@ -9632,6 +9686,7 @@ static virHypervisorDriver testHypervisorDriver = { .domainGetVcpuPinInfo = testDomainGetVcpuPinInfo, /* 1.2.18 */ .domainGetMaxVcpus = testDomainGetMaxVcpus, /* 0.7.3 */ .domainAddIOThread = testDomainAddIOThread, /* 7.7.0 */ + .domainDelIOThread = testDomainDelIOThread, /* 7.7.0 */ .domainGetSecurityLabel = testDomainGetSecurityLabel, /* 7.5.0 */ .nodeGetSecurityModel = testNodeGetSecurityModel, /* 7.5.0 */ .domainGetXMLDesc = testDomainGetXMLDesc, /* 0.1.4 */ -- 2.32.0

The test driver can share the same code with qemu driver when implement testDomainGetIOThreadsConfig, so extract it for test driver to use. Signed-off-by: Luke Yue <lukedyue@gmail.com> --- src/hypervisor/domain_driver.c | 68 ++++++++++++++++++++++++++++++++++ src/hypervisor/domain_driver.h | 4 ++ src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 53 +------------------------- 4 files changed, 74 insertions(+), 52 deletions(-) diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c index 3eb2401053..31737b0f4a 100644 --- a/src/hypervisor/domain_driver.c +++ b/src/hypervisor/domain_driver.c @@ -576,3 +576,71 @@ virDomainDriverDelIOThreadCheck(virDomainDef *def, return 0; } + +/** + * virDomainDriverGetIOThreadsConfig: + * @targetDef: domain definition + * @info: information about the IOThread in a domain + * @bitmap_size: generate bitmap with bitmap_size, 0 for getting the size + * from host + * + * Returns the number of IOThreads in the given domain or -1 in case of error + */ +int +virDomainDriverGetIOThreadsConfig(virDomainDef *targetDef, + virDomainIOThreadInfoPtr **info, + unsigned int bitmap_size) +{ + virDomainIOThreadInfoPtr *info_ret = NULL; + virBitmap *bitmap = NULL; + virBitmap *cpumask = NULL; + size_t i; + int ret = -1; + + if (targetDef->niothreadids == 0) + return 0; + + info_ret = g_new0(virDomainIOThreadInfoPtr, targetDef->niothreadids); + + for (i = 0; i < targetDef->niothreadids; i++) { + info_ret[i] = g_new0(virDomainIOThreadInfo, 1); + + /* IOThread ID's are taken from the iothreadids list */ + info_ret[i]->iothread_id = targetDef->iothreadids[i]->iothread_id; + + cpumask = targetDef->iothreadids[i]->cpumask; + if (!cpumask) { + if (targetDef->cpumask) { + cpumask = targetDef->cpumask; + } else { + if (bitmap_size) { + if (!(bitmap = virBitmapNew(bitmap_size))) + goto cleanup; + virBitmapSetAll(bitmap); + } else { + if (!(bitmap = virHostCPUGetAvailableCPUsBitmap())) + goto cleanup; + } + cpumask = bitmap; + } + } + if (virBitmapToData(cpumask, &info_ret[i]->cpumap, + &info_ret[i]->cpumaplen) < 0) + goto cleanup; + virBitmapFree(bitmap); + bitmap = NULL; + } + + *info = g_steal_pointer(&info_ret); + ret = targetDef->niothreadids; + + cleanup: + if (info_ret) { + for (i = 0; i < targetDef->niothreadids; i++) + virDomainIOThreadInfoFree(info_ret[i]); + VIR_FREE(info_ret); + } + virBitmapFree(bitmap); + + return ret; +} diff --git a/src/hypervisor/domain_driver.h b/src/hypervisor/domain_driver.h index d91d21bc91..7b0fbae2fd 100644 --- a/src/hypervisor/domain_driver.h +++ b/src/hypervisor/domain_driver.h @@ -66,3 +66,7 @@ int virDomainDriverAddIOThreadCheck(virDomainDef *def, int virDomainDriverDelIOThreadCheck(virDomainDef *def, unsigned int iothread_id); + +int virDomainDriverGetIOThreadsConfig(virDomainDef *targetDef, + virDomainIOThreadInfoPtr **info, + unsigned int bitmap_size); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index d74f43da73..ea76b6bdc9 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1537,6 +1537,7 @@ virDomainDriverAddIOThreadCheck; virDomainDriverDelIOThreadCheck; virDomainDriverGenerateMachineName; virDomainDriverGenerateRootHash; +virDomainDriverGetIOThreadsConfig; virDomainDriverMergeBlkioDevice; virDomainDriverNodeDeviceDetachFlags; virDomainDriverNodeDeviceGetPCIInfo; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 908ad61785..43c9e5cc56 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -5079,57 +5079,6 @@ qemuDomainGetIOThreadsLive(virQEMUDriver *driver, return ret; } -static int -qemuDomainGetIOThreadsConfig(virDomainDef *targetDef, - virDomainIOThreadInfoPtr **info) -{ - virDomainIOThreadInfoPtr *info_ret = NULL; - virBitmap *bitmap = NULL; - virBitmap *cpumask = NULL; - size_t i; - int ret = -1; - - if (targetDef->niothreadids == 0) - return 0; - - info_ret = g_new0(virDomainIOThreadInfoPtr, targetDef->niothreadids); - - for (i = 0; i < targetDef->niothreadids; i++) { - info_ret[i] = g_new0(virDomainIOThreadInfo, 1); - - /* IOThread ID's are taken from the iothreadids list */ - info_ret[i]->iothread_id = targetDef->iothreadids[i]->iothread_id; - - cpumask = targetDef->iothreadids[i]->cpumask; - if (!cpumask) { - if (targetDef->cpumask) { - cpumask = targetDef->cpumask; - } else { - if (!(bitmap = virHostCPUGetAvailableCPUsBitmap())) - goto cleanup; - cpumask = bitmap; - } - } - if (virBitmapToData(cpumask, &info_ret[i]->cpumap, - &info_ret[i]->cpumaplen) < 0) - goto cleanup; - virBitmapFree(bitmap); - bitmap = NULL; - } - - *info = g_steal_pointer(&info_ret); - ret = targetDef->niothreadids; - - cleanup: - if (info_ret) { - for (i = 0; i < targetDef->niothreadids; i++) - virDomainIOThreadInfoFree(info_ret[i]); - VIR_FREE(info_ret); - } - virBitmapFree(bitmap); - - return ret; -} static int qemuDomainGetIOThreadInfo(virDomainPtr dom, @@ -5156,7 +5105,7 @@ qemuDomainGetIOThreadInfo(virDomainPtr dom, if (!targetDef) ret = qemuDomainGetIOThreadsLive(driver, vm, info); else - ret = qemuDomainGetIOThreadsConfig(targetDef, info); + ret = virDomainDriverGetIOThreadsConfig(targetDef, info, 0); cleanup: virDomainObjEndAPI(&vm); -- 2.32.0

Signed-off-by: Luke Yue <lukedyue@gmail.com> --- src/test/test_driver.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 2813320939..67337879ef 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -9490,6 +9490,34 @@ testDomainGetMessages(virDomainPtr dom, return rv; } +static int +testDomainGetIOThreadInfo(virDomainPtr dom, + virDomainIOThreadInfoPtr **info, + unsigned int flags) +{ + virDomainObj *vm; + virDomainDef *targetDef = NULL; + unsigned int bitmap_size = 0; + int ret = -1; + + virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | + VIR_DOMAIN_AFFECT_CONFIG, -1); + + if (!(vm = testDomObjFromDomain(dom))) + goto cleanup; + + if (!(targetDef = virDomainObjGetOneDef(vm, flags))) + goto cleanup; + + bitmap_size = virDomainDefGetVcpus(targetDef); + + ret = virDomainDriverGetIOThreadsConfig(targetDef, info, bitmap_size); + + cleanup: + virDomainObjEndAPI(&vm); + return ret; +} + typedef enum { VIR_DOMAIN_IOTHREAD_ACTION_ADD, VIR_DOMAIN_IOTHREAD_ACTION_DEL, @@ -9685,6 +9713,7 @@ static virHypervisorDriver testHypervisorDriver = { .domainGetVcpus = testDomainGetVcpus, /* 0.7.3 */ .domainGetVcpuPinInfo = testDomainGetVcpuPinInfo, /* 1.2.18 */ .domainGetMaxVcpus = testDomainGetMaxVcpus, /* 0.7.3 */ + .domainGetIOThreadInfo = testDomainGetIOThreadInfo, /* 7.7.0 */ .domainAddIOThread = testDomainAddIOThread, /* 7.7.0 */ .domainDelIOThread = testDomainDelIOThread, /* 7.7.0 */ .domainGetSecurityLabel = testDomainGetSecurityLabel, /* 7.5.0 */ -- 2.32.0

Signed-off-by: Luke Yue <lukedyue@gmail.com> --- src/test/test_driver.c | 50 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 67337879ef..385c8b3ad3 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -9647,6 +9647,55 @@ testDomainDelIOThread(virDomainPtr dom, return ret; } +static int +testDomainPinIOThread(virDomainPtr dom, + unsigned int iothread_id, + unsigned char *cpumap, + int maplen, + unsigned int flags) +{ + int ret = -1; + virDomainObj *vm; + virDomainDef *def; + virDomainIOThreadIDDef *iothrid; + virBitmap *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 = g_steal_pointer(&cpumask); + iothrid->autofill = false; + + ret = 0; + + cleanup: + virBitmapFree(cpumask); + virDomainObjEndAPI(&vm); + return ret; +} + /* * Test driver */ @@ -9716,6 +9765,7 @@ static virHypervisorDriver testHypervisorDriver = { .domainGetIOThreadInfo = testDomainGetIOThreadInfo, /* 7.7.0 */ .domainAddIOThread = testDomainAddIOThread, /* 7.7.0 */ .domainDelIOThread = testDomainDelIOThread, /* 7.7.0 */ + .domainPinIOThread = testDomainPinIOThread, /* 7.7.0 */ .domainGetSecurityLabel = testDomainGetSecurityLabel, /* 7.5.0 */ .nodeGetSecurityModel = testNodeGetSecurityModel, /* 7.5.0 */ .domainGetXMLDesc = testDomainGetXMLDesc, /* 0.1.4 */ -- 2.32.0

Signed-off-by: Luke Yue <lukedyue@gmail.com> --- src/test/test_driver.c | 90 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 385c8b3ad3..1d439a89b6 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -9521,6 +9521,7 @@ testDomainGetIOThreadInfo(virDomainPtr dom, typedef enum { VIR_DOMAIN_IOTHREAD_ACTION_ADD, VIR_DOMAIN_IOTHREAD_ACTION_DEL, + VIR_DOMAIN_IOTHREAD_ACTION_MOD, } virDomainIOThreadAction; static int @@ -9552,6 +9553,16 @@ testDomainChgIOThread(virDomainObj *vm, virDomainIOThreadIDDel(def, iothread_id); + break; + + case VIR_DOMAIN_IOTHREAD_ACTION_MOD: + if (!(virDomainIOThreadIDFind(def, iothread_id))) { + virReportError(VIR_ERR_INVALID_ARG, + _("cannot find IOThread '%u' in iothreadids"), + iothread_id); + return ret; + } + break; } } @@ -9696,6 +9707,84 @@ testDomainPinIOThread(virDomainPtr dom, return ret; } +static int +testDomainIOThreadParseParams(virTypedParameterPtr params, + int nparams, + testIOThreadInfo *iothread) +{ + 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) + return -1; + + if (virTypedParamsGetULLong(params, nparams, + VIR_DOMAIN_IOTHREAD_POLL_MAX_NS, + &iothread->poll_max_ns) < 0) + return -1; + + if (virTypedParamsGetUInt(params, nparams, + VIR_DOMAIN_IOTHREAD_POLL_GROW, + &iothread->poll_grow) < 0) + return -1; + + if (virTypedParamsGetUInt(params, nparams, + VIR_DOMAIN_IOTHREAD_POLL_SHRINK, + &iothread->poll_shrink) < 0) + return -1; + + return 0; +} + +static int +testDomainSetIOThreadParams(virDomainPtr dom, + unsigned int iothread_id, + virTypedParameterPtr params, + int nparams, + unsigned int flags) +{ + virDomainObj *vm = NULL; + testDomainObjPrivate *priv; + size_t i; + int ret = -1; + + virCheckFlags(VIR_DOMAIN_AFFECT_LIVE, -1); + + if (iothread_id == 0) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("invalid value of 0 for iothread_id")); + goto cleanup; + } + + if (!(vm = testDomObjFromDomain(dom))) + goto cleanup; + + if (testDomainChgIOThread(vm, iothread_id, + VIR_DOMAIN_IOTHREAD_ACTION_MOD, flags) < 0) + goto cleanup; + + priv = vm->privateData; + + for (i = 0; i < priv->iothreads->len; i++) { + testIOThreadInfo *iothread = &g_array_index(priv->iothreads, + testIOThreadInfo, i); + if (iothread->iothread_id == iothread_id) { + if (testDomainIOThreadParseParams(params, nparams, iothread) < 0) + goto cleanup; + ret = 0; + break; + } + } + + cleanup: + virDomainObjEndAPI(&vm); + return ret; +} + /* * Test driver */ @@ -9766,6 +9855,7 @@ static virHypervisorDriver testHypervisorDriver = { .domainAddIOThread = testDomainAddIOThread, /* 7.7.0 */ .domainDelIOThread = testDomainDelIOThread, /* 7.7.0 */ .domainPinIOThread = testDomainPinIOThread, /* 7.7.0 */ + .domainSetIOThreadParams = testDomainSetIOThreadParams, /* 7.7.0 */ .domainGetSecurityLabel = testDomainGetSecurityLabel, /* 7.5.0 */ .nodeGetSecurityModel = testNodeGetSecurityModel, /* 7.5.0 */ .domainGetXMLDesc = testDomainGetXMLDesc, /* 0.1.4 */ -- 2.32.0

Implement virConnectGetAllDomainStats in a modular way just like QEMU driver, though remove some params in GetStatsWorker that we don't need in test driver currently. Only add the worker to get state so far, more worker will be added in the future. Signed-off-by: Luke Yue <lukedyue@gmail.com> --- src/test/test_driver.c | 135 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 1d439a89b6..6eebd85cf3 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -9785,6 +9785,140 @@ testDomainSetIOThreadParams(virDomainPtr dom, return ret; } +static int +testDomainGetStatsState(virDomainObj *dom, + virTypedParamList *params) +{ + if (virTypedParamListAddInt(params, dom->state.state, "state.state") < 0) + return -1; + + if (virTypedParamListAddInt(params, dom->state.reason, "state.reason") < 0) + return -1; + + return 0; +} + +typedef int +(*testDomainGetStatsFunc)(virDomainObj *dom, + virTypedParamList *list); + +struct testDomainGetStatsWorker { + testDomainGetStatsFunc func; + unsigned int stats; +}; + +static struct testDomainGetStatsWorker testDomainGetStatsWorkers[] = { + { testDomainGetStatsState, VIR_DOMAIN_STATS_STATE }, + { NULL, 0 } +}; + +static int +testDomainGetStats(virConnectPtr conn, + virDomainObj *dom, + unsigned int stats, + virDomainStatsRecordPtr *record) +{ + g_autofree virDomainStatsRecordPtr tmp = NULL; + g_autoptr(virTypedParamList) params = NULL; + size_t i; + + params = g_new0(virTypedParamList, 1); + + for (i = 0; testDomainGetStatsWorkers[i].func; i++) { + if (stats & testDomainGetStatsWorkers[i].stats) { + if (testDomainGetStatsWorkers[i].func(dom, params) < 0) + return -1; + } + } + + tmp = g_new0(virDomainStatsRecord, 1); + + if (!(tmp->dom = virGetDomain(conn, dom->def->name, + dom->def->uuid, dom->def->id))) + return -1; + + tmp->nparams = virTypedParamListStealParams(params, &tmp->params); + *record = g_steal_pointer(&tmp); + return 0; +} + +static int +testConnectGetAllDomainStats(virConnectPtr conn, + virDomainPtr *doms, + unsigned int ndoms, + unsigned int stats, + virDomainStatsRecordPtr **retStats, + unsigned int flags) +{ + testDriver *driver = conn->privateData; + unsigned int lflags = flags & (VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE | + VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT | + VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE); + + unsigned int supported = VIR_DOMAIN_STATS_STATE; + virDomainObj **vms = NULL; + size_t nvms; + virDomainStatsRecordPtr *tmpstats = NULL; + int nstats = 0; + int ret = -1; + size_t i; + + virCheckFlags(VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE | + VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT | + VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE | + VIR_CONNECT_GET_ALL_DOMAINS_STATS_NOWAIT | + VIR_CONNECT_GET_ALL_DOMAINS_STATS_BACKING | + VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS, -1); + + if (!stats) { + stats = supported; + } else if ((flags & VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS) && + (stats & ~supported)) { + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, + _("Stats types bits 0x%x are not supported by this daemon"), + stats & ~supported); + return -1; + } + + if (ndoms) { + if (virDomainObjListConvert(driver->domains, conn, doms, ndoms, &vms, + &nvms, NULL, lflags, true) < 0) + return -1; + } else { + if (virDomainObjListCollect(driver->domains, conn, &vms, &nvms, + NULL, lflags) < 0) + return -1; + } + + tmpstats = g_new0(virDomainStatsRecordPtr, nvms + 1); + + for (i = 0; i < nvms; i++) { + virDomainStatsRecordPtr tmp = NULL; + virDomainObj *vm = vms[i]; + + virObjectLock(vm); + + if ((testDomainGetStats(conn, vm, stats, &tmp)) < 0) + goto cleanup; + + virObjectUnlock(vm); + + if (!tmp) + goto cleanup; + + tmpstats[nstats++] = tmp; + } + + *retStats = g_steal_pointer(&tmpstats); + ret = nstats; + + cleanup: + virDomainStatsRecordListFree(tmpstats); + virObjectListFreeCount(vms, nvms); + + return ret; +} + /* * Test driver */ @@ -9799,6 +9933,7 @@ static virHypervisorDriver testHypervisorDriver = { .nodeGetCPUStats = testNodeGetCPUStats, /* 2.3.0 */ .nodeGetFreeMemory = testNodeGetFreeMemory, /* 2.3.0 */ .nodeGetFreePages = testNodeGetFreePages, /* 2.3.0 */ + .connectGetAllDomainStats = testConnectGetAllDomainStats, /* 7.7.0 */ .connectGetCapabilities = testConnectGetCapabilities, /* 0.2.1 */ .connectGetSysinfo = testConnectGetSysinfo, /* 2.3.0 */ .connectGetType = testConnectGetType, /* 2.3.0 */ -- 2.32.0

On Thu, 2021-08-12 at 18:50 +0800, Luke Yue wrote:
Implement virConnectGetAllDomainStats in a modular way just like QEMU driver, though remove some params in GetStatsWorker that we don't need in test driver currently.
Only add the worker to get state so far, more worker will be added in the future.
Signed-off-by: Luke Yue <lukedyue@gmail.com> --- src/test/test_driver.c | 135 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+)
diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 1d439a89b6..6eebd85cf3 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -9785,6 +9785,140 @@ testDomainSetIOThreadParams(virDomainPtr dom, return ret; } +static int +testDomainGetStatsState(virDomainObj *dom, + virTypedParamList *params) +{ + if (virTypedParamListAddInt(params, dom->state.state, "state.state") < 0) + return -1; + + if (virTypedParamListAddInt(params, dom->state.reason, "state.reason") < 0) + return -1; + + return 0; +} + +typedef int +(*testDomainGetStatsFunc)(virDomainObj *dom, + virTypedParamList *list); + +struct testDomainGetStatsWorker { + testDomainGetStatsFunc func; + unsigned int stats; +}; + +static struct testDomainGetStatsWorker testDomainGetStatsWorkers[] = { + { testDomainGetStatsState, VIR_DOMAIN_STATS_STATE }, + { NULL, 0 } +}; + +static int +testDomainGetStats(virConnectPtr conn, + virDomainObj *dom, + unsigned int stats, + virDomainStatsRecordPtr *record) +{ + g_autofree virDomainStatsRecordPtr tmp = NULL; + g_autoptr(virTypedParamList) params = NULL; + size_t i; + + params = g_new0(virTypedParamList, 1); + + for (i = 0; testDomainGetStatsWorkers[i].func; i++) { + if (stats & testDomainGetStatsWorkers[i].stats) { + if (testDomainGetStatsWorkers[i].func(dom, params) < 0) + return -1; + } + } + + tmp = g_new0(virDomainStatsRecord, 1); + + if (!(tmp->dom = virGetDomain(conn, dom->def->name, + dom->def->uuid, dom->def->id))) + return -1; + + tmp->nparams = virTypedParamListStealParams(params, &tmp->params); + *record = g_steal_pointer(&tmp); + return 0; +} + +static int +testConnectGetAllDomainStats(virConnectPtr conn, + virDomainPtr *doms, + unsigned int ndoms, + unsigned int stats, + virDomainStatsRecordPtr **retStats, + unsigned int flags) +{ + testDriver *driver = conn->privateData; + unsigned int lflags = flags & (VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE | + VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT | + VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE); + + unsigned int supported = VIR_DOMAIN_STATS_STATE; + virDomainObj **vms = NULL; + size_t nvms; + virDomainStatsRecordPtr *tmpstats = NULL; + int nstats = 0; + int ret = -1; + size_t i; + + virCheckFlags(VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE | + VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT | + VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE | + VIR_CONNECT_GET_ALL_DOMAINS_STATS_NOWAIT | + VIR_CONNECT_GET_ALL_DOMAINS_STATS_BACKING | + VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS, - 1); + + if (!stats) { + stats = supported; + } else if ((flags & VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS) && + (stats & ~supported)) { + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, + _("Stats types bits 0x%x are not supported by this daemon"), + stats & ~supported); + return -1; + } + + if (ndoms) { + if (virDomainObjListConvert(driver->domains, conn, doms, ndoms, &vms, + &nvms, NULL, lflags, true) < 0) + return -1; + } else { + if (virDomainObjListCollect(driver->domains, conn, &vms, &nvms, + NULL, lflags) < 0) + return -1; + } + + tmpstats = g_new0(virDomainStatsRecordPtr, nvms + 1); + + for (i = 0; i < nvms; i++) { + virDomainStatsRecordPtr tmp = NULL; + virDomainObj *vm = vms[i]; + + virObjectLock(vm); + + if ((testDomainGetStats(conn, vm, stats, &tmp)) < 0) + goto cleanup; + + virObjectUnlock(vm); +
I am sorry but I just realized that it should be if ((testDomainGetStats(conn, vm, stats, &tmp)) < 0) { virObjectUnlock(vm); goto cleanup; } virObjectUnlock(vm); here, I will fix this in v4. Thanks, Luke
+ if (!tmp) + goto cleanup; + + tmpstats[nstats++] = tmp; + } + + *retStats = g_steal_pointer(&tmpstats); + ret = nstats; + + cleanup: + virDomainStatsRecordListFree(tmpstats); + virObjectListFreeCount(vms, nvms); + + return ret; +} + /* * Test driver */ @@ -9799,6 +9933,7 @@ static virHypervisorDriver testHypervisorDriver = { .nodeGetCPUStats = testNodeGetCPUStats, /* 2.3.0 */ .nodeGetFreeMemory = testNodeGetFreeMemory, /* 2.3.0 */ .nodeGetFreePages = testNodeGetFreePages, /* 2.3.0 */ + .connectGetAllDomainStats = testConnectGetAllDomainStats, /* 7.7.0 */ .connectGetCapabilities = testConnectGetCapabilities, /* 0.2.1 */ .connectGetSysinfo = testConnectGetSysinfo, /* 2.3.0 */ .connectGetType = testConnectGetType, /* 2.3.0 */

Introduce testDomainGetStatsIOThread to add support for testConnectGetAllDomainStats to get IOThread infos. Signed-off-by: Luke Yue <lukedyue@gmail.com> --- src/test/test_driver.c | 44 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 6eebd85cf3..3c4015a67d 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -9798,6 +9798,46 @@ testDomainGetStatsState(virDomainObj *dom, return 0; } +static int +testDomainGetStatsIOThread(virDomainObj *dom, + virTypedParamList *params) +{ + testDomainObjPrivate *priv = dom->privateData; + size_t i; + int niothreads = 0; + + if (!virDomainObjIsActive(dom)) + return 0; + + niothreads = priv->iothreads->len; + + if (niothreads == 0) { + return 0; + } + + if (virTypedParamListAddUInt(params, niothreads, "iothread.count") < 0) + return -1; + + for (i = 0; i < niothreads; i++) { + testIOThreadInfo iothread = g_array_index(priv->iothreads, + testIOThreadInfo, i); + if (virTypedParamListAddULLong(params, iothread.poll_max_ns, + "iothread.%u.poll-max-ns", + iothread.iothread_id) < 0) + return -1; + if (virTypedParamListAddUInt(params, iothread.poll_grow, + "iothread.%u.poll-grow", + iothread.iothread_id) < 0) + return -1; + if (virTypedParamListAddUInt(params, iothread.poll_shrink, + "iothread.%u.poll-shrink", + iothread.iothread_id) < 0) + return -1; + } + + return 0; +} + typedef int (*testDomainGetStatsFunc)(virDomainObj *dom, virTypedParamList *list); @@ -9809,6 +9849,7 @@ struct testDomainGetStatsWorker { static struct testDomainGetStatsWorker testDomainGetStatsWorkers[] = { { testDomainGetStatsState, VIR_DOMAIN_STATS_STATE }, + { testDomainGetStatsIOThread, VIR_DOMAIN_STATS_IOTHREAD }, { NULL, 0 } }; @@ -9855,7 +9896,8 @@ testConnectGetAllDomainStats(virConnectPtr conn, VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT | VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE); - unsigned int supported = VIR_DOMAIN_STATS_STATE; + unsigned int supported = VIR_DOMAIN_STATS_STATE | + VIR_DOMAIN_STATS_IOTHREAD; virDomainObj **vms = NULL; size_t nvms; virDomainStatsRecordPtr *tmpstats = NULL; -- 2.32.0

Signed-off-by: Luke Yue <lukedyue@gmail.com> --- tests/virshtest.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/tests/virshtest.c b/tests/virshtest.c index 53db2aa19a..e2d6ddd72b 100644 --- a/tests/virshtest.c +++ b/tests/virshtest.c @@ -30,6 +30,7 @@ main(void) tainted: custom device tree blob used\n\ tainted: use of deprecated configuration settings\n\ deprecated configuration: CPU model Deprecated-Test" +# define EQUAL "=" static const char *dominfo_fc4 = "\ Id: 2\n\ @@ -69,6 +70,17 @@ Security DOI: \n\ Security label: " SECURITY_LABEL "\n\ Messages: " FC5_MESSAGES "\n\ \n"; +static const char *domstats_fc4 = "\ +Domain: 'fc4'\n\ + state.state" EQUAL "1\n\ + state.reason" EQUAL "0\n\ + iothread.count" EQUAL "2\n\ + iothread.2.poll-max-ns" EQUAL "32768\n\ + iothread.2.poll-grow" EQUAL "0\n\ + iothread.2.poll-shrink" EQUAL "0\n\ + iothread.4.poll-max-ns" EQUAL "32768\n\ + iothread.4.poll-grow" EQUAL "0\n\ + iothread.4.poll-shrink" EQUAL "0\n\n"; static int testFilterLine(char *buffer, const char *toRemove) @@ -291,6 +303,60 @@ static int testCompareDomControlInfoByName(const void *data G_GNUC_UNUSED) return testCompareOutputLit(exp, NULL, argv); } +static int testIOThreadAdd(const void *data G_GNUC_UNUSED) +{ + const char *const argv[] = { VIRSH_CUSTOM, "iothreadadd", "--domain", + "fc4", "--id", "1", NULL}; + const char *exp = "\n"; + return testCompareOutputLit(exp, NULL, argv); +} + +static int testIOThreadDel(const void *data G_GNUC_UNUSED) +{ + const char *const argv[] = { VIRSH_CUSTOM, "iothreaddel", "--domain", + "fc4", "--id", "2", NULL}; + const char *exp = "\n"; + return testCompareOutputLit(exp, NULL, argv); +} + +static int testIOThreadInfo(const void *data G_GNUC_UNUSED) +{ + const char *const argv[] = { VIRSH_CUSTOM, "iothreadinfo", "--domain", + "fc4", NULL}; + const char *exp = "\ + IOThread ID CPU Affinity\n\ +-----------------------------\n\ + 2 0\n\ + 4 0\n\ +\n"; + return testCompareOutputLit(exp, NULL, argv); +} + +static int testIOThreadSet(const void *data G_GNUC_UNUSED) +{ + const char *const argv[] = { VIRSH_CUSTOM, "iothreadset", "--domain", + "fc4", "--id", "2", "--poll-max-ns", "100", + "--poll-shrink", "10", "--poll-grow", + "10", NULL}; + const char *exp = "\n"; + return testCompareOutputLit(exp, NULL, argv); +} + +static int testIOThreadPin(const void *data G_GNUC_UNUSED) +{ + const char *const argv[] = { VIRSH_CUSTOM, "iothreadpin", "fc4", + "--iothread", "2", "--cpulist", "0", NULL}; + const char *exp = "\n"; + return testCompareOutputLit(exp, NULL, argv); +} + +static int testDomStats(const void *data G_GNUC_UNUSED) +{ + const char *const argv[] = { VIRSH_CUSTOM, "domstats", "fc4", NULL }; + const char *exp = domstats_fc4; + return testCompareOutputLit(exp, NULL, argv); +} + struct testInfo { const char *const *argv; const char *result; @@ -383,6 +449,30 @@ mymain(void) testCompareDomControlInfoByName, NULL) != 0) ret = -1; + if (virTestRun("virsh iothreadadd", + testIOThreadAdd, NULL) != 0) + ret = -1; + + if (virTestRun("virsh iothreaddel", + testIOThreadDel, NULL) != 0) + ret = -1; + + if (virTestRun("virsh iothreadinfo", + testIOThreadInfo, NULL) != 0) + ret = -1; + + if (virTestRun("virsh iothreadset", + testIOThreadSet, NULL) != 0) + ret = -1; + + if (virTestRun("virsh iothreadpin", + testIOThreadPin, NULL) != 0) + ret = -1; + + if (virTestRun("virsh domstats (by name)", + testDomStats, NULL) != 0) + ret = -1; + /* It's a bit awkward listing result before argument, but that's a * limitation of C99 vararg macros. */ # define DO_TEST(i, result, ...) \ -- 2.32.0
participants (1)
-
Luke Yue