[libvirt] [PATCH] Return right error code for baselineCPU

This Python interface code is returning a -1 on errors for the `baselineCPU' API. Since this API is supposed to return a pointer the error return value should really be VIR_PY_NONE. NB: I've checked all the other APIs in this file and this is the only pointer API that is returning -1. Signed-off-by: Don Dugger <donald.d.dugger@intel.com> --- python/libvirt-override.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/python/libvirt-override.c b/python/libvirt-override.c index c60747d..b471605 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -4471,13 +4471,13 @@ libvirt_virConnectBaselineCPU(PyObject *self ATTRIBUTE_UNUSED, ncpus = PyList_Size(list); if (VIR_ALLOC_N_QUIET(xmlcpus, ncpus) < 0) - return VIR_PY_INT_FAIL; + return VIR_PY_NONE; for (i = 0; i < ncpus; i++) { xmlcpus[i] = PyString_AsString(PyList_GetItem(list, i)); if (xmlcpus[i] == NULL) { VIR_FREE(xmlcpus); - return VIR_PY_INT_FAIL; + return VIR_PY_NONE; } } } @@ -4489,13 +4489,13 @@ libvirt_virConnectBaselineCPU(PyObject *self ATTRIBUTE_UNUSED, VIR_FREE(xmlcpus); if (base_cpu == NULL) - return VIR_PY_INT_FAIL; + return VIR_PY_NONE; pybase_cpu = PyString_FromString(base_cpu); VIR_FREE(base_cpu); if (pybase_cpu == NULL) - return VIR_PY_INT_FAIL; + return VIR_PY_NONE; return pybase_cpu; } -- 1.7.10.4 -- Don Dugger "Censeo Toto nos in Kansa esse decisse." - D. Gale n0ano@n0ano.com Ph: 303/443-3786

On Sat, Nov 23, 2013 at 3:15 PM, Don Dugger <n0ano@n0ano.com> wrote:
This Python interface code is returning a -1 on errors for the `baselineCPU' API. Since this API is supposed to return a pointer the error return value should really be VIR_PY_NONE.
NB: I've checked all the other APIs in this file and this is the only pointer API that is returning -1.
Signed-off-by: Don Dugger <donald.d.dugger@intel.com> --- python/libvirt-override.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/python/libvirt-override.c b/python/libvirt-override.c index c60747d..b471605 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -4471,13 +4471,13 @@ libvirt_virConnectBaselineCPU(PyObject *self ATTRIBUTE_UNUSED,
ncpus = PyList_Size(list); if (VIR_ALLOC_N_QUIET(xmlcpus, ncpus) < 0) - return VIR_PY_INT_FAIL; + return VIR_PY_NONE;
for (i = 0; i < ncpus; i++) { xmlcpus[i] = PyString_AsString(PyList_GetItem(list, i)); if (xmlcpus[i] == NULL) { VIR_FREE(xmlcpus); - return VIR_PY_INT_FAIL; + return VIR_PY_NONE; } } } @@ -4489,13 +4489,13 @@ libvirt_virConnectBaselineCPU(PyObject *self ATTRIBUTE_UNUSED, VIR_FREE(xmlcpus);
if (base_cpu == NULL) - return VIR_PY_INT_FAIL; + return VIR_PY_NONE;
pybase_cpu = PyString_FromString(base_cpu); VIR_FREE(base_cpu);
if (pybase_cpu == NULL) - return VIR_PY_INT_FAIL; + return VIR_PY_NONE;
return pybase_cpu; } -- 1.7.10.4
ACK. This is correct. But it obviously changes our API so I'm not really sure how we should handle this, (e.g. document the API as is as note that its broken or fix it). -- Doug Goldstein

On Sun, Nov 24, 2013 at 10:46:13AM -0600, Doug Goldstein wrote:
On Sat, Nov 23, 2013 at 3:15 PM, Don Dugger <n0ano@n0ano.com> wrote:
This Python interface code is returning a -1 on errors for the `baselineCPU' API. Since this API is supposed to return a pointer the error return value should really be VIR_PY_NONE.
NB: I've checked all the other APIs in this file and this is the only pointer API that is returning -1.
Signed-off-by: Don Dugger <donald.d.dugger@intel.com> --- python/libvirt-override.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/python/libvirt-override.c b/python/libvirt-override.c index c60747d..b471605 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -4471,13 +4471,13 @@ libvirt_virConnectBaselineCPU(PyObject *self ATTRIBUTE_UNUSED,
ncpus = PyList_Size(list); if (VIR_ALLOC_N_QUIET(xmlcpus, ncpus) < 0) - return VIR_PY_INT_FAIL; + return VIR_PY_NONE;
for (i = 0; i < ncpus; i++) { xmlcpus[i] = PyString_AsString(PyList_GetItem(list, i)); if (xmlcpus[i] == NULL) { VIR_FREE(xmlcpus); - return VIR_PY_INT_FAIL; + return VIR_PY_NONE; } } } @@ -4489,13 +4489,13 @@ libvirt_virConnectBaselineCPU(PyObject *self ATTRIBUTE_UNUSED, VIR_FREE(xmlcpus);
if (base_cpu == NULL) - return VIR_PY_INT_FAIL; + return VIR_PY_NONE;
pybase_cpu = PyString_FromString(base_cpu); VIR_FREE(base_cpu);
if (pybase_cpu == NULL) - return VIR_PY_INT_FAIL; + return VIR_PY_NONE;
return pybase_cpu; } -- 1.7.10.4
ACK. This is correct. But it obviously changes our API so I'm not really sure how we should handle this, (e.g. document the API as is as note that its broken or fix it).
I'd say this _also_ depends also on how things are documented. Since I'm not aware of any documentation explicitly mentioning that this particular (an only python) API should return -1 in case of allocation error, I'd say this was an error all along. I'd also say go ahead with it since this is the proper behavior and I can't imagine a project where one would rely on this API to return -1 for allocation errors without a OOM exception instead of all others. OTOH, though, there are places where similar behavior was already many times said to be "kept for consistency" (e.g. public *Free() functions segfaulting with NULL parameter, even though the HACKING file says they should be no-op in that case), so I must say this is a thing I cannot clearly resolve with my own logic. In case of voting, I'm all for cleaning this 3yo mistake. My $0.02, Martin

On Sun, Nov 24, 2013 at 10:46:13AM -0600, Doug Goldstein wrote:
On Sat, Nov 23, 2013 at 3:15 PM, Don Dugger <n0ano@n0ano.com> wrote:
This Python interface code is returning a -1 on errors for the `baselineCPU' API. Since this API is supposed to return a pointer the error return value should really be VIR_PY_NONE.
NB: I've checked all the other APIs in this file and this is the only pointer API that is returning -1.
Signed-off-by: Don Dugger <donald.d.dugger@intel.com> --- python/libvirt-override.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/python/libvirt-override.c b/python/libvirt-override.c index c60747d..b471605 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -4471,13 +4471,13 @@ libvirt_virConnectBaselineCPU(PyObject *self ATTRIBUTE_UNUSED,
ncpus = PyList_Size(list); if (VIR_ALLOC_N_QUIET(xmlcpus, ncpus) < 0) - return VIR_PY_INT_FAIL; + return VIR_PY_NONE;
for (i = 0; i < ncpus; i++) { xmlcpus[i] = PyString_AsString(PyList_GetItem(list, i)); if (xmlcpus[i] == NULL) { VIR_FREE(xmlcpus); - return VIR_PY_INT_FAIL; + return VIR_PY_NONE; } } } @@ -4489,13 +4489,13 @@ libvirt_virConnectBaselineCPU(PyObject *self ATTRIBUTE_UNUSED, VIR_FREE(xmlcpus);
if (base_cpu == NULL) - return VIR_PY_INT_FAIL; + return VIR_PY_NONE;
pybase_cpu = PyString_FromString(base_cpu); VIR_FREE(base_cpu);
if (pybase_cpu == NULL) - return VIR_PY_INT_FAIL; + return VIR_PY_NONE;
return pybase_cpu; } -- 1.7.10.4
ACK. This is correct. But it obviously changes our API so I'm not really sure how we should handle this, (e.g. document the API as is as note that its broken or fix it).
The implicit expectation with python APIs is that they all raise an exception if the libvirt call fails. So ACK to this bug fix & we should put it in maint branches. That said, please hold off applying this to GIT. We'll put it into the new libvirt-python git I'm about to push instead. Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On Mon, Nov 25, 2013 at 10:45:38AM +0000, Daniel P. Berrange wrote:
On Sun, Nov 24, 2013 at 10:46:13AM -0600, Doug Goldstein wrote:
On Sat, Nov 23, 2013 at 3:15 PM, Don Dugger <n0ano@n0ano.com> wrote:
This Python interface code is returning a -1 on errors for the `baselineCPU' API. Since this API is supposed to return a pointer the error return value should really be VIR_PY_NONE.
...
ACK. This is correct. But it obviously changes our API so I'm not really sure how we should handle this, (e.g. document the API as is as note that its broken or fix it).
The implicit expectation with python APIs is that they all raise an exception if the libvirt call fails. So ACK to this bug fix & we should put it in maint branches.
Much as I hate to raise the issue this assumption is true for pointer APIs but APIs that return an integer don't raise an exception, they just return -1. Obviously, changing this behavior would be way too invasive but documenting this behavior should be done somewhere. -- Don Dugger "Censeo Toto nos in Kansa esse decisse." - D. Gale n0ano@n0ano.com Ph: 303/443-3786

On Mon, Nov 25, 2013 at 08:40:41AM -0700, Don Dugger wrote:
On Mon, Nov 25, 2013 at 10:45:38AM +0000, Daniel P. Berrange wrote:
On Sun, Nov 24, 2013 at 10:46:13AM -0600, Doug Goldstein wrote:
On Sat, Nov 23, 2013 at 3:15 PM, Don Dugger <n0ano@n0ano.com> wrote:
This Python interface code is returning a -1 on errors for the `baselineCPU' API. Since this API is supposed to return a pointer the error return value should really be VIR_PY_NONE.
...
ACK. This is correct. But it obviously changes our API so I'm not really sure how we should handle this, (e.g. document the API as is as note that its broken or fix it).
The implicit expectation with python APIs is that they all raise an exception if the libvirt call fails. So ACK to this bug fix & we should put it in maint branches.
Much as I hate to raise the issue this assumption is true for pointer APIs but APIs that return an integer don't raise an exception, they just return -1. Obviously, changing this behavior would be way too invasive but documenting this behavior should be done somewhere.
What APIs in particular ? Any API which results in a libvirt error being set should be translated into an exception in the python. This is done whether they're APIs returning NULL pointers or -1 ints. If there are other exceptions to the rule they must be fixed too. Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On Mon, Nov 25, 2013 at 03:48:45PM +0000, Daniel P. Berrange wrote:
On Mon, Nov 25, 2013 at 08:40:41AM -0700, Don Dugger wrote:
On Mon, Nov 25, 2013 at 10:45:38AM +0000, Daniel P. Berrange wrote:
On Sun, Nov 24, 2013 at 10:46:13AM -0600, Doug Goldstein wrote:
On Sat, Nov 23, 2013 at 3:15 PM, Don Dugger <n0ano@n0ano.com> wrote:
This Python interface code is returning a -1 on errors for the `baselineCPU' API. Since this API is supposed to return a pointer the error return value should really be VIR_PY_NONE.
...
ACK. This is correct. But it obviously changes our API so I'm not really sure how we should handle this, (e.g. document the API as is as note that its broken or fix it).
The implicit expectation with python APIs is that they all raise an exception if the libvirt call fails. So ACK to this bug fix & we should put it in maint branches.
Much as I hate to raise the issue this assumption is true for pointer APIs but APIs that return an integer don't raise an exception, they just return -1. Obviously, changing this behavior would be way too invasive but documenting this behavior should be done somewhere.
What APIs in particular ? Any API which results in a libvirt error being set should be translated into an exception in the python. This is done whether they're APIs returning NULL pointers or -1 ints. If there are other exceptions to the rule they must be fixed too.
I'm basing this on code inspection so I could be wrong but if you look at the Python interface code for libvirt_virDomainSetSchedulerParameters it checks the return value from virDomainSetSchedulerParameters and, if it is <0, then the Pythong code returns -1, without raising an exception.
Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
-- Don Dugger "Censeo Toto nos in Kansa esse decisse." - D. Gale n0ano@n0ano.com Ph: 303/443-3786

On 11/25/2013 08:55 AM, Don Dugger wrote:
I'm basing this on code inspection so I could be wrong but if you look at the Python interface code for libvirt_virDomainSetSchedulerParameters it checks the return value from virDomainSetSchedulerParameters and, if it is <0, then the Pythong code returns -1, without raising an exception.
We have two layers of python code. The libvirt-override.c layer returns None/-1 if a libvirt error is present, then the generated layer turns that into a python exception to the end user. Look at the generated libvirt.py for a lot of examples of code that does: if ret == -1: raise libvirtError ('... failed') for anything where the C code fails with a -1, and does: if ret is None: raise libvirtError ('... failed') for anything where the C code fails with NULL. The bug that we are fixing here is that we were returning -1 instead of None for C code that fails with NULL, so the generated wrapper was not properly throwing a libvirtError. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On Mon, Nov 25, 2013 at 08:55:12AM -0700, Don Dugger wrote:
On Mon, Nov 25, 2013 at 03:48:45PM +0000, Daniel P. Berrange wrote:
On Mon, Nov 25, 2013 at 08:40:41AM -0700, Don Dugger wrote:
On Mon, Nov 25, 2013 at 10:45:38AM +0000, Daniel P. Berrange wrote:
On Sun, Nov 24, 2013 at 10:46:13AM -0600, Doug Goldstein wrote:
On Sat, Nov 23, 2013 at 3:15 PM, Don Dugger <n0ano@n0ano.com> wrote:
This Python interface code is returning a -1 on errors for the `baselineCPU' API. Since this API is supposed to return a pointer the error return value should really be VIR_PY_NONE.
...
ACK. This is correct. But it obviously changes our API so I'm not really sure how we should handle this, (e.g. document the API as is as note that its broken or fix it).
The implicit expectation with python APIs is that they all raise an exception if the libvirt call fails. So ACK to this bug fix & we should put it in maint branches.
Much as I hate to raise the issue this assumption is true for pointer APIs but APIs that return an integer don't raise an exception, they just return -1. Obviously, changing this behavior would be way too invasive but documenting this behavior should be done somewhere.
What APIs in particular ? Any API which results in a libvirt error being set should be translated into an exception in the python. This is done whether they're APIs returning NULL pointers or -1 ints. If there are other exceptions to the rule they must be fixed too.
I'm basing this on code inspection so I could be wrong but if you look at the Python interface code for libvirt_virDomainSetSchedulerParameters it checks the return value from virDomainSetSchedulerParameters and, if it is <0, then the Pythong code returns -1, without raising an exception.
That code is the low-level module (called libvirtmod) which interfaces to the C library, and is not called directly by applications. Applications call the main module (called libvirt) which translates to the lowlevel module. eg in this case it does: def setSchedulerParametersFlags(self, params, flags=0): """Change the scheduler parameters """ ret = libvirtmod.virDomainSetSchedulerParametersFlags(self._o, params, flags) if ret == -1: raise libvirtError ('virDomainSetSchedulerParametersFlags() failed', dom=self) return ret so the -1 error is turned into an exception for applications. The flaw the original patch in this thread was fixing is that the low level libvirtmod was returning NULL, where the high level libvirt expected to see -1, so the exception translation was missed. Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On Mon, Nov 25, 2013 at 04:02:37PM +0000, Daniel P. Berrange wrote:
On Mon, Nov 25, 2013 at 08:55:12AM -0700, Don Dugger wrote:
On Mon, Nov 25, 2013 at 03:48:45PM +0000, Daniel P. Berrange wrote:
On Mon, Nov 25, 2013 at 08:40:41AM -0700, Don Dugger wrote:
On Mon, Nov 25, 2013 at 10:45:38AM +0000, Daniel P. Berrange wrote:
On Sun, Nov 24, 2013 at 10:46:13AM -0600, Doug Goldstein wrote:
On Sat, Nov 23, 2013 at 3:15 PM, Don Dugger <n0ano@n0ano.com> wrote: > > This Python interface code is returning a -1 on errors for the > `baselineCPU' API. Since this API is supposed to return a pointer > the error return value should really be VIR_PY_NONE. ... >
ACK. This is correct. But it obviously changes our API so I'm not really sure how we should handle this, (e.g. document the API as is as note that its broken or fix it).
The implicit expectation with python APIs is that they all raise an exception if the libvirt call fails. So ACK to this bug fix & we should put it in maint branches.
Much as I hate to raise the issue this assumption is true for pointer APIs but APIs that return an integer don't raise an exception, they just return -1. Obviously, changing this behavior would be way too invasive but documenting this behavior should be done somewhere.
What APIs in particular ? Any API which results in a libvirt error being set should be translated into an exception in the python. This is done whether they're APIs returning NULL pointers or -1 ints. If there are other exceptions to the rule they must be fixed too.
I'm basing this on code inspection so I could be wrong but if you look at the Python interface code for libvirt_virDomainSetSchedulerParameters it checks the return value from virDomainSetSchedulerParameters and, if it is <0, then the Pythong code returns -1, without raising an exception.
That code is the low-level module (called libvirtmod) which interfaces to the C library, and is not called directly by applications.
Applications call the main module (called libvirt) which translates to the lowlevel module. eg in this case it does:
def setSchedulerParametersFlags(self, params, flags=0): """Change the scheduler parameters """ ret = libvirtmod.virDomainSetSchedulerParametersFlags(self._o, params, flags) if ret == -1: raise libvirtError ('virDomainSetSchedulerParametersFlags() failed', dom=self) return ret
so the -1 error is turned into an exception for applications.
The flaw the original patch in this thread was fixing is that the low level libvirtmod was returning NULL, where the high level libvirt expected to see -1, so the exception translation was missed.
Eric/Daniel- That's why I distrust code inspection, there's always a hidden gotcha. Tnx for the clarification.
Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
-- Don Dugger "Censeo Toto nos in Kansa esse decisse." - D. Gale n0ano@n0ano.com Ph: 303/443-3786

On 12/14/2013 01:36 PM, Daniel P. Berrange wrote:
On Sun, Nov 24, 2013 at 10:46:13AM -0600, Doug Goldstein wrote:
On Sat, Nov 23, 2013 at 3:15 PM, Don Dugger <n0ano@n0ano.com> wrote:
This Python interface code is returning a -1 on errors for the `baselineCPU' API. Since this API is supposed to return a pointer the error return value should really be VIR_PY_NONE.
NB: I've checked all the other APIs in this file and this is the only pointer API that is returning -1.
Signed-off-by: Don Dugger <donald.d.dugger@intel.com> --- python/libvirt-override.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/python/libvirt-override.c b/python/libvirt-override.c index c60747d..b471605 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -4471,13 +4471,13 @@ libvirt_virConnectBaselineCPU(PyObject *self ATTRIBUTE_UNUSED,
ncpus = PyList_Size(list); if (VIR_ALLOC_N_QUIET(xmlcpus, ncpus) < 0) - return VIR_PY_INT_FAIL; + return VIR_PY_NONE;
for (i = 0; i < ncpus; i++) { xmlcpus[i] = PyString_AsString(PyList_GetItem(list, i)); if (xmlcpus[i] == NULL) { VIR_FREE(xmlcpus); - return VIR_PY_INT_FAIL; + return VIR_PY_NONE; } } } @@ -4489,13 +4489,13 @@ libvirt_virConnectBaselineCPU(PyObject *self ATTRIBUTE_UNUSED, VIR_FREE(xmlcpus);
if (base_cpu == NULL) - return VIR_PY_INT_FAIL; + return VIR_PY_NONE;
pybase_cpu = PyString_FromString(base_cpu); VIR_FREE(base_cpu);
if (pybase_cpu == NULL) - return VIR_PY_INT_FAIL; + return VIR_PY_NONE;
return pybase_cpu; } -- 1.7.10.4
ACK. This is correct. But it obviously changes our API so I'm not really sure how we should handle this, (e.g. document the API as is as note that its broken or fix it).
The implicit expectation with python APIs is that they all raise an exception if the libvirt call fails. So ACK to this bug fix & we should put it in maint branches.
That said, please hold off applying this to GIT. We'll put it into the new libvirt-python git I'm about to push instead.
I've pushed this to 0.10.2 and 1.0.5 maint branches now. Thanks, Cole
participants (6)
-
Cole Robinson
-
Daniel P. Berrange
-
Don Dugger
-
Doug Goldstein
-
Eric Blake
-
Martin Kletzander