[libvirt] [PATCH] python: fix about some of python binding APIs don't raise and exception
by Guannan Ren
For example:
>>> dom.memoryStats()
libvir: QEMU Driver error : Requested operation is not valid:\
domain is not running
There are six such python API functions like so.
The root reason is that generator.py script checks the type of return
value of a python stub function defined in libvirt-api.xml or
libvirt-override-api.xml to see whether adding the raise clause or not
in python wrapper code in libvirt.py.
The type of return value is supposed to be C types.
For those stub functions which return python non-integer data type like
string, list, tuple, dictionary, the existing type in functions varies
from each other which leads problem like this.
Currently, in generator.py, it maintains a buggy whitelist for stub functions
returning a list type. I think it is easy to forget adding new function name
in the whitelist.
This patch makes the value of type consistent with C type "char *"
in libvirt-override-api.xml. For python, any of types could be printed
as string, so I choose "char *"in this case. And the comment in xml
could explain it when adding new function definition.
<function name='virNodeGetCPUStats' file='python'>
...
- <return type='virNodeCPUStats' info='...'/>
+ <return type='char *' info='...'/>
...
</function>
---
python/generator.py | 10 ++--
python/libvirt-override-api.xml | 116 +++++++++++++++++++++-------------------
2 files changed, 66 insertions(+), 60 deletions(-)
diff --git a/python/generator.py b/python/generator.py
index 8236bd2..bebc644 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -1008,11 +1008,9 @@ functions_list_exception_test = {
}
functions_list_default_test = "%s is None"
-def is_list_type (name):
- whitelist = [ "virDomainBlockStats",
- "virDomainInterfaceStats" ]
+def is_python_noninteger_type (name):
- return name[-1:] == "*" or name in whitelist
+ return name[-1:] == "*"
def nameFixup(name, classe, type, file):
# avoid a desastrous clash
@@ -1386,7 +1384,7 @@ def buildWrappers(module):
("ret", name))
classes.write(" return ret\n")
- elif is_list_type (ret[0]):
+ elif is_python_noninteger_type (ret[0]):
if not functions_noexcept.has_key (name):
if functions_list_exception_test.has_key (name):
test = functions_list_exception_test[name]
@@ -1656,7 +1654,7 @@ def buildWrappers(module):
classes.write (" return ret\n")
- elif is_list_type (ret[0]):
+ elif is_python_noninteger_type (ret[0]):
if not functions_noexcept.has_key (name):
if functions_list_exception_test.has_key (name):
test = functions_list_exception_test[name]
diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml
index 5976fb2..6087f86 100644
--- a/python/libvirt-override-api.xml
+++ b/python/libvirt-override-api.xml
@@ -1,5 +1,13 @@
<?xml version="1.0"?>
<api name='libvir-python'>
+ <!-- This file lists libvirt API functions whose Python stubs are written by hand
+ in libvirt-override.c, but the Python-level code are still automatically generated
+ by generator.py script.
+
+ The type of return value is supposed to be C types. If a function's stub will return
+ a python non-integer data type like string, list, tuple, dictionary, etc,
+ please using "char *" as the type of its return value.
+ -->
<symbols>
<function name="virConnectGetVersion" file='python'>
<info>Returns the running hypervisor version of the connection host</info>
@@ -14,34 +22,34 @@
<function name="virConnectListDomainsID" file='python'>
<info>Returns the list of the ID of the domains on the hypervisor</info>
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
- <return type='int *' info="the list of ID or None in case of error"/>
+ <return type='char *' info="the list of ID or None in case of error"/>
</function>
<function name='virConnectListDefinedDomains' file='python'>
<info>list the defined domains, stores the pointers to the names in @names</info>
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
- <return type='str *' info='the list of Names or None in case of error'/>
+ <return type='char *' info='the list of Names or None in case of error'/>
</function>
<function name='virConnectListAllDomains' file='python'>
<info>returns list of all defined domains</info>
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
<arg name='flags' type='unsigned int' info='optional flags'/>
- <return type='domain *' info='the list of domains or None in case of error'/>
+ <return type='char *' info='the list of domains or None in case of error'/>
</function>
<function name='virConnectListNetworks' file='python'>
<info>list the networks, stores the pointers to the names in @names</info>
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
- <return type='str *' info='the list of Names or None in case of error'/>
+ <return type='char *' info='the list of Names or None in case of error'/>
</function>
<function name='virConnectListDefinedNetworks' file='python'>
<info>list the defined networks, stores the pointers to the names in @names</info>
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
- <return type='str *' info='the list of Names or None in case of error'/>
+ <return type='char *' info='the list of Names or None in case of error'/>
</function>
<function name='virConnectListAllNetworks' file='python'>
<info>returns list of all networks</info>
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
<arg name='flags' type='unsigned int' info='optional flags'/>
- <return type='network *' info='the list of networks or None in case of error'/>
+ <return type='char *' info='the list of networks or None in case of error'/>
</function>
<function name='virDomainLookupByUUID' file='python'>
<info>Try to lookup a domain on the given hypervisor based on its UUID.</info>
@@ -57,54 +65,54 @@
</function>
<function name='virDomainGetInfo' file='python'>
<info>Extract information about a domain. Note that if the connection used to get the domain is limited only a partial set of the information can be extracted.</info>
- <return type='int *' info='the list of information or None in case of error'/>
+ <return type='char *' info='the list of information or None in case of error'/>
<arg name='domain' type='virDomainPtr' info='a domain object'/>
</function>
<function name='virDomainGetState' file='python'>
<info>Extract domain state.</info>
- <return type='int *' info='the list containing state and reason or None in case of error'/>
+ <return type='char *' info='the list containing state and reason or None in case of error'/>
<arg name='domain' type='virDomainPtr' info='a domain object'/>
<arg name='flags' type='unsigned int' info='additional flags'/>
</function>
<function name='virDomainGetControlInfo' file='python'>
<info>Extract details about current state of control interface to a domain.</info>
- <return type='int *' info='the list of information or None in case of error'/>
+ <return type='char *' info='the list of information or None in case of error'/>
<arg name='domain' type='virDomainPtr' info='a domain object'/>
<arg name='flags' type='unsigned int' info='additional flags'/>
</function>
<function name='virDomainGetBlockInfo' file='python'>
<info>Extract information about a domain block device size</info>
- <return type='int *' info='the list of information or None in case of error'/>
+ <return type='char *' info='the list of information or None in case of error'/>
<arg name='domain' type='virDomainPtr' info='a domain object'/>
<arg name='path' type='const char *' info='path to the block device or file'/>
<arg name='flags' type='unsigned int' info='currently unused'/>
</function>
<function name='virDomainGetJobInfo' file='python'>
<info>Extract information about an active job being processed for a domain.</info>
- <return type='int *' info='the list of information or None in case of error'/>
+ <return type='char *' info='the list of information or None in case of error'/>
<arg name='domain' type='virDomainPtr' info='a domain object'/>
</function>
<function name='virDomainGetJobStats' file='python'>
<info>Extract information about an active job being processed for a domain.</info>
- <return type='virDomainJobStats' info='dictionary mapping field names to values or None in case of error'/>
+ <return type='char *' info='dictionary mapping field names to values or None in case of error'/>
<arg name='domain' type='virDomainPtr' info='a domain object'/>
<arg name='flags' type='unsigned int' info='flags, currently unused, pass 0.'/>
</function>
<function name='virNodeGetInfo' file='python'>
<info>Extract hardware information about the Node.</info>
- <return type='int *' info='the list of information or None in case of error'/>
+ <return type='char *' info='the list of information or None in case of error'/>
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
</function>
<function name='virNodeGetCPUStats' file='python'>
<info>Extract node's CPU statistics.</info>
- <return type='virNodeCPUStats' info='dictionary mapping field names to values or None in case of error'/>
+ <return type='char *' info='dictionary mapping field names to values or None in case of error'/>
<arg name='conn' type='virConnectPtr' info='pointer to hypervisor connection'/>
<arg name='cpuNum' type='int' info='number of node cpu. (VIR_NODE_CPU_STATS_ALL_CPUS means total cpu statistics)'/>
<arg name='flags' type='unsigned int' info='additional flags'/>
</function>
<function name='virNodeGetMemoryStats' file='python'>
<info>Extract node's memory statistics.</info>
- <return type='virNodeMemoryStats' info='dictionary mapping field names to values or None in case of error'/>
+ <return type='char *' info='dictionary mapping field names to values or None in case of error'/>
<arg name='conn' type='virConnectPtr' info='pointer to hypervisor connection'/>
<arg name='cellNum' type='int' info='number of node cell. (VIR_NODE_MEMORY_STATS_ALL_CELLS means total cell statistics)'/>
<arg name='flags' type='unsigned int' info='additional flags'/>
@@ -156,13 +164,13 @@
</function>
<function name='virDomainBlockStats' file='python'>
<info>Extracts block device statistics for a domain</info>
- <return type='virDomainBlockStats' info='a tuple of statistics'/>
+ <return type='char *' info='a tuple of statistics'/>
<arg name='domain' type='virDomainPtr' info='a domain object'/>
<arg name='path' type='char *' info='the path for the block device'/>
</function>
<function name='virDomainBlockStatsFlags' file='python'>
<info>Extracts block device statistics parameters of a running domain</info>
- <return type='str *' info='None in case of error, returns a dictionary of params'/>
+ <return type='char *' info='None in case of error, returns a dictionary of params'/>
<arg name='domain' type='virDomainPtr' info='pointer to domain object'/>
<arg name='path' type='char *' info='the path for the block device'/>
<arg name='flags' type='int' info='flags (unused; pass 0)'/>
@@ -175,20 +183,20 @@
[{cpu_time:xxx}, {cpu_time:xxx}, ...]
If it is True or 1, it returns total domain CPU statistics in the format of
[{cpu_time:xxx, user_time:xxx, system_time:xxx}]</info>
- <return type='str *' info='returns a list of dictionary in case of success, None in case of error'/>
+ <return type='char *' info='returns a list of dictionary in case of success, None in case of error'/>
<arg name='domain' type='virDomainPtr' info='pointer to domain object'/>
<arg name='total' type='bool' info='on true, return total domain CPU statistics, false return per-cpu info'/>
<arg name='flags' type='int' info='flags (unused; pass 0)'/>
</function>
<function name='virDomainInterfaceStats' file='python'>
<info>Extracts interface device statistics for a domain</info>
- <return type='virDomainInterfaceStats' info='a tuple of statistics'/>
+ <return type='char *' info='a tuple of statistics'/>
<arg name='domain' type='virDomainPtr' info='a domain object'/>
<arg name='path' type='char *' info='the path for the interface device'/>
</function>
<function name='virDomainMemoryStats' file='python'>
<info>Extracts memory statistics for a domain</info>
- <return type='virDomainMemoryStats' info='a dictionary of statistics'/>
+ <return type='char *' info='a dictionary of statistics'/>
<arg name='domain' type='virDomainPtr' info='a domain object'/>
</function>
<function name="virNodeGetCellsFreeMemory" file='python'>
@@ -196,16 +204,16 @@
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
<arg name='startCell' type='int' info='first cell in the list'/>
<arg name='maxCells' type='int' info='number of cell in the list'/>
- <return type='int *' info="the list available memory in the cells"/>
+ <return type='char *' info="the list available memory in the cells"/>
</function>
<function name='virDomainGetSchedulerParameters' file='python'>
<info>Get the scheduler parameters, the @params array will be filled with the values.</info>
- <return type='str *' info='None in case of error, returns a dictionary of params.'/>
+ <return type='char *' info='None in case of error, returns a dictionary of params.'/>
<arg name='domain' type='virDomainPtr' info='pointer to domain object'/>
</function>
<function name='virDomainGetSchedulerParametersFlags' file='python'>
<info>Get the scheduler parameters</info>
- <return type='str *' info='None in case of error, returns a dictionary of params'/>
+ <return type='char *' info='None in case of error, returns a dictionary of params'/>
<arg name='domain' type='virDomainPtr' info='pointer to domain object'/>
<arg name='flags' type='int' info='an OR'ed set of virDomainModificationImpact'/>
</function>
@@ -236,7 +244,7 @@
</function>
<function name='virDomainGetVcpuPinInfo' file='python'>
<info>Query the CPU affinity setting of all virtual CPUs of domain</info>
- <return type='unsigned char *' info='the array of cpumap'/>
+ <return type='char *' info='the array of cpumap'/>
<arg name='domain' type='virDomainPtr' info='pointer to domain object, or NULL for Domain0'/>
<arg name='flags' type='int' info='an OR'ed set of virDomainModificationImpact'/>
</function>
@@ -262,7 +270,7 @@
</function>
<function name='virDomainGetBlkioParameters' file='python'>
<info>Get the blkio parameters</info>
- <return type='str *' info='None in case of error, returns a dictionary of params'/>
+ <return type='char *' info='None in case of error, returns a dictionary of params'/>
<arg name='domain' type='virDomainPtr' info='pointer to domain object'/>
<arg name='flags' type='int' info='an OR'ed set of virDomainModificationImpact'/>
</function>
@@ -275,7 +283,7 @@
</function>
<function name='virDomainGetMemoryParameters' file='python'>
<info>Get the memory parameters</info>
- <return type='str *' info='None in case of error, returns a dictionary of params'/>
+ <return type='char *' info='None in case of error, returns a dictionary of params'/>
<arg name='domain' type='virDomainPtr' info='pointer to domain object'/>
<arg name='flags' type='int' info='an OR'ed set of virDomainModificationImpact'/>
</function>
@@ -288,7 +296,7 @@
</function>
<function name='virDomainGetNumaParameters' file='python'>
<info>Get the NUMA parameters</info>
- <return type='str *' info='returns a dictionary of params in case of success, None in case of error'/>
+ <return type='char *' info='returns a dictionary of params in case of success, None in case of error'/>
<arg name='domain' type='virDomainPtr' info='pointer to domain object'/>
<arg name='flags' type='int' info='an OR'ed set of virDomainModificationImpact'/>
</function>
@@ -305,44 +313,44 @@
<arg name='dom' type='virDomainPtr' info='pointer to the domain'/>
<arg name='device' type='const char *' info='interface name'/>
<arg name='flags' type='unsigned int' info='an OR'ed set of virDomainModificationImpact'/>
- <return type='str *' info='the bandwidth tunables value or None in case of error'/>
+ <return type='char *' info='the bandwidth tunables value or None in case of error'/>
</function>
<function name='virConnectListStoragePools' file='python'>
<info>list the storage pools, stores the pointers to the names in @names</info>
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
- <return type='str *' info='the list of Names of None in case of error'/>
+ <return type='char *' info='the list of Names of None in case of error'/>
</function>
<function name='virConnectListDefinedStoragePools' file='python'>
<info>list the defined storage pool, stores the pointers to the names in @names</info>
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
- <return type='str *' info='the list of Names of None in case of error'/>
+ <return type='char *' info='the list of Names of None in case of error'/>
</function>
<function name='virConnectListAllStoragePools' file='python'>
<info>returns list of all storage pools</info>
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
<arg name='flags' type='unsigned int' info='optional flags'/>
- <return type='pool *' info='the list of pools or None in case of error'/>
+ <return type='char *' info='the list of pools or None in case of error'/>
</function>
<function name='virStoragePoolListVolumes' file='python'>
<info>list the storage volumes, stores the pointers to the names in @names</info>
<arg name='pool' type='virStoragePoolPtr' info='pointer to the storage pool'/>
- <return type='str *' info='the list of Names or None in case of error'/>
+ <return type='char *' info='the list of Names or None in case of error'/>
</function>
<function name='virStoragePoolListAllVolumes' file='python'>
<info>return list of storage volume objects</info>
<arg name='pool' type='virStoragePoolPtr' info='pointer to the storage pool'/>
<arg name='flags' type='unsigned int' info='optional flags'/>
- <return type='volume *' info='the list of volumes or None in case of error'/>
+ <return type='char *' info='the list of volumes or None in case of error'/>
</function>
<function name='virStoragePoolGetInfo' file='python'>
<info>Extract information about a storage pool. Note that if the connection used to get the domain is limited only a partial set of the information can be extracted.</info>
- <return type='int *' info='the list of information or None in case of error'/>
+ <return type='char *' info='the list of information or None in case of error'/>
<arg name='pool' type='virStoragePoolPtr' info='a storage pool object'/>
</function>
<function name='virStorageVolGetInfo' file='python'>
<info>Extract information about a storage volume. Note that if the connection used to get the domain is limited only a partial set of the information can be extracted.</info>
- <return type='int *' info='the list of information or None in case of error'/>
+ <return type='char *' info='the list of information or None in case of error'/>
<arg name='vol' type='virStorageVolPtr' info='a storage vol object'/>
</function>
<function name='virNodeListDevices' file='python'>
@@ -350,18 +358,18 @@
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
<arg name='cap' type='const unsigned char *' info='capability name'/>
<arg name='flags' type='unsigned int' info='flags (unused; pass 0)'/>
- <return type='str *' info='the list of Names or None in case of error'/>
+ <return type='char *' info='the list of Names or None in case of error'/>
</function>
<function name='virConnectListAllNodeDevices' file='python'>
<info>returns list of all host node devices</info>
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
<arg name='flags' type='unsigned int' info='optional flags'/>
- <return type='device *' info='the list of host node device or None in case of error'/>
+ <return type='char *' info='the list of host node device or None in case of error'/>
</function>
<function name='virNodeDeviceListCaps' file='python'>
<info>list the node device's capabilities</info>
<arg name='dev' type='virNodeDevicePtr' info='pointer to the node device'/>
- <return type='str *' info='the list of Names or None in case of error'/>
+ <return type='char *' info='the list of Names or None in case of error'/>
</function>
<function name='virSecretGetValue' file='libvirt' module='libvirt'>
<info>Fetches the value associated with a secret.</info>
@@ -372,13 +380,13 @@
<function name='virConnectListSecrets' file='libvirt' module='libvirt'>
<info>List the defined secret IDs</info>
<arg name='conn' type='virConnectPtr' info='virConnect connection'/>
- <return type='str *' info='the list of secret IDs or None in case of error'/>
+ <return type='char *' info='the list of secret IDs or None in case of error'/>
</function>
<function name='virConnectListAllSecrets' file='python'>
<info>returns list of all interfaces</info>
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
<arg name='flags' type='unsigned int' info='optional flags'/>
- <return type='secret *' info='the list of secrets or None in case of error'/>
+ <return type='char *' info='the list of secrets or None in case of error'/>
</function>
<function name='virSecretSetValue' file='libvirt' module='libvirt'>
<info>Associates a value with a secret.</info>
@@ -406,13 +414,13 @@
<function name='virConnectListNWFilters' file='libvirt' module='libvirt'>
<info>List the defined network filters</info>
<arg name='conn' type='virConnectPtr' info='virConnect connection'/>
- <return type='str *' info='the list of network filter IDs or None in case of error'/>
+ <return type='char *' info='the list of network filter IDs or None in case of error'/>
</function>
<function name='virConnectListAllNWFilters' file='python'>
<info>returns list of all network fitlers</info>
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
<arg name='flags' type='unsigned int' info='optional flags'/>
- <return type='nwfilter *' info='the list of network filters or None in case of error'/>
+ <return type='char *' info='the list of network filters or None in case of error'/>
</function>
<function name='virNWFilterLookupByUUID' file='python'>
<info>Try to lookup a network filter on the given hypervisor based on its UUID.</info>
@@ -433,18 +441,18 @@
<function name='virConnectListInterfaces' file='python'>
<info>list the running interfaces, stores the pointers to the names in @names</info>
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
- <return type='str *' info='the list of Names of None in case of error'/>
+ <return type='char *' info='the list of Names of None in case of error'/>
</function>
<function name='virConnectListDefinedInterfaces' file='python'>
<info>list the defined interfaces, stores the pointers to the names in @names</info>
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
- <return type='str *' info='the list of Names of None in case of error'/>
+ <return type='char *' info='the list of Names of None in case of error'/>
</function>
<function name='virConnectListAllInterfaces' file='python'>
<info>returns list of all interfaces</info>
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
<arg name='flags' type='unsigned int' info='optional flags'/>
- <return type='interface *' info='the list of interfaces or None in case of error'/>
+ <return type='char *' info='the list of interfaces or None in case of error'/>
</function>
<function name='virConnectBaselineCPU' file='python'>
<info>Computes the most feature-rich CPU which is compatible with all given host CPUs.</info>
@@ -457,25 +465,25 @@
<info>collect the list of snapshot names for the given domain</info>
<arg name='dom' type='virDomainPtr' info='pointer to the domain'/>
<arg name='flags' type='unsigned int' info='flags'/>
- <return type='str *' info='the list of Names or None in case of error'/>
+ <return type='char *' info='the list of Names or None in case of error'/>
</function>
<function name='virDomainListAllSnapshots' file='python'>
<info>returns the list of snapshots for the given domain</info>
<arg name='dom' type='virDomainPtr' info='pointer to the domain'/>
<arg name='flags' type='unsigned int' info='flags'/>
- <return type='snapshot *' info='the list of snapshots or None in case of error'/>
+ <return type='char *' info='the list of snapshots or None in case of error'/>
</function>
<function name='virDomainSnapshotListChildrenNames' file='python'>
<info>collect the list of child snapshot names for the given snapshot</info>
<arg name='snapshot' type='virDomainSnapshotPtr' info='pointer to the snapshot'/>
<arg name='flags' type='unsigned int' info='flags'/>
- <return type='str *' info='the list of Names or None in case of error'/>
+ <return type='char *' info='the list of Names or None in case of error'/>
</function>
<function name='virDomainSnapshotListAllChildren' file='python'>
<info>returns the list of child snapshots for the given snapshot</info>
<arg name='snapshot' type='virDomainSnapshotPtr' info='pointer to the snapshot'/>
<arg name='flags' type='unsigned int' info='flags'/>
- <return type='snapshot *' info='the list of snapshots or None in case of error'/>
+ <return type='char *' info='the list of snapshots or None in case of error'/>
</function>
<function name='virDomainRevertToSnapshot' file='python'>
<info>revert the domain to the given snapshot</info>
@@ -489,7 +497,7 @@
<arg name='dom' type='virDomainPtr' info='pointer to the domain'/>
<arg name='path' type='const char *' info='Fully-qualified filename of disk'/>
<arg name='flags' type='unsigned int' info='fine-tuning flags, currently unused, pass 0.'/>
- <return type='virDomainBlockJobInfo' info='A dictionary containing job information.' />
+ <return type='char *' info='A dictionary containing job information.' />
</function>
<function name='virDomainMigrateGetCompressionCache' file='python'>
<info>Get current size of the cache (in bytes) used for compressing
@@ -517,7 +525,7 @@
<arg name='dom' type='virDomainPtr' info='pointer to the domain'/>
<arg name='disk' type='const char *' info='disk name'/>
<arg name='flags' type='unsigned int' info='an OR'ed set of virDomainModificationImpact'/>
- <return type='str *' info='the I/O tunables value or None in case of error'/>
+ <return type='char *' info='the I/O tunables value or None in case of error'/>
</function>
<function name='virDomainBlockPeek' file='python'>
<info>Read the contents of domain's disk device</info>
@@ -538,7 +546,7 @@
</function>
<function name='virDomainGetDiskErrors' file='python'>
<info>Extract errors on disk devices.</info>
- <return type='virDomainDiskErrorPtr' info='dictionary of disks and their errors or None in case of error'/>
+ <return type='char *' info='dictionary of disks and their errors or None in case of error'/>
<arg name='domain' type='virDomainPtr' info='a domain object'/>
<arg name='flags' type='unsigned int' info='unused, always pass 0'/>
</function>
@@ -551,13 +559,13 @@
</function>
<function name='virNodeGetMemoryParameters' file='python'>
<info>Get the node memory parameters</info>
- <return type='str *' info='None in case of error, returns a dictionary of params'/>
+ <return type='char *' info='None in case of error, returns a dictionary of params'/>
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
<arg name='flags' type='int' info='unused, always pass 0'/>
</function>
<function name='virNodeGetCPUMap' file='python'>
<info>Get node CPU information</info>
- <return type='str *' info='(cpunum, cpumap, online) on success, None on error'/>
+ <return type='char *' info='(cpunum, cpumap, online) on success, None on error'/>
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
<arg name='flags' type='int' info='unused, pass 0'/>
</function>
--
1.7.11.2
12 years, 1 month
[libvirt] [PATCH 00/13] Network disk improvements (NBD & libiscsi)
by Paolo Bonzini
This series improves support for NBD disks (patches 1-6), and adds
support for the libiscsi userspace initiator (patches 7-13).
Please review!
Paolo
Paolo Bonzini (13):
qemu: fix use-after-free when parsing NBD disk
qemu: do not support non-network disks without -drive
qemu: rewrite NBD command-line builder and parser
qemu: support named nbd exports
qemu: support NBD with Unix sockets
qemu: support URI syntax for NBD
domain: add support for iscsi network disks
qemu: add support for libiscsi
qemu: support LUN numbers for iSCSI disks
domain: make port optional for network disks
secret: add iscsi to possible usage types
domain: parse XML for iscsi authorization credentials
qemu: pass iscsi authorization credentials
docs/formatdomain.html.in | 42 +-
docs/formatsecret.html.in | 12 +
docs/schemas/domaincommon.rng | 37 +-
docs/schemas/secret.rng | 10 +
include/libvirt/libvirt.h.in | 1 +
src/conf/domain_conf.c | 51 ++-
src/conf/domain_conf.h | 3 +
src/conf/secret_conf.c | 22 +-
src/conf/secret_conf.h | 1 +
src/qemu/qemu_command.c | 432 ++++++++++++++-------
src/secret/secret_driver.c | 8 +
tests/qemuargv2xmltest.c | 5 +
.../qemuxml2argv-disk-drive-network-gluster.args | 2 +-
...qemuxml2argv-disk-drive-network-iscsi-auth.args | 1 +
.../qemuxml2argv-disk-drive-network-iscsi-auth.xml | 31 ++
.../qemuxml2argv-disk-drive-network-iscsi.args | 1 +
.../qemuxml2argv-disk-drive-network-iscsi.xml | 34 ++
...qemuxml2argv-disk-drive-network-nbd-export.args | 5 +
.../qemuxml2argv-disk-drive-network-nbd-export.xml | 33 ++
...ml2argv-disk-drive-network-nbd-ipv6-export.args | 5 +
...xml2argv-disk-drive-network-nbd-ipv6-export.xml | 33 ++
.../qemuxml2argv-disk-drive-network-nbd-ipv6.args | 5 +
.../qemuxml2argv-disk-drive-network-nbd-ipv6.xml | 33 ++
.../qemuxml2argv-disk-drive-network-nbd-unix.args | 5 +
.../qemuxml2argv-disk-drive-network-nbd-unix.xml | 33 ++
tests/qemuxml2argvtest.c | 12 +
tests/qemuxml2xmltest.c | 7 +
27 files changed, 687 insertions(+), 177 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi-auth.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi-auth.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-export.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-export.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-ipv6-export.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-ipv6-export.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-ipv6.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-ipv6.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-unix.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-unix.xml
--
1.8.1.2
12 years, 1 month
[libvirt] [PATCH RESEND 1/2] NUMA: cleanup for numa related codes
by Gao feng
Intend to reduce the redundant code,use virNumaSetupMemoryPolicy
to replace virLXCControllerSetupNUMAPolicy and
qemuProcessInitNumaMemoryPolicy.
This patch also moves the numa related codes to the
file virnuma.c and virnuma.h
Signed-off-by: Gao feng <gaofeng(a)cn.fujitsu.com>
---
src/conf/domain_conf.c | 31 ++++--------
src/conf/domain_conf.h | 25 +---------
src/libvirt_private.syms | 9 ++--
src/lxc/lxc_controller.c | 116 +------------------------------------------
src/qemu/qemu_cgroup.c | 4 +-
src/qemu/qemu_driver.c | 6 +--
src/qemu/qemu_process.c | 123 +--------------------------------------------
src/util/virnuma.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++
src/util/virnuma.h | 30 +++++++++++
9 files changed, 182 insertions(+), 288 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index a1cfc76..fa70329 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -690,11 +690,6 @@ VIR_ENUM_IMPL(virDomainTimerMode, VIR_DOMAIN_TIMER_MODE_LAST,
"paravirt",
"smpsafe");
-VIR_ENUM_IMPL(virDomainNumatuneMemMode, VIR_DOMAIN_NUMATUNE_MEM_LAST,
- "strict",
- "preferred",
- "interleave");
-
VIR_ENUM_IMPL(virDomainStartupPolicy, VIR_DOMAIN_STARTUP_POLICY_LAST,
"default",
"mandatory",
@@ -709,12 +704,6 @@ VIR_ENUM_IMPL(virDomainDiskTray, VIR_DOMAIN_DISK_TRAY_LAST,
"closed",
"open");
-VIR_ENUM_IMPL(virDomainNumatuneMemPlacementMode,
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_LAST,
- "default",
- "static",
- "auto");
-
VIR_ENUM_IMPL(virDomainRNGModel,
VIR_DOMAIN_RNG_MODEL_LAST,
"virtio");
@@ -9852,7 +9841,7 @@ virDomainDefParseXML(virCapsPtr caps,
int placement_mode = 0;
if (placement) {
if ((placement_mode =
- virDomainNumatuneMemPlacementModeTypeFromString(placement)) < 0) {
+ virNumaTuneMemPlacementModeTypeFromString(placement)) < 0) {
virReportError(VIR_ERR_XML_ERROR,
_("Unsupported memory placement "
"mode '%s'"), placement);
@@ -9862,18 +9851,18 @@ virDomainDefParseXML(virCapsPtr caps,
VIR_FREE(placement);
} else if (def->numatune.memory.nodemask) {
/* Defaults to "static" if nodeset is specified. */
- placement_mode = VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC;
+ placement_mode = VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC;
} else {
/* Defaults to "placement" of <vcpu> if nodeset is
* not specified.
*/
if (def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_STATIC)
- placement_mode = VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC;
+ placement_mode = VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC;
else
- placement_mode = VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO;
+ placement_mode = VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO;
}
- if (placement_mode == VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC &&
+ if (placement_mode == VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC &&
!def->numatune.memory.nodemask) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("nodeset for NUMA memory tuning must be set "
@@ -9882,13 +9871,13 @@ virDomainDefParseXML(virCapsPtr caps,
}
/* Ignore 'nodeset' if 'placement' is 'auto' finally */
- if (placement_mode == VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)
+ if (placement_mode == VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO)
virBitmapFree(def->numatune.memory.nodemask);
/* Copy 'placement' of <numatune> to <vcpu> if its 'placement'
* is not specified and 'placement' of <numatune> is specified.
*/
- if (placement_mode == VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO &&
+ if (placement_mode == VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO &&
!def->cpumask)
def->placement_mode = VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO;
@@ -9907,7 +9896,7 @@ virDomainDefParseXML(virCapsPtr caps,
* and 'placement' of <vcpu> is 'auto'.
*/
if (def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) {
- def->numatune.memory.placement_mode = VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO;
+ def->numatune.memory.placement_mode = VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO;
def->numatune.memory.mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
}
}
@@ -14818,7 +14807,7 @@ virDomainDefFormatInternal(virDomainDefPtr def,
virBufferAsprintf(buf, " <memory mode='%s' ", mode);
if (def->numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC) {
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC) {
nodemask = virBitmapFormat(def->numatune.memory.nodemask);
if (nodemask == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -14829,7 +14818,7 @@ virDomainDefFormatInternal(virDomainDefPtr def,
virBufferAsprintf(buf, "nodeset='%s'/>\n", nodemask);
VIR_FREE(nodemask);
} else if (def->numatune.memory.placement_mode) {
- placement = virDomainNumatuneMemPlacementModeTypeToString(def->numatune.memory.placement_mode);
+ placement = virNumaTuneMemPlacementModeTypeToString(def->numatune.memory.placement_mode);
virBufferAsprintf(buf, "placement='%s'/>\n", placement);
}
virBufferAddLit(buf, " </numatune>\n");
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index bfc37a0..6d856a3 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -47,6 +47,7 @@
# include "device_conf.h"
# include "virbitmap.h"
# include "virstoragefile.h"
+# include "virnuma.h"
/* forward declarations of all device types, required by
* virDomainDeviceDef
@@ -1605,14 +1606,6 @@ enum virDomainCpuPlacementMode {
VIR_DOMAIN_CPU_PLACEMENT_MODE_LAST
};
-enum virDomainNumatuneMemPlacementMode {
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_DEFAULT = 0,
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC,
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO,
-
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_LAST
-};
-
typedef struct _virDomainTimerCatchupDef virDomainTimerCatchupDef;
typedef virDomainTimerCatchupDef *virDomainTimerCatchupDefPtr;
struct _virDomainTimerCatchupDef {
@@ -1701,18 +1694,6 @@ virDomainVcpuPinDefPtr virDomainVcpuPinFindByVcpu(virDomainVcpuPinDefPtr *def,
int nvcpupin,
int vcpu);
-typedef struct _virDomainNumatuneDef virDomainNumatuneDef;
-typedef virDomainNumatuneDef *virDomainNumatuneDefPtr;
-struct _virDomainNumatuneDef {
- struct {
- virBitmapPtr nodemask;
- int mode;
- int placement_mode; /* enum virDomainNumatuneMemPlacementMode */
- } memory;
-
- /* Future NUMA tuning related stuff should go here. */
-};
-
typedef struct _virBlkioDeviceWeight virBlkioDeviceWeight;
typedef virBlkioDeviceWeight *virBlkioDeviceWeightPtr;
struct _virBlkioDeviceWeight {
@@ -1802,7 +1783,7 @@ struct _virDomainDef {
virDomainVcpuPinDefPtr emulatorpin;
} cputune;
- virDomainNumatuneDef numatune;
+ virNumaTuneDef numatune;
/* These 3 are based on virDomainLifeCycleAction enum flags */
int onReboot;
@@ -2397,8 +2378,6 @@ VIR_ENUM_DECL(virDomainGraphicsSpicePlaybackCompression)
VIR_ENUM_DECL(virDomainGraphicsSpiceStreamingMode)
VIR_ENUM_DECL(virDomainGraphicsSpiceClipboardCopypaste)
VIR_ENUM_DECL(virDomainGraphicsSpiceMouseMode)
-VIR_ENUM_DECL(virDomainNumatuneMemMode)
-VIR_ENUM_DECL(virDomainNumatuneMemPlacementMode)
VIR_ENUM_DECL(virDomainHyperv)
VIR_ENUM_DECL(virDomainRNGModel)
VIR_ENUM_DECL(virDomainRNGBackend)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index dc01bfa..8890859 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -252,10 +252,6 @@ virDomainNetRemove;
virDomainNetTypeToString;
virDomainNostateReasonTypeFromString;
virDomainNostateReasonTypeToString;
-virDomainNumatuneMemModeTypeFromString;
-virDomainNumatuneMemModeTypeToString;
-virDomainNumatuneMemPlacementModeTypeFromString;
-virDomainNumatuneMemPlacementModeTypeToString;
virDomainObjAssignDef;
virDomainObjCopyPersistentDef;
virDomainObjGetPersistentDef;
@@ -1557,7 +1553,12 @@ virNodeSuspendGetTargetMask;
# util/virnuma.h
+virDomainNumatuneMemModeTypeFromString;
+virDomainNumatuneMemModeTypeToString;
+virNumaTuneMemPlacementModeTypeFromString;
+virNumaTuneMemPlacementModeTypeToString;
virNumaGetAutoPlacementAdvice;
+virNumaSetupMemoryPolicy;
# util/virobject.h
virClassForObject;
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index 405205c..f19f8c1 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -46,11 +46,6 @@
# include <cap-ng.h>
#endif
-#if WITH_NUMACTL
-# define NUMA_VERSION1_COMPATIBILITY 1
-# include <numa.h>
-#endif
-
#include "virerror.h"
#include "virlog.h"
#include "virutil.h"
@@ -469,113 +464,6 @@ cleanup:
return ret;
}
-#if WITH_NUMACTL
-static int virLXCControllerSetupNUMAPolicy(virLXCControllerPtr ctrl,
- virBitmapPtr nodemask)
-{
- nodemask_t mask;
- int mode = -1;
- int node = -1;
- int ret = -1;
- int i = 0;
- int maxnode = 0;
- bool warned = false;
- virDomainNumatuneDef numatune = ctrl->def->numatune;
- virBitmapPtr tmp_nodemask = NULL;
-
- if (numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC) {
- if (!numatune.memory.nodemask)
- return 0;
- VIR_DEBUG("Set NUMA memory policy with specified nodeset");
- tmp_nodemask = numatune.memory.nodemask;
- } else if (numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO) {
- VIR_DEBUG("Set NUMA memory policy with advisory nodeset from numad");
- tmp_nodemask = nodemask;
- } else {
- return 0;
- }
-
- VIR_DEBUG("Setting NUMA memory policy");
-
- if (numa_available() < 0) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- "%s", _("Host kernel is not aware of NUMA."));
- return -1;
- }
-
- maxnode = numa_max_node() + 1;
-
- /* Convert nodemask to NUMA bitmask. */
- nodemask_zero(&mask);
- i = -1;
- while ((i = virBitmapNextSetBit(tmp_nodemask, i)) >= 0) {
- if (i > NUMA_NUM_NODES) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("Host cannot support NUMA node %d"), i);
- return -1;
- }
- if (i > maxnode && !warned) {
- VIR_WARN("nodeset is out of range, there is only %d NUMA "
- "nodes on host", maxnode);
- warned = true;
- }
- nodemask_set(&mask, i);
- }
-
- mode = ctrl->def->numatune.memory.mode;
-
- if (mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
- numa_set_bind_policy(1);
- numa_set_membind(&mask);
- numa_set_bind_policy(0);
- } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_PREFERRED) {
- int nnodes = 0;
- for (i = 0; i < NUMA_NUM_NODES; i++) {
- if (nodemask_isset(&mask, i)) {
- node = i;
- nnodes++;
- }
- }
-
- if (nnodes != 1) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- "%s", _("NUMA memory tuning in 'preferred' mode "
- "only supports single node"));
- goto cleanup;
- }
-
- numa_set_bind_policy(0);
- numa_set_preferred(node);
- } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE) {
- numa_set_interleave_mask(&mask);
- } else {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("Unable to set NUMA policy %s"),
- virDomainNumatuneMemModeTypeToString(mode));
- goto cleanup;
- }
-
- ret = 0;
-
-cleanup:
- return ret;
-}
-#else
-static int virLXCControllerSetupNUMAPolicy(virLXCControllerPtr ctrl,
- virBitmapPtr nodemask ATTRIBUTE_UNUSED)
-{
- if (ctrl->def->numatune.memory.nodemask) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("NUMA policy is not available on this platform"));
- return -1;
- }
-
- return 0;
-}
-#endif
-
/*
* To be run while still single threaded
@@ -638,7 +526,7 @@ static int virLXCControllerGetNumadAdvice(virLXCControllerPtr ctrl,
if ((ctrl->def->placement_mode ==
VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) ||
(ctrl->def->numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)) {
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO)) {
nodeset = virNumaGetAutoPlacementAdvice(ctrl->def->vcpus,
ctrl->def->mem.cur_balloon);
if (!nodeset)
@@ -675,7 +563,7 @@ static int virLXCControllerSetupResourceLimits(virLXCControllerPtr ctrl,
int ret = -1;
if (virLXCControllerGetNumadAdvice(ctrl, &nodemask) < 0 ||
- virLXCControllerSetupNUMAPolicy(ctrl, nodemask) < 0)
+ virNumaSetupMemoryPolicy(ctrl->def->numatune, nodemask) < 0)
goto cleanup;
if (virLXCControllerSetupCpuAffinity(ctrl) < 0)
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 9d6e88b..c9b4ca2 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -423,12 +423,12 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
if ((vm->def->numatune.memory.nodemask ||
(vm->def->numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)) &&
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO)) &&
vm->def->numatune.memory.mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) {
char *mask = NULL;
if (vm->def->numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO)
mask = virBitmapFormat(nodemask);
else
mask = virBitmapFormat(vm->def->numatune.memory.nodemask);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 9cd9e44..f057d38 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7648,7 +7648,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
virBitmapFree(vm->def->numatune.memory.nodemask);
vm->def->numatune.memory.placement_mode =
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC;
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC;
vm->def->numatune.memory.nodemask = virBitmapNewCopy(nodeset);
}
@@ -7657,7 +7657,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
persistentDef->numatune.memory.nodemask = nodeset;
persistentDef->numatune.memory.placement_mode =
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC;
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC;
nodeset = NULL;
}
virBitmapFree(nodeset);
@@ -7667,7 +7667,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
if (!persistentDef->numatune.memory.placement_mode)
persistentDef->numatune.memory.placement_mode =
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO;
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO;
if (virDomainSaveConfig(cfg->configDir, persistentDef) < 0)
ret = -1;
}
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 2465938..fcb3c50 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -45,11 +45,6 @@
#include "qemu_bridge_filter.h"
#include "qemu_migration.h"
-#if WITH_NUMACTL
-# define NUMA_VERSION1_COMPATIBILITY 1
-# include <numa.h>
-#endif
-
#include "datatypes.h"
#include "virlog.h"
#include "virerror.h"
@@ -1791,120 +1786,6 @@ qemuProcessDetectVcpuPIDs(virQEMUDriverPtr driver,
}
-/*
- * Set NUMA memory policy for qemu process, to be run between
- * fork/exec of QEMU only.
- */
-#if WITH_NUMACTL
-static int
-qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm,
- virBitmapPtr nodemask)
-{
- nodemask_t mask;
- int mode = -1;
- int node = -1;
- int ret = -1;
- int i = 0;
- int maxnode = 0;
- bool warned = false;
- virDomainNumatuneDef numatune = vm->def->numatune;
- virBitmapPtr tmp_nodemask = NULL;
-
- if (numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC) {
- if (!numatune.memory.nodemask)
- return 0;
- VIR_DEBUG("Set NUMA memory policy with specified nodeset");
- tmp_nodemask = numatune.memory.nodemask;
- } else if (numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO) {
- VIR_DEBUG("Set NUMA memory policy with advisory nodeset from numad");
- tmp_nodemask = nodemask;
- } else {
- return 0;
- }
-
- if (numa_available() < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("Host kernel is not aware of NUMA."));
- return -1;
- }
-
- maxnode = numa_max_node() + 1;
- /* Convert nodemask to NUMA bitmask. */
- nodemask_zero(&mask);
- i = -1;
- while ((i = virBitmapNextSetBit(tmp_nodemask, i)) >= 0) {
- if (i > NUMA_NUM_NODES) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Host cannot support NUMA node %d"), i);
- return -1;
- }
- if (i > maxnode && !warned) {
- VIR_WARN("nodeset is out of range, there is only %d NUMA "
- "nodes on host", maxnode);
- warned = true;
- }
- nodemask_set(&mask, i);
- }
-
- mode = numatune.memory.mode;
-
- if (mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
- numa_set_bind_policy(1);
- numa_set_membind(&mask);
- numa_set_bind_policy(0);
- } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_PREFERRED) {
- int nnodes = 0;
- for (i = 0; i < NUMA_NUM_NODES; i++) {
- if (nodemask_isset(&mask, i)) {
- node = i;
- nnodes++;
- }
- }
-
- if (nnodes != 1) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("NUMA memory tuning in 'preferred' mode "
- "only supports single node"));
- goto cleanup;
- }
-
- numa_set_bind_policy(0);
- numa_set_preferred(node);
- } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE) {
- numa_set_interleave_mask(&mask);
- } else {
- /* XXX: Shouldn't go here, as we already do checking when
- * parsing domain XML.
- */
- virReportError(VIR_ERR_XML_ERROR,
- "%s", _("Invalid mode for memory NUMA tuning."));
- goto cleanup;
- }
-
- ret = 0;
-
-cleanup:
- return ret;
-}
-#else
-static int
-qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm,
- virBitmapPtr nodemask ATTRIBUTE_UNUSED)
-{
- if (vm->def->numatune.memory.nodemask) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("libvirt is compiled without NUMA tuning support"));
-
- return -1;
- }
-
- return 0;
-}
-#endif
-
-
/* Helper to prepare cpumap for affinity setting, convert
* NUMA nodeset into cpuset if @nodemask is not NULL, otherwise
* just return a new allocated bitmap.
@@ -2654,7 +2535,7 @@ static int qemuProcessHook(void *data)
qemuProcessInitCpuAffinity(h->driver, h->vm, h->nodemask) < 0)
goto cleanup;
- if (qemuProcessInitNumaMemoryPolicy(h->vm, h->nodemask) < 0)
+ if (virNumaSetupMemoryPolicy(h->vm->def->numatune, h->nodemask) < 0)
goto cleanup;
ret = 0;
@@ -3608,7 +3489,7 @@ int qemuProcessStart(virConnectPtr conn,
if ((vm->def->placement_mode ==
VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) ||
(vm->def->numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)) {
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO)) {
nodeset = virNumaGetAutoPlacementAdvice(vm->def->vcpus,
vm->def->mem.cur_balloon);
if (!nodeset)
diff --git a/src/util/virnuma.c b/src/util/virnuma.c
index f6a6eb2..bace06f 100644
--- a/src/util/virnuma.c
+++ b/src/util/virnuma.c
@@ -21,12 +21,30 @@
#include <config.h>
+#if WITH_NUMACTL
+# define NUMA_VERSION1_COMPATIBILITY 1
+# include <numa.h>
+#endif
+
#include "virnuma.h"
#include "vircommand.h"
#include "virerror.h"
+#include "virlog.h"
#define VIR_FROM_THIS VIR_FROM_NONE
+VIR_ENUM_IMPL(virDomainNumatuneMemMode,
+ VIR_DOMAIN_NUMATUNE_MEM_LAST,
+ "strict",
+ "preferred",
+ "interleave");
+
+VIR_ENUM_IMPL(virNumaTuneMemPlacementMode,
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_LAST,
+ "default",
+ "static",
+ "auto");
+
#if HAVE_NUMAD
char *
virNumaGetAutoPlacementAdvice(unsigned short vcpus,
@@ -59,3 +77,111 @@ virNumaGetAutoPlacementAdvice(unsigned short vcpus ATTRIBUTE_UNUSED,
return NULL;
}
#endif
+
+#if WITH_NUMACTL
+int
+virNumaSetupMemoryPolicy(virNumaTuneDef numatune,
+ virBitmapPtr nodemask)
+{
+ nodemask_t mask;
+ int mode = -1;
+ int node = -1;
+ int ret = -1;
+ int i = 0;
+ int maxnode = 0;
+ bool warned = false;
+ virBitmapPtr tmp_nodemask = NULL;
+
+ if (numatune.memory.placement_mode ==
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC) {
+ if (!numatune.memory.nodemask)
+ return 0;
+ VIR_DEBUG("Set NUMA memory policy with specified nodeset");
+ tmp_nodemask = numatune.memory.nodemask;
+ } else if (numatune.memory.placement_mode ==
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO) {
+ VIR_DEBUG("Set NUMA memory policy with advisory nodeset from numad");
+ tmp_nodemask = nodemask;
+ } else {
+ return 0;
+ }
+
+ if (numa_available() < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Host kernel is not aware of NUMA."));
+ return -1;
+ }
+
+ maxnode = numa_max_node() + 1;
+ /* Convert nodemask to NUMA bitmask. */
+ nodemask_zero(&mask);
+ i = -1;
+ while ((i = virBitmapNextSetBit(tmp_nodemask, i)) >= 0) {
+ if (i > NUMA_NUM_NODES) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Host cannot support NUMA node %d"), i);
+ return -1;
+ }
+ if (i > maxnode && !warned) {
+ VIR_WARN("nodeset is out of range, there is only %d NUMA "
+ "nodes on host", maxnode);
+ warned = true;
+ }
+ nodemask_set(&mask, i);
+ }
+
+ mode = numatune.memory.mode;
+
+ if (mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
+ numa_set_bind_policy(1);
+ numa_set_membind(&mask);
+ numa_set_bind_policy(0);
+ } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_PREFERRED) {
+ int nnodes = 0;
+ for (i = 0; i < NUMA_NUM_NODES; i++) {
+ if (nodemask_isset(&mask, i)) {
+ node = i;
+ nnodes++;
+ }
+ }
+
+ if (nnodes != 1) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("NUMA memory tuning in 'preferred' mode "
+ "only supports single node"));
+ goto cleanup;
+ }
+
+ numa_set_bind_policy(0);
+ numa_set_preferred(node);
+ } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE) {
+ numa_set_interleave_mask(&mask);
+ } else {
+ /* XXX: Shouldn't go here, as we already do checking when
+ * parsing domain XML.
+ */
+ virReportError(VIR_ERR_XML_ERROR,
+ "%s", _("Invalid mode for memory NUMA tuning."));
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ return ret;
+}
+#else
+int
+virNumaSetupMemoryPolicy(virNumaTuneDef numatune,
+ virBitmapPtr nodemask ATTRIBUTE_UNUSED)
+{
+ if (numatune.memory.nodemask) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("libvirt is compiled without NUMA tuning support"));
+
+ return -1;
+ }
+
+ return 0;
+}
+#endif
diff --git a/src/util/virnuma.h b/src/util/virnuma.h
index d3d7d3e..9ff8e69 100644
--- a/src/util/virnuma.h
+++ b/src/util/virnuma.h
@@ -22,7 +22,37 @@
#ifndef __VIR_NUMA_H__
# define __VIR_NUMA_H__
+# include "internal.h"
+# include "virbitmap.h"
+# include "virutil.h"
+
+enum virNumaTuneMemPlacementMode {
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_DEFAULT = 0,
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC,
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO,
+
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_LAST
+};
+
+VIR_ENUM_DECL(virNumaTuneMemPlacementMode)
+
+VIR_ENUM_DECL(virDomainNumatuneMemMode)
+
+typedef struct _virNumaTuneDef virNumaTuneDef;
+typedef virNumaTuneDef *virNumaTuneDefPtr;
+struct _virNumaTuneDef {
+ struct {
+ virBitmapPtr nodemask;
+ int mode;
+ int placement_mode; /* enum virNumaTuneMemPlacementMode */
+ } memory;
+
+ /* Future NUMA tuning related stuff should go here. */
+};
+
char *virNumaGetAutoPlacementAdvice(unsigned short vcups,
unsigned long long balloon);
+int virNumaSetupMemoryPolicy(virNumaTuneDef numatune,
+ virBitmapPtr nodemask);
#endif /* __VIR_NUMA_H__ */
--
1.7.11.7
12 years, 1 month
Re: [libvirt] Consultation of the patch "util: Prepare helpers for unpriv_sgio setting"
by yuxh
On 03/13/2013 11:33 AM, Osier Yang wrote:
> On 2013年03月13日 11:04, yuxh wrote:
>> To Osier Yang
>>
>> Sorry for disturbing you on the working time, but I really need your
>> help.
>> I met a problem when I do the virtualization test on the environment of
>> (Host: RHEL6.4GA. Guest: RHEL6.4GA) and it seems to have relationship
>> with your patch of "util: Prepare helpers for unpriv_sgio setting".
>
> Never mind, it's the bug I produced. :(
>
>>
>> I added a disk to virtio-scsi bus through the VM's XML file like this:
>> <disk type='block' device='disk'>
>> <driver name='qemu' type='raw' io='threads'/>
>> <source dev='/mnt/test.raw'/>
>> <target dev='sdb' bus='scsi'/>
>> <shareable/>
>> </disk>
>>
>> Then when I started the VM, I met the error.
>> [root@build SOURCES]# virsh start pan64ga
>> error: Failed to start domain pan64ga
>> error: Unable to get minor number of device '/mnt/test.raw': Invalid
>> argument
>>
>> [root@build SOURCES]#
>>
>> I tried other source files and other way of using if and I found:
>> 1). If we use the files which format is raw, qed and qcow2 as the disk
>> this error occur again.
>> 2). If we use partition(such as /dev/sdb1) or whole disk(such as
>> /dev/sdb) this error doesn't occur.
>> 3). If we delete the "<shareable/>" then files, partition and disk all
>> can be used correctly.
>>
>> And I investigate the error msg. it is returned by qemuGetSharedDiskKey
>> fuction.
>> char *
>> qemuGetSharedDiskKey(const char *disk_path)
>> {
>> ...
>> // error occur here. return value is -22
>> if ((rc = virGetDeviceID(disk_path, &maj, &min)) < 0) {
>> virReportSystemError(-rc,
>> _("Unable to get minor number of device '%s'"),
>> disk_path);
>> return NULL;
>> }
>> ...
>> }
>>
>> Go on the virGetDeviceID fuction:
>> int
>> virGetDeviceID(const char *path, int *maj, int *min)
>> {
>> ...
>>
>> if (!S_ISBLK(sb.st_mode)) {
>> VIR_FREE(canonical_path);
>> return -EINVAL; // error occur here and it return -22
>> }
>> ...
>> }
>>
>> So the error occur place is "S_ISBLK(sb.st_mode)" and I tried compiled
>> the libvirt with these lines deleted and the error didn't happen again.
>> Also I checked the disk if VM and it worked well.
>> I found this fuction virGetDeviceID is come from your patch of "util:
>> Prepare helpers for unpriv_sgio setting". But I am not familiar with
>> libvirt.
>> So I have to consult with you about whether this "S_ISBLK" check is
>> vital and If we can delete it or
>> find out some method to avoid this error so we can use the file as
>> shared disk in VM.
>
> It's fixd by
> https://www.redhat.com/archives/libvir-list/2013-February/msg01024.html,
> which is already committed to upstream, and backported
> to 6.4.z. You will see the fix in the new build, which will come soon.
>
> Regards,
> Osier
Sorry, I have tried the the libvirt's upstream code and it still have
this error.
According to the code, if we use "<disk type='block' device='disk'> "
and "<shareable/> " to set the disk's configuration in VM's XML file, it
will go through like below:
int
qemuAddSharedDisk(virQEMUDriverPtr driver,
virDomainDiskDefPtr disk,
const char *name)
{ ...
if (!(key = qemuGetSharedDiskKey(disk->src)))
goto cleanup;
...
}
char *
qemuGetSharedDiskKey(const char *disk_path)
{
...
if ((rc = virGetDeviceID(disk_path, &maj, &min)) < 0) {
virReportSystemError(-rc,
_("Unable to get minor number of device
'%s'"),
disk_path);
return NULL;
}
...
}
int
virGetDeviceID(const char *path, int *maj, int *min)
{
struct stat sb;
if (stat(path, &sb) < 0)
return -errno;
if (!S_ISBLK(sb.st_mode))
return -EINVAL;
if (maj)
*maj = major(sb.st_rdev);
if (min)
*min = minor(sb.st_rdev);
return 0;
}
To make a long story short, the virGetDeviceID fuction want to get the
maj and min number of the source file which we provided as the VM's
disk. But the file such as /mnt/test.raw doesn't have the maj and min
number.
So virGetDeviceID return " -EINVAL" and qemuGetSharedDiskKey print the
error message of "Unable to get minor number of device /mnt/test.raw".
That's the reason the VM can't be started.
So I just want to know now, if the way I used a file to act as VM's disk
and set "<disk type='block' device='disk'>" , "<shareable/> " at the
same time is reasonable.
Thanks
yuxh
>
>
--
以上
第一软件事业部 第一开发部 driver组 于星海
Best Regards
--------------------------------------------------
Yu Xinghai
Development Dept.I
Nanjing Fujitsu Nanda Software Tech. Co., Ltd.(FNST)
No.6 Wenzhu Road, Nanjing, 210012, China
TEL: +86+25-86630566-8533
FUJITSU INTERNAL: 7998-8533
FAX: +86+25-83317685
MAIL: yuxinghai(a)cn.fujitsu.com
--------------------------------------------------
12 years, 1 month
[libvirt] [PATCH 1/1] Clean redundant code about VCPU string checking
by Li Zhang
From: Li Zhang <zhlcindy(a)linux.vnet.ibm.com>
Now that VCPU number are removed from qemu_monitor_text.c.
VCPU string checking also should be removed.
Report-by: John Ferlan <jferlan(a)redhat.com>
Signed-off-by: Li Zhang <zhlcindy(a)linux.vnet.ibm.com>
---
src/qemu/qemu_monitor_text.c | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 1b6efba..3a0c55f 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -527,17 +527,10 @@ int qemuMonitorTextGetCPUInfo(qemuMonitorPtr mon,
*/
line = qemucpus;
do {
- char *offset = strchr(line, '#');
+ char *offset = NULL;
char *end = NULL;
int tid = 0;
- /* See if we're all done */
- if (offset == NULL)
- break;
-
- if (end == NULL || *end != ':')
- goto error;
-
/* Extract host Thread ID */
if ((offset = strstr(line, "thread_id=")) == NULL)
goto error;
--
1.7.10.1
12 years, 1 month
[libvirt] [PATCH] Don't fail if SELinux is diabled
by Guido Günther
but libvirt is built with --with-selinux. In this case getpeercon
returns ENOPROTOOPT so dont' return an error in that case but simply
don't set seccon.
---
src/rpc/virnetsocket.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c
index 39504ac..c4fd9ee 100644
--- a/src/rpc/virnetsocket.c
+++ b/src/rpc/virnetsocket.c
@@ -1171,7 +1171,7 @@ int virNetSocketGetSecurityContext(virNetSocketPtr sock,
virObjectLock(sock);
if (getpeercon(sock->fd, &seccon) < 0) {
- if (errno == ENOSYS) {
+ if (errno == ENOSYS || errno == ENOPROTOOPT) {
ret = 0;
goto cleanup;
}
--
1.7.10.4
12 years, 1 month
[libvirt] [PATCH] clarify vmrsh net commands
by Gene Czarcinski
Clarify that net-create deals with a transient virtual
network whereas net-define defines a persistent virtual
network definition and will create the network (xml)
definition file.
Clarify that net-destroy works with both transient and
persistent virtual networks.
Change the comment about error checking with respect to
net-edit and net-define: same error checking and
diagnostics.
Signed-off-by: Gene Czarcinski <gene(a)czarc.net>
---
tools/virsh.pod | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/tools/virsh.pod b/tools/virsh.pod
index a5d8fe6..1fe08f4 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -2034,19 +2034,20 @@ The I<--disable> option disable autostarting.
=item B<net-create> I<file>
-Create a virtual network from an XML I<file>, see the documentation at
-L<http://libvirt.org/formatnetwork.html> to get a description of the
-XML network format used by libvirt.
+Create a transient (temporary) virtual network from an
+XML I<file> and instantiate (start) the network.
+See the documentation at L<http://libvirt.org/formatnetwork.html>
+to get a description of the XML network format used by libvirt.
=item B<net-define> I<file>
-Define a virtual network from an XML I<file>, the network is just defined but
-not instantiated.
+Define a persistent virtual network from an XML I<file>, the network is just defined but
+not instantiated (started).
=item B<net-destroy> I<network>
-Destroy (stop) a given virtual network specified by its name or UUID. This
-takes effect immediately.
+Destroy (stop) a given transient or persistent virtual network
+specified by its name or UUID. This takes effect immediately.
=item B<net-dumpxml> I<network> [I<--inactive>]
@@ -2064,7 +2065,8 @@ This is equivalent to:
vi network.xml (or make changes with your other text editor)
virsh net-define network.xml
-except that it does some error checking.
+The same error checking is performed by net-edit and net-define and
+the same diagnostic error messages will be issued.
The editor used can be supplied by the C<$VISUAL> or C<$EDITOR> environment
variables, and defaults to C<vi>.
--
1.8.1.4
12 years, 1 month
[libvirt] about Application_Development_Guide.pdf
by huyp1024
HI,buddy. I'm sheldon.
I'm trying to develop virtual machine lifecycle management software using libvirt.
I found the development guide is very useful,it helps a lot.
But this book I download from offical website is a draft,there are a lot of funcitons which are not claimed.
I appreciate very much that you give me some document that developers are being in reference to .
Best wishes! keep in touch.
Yours sincely!
.
12 years, 1 month
[libvirt] [PATCH 1/4] doc/schema: add ocfs2 to storage pool
by Philipp Hahn
Add ocfs2 for disk pool.
Signed-off-by: Philipp Hahn <hahn(a)univention.de>
---
docs/schemas/storagevol.rng | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/docs/schemas/storagevol.rng b/docs/schemas/storagevol.rng
index ba95c55..765c5a5 100644
--- a/docs/schemas/storagevol.rng
+++ b/docs/schemas/storagevol.rng
@@ -179,11 +179,10 @@
<value>vfat</value>
<value>hfs+</value>
<value>xfs</value>
+ <value>ocfs2</value>
</choice>
-
</define>
-
<define name='formatfile'>
<choice>
<value>unknown</value>
--
1.7.10.4
12 years, 1 month