Bug 950419

Summary: blockJobInfo python API run success but return None
Product: Red Hat Enterprise Linux 7 Reporter: Wayne Sun <gsun>
Component: libvirtAssignee: Gunannan Ren <gren>
Status: CLOSED CURRENTRELEASE QA Contact: Virtualization Bugs <virt-bugs>
Severity: medium Docs Contact:
Priority: medium    
Version: 7.0CC: acathrow, cwei, dallan, dyuan, gren, honzhang, mzhan
Target Milestone: rc   
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: libvirt-1.1.1-1.el7 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: 912172
: 999077 999454 (view as bug list) Environment:
Last Closed: 2014-06-13 09:41:00 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, 912172    
Bug Blocks: 999077, 999454    

Description Wayne Sun 2013-04-10 08:36:34 UTC
+++ This bug was initially created as a clone of Bug #912172 +++

the problem also on:
libvirt-1.0.2-1.el7.x86_64
libvirt-python-1.0.2-1.el7.x86_64

+++ This bug was initially created as a clone of Bug #912170 +++

Description of problem:
memoryStats fail did not raise libvirtError 

# 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')
>>> dom.memoryStats()
libvir: QEMU Driver error : Requested operation is not valid: domain is not running

user will fail to catch exception. 

Version-Release number of selected component (if applicable):
libvirt-0.10.2-18.el6.x86_64 

How reproducible:
always

Steps to Reproduce:
1. as description 
2.
3.
  
Actual results:
memoryStats fail did not raise libvirtError 

Expected results:
memoryStats fail raise libvirtError

>>> dom.memoryStats()
libvir: 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 memoryStats
    if ret is None: raise libvirtError ('virDomainMemoryStats() failed', dom=self)
libvirt.libvirtError: Requested operation is not valid: domain is not running


--- Additional comment from Gunannan Ren on 2013-03-20 23:25:41 EDT ---

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>

--- Additional comment from Wayne Sun on 2013-04-10 03:43:44 EDT ---

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:

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.

--- Additional comment from Gunannan Ren on 2013-04-10 04:28:50 EDT ---


> >>> 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;

Comment 2 Gunannan Ren 2013-05-17 06:56:45 UTC
proposed patch
https://www.redhat.com/archives/libvir-list/2013-May/msg01290.html

Comment 3 Gunannan Ren 2013-07-15 10:18:39 UTC
commit 0f9e67bfad96c4a2e69769d8a5908ee145a86766
Author: Guannan Ren <gren>
Date:   Fri May 17 14:30:10 2013 +0800

    python: return dictionary without value in case of no blockjob
    
    Currently, when there is no blockjob, dom.blockJobInfo('vda')
    still reports error because it doesn't distinguish return value 0 from -1.
    libvirt.libvirtError: virDomainGetBlockJobInfo() failed
    
    virDomainGetBlockJobInfo() API return value:
     -1 in case of failure, 0 when nothing found, 1 found.
    
    And use PyDict_SetItemString instead of PyDict_SetItem when key is
    of string type. PyDict_SetItemString increments key/value reference
    count, so call Py_DECREF() for value. For key, we don't need to
    do this, because PyDict_SetItemString will handle it internally.

Comment 4 hongming 2013-07-31 06:50:43 UTC
Verify it as follows.The result is expected.Move its status to VERIFIED.

Version
libvirt-1.1.1-1.el7.x86_64
libvirt-python-1.1.1-1.el7.x86_64


# virsh blockjob kvm-rhel7.0-x86_64-qcow2-virtio vda;echo $?

0

# python
Python 2.7.5 (default, May 28 2013, 19:05:42) 
[GCC 4.8.0 20130510 (Red Hat 4.8.0-5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import libvirt
>>> con = libvirt.open('')
>>> dom = con.lookupByName('kvm-rhel7.0-x86_64-qcow2-virtio')
>>> dom.blockJobInfo('vda')
{}

Comment 5 Ludek Smid 2014-06-13 09:41:00 UTC
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.