Support the libvirt_virDomainSetIOThreads method using code that mimics the existing libvirt_virDomainPinVcpuFlags method The following is a sample session assuming guest 'iothr-gst' has IOThreads configured (it's currently running, too) >>> import libvirt >>> con=libvirt.open("qemu:///system") >>> dom=con.lookupByName('iothr-gst') >>> dom.ioThreadsInfo() [(1, [False, False, True, False], ['/home/vm-images/iothr-vol1']), (2, [False, False, False, True], ['/home/vm-images/iothr-vol2']), (3, [False, False, False, True], [])] >>> cpumap=(True,True,True,False) >>> dom.setIOThreads(3,cpumap) 0 >>> print dom.ioThreadsInfo() [(1, [False, False, True, False], ['/home/vm-images/iothr-vol1']), (2, [False, False, False, True], ['/home/vm-images/iothr-vol2']), (3, [True, True, True, False], [])] >>> Signed-off-by: John Ferlan <jferlan@xxxxxxxxxx> --- generator.py | 1 + libvirt-override-api.xml | 8 ++++++ libvirt-override.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) diff --git a/generator.py b/generator.py index 8165a18..aa140ed 100755 --- a/generator.py +++ b/generator.py @@ -436,6 +436,7 @@ skip_impl = ( 'virDomainGetEmulatorPinInfo', 'virDomainPinEmulator', 'virDomainGetIOThreadsInfo', + 'virDomainSetIOThreads', 'virSecretGetValue', 'virSecretSetValue', 'virSecretGetUUID', diff --git a/libvirt-override-api.xml b/libvirt-override-api.xml index e512311..19667b6 100644 --- a/libvirt-override-api.xml +++ b/libvirt-override-api.xml @@ -284,6 +284,14 @@ <arg name='flags' type='int' info='an OR'ed set of virDomainModificationImpact'/> <return type='char *' info="list of IOThreads information including the iothread_id, the cpumap, the cpumap length, number of associated resources, and a list of each resource assigned to the iothread_id."/> </function> + <function name='virDomainSetIOThreads' file='python'> + <info>Dynamically change the real CPUs which can be allocated to an IOThread. This function requires privileged access to the hypervisor.</info> + <return type='int' info='0 in case of success, -1 in case of failure.'/> + <arg name='domain' type='virDomainPtr' info='pointer to domain object'/> + <arg name='iothread_val' type='unsigned int' info='iothread_id number'/> + <arg name='cpumap' type='unsigned char *' info='pointer to a bit map of real CPUs (in 8-bit bytes) (IN) Each bit set to 1 means that corresponding CPU is usable. Bytes are stored in little-endian order: CPU0-7, 8-15... In each byte, lowest CPU number is least significant bit.'/> + <arg name='flags' type='int' info='an OR'ed set of virDomainIOThreadsFlags'/> + </function> <function name='virDomainSetSchedulerParameters' file='python'> <info>Change the scheduler parameters</info> <return type='int' info='-1 in case of error, 0 in case of success.'/> diff --git a/libvirt-override.c b/libvirt-override.c index 580a1b2..8823a39 100644 --- a/libvirt-override.c +++ b/libvirt-override.c @@ -2100,6 +2100,71 @@ cleanup: return error; } +static PyObject * +libvirt_virDomainSetIOThreads(PyObject *self ATTRIBUTE_UNUSED, + PyObject *args) +{ + virDomainPtr domain; + PyObject *pyobj_domain, *pycpumap; + PyObject *ret = NULL; + unsigned char *cpumap; + int cpumaplen, iothread_val, tuple_size, cpunum; + size_t i; + unsigned int flags; + int i_retval; + + if (!PyArg_ParseTuple(args, (char *)"OiOI:virDomainSetIOThread", + &pyobj_domain, &iothread_val, &pycpumap, &flags)) + return NULL; + domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); + + if ((cpunum = getPyNodeCPUCount(virDomainGetConnect(domain))) < 0) + return VIR_PY_INT_FAIL; + + if (PyTuple_Check(pycpumap)) { + if ((tuple_size = PyTuple_Size(pycpumap)) == -1) + return ret; + } else { + PyErr_SetString(PyExc_TypeError, "Unexpected type, tuple is required"); + return ret; + } + + cpumaplen = VIR_CPU_MAPLEN(cpunum); + if (VIR_ALLOC_N(cpumap, cpumaplen) < 0) + return PyErr_NoMemory(); + + for (i = 0; i < tuple_size; i++) { + PyObject *flag = PyTuple_GetItem(pycpumap, i); + bool b; + + if (!flag || libvirt_boolUnwrap(flag, &b) < 0) + goto cleanup; + + if (b) + VIR_USE_CPU(cpumap, i); + else + VIR_UNUSE_CPU(cpumap, i); + } + + for (; i < cpunum; i++) + VIR_UNUSE_CPU(cpumap, i); + + flags |= VIR_DOMAIN_IOTHREADS_PIN; + LIBVIRT_BEGIN_ALLOW_THREADS; + i_retval = virDomainSetIOThreads(domain, iothread_val, + cpumap, cpumaplen, flags); + LIBVIRT_END_ALLOW_THREADS; + if (i_retval < 0) { + ret = VIR_PY_INT_FAIL; + goto cleanup; + } + ret = VIR_PY_INT_SUCCESS; + +cleanup: + VIR_FREE(cpumap); + return ret; +} + #endif /* LIBVIR_CHECK_VERSION(1, 2, 13) */ /************************************************************************ @@ -8596,6 +8661,7 @@ static PyMethodDef libvirtMethods[] = { #endif /* LIBVIR_CHECK_VERSION(0, 10, 0) */ #if LIBVIR_CHECK_VERSION(1, 2, 13) {(char *) "virDomainGetIOThreadsInfo", libvirt_virDomainGetIOThreadsInfo, METH_VARARGS, NULL}, + {(char *) "virDomainSetIOThreads", libvirt_virDomainSetIOThreads, METH_VARARGS, NULL}, #endif /* LIBVIR_CHECK_VERSION(1, 2, 13) */ {(char *) "virConnectListStoragePools", libvirt_virConnectListStoragePools, METH_VARARGS, NULL}, {(char *) "virConnectListDefinedStoragePools", libvirt_virConnectListDefinedStoragePools, METH_VARARGS, NULL}, -- 2.1.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list