[PATCH 0/5] Implement some IOThread related APIs for test driver

- Implement virDomainAddIOThread - Implement virDomainDelIOThread - Implement virDomainGetIOThreadInfo - Add tests for these APIs Luke Yue (5): conf: domain: Introduce and use virDomainAddIOThreadCheck() test_driver: Implement virDomainAddIOThread and virDomainDelIOThread conf: domain: Introduce and use virDomainGetIOThreadsConfig() test_driver: Implement virDomainGetIOThreadInfo tests: Test IOThread related functions for test driver examples/xml/test/testdomfc4.xml | 4 + src/conf/domain_conf.c | 126 +++++++++++++++++++++ src/conf/domain_conf.h | 12 ++ src/libvirt_private.syms | 3 + src/qemu/qemu_driver.c | 113 +------------------ src/test/test_driver.c | 186 +++++++++++++++++++++++++++++++ tests/virshtest.c | 40 +++++++ 7 files changed, 376 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/conf/domain_conf.c | 66 ++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 8 +++++ src/libvirt_private.syms | 2 ++ src/qemu/qemu_driver.c | 60 +++--------------------------------- 4 files changed, 80 insertions(+), 56 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 04c10df0a9..2721e2269e 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -31153,3 +31153,69 @@ virHostdevIsVFIODevice(const virDomainHostdevDef *hostdev) hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && hostdev->source.subsys.u.pci.backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO; } + + +/** + * virDomainAddIOThreadCheck: + * @def: domain definition + * @iothread_id: iothread id + * + * Returns -1 if an IOThread is already using the given iothread id + */ +int +virDomainAddIOThreadCheck(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; +} + + +/** + * virDomainDelIOThreadCheck: + * @def: domain definition + * @iothread_id: iothread id + * + * Returns -1 if there is no IOThread using the given iothread id + */ +int +virDomainDelIOThreadCheck(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/conf/domain_conf.h b/src/conf/domain_conf.h index 4d9d499b16..0d06939e2b 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -4140,3 +4140,11 @@ virHostdevIsMdevDevice(const virDomainHostdevDef *hostdev) bool virHostdevIsVFIODevice(const virDomainHostdevDef *hostdev) ATTRIBUTE_NONNULL(1); + +int +virDomainAddIOThreadCheck(virDomainDef *def, + unsigned int iothread_id); + +int +virDomainDelIOThreadCheck(virDomainDef *def, + unsigned int iothread_id); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 43e6398ae5..fa0462a133 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -226,6 +226,7 @@ virDiskNameParse; virDiskNameToBusDeviceIndex; virDiskNameToIndex; virDomainActualNetDefFree; +virDomainAddIOThreadCheck; virDomainAudioFormatTypeFromString; virDomainAudioFormatTypeToString; virDomainAudioIOCommonIsSet; @@ -349,6 +350,7 @@ virDomainDefSetVcpus; virDomainDefSetVcpusMax; virDomainDefVcpuOrderClear; virDomainDeleteConfig; +virDomainDelIOThreadCheck; virDomainDeviceAliasIsUserAlias; virDomainDeviceDefCopy; virDomainDeviceDefFree; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 235f575901..334c043b60 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -5478,58 +5478,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 @@ -5663,7 +5611,7 @@ qemuDomainChgIOThread(virQEMUDriver *driver, switch (action) { case VIR_DOMAIN_IOTHREAD_ACTION_ADD: - if (qemuDomainAddIOThreadCheck(def, iothread.iothread_id) < 0) + if (virDomainAddIOThreadCheck(def, iothread.iothread_id) < 0) goto endjob; if (qemuDomainHotplugAddIOThread(driver, vm, iothread.iothread_id) < 0) @@ -5672,7 +5620,7 @@ qemuDomainChgIOThread(virQEMUDriver *driver, break; case VIR_DOMAIN_IOTHREAD_ACTION_DEL: - if (qemuDomainDelIOThreadCheck(def, iothread.iothread_id) < 0) + if (virDomainDelIOThreadCheck(def, iothread.iothread_id) < 0) goto endjob; if (qemuDomainHotplugDelIOThread(driver, vm, iothread.iothread_id) < 0) @@ -5702,7 +5650,7 @@ qemuDomainChgIOThread(virQEMUDriver *driver, if (persistentDef) { switch (action) { case VIR_DOMAIN_IOTHREAD_ACTION_ADD: - if (qemuDomainAddIOThreadCheck(persistentDef, iothread.iothread_id) < 0) + if (virDomainAddIOThreadCheck(persistentDef, iothread.iothread_id) < 0) goto endjob; if (!virDomainIOThreadIDAdd(persistentDef, iothread.iothread_id)) @@ -5711,7 +5659,7 @@ qemuDomainChgIOThread(virQEMUDriver *driver, break; case VIR_DOMAIN_IOTHREAD_ACTION_DEL: - if (qemuDomainDelIOThreadCheck(persistentDef, iothread.iothread_id) < 0) + if (virDomainDelIOThreadCheck(persistentDef, iothread.iothread_id) < 0) goto endjob; virDomainIOThreadIDDel(persistentDef, iothread.iothread_id); -- 2.32.0

Signed-off-by: Luke Yue <lukedyue@gmail.com> --- src/test/test_driver.c | 160 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index ef0ddab54d..6573ee3d61 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -182,6 +182,19 @@ struct _testDomainNamespaceDef { xmlNodePtr *snap_nodes; }; +typedef struct _testMonitorIOThreadInfo testMonitorIOThreadInfo; +struct _testMonitorIOThreadInfo { + unsigned int iothread_id; + int thread_id; + bool poll_valid; + unsigned long long poll_max_ns; + unsigned int poll_grow; + unsigned int poll_shrink; + bool set_poll_max_ns; + bool set_poll_grow; + bool set_poll_shrink; +}; + static void testDomainDefNamespaceFree(void *data) { @@ -9291,6 +9304,151 @@ testDomainCheckpointDelete(virDomainCheckpointPtr checkpoint, return ret; } +typedef enum { + VIR_DOMAIN_IOTHREAD_ACTION_ADD, + VIR_DOMAIN_IOTHREAD_ACTION_DEL, + VIR_DOMAIN_IOTHREAD_ACTION_MOD, +} virDomainIOThreadAction; + +static int +testDomainChgIOThread(virDomainObj *vm, + testMonitorIOThreadInfo iothread, + virDomainIOThreadAction action, + unsigned int flags) +{ + virDomainDef *def; + virDomainDef *persistentDef; + int ret = -1; + + if (virDomainObjGetDefs(vm, flags, &def, &persistentDef) < 0) + return ret; + + if (def) { + switch (action) { + case VIR_DOMAIN_IOTHREAD_ACTION_ADD: + if (virDomainAddIOThreadCheck(def, iothread.iothread_id) < 0) + return ret; + + if (!virDomainIOThreadIDAdd(def, iothread.iothread_id)) + return ret; + + break; + + case VIR_DOMAIN_IOTHREAD_ACTION_DEL: + if (virDomainDelIOThreadCheck(def, iothread.iothread_id) < 0) + return ret; + + virDomainIOThreadIDDel(def, iothread.iothread_id); + + break; + + case VIR_DOMAIN_IOTHREAD_ACTION_MOD: + if (!(virDomainIOThreadIDFind(def, iothread.iothread_id))) { + virReportError(VIR_ERR_INVALID_ARG, + _("cannot find IOThread '%u' in iothreadids"), + iothread.iothread_id); + return ret; + } + + break; + } + } + + if (persistentDef) { + switch (action) { + case VIR_DOMAIN_IOTHREAD_ACTION_ADD: + if (virDomainAddIOThreadCheck(persistentDef, iothread.iothread_id) < 0) + return ret; + + if (!virDomainIOThreadIDAdd(persistentDef, iothread.iothread_id)) + return ret; + + break; + + case VIR_DOMAIN_IOTHREAD_ACTION_DEL: + if (virDomainDelIOThreadCheck(persistentDef, iothread.iothread_id) < 0) + return ret; + + virDomainIOThreadIDDel(persistentDef, iothread.iothread_id); + + break; + + case VIR_DOMAIN_IOTHREAD_ACTION_MOD: + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("configuring persistent polling values is " + "not supported")); + return ret; + + break; + } + } + + ret = 0; + + return ret; +} + +static int +testDomainAddIOThread(virDomainPtr dom, + unsigned int iothread_id, + unsigned int flags) +{ + virDomainObj *vm = NULL; + testMonitorIOThreadInfo 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")); + return -1; + } + + if (!(vm = testDomObjFromDomain(dom))) + goto cleanup; + + iothread.iothread_id = iothread_id; + ret = testDomainChgIOThread(vm, iothread, + VIR_DOMAIN_IOTHREAD_ACTION_ADD, flags); + + cleanup: + virDomainObjEndAPI(&vm); + return ret; +} + + +static int +testDomainDelIOThread(virDomainPtr dom, + unsigned int iothread_id, + unsigned int flags) +{ + virDomainObj *vm = NULL; + testMonitorIOThreadInfo 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")); + return -1; + } + + if (!(vm = testDomObjFromDomain(dom))) + goto cleanup; + + iothread.iothread_id = iothread_id; + ret = testDomainChgIOThread(vm, iothread, + VIR_DOMAIN_IOTHREAD_ACTION_DEL, flags); + + cleanup: + virDomainObjEndAPI(&vm); + return ret; +} + /* * Test driver */ @@ -9356,6 +9514,8 @@ static virHypervisorDriver testHypervisorDriver = { .domainGetVcpus = testDomainGetVcpus, /* 0.7.3 */ .domainGetVcpuPinInfo = testDomainGetVcpuPinInfo, /* 1.2.18 */ .domainGetMaxVcpus = testDomainGetMaxVcpus, /* 0.7.3 */ + .domainAddIOThread = testDomainAddIOThread, /* 7.6.0 */ + .domainDelIOThread = testDomainDelIOThread, /* 7.6.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/conf/domain_conf.c | 60 ++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 4 +++ src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 53 +---------------------------------- 4 files changed, 66 insertions(+), 52 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 2721e2269e..03a0fb55fe 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -31219,3 +31219,63 @@ virDomainDelIOThreadCheck(virDomainDef *def, return 0; } + + +/** + * virDomainGetIOThreadsConfig: + * @targetDef: domain definition + * @info: information about the IOThread in a domain + * + * Returns the number of IOThreads in the given domain or -1 in case of error + */ +int +virDomainGetIOThreadsConfig(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; +} diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 0d06939e2b..7d2f1420ba 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -4148,3 +4148,7 @@ virDomainAddIOThreadCheck(virDomainDef *def, int virDomainDelIOThreadCheck(virDomainDef *def, unsigned int iothread_id); + +int +virDomainGetIOThreadsConfig(virDomainDef *targetDef, + virDomainIOThreadInfoPtr **info); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index fa0462a133..06b875e045 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -423,6 +423,7 @@ virDomainFSWrpolicyTypeFromString; virDomainFSWrpolicyTypeToString; virDomainGetBlkioParametersAssignFromDef; virDomainGetFilesystemForTarget; +virDomainGetIOThreadsConfig; virDomainGraphicsAuthConnectedTypeFromString; virDomainGraphicsAuthConnectedTypeToString; virDomainGraphicsDefFree; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 334c043b60..e7365570d4 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -5080,57 +5080,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, @@ -5157,7 +5106,7 @@ qemuDomainGetIOThreadInfo(virDomainPtr dom, if (!targetDef) ret = qemuDomainGetIOThreadsLive(driver, vm, info); else - ret = qemuDomainGetIOThreadsConfig(targetDef, info); + ret = virDomainGetIOThreadsConfig(targetDef, info); cleanup: virDomainObjEndAPI(&vm); -- 2.32.0

Signed-off-by: Luke Yue <lukedyue@gmail.com> --- src/test/test_driver.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 6573ee3d61..20aee59f98 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -9304,6 +9304,31 @@ testDomainCheckpointDelete(virDomainCheckpointPtr checkpoint, return ret; } +static int +testDomainGetIOThreadInfo(virDomainPtr dom, + virDomainIOThreadInfoPtr **info, + unsigned int flags) +{ + virDomainObj *vm; + virDomainDef *targetDef = NULL; + int ret = -1; + + virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | + VIR_DOMAIN_AFFECT_CONFIG, -1); + + if (!(vm = testDomObjFromDomain(dom))) + goto cleanup; + + targetDef = vm->def; + + if (targetDef) + ret = virDomainGetIOThreadsConfig(targetDef, info); + + cleanup: + virDomainObjEndAPI(&vm); + return ret; +} + typedef enum { VIR_DOMAIN_IOTHREAD_ACTION_ADD, VIR_DOMAIN_IOTHREAD_ACTION_DEL, @@ -9514,6 +9539,7 @@ static virHypervisorDriver testHypervisorDriver = { .domainGetVcpus = testDomainGetVcpus, /* 0.7.3 */ .domainGetVcpuPinInfo = testDomainGetVcpuPinInfo, /* 1.2.18 */ .domainGetMaxVcpus = testDomainGetMaxVcpus, /* 0.7.3 */ + .domainGetIOThreadInfo = testDomainGetIOThreadInfo, /* 7.6.0 */ .domainAddIOThread = testDomainAddIOThread, /* 7.6.0 */ .domainDelIOThread = testDomainDelIOThread, /* 7.6.0 */ .domainGetSecurityLabel = testDomainGetSecurityLabel, /* 7.5.0 */ -- 2.32.0

Signed-off-by: Luke Yue <lukedyue@gmail.com> --- examples/xml/test/testdomfc4.xml | 4 ++++ tests/virshtest.c | 40 ++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/examples/xml/test/testdomfc4.xml b/examples/xml/test/testdomfc4.xml index 26b7f25a06..25ad45365a 100644 --- a/examples/xml/test/testdomfc4.xml +++ b/examples/xml/test/testdomfc4.xml @@ -11,6 +11,10 @@ <memory>261072</memory> <currentMemory>131072</currentMemory> <vcpu>1</vcpu> + <iothreads>1</iothreads> + <iothreadids> + <iothread id="2"/> + </iothreadids> <devices> <disk type='file'> <source file='/u/fc4.img'/> diff --git a/tests/virshtest.c b/tests/virshtest.c index c1974c46cb..10ff5a4b78 100644 --- a/tests/virshtest.c +++ b/tests/virshtest.c @@ -250,6 +250,34 @@ static int testCompareDomstateByName(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-7\n\ +\n"; + + return testCompareOutputLit(exp, NULL, argv); +} + struct testInfo { const char *const *argv; const char *result; @@ -334,6 +362,18 @@ mymain(void) testCompareDomstateByName, 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; + /* 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