Bug 912172
| Summary: | memoryStats fail did not raise libvirtError | |||
|---|---|---|---|---|
| Product: | Red Hat Enterprise Linux 7 | Reporter: | Wayne Sun <gsun> | |
| Component: | libvirt | Assignee: | Gunannan Ren <gren> | |
| Status: | CLOSED CURRENTRELEASE | QA Contact: | Virtualization Bugs <virt-bugs> | |
| Severity: | medium | Docs Contact: | ||
| Priority: | medium | |||
| Version: | 7.0 | CC: | acathrow, cwei, dallan, dyuan, honzhang, mzhan | |
| Target Milestone: | rc | |||
| Target Release: | --- | |||
| Hardware: | x86_64 | |||
| OS: | Linux | |||
| Whiteboard: | ||||
| Fixed In Version: | libvirt-1.0.4-1.el7 | Doc Type: | Bug Fix | |
| Doc Text: | Story Points: | --- | ||
| Clone Of: | 912170 | |||
| : | 950419 (view as bug list) | Environment: | ||
| Last Closed: | 2014-06-13 10:07:44 UTC | Type: | Bug | |
| Regression: | --- | Mount Type: | --- | |
| Documentation: | --- | CRM: | ||
| Verified Versions: | Category: | --- | ||
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | ||
| Cloudforms Team: | --- | Target Upstream Version: | ||
| Embargoed: | ||||
| Bug Depends On: | 912170 | |||
| Bug Blocks: | 950419, 999077, 999454 | |||
|
Description
Wayne Sun
2013-02-18 02:32:49 UTC
patch sent to uptream https://www.redhat.com/archives/libvir-list/2013-March/msg00011.html commit 4b143ab23173000d1afa258726be0ff38cf2b386
Author: Guannan Ren <gren>
Date: Thu Mar 21 11:24:49 2013 +0800
python: fix bindings that don't raise an exception
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 to add 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>
pkgs: libvirt-1.0.4-1.el7.x86_64 libvirt-python-1.0.4-1.el7.x86_64 kernel-3.7.0-0.32.el7.x86_64 qemu-kvm-1.4.0-2.el7.x86_64 steps: # virsh list --all Id Name State ---------------------------------------------------- 2 aa running - test shut off # python Python 2.7.3 (default, Aug 10 2012, 02:54:27) [GCC 4.7.1 20120720 (Red Hat 4.7.1-5)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import libvirt >>> con = libvirt.open(None) >>> dom = con.lookupByName('test') >>> dom1 = con.lookupByName('aa') >>> con.listDomainsID() [2] >>> con.listDefinedDomains() ['test', 'qcow2'] >>> con.listAllDomains() [<libvirt.virDomain object at 0x188e090>, <libvirt.virDomain object at 0x188e0d0>, <libvirt.virDomain object at 0x188e110>] >>> con.listNetworks() ['default'] >>> con.listDefinedNetworks() [] >>> con.listAllNetworks() [<libvirt.virNetwork object at 0x188e0d0>] >>> dom.info() [5, 1048576L, 1048576L, 2, 0L] >>> dom.state() [5, 0] >>> dom.controlInfo() libvirt: QEMU Driver error : Requested operation is not valid: domain is not running Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib64/python2.7/site-packages/libvirt.py", line 1933, in controlInfo if ret is None: raise libvirtError ('virDomainGetControlInfo() failed', dom=self) libvirt.libvirtError: Requested operation is not valid: domain is not running >>> dom1.controlInfo() [0, 0, 0L] >>> dom.blockInfo('hda', 0) [8589934592L, 0L, 0L] >>> dom.jobInfo() libvirt: QEMU Driver error : Requested operation is not valid: domain is not running Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib64/python2.7/site-packages/libvirt.py", line 1981, in jobInfo if ret is None: raise libvirtError ('virDomainGetJobInfo() failed', dom=self) libvirt.libvirtError: Requested operation is not valid: domain is not running >>> dom1.jobInfo() [0, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L] >>> dom.jobStats() libvirt: QEMU Driver error : Requested operation is not valid: domain is not running Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib64/python2.7/site-packages/libvirt.py", line 1987, in jobStats if ret is None: raise libvirtError ('virDomainGetJobStats() failed', dom=self) libvirt.libvirtError: Requested operation is not valid: domain is not running >>> dom1.jobStats() {'type': 0} >>> con.getInfo() ['x86_64', 128784, 32, 1064, 2, 1, 8, 2] >>> con.getCPUStats(0) {'kernel': 5227810000000L, 'idle': 2597845980000000L, 'user': 268150000000L, 'iowait': 26050000000L} >>> con.getMemoryStats(0) {'total': 67086568L, 'free': 50861852L} >>> dom.blockStats('hda') libvirt: QEMU Driver error : Requested operation is not valid: domain is not running Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib64/python2.7/site-packages/libvirt.py", line 1921, in blockStats if ret is None: raise libvirtError ('virDomainBlockStats() failed', dom=self) libvirt.libvirtError: Requested operation is not valid: domain is not running >>> dom1.blockStats('hda') (46205L, 106440704L, 10594L, 57521152L, -1L) >>> dom.blockStatsFlags('hda') libvirt: QEMU Driver error : Requested operation is not valid: domain is not running Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib64/python2.7/site-packages/libvirt.py", line 1927, in blockStatsFlags if ret is None: raise libvirtError ('virDomainBlockStatsFlags() failed', dom=self) libvirt.libvirtError: Requested operation is not valid: domain is not running >>> dom1.blockStatsFlags('hda') {'wr_total_times': 5236427586L, 'rd_operations': 46205L, 'flush_total_times': 85025188017L, 'rd_total_times': 5232705574L, 'rd_bytes': 106440704L, 'flush_operations': 4779L, 'wr_operations': 10594L, 'wr_bytes': 57521152L} >>> dom.getCPUStats(2) libvirt: QEMU Driver error : Requested operation is not valid: domain is not running Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib64/python2.7/site-packages/libvirt.py", line 1957, in getCPUStats if ret is None: raise libvirtError ('virDomainGetCPUStats() failed', dom=self) libvirt.libvirtError: Requested operation is not valid: domain is not running >>> dom1.getCPUStats(2) [{'cpu_time': 340118248328L, 'system_time': 136740000000L, 'user_time': 7690000000L}] >>> dom.interfaceStats('vnet0') libvirt: QEMU Driver error : Requested operation is not valid: domain is not running Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib64/python2.7/site-packages/libvirt.py", line 1975, in interfaceStats if ret is None: raise libvirtError ('virDomainInterfaceStats() failed', dom=self) libvirt.libvirtError: Requested operation is not valid: domain is not running >>> dom1.interfaceStats('vnet0') (2638350L, 50301L, 0L, 0L, 42312L, 396L, 0L, 0L) >>> dom.memoryStats() libvirt: QEMU Driver error : Requested operation is not valid: domain is not running Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib64/python2.7/site-packages/libvirt.py", line 2005, in memoryStats if ret is None: raise libvirtError ('virDomainMemoryStats() failed', dom=self) libvirt.libvirtError: Requested operation is not valid: domain is not running >>> dom1.memoryStats() {'actual': 1048576L, 'rss': 371148L} >>> con.getCellsFreeMemory(0, 3) [52081434624L, 48385654784L] >>> dom.schedulerParameters() {'vcpu_quota': 0L, 'vcpu_period': 0L, 'emulator_period': 0L, 'emulator_quota': 0L, 'cpu_shares': 0L} >>> dom.schedulerParametersFlags() {'vcpu_quota': 0L, 'vcpu_period': 0L, 'emulator_period': 0L, 'emulator_quota': 0L, 'cpu_shares': 0L} >>> dom1.schedulerParametersFlags() {'vcpu_quota': -1L, 'vcpu_period': 100000L, 'emulator_period': 100000L, 'emulator_quota': -1L, 'cpu_shares': 1024L} >>> dom.vcpuPinInfo() [(True, True, True, True, True, True, True, True, False, False, False, False, False, False, False, False, True, True, True, True, True, True, True, True, False, False, False, False, False, False, False, False), (True, True, True, True, True, True, True, True, False, False, False, False, False, False, False, False, True, True, True, True, True, True, True, True, False, False, False, False, False, False, False, False)] >>> dom1.vcpuPinInfo() [(True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True), (True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True), (True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True), (True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True)] >>> dom.blkioParameters() {'device_weight': '', 'weight': 0} >>> dom1.blkioParameters() {'device_weight': '', 'weight': 500} >>> dom.memoryParameters() {'swap_hard_limit': 0L, 'hard_limit': 0L, 'soft_limit': 0L} >>> dom1.memoryParameters() {'swap_hard_limit': 9007199254740991L, 'hard_limit': 1824256L, 'soft_limit': 9007199254740991L} >>> dom.numaParameters() {'numa_nodeset': '', 'numa_mode': 0} >>> dom1.numaParameters() {'numa_nodeset': '0-1', 'numa_mode': 0} >>> dom1.interfaceParameters('vnet0') {'outbound.peak': 0, 'inbound.peak': 0, 'inbound.burst': 0, 'inbound.average': 0, 'outbound.average': 0, 'outbound.burst': 0} >>> dom.interfaceParameters('vnet0') libvirt: QEMU Driver error : invalid argument: Can't find device vnet0 Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib64/python2.7/site-packages/libvirt.py", line 1969, in interfaceParameters if ret is None: raise libvirtError ('virDomainGetInterfaceParameters() failed', dom=self) libvirt.libvirtError: invalid argument: Can't find device vnet0 >>> con.listStoragePools() ['default'] >>> con.listDefinedStoragePools() [] >>> con.listAllStoragePools() [<libvirt.virStoragePool object at 0x188e0d0>] >>> poolobj = con.listAllStoragePools()[0] >>> poolobj.listVolumes() ['test.img', 'qcow2_foo.img', 'qcow2.img'] >>> poolobj.listAllVolumes() [<libvirt.virStorageVol object at 0x188e210>, <libvirt.virStorageVol object at 0x188e110>, <libvirt.virStorageVol object at 0x188e290>] >>> poolobj.info() [2, 53660876800L, 38417567744L, 15243309056L] >>> volobj = poolobj.listAllVolumes()[0] >>> volobj.info() [0, 8589934592L, 0L] >>> con.numOfDevices(None) 189 >>> con.listAllDevices() [<libvirt.virNodeDevice object at 0x188e110>, <libvirt.virNodeDevice object at 0x188e0d0>,.....] >>> nodeobj.numOfCaps() 1 >>> nodeobj.listCaps() ['pci'] >>> con.listSecrets() [] >>> con.listAllSecrets() [] >>> con.listNWFilters() ['allow-arp', 'allow-dhcp-server', 'allow-dhcp', 'allow-incoming-ipv4', 'allow-ipv4', 'clean-traffic', 'no-arp-ip-spoofing', 'no-arp-mac-spoofing', 'no-arp-spoofing', 'no-ip-multicast', 'no-ip-spoofing', 'no-mac-broadcast', 'no-mac-spoofing', 'no-other-l2-traffic', 'no-other-rarp-traffic', 'qemu-announce-self-rarp', 'qemu-announce-self'] >>> con.listAllNWFilters() [<libvirt.virNWFilter object at 0x188e310>, <libvirt.virNWFilter object at 0x188e350>, <libvirt.virNWFilter object at 0x188e390>, <libvirt.virNWFilter object at 0x188e3d0>, <libvirt.virNWFilter object at 0x188e410>, <libvirt.virNWFilter object at 0x188e450>, <libvirt.virNWFilter object at 0x188e490>, <libvirt.virNWFilter object at 0x188e4d0>, <libvirt.virNWFilter object at 0x188e510>, <libvirt.virNWFilter object at 0x188e550>, <libvirt.virNWFilter object at 0x188e590>, <libvirt.virNWFilter object at 0x188e5d0>, <libvirt.virNWFilter object at 0x188e610>, <libvirt.virNWFilter object at 0x188e650>, <libvirt.virNWFilter object at 0x188e690>, <libvirt.virNWFilter object at 0x188e6d0>, <libvirt.virNWFilter object at 0x188e710>] >>> con.listInterfaces() ['eth0', 'lo'] >>> con.listDefinedInterfaces() [] >>> con.listAllInterfaces() [] >>> dom1.listAllSnapshots() [<libvirt.virDomainSnapshot object at 0x188e350>] >>> snap = dom1.listAllSnapshots()[0] >>> snap.listChildrenNames() [] >>> dom1.snapshotListNames() ['snap'] >>> snap.listAllChildren() [] >>> dom1.blockIoTune('hda') {'write_bytes_sec': 0L, 'total_iops_sec': 0L, 'read_iops_sec': 0L, 'read_bytes_sec': 0L, 'write_iops_sec': 0L, 'total_bytes_sec': 0L} >>> dom1.diskErrors() {} >>> dom.diskErrors() libvirt: QEMU Driver error : Requested operation is not valid: domain is not running Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib64/python2.7/site-packages/libvirt.py", line 1939, in diskErrors if ret is None: raise libvirtError ('virDomainGetDiskErrors() failed', dom=self) libvirt.libvirtError: Requested operation is not valid: domain is not running >>> con.getMemoryParameters() {'shm_pages_shared': 21L, 'shm_full_scans': 50L, 'shm_pages_to_scan': 100, 'shm_pages_unshared': 2947L, 'shm_sleep_millisecs': 20, 'shm_pages_sharing': 1532L, 'shm_pages_volatile': 677L} >>> con.getCPUMap() (32L, [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True], 32L) As far all affected API works fine except for blockJobInfo: # virsh blockjob aa hda;echo $? 0 >>> dom1.blockJobInfo('hda') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib64/python2.7/site-packages/libvirt.py", line 1909, in blockJobInfo if ret is None: raise libvirtError ('virDomainGetBlockJobInfo() failed', dom=self) libvirt.libvirtError: virDomainGetBlockJobInfo() failed >>> the return is None as no block job running, virsh not fail but python will raise exception.
> >>> dom1.blockJobInfo('hda')
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> File "/usr/lib64/python2.7/site-packages/libvirt.py", line 1909, in
> blockJobInfo
> if ret is None: raise libvirtError ('virDomainGetBlockJobInfo() failed',
> dom=self)
> libvirt.libvirtError: virDomainGetBlockJobInfo() failed
> >>>
>
> the return is None as no block job running, virsh not fail but python will
> raise exception.
The virDomainGetBlockJobInfo API
Returns -1 in case of failure, 0 when nothing found, 1 when info was found.
But in the python C stub, it doesn't distinguish the case of failure from nothing found like, I think there is a new bug found.
if (c_ret != 1)
return VIR_PY_NONE;
(In reply to comment #5) > > >>> dom1.blockJobInfo('hda') > > Traceback (most recent call last): > > File "<stdin>", line 1, in <module> > > File "/usr/lib64/python2.7/site-packages/libvirt.py", line 1909, in > > blockJobInfo > > if ret is None: raise libvirtError ('virDomainGetBlockJobInfo() failed', > > dom=self) > > libvirt.libvirtError: virDomainGetBlockJobInfo() failed > > >>> > > > > the return is None as no block job running, virsh not fail but python will > > raise exception. > > The virDomainGetBlockJobInfo API > Returns -1 in case of failure, 0 when nothing found, 1 when info was found. > > But in the python C stub, it doesn't distinguish the case of failure from > nothing found like, I think there is a new bug found. > > if (c_ret != 1) > return VIR_PY_NONE; filed a new bug to track this problem https://bugzilla.redhat.com/show_bug.cgi?id=950419 and mark this verified. This request was resolved in Red Hat Enterprise Linux 7.0. Contact your manager or support representative in case you have further questions about the request. |