[libvirt] API break from the VMware player driver

All, I'll preface this by saying that I'm not 100% sure I'm correct. But I still think there may be an API break that was introduced with the VMware player driver. In include/libvirt/virterror.h, VIR_FROM_VMWARE was added to the *middle* of the enum for virErrorDomain. If any clients of libvirt happen to be using hardcoded numbers, then they will now have the wrong number for everything after VIR_FROM_VMWARE. Looking back through the history of virErrorDomain, it doesn't seem like this is the first time this has happened. What's the thinking with virErrorDomain? Part of the API, or up to the clients to properly use the named enums? -- Chris Lalancette

On 12/21/2010 11:34 AM, Chris Lalancette wrote:
All, I'll preface this by saying that I'm not 100% sure I'm correct. But I still think there may be an API break that was introduced with the VMware player driver. In include/libvirt/virterror.h, VIR_FROM_VMWARE was added to the *middle* of the enum for virErrorDomain. If any clients of libvirt happen to be using hardcoded numbers, then they will now have the wrong number for everything after VIR_FROM_VMWARE.
virterror.h is public, we should fix it now before the next release, because these values are passed over the wire in RPC calls, and if the server on one machine uses different values than the client on another machine, then the client can misinterpret the error values.
Looking back through the history of virErrorDomain, it doesn't seem like this is the first time this has happened. What's the thinking with virErrorDomain?
I just glanced at recent changes; we broke virErrorNumber in March 2010 with commit 46e9b0f, but the last time we broke virErrorDomain was commit f163895 in Mar 2008. (Most other commits that touched mid-enum were just fixing typos or spacing). I don't know what to do about those two API breakages.
Part of the API, or up to the clients to properly use the named enums?
Part of the API, I'm afraid. See the tail end of: https://www.redhat.com/archives/libvir-list/2010-December/msg00617.html +/* NB. Fields "code", "domain" and "level" are really enums. The + * numeric value should remain compatible between libvirt and + * libvirtd. This means, no changing or reordering the enums as + * defined in <virterror.h> (but we don't do that anyway, for separate + * ABI reasons). + */ +struct virNetMessageError { + int code; + int domain; -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

2010/12/21 Eric Blake <eblake@redhat.com>:
On 12/21/2010 11:34 AM, Chris Lalancette wrote:
All, I'll preface this by saying that I'm not 100% sure I'm correct. But I still think there may be an API break that was introduced with the VMware player driver. In include/libvirt/virterror.h, VIR_FROM_VMWARE was added to the *middle* of the enum for virErrorDomain. If any clients of libvirt happen to be using hardcoded numbers, then they will now have the wrong number for everything after VIR_FROM_VMWARE.
virterror.h is public, we should fix it now before the next release, because these values are passed over the wire in RPC calls, and if the server on one machine uses different values than the client on another machine, then the client can misinterpret the error values.
We might explicit write out all values of the enum members. That'll make it more obvious that adding in the middle is a bad idea. Can we add a make syntax-check rule to avoid future breakage, like we have for the XDR protocol? PS: Sorry, for not noticing this during review of the VMware driver. Matthias

Fix glitch in commit cddd2a06 (thankfully post-0.8.6, so no released version has the glitch). Document and try to workaround glitch in commit 46e9b0f (in 0.8.0, which invalidated 6 virErrorNumber dating back to 0.7.1). Thankfully, my audit did not find any other glitches until pre-0.1.0 days. I'm not sure how to add a syntax-check off the top of my head, but hopefully the explicit numbering will make people think twice about renumbering in the future. * include/libvirt/virterror.h (virErrorDomain): Avoid inserting new values in the middle, and add explicit numbering to help avoid this in the future. (virErrorNumber): Add explicit numbering, and document the snafu. * src/remote/remote_driver.c (remoteIO): Compensate for the snafu. --- include/libvirt/virterror.h | 266 ++++++++++++++++++++++++------------------ src/remote/remote_driver.c | 30 +++++- 2 files changed, 181 insertions(+), 115 deletions(-) diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index a1f88f4..0e59c0e 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -4,7 +4,7 @@ * Description: Provides the interfaces of the libvirt library to handle * errors raised while using the library. * - * Copy: Copyright (C) 2006 Red Hat, Inc. + * Copy: Copyright (C) 2006, 2010 Red Hat, Inc. * * See COPYING.LIB for the License of this software * @@ -34,49 +34,51 @@ typedef enum { /** * virErrorDomain: * - * Indicates where an error may have come from + * Indicates where an error may have come from. This should remain + * stable, with all additions placed at the end since libvirt 0.1.0. */ typedef enum { VIR_FROM_NONE = 0, - VIR_FROM_XEN, /* Error at Xen hypervisor layer */ - VIR_FROM_XEND, /* Error at connection with xend daemon */ - VIR_FROM_XENSTORE, /* Error at connection with xen store */ - VIR_FROM_SEXPR, /* Error in the S-Expression code */ - VIR_FROM_XML, /* Error in the XML code */ - VIR_FROM_DOM, /* Error when operating on a domain */ - VIR_FROM_RPC, /* Error in the XML-RPC code */ - VIR_FROM_PROXY, /* Error in the proxy code */ /* unused since 0.8.6 */ - VIR_FROM_CONF, /* Error in the configuration file handling */ - VIR_FROM_QEMU, /* Error at the QEMU daemon */ - VIR_FROM_NET, /* Error when operating on a network */ - VIR_FROM_TEST, /* Error from test driver */ - VIR_FROM_REMOTE, /* Error from remote driver */ - VIR_FROM_OPENVZ, /* Error from OpenVZ driver */ - VIR_FROM_VMWARE, /* Error from VMware driver */ - VIR_FROM_XENXM, /* Error at Xen XM layer */ - VIR_FROM_STATS_LINUX,/* Error in the Linux Stats code */ - VIR_FROM_LXC, /* Error from Linux Container driver */ - VIR_FROM_STORAGE, /* Error from storage driver */ - VIR_FROM_NETWORK, /* Error from network config */ - VIR_FROM_DOMAIN, /* Error from domain config */ - VIR_FROM_UML, /* Error at the UML driver */ - VIR_FROM_NODEDEV, /* Error from node device monitor */ - VIR_FROM_XEN_INOTIFY,/* Error from xen inotify layer */ - VIR_FROM_SECURITY, /* Error from security framework */ - VIR_FROM_VBOX, /* Error from VirtualBox driver */ - VIR_FROM_INTERFACE, /* Error when operating on an interface */ - VIR_FROM_ONE, /* Error from OpenNebula driver */ - VIR_FROM_ESX, /* Error from ESX driver */ - VIR_FROM_PHYP, /* Error from IBM power hypervisor */ - VIR_FROM_SECRET, /* Error from secret storage */ - VIR_FROM_CPU, /* Error from CPU driver */ - VIR_FROM_XENAPI, /* Error from XenAPI */ - VIR_FROM_NWFILTER, /* Error from network filter driver */ - VIR_FROM_HOOK, /* Error from Synchronous hooks */ - VIR_FROM_DOMAIN_SNAPSHOT, /* Error from domain snapshot */ - VIR_FROM_AUDIT, /* Error from auditing subsystem */ - VIR_FROM_SYSINFO, /* Error from sysinfo/SMBIOS */ - VIR_FROM_STREAMS, /* Error from I/O streams */ + VIR_FROM_XEN = 1, /* Error at Xen hypervisor layer */ + VIR_FROM_XEND = 2, /* Error at connection with xend daemon */ + VIR_FROM_XENSTORE = 3, /* Error at connection with xen store */ + VIR_FROM_SEXPR = 4, /* Error in the S-Expression code */ + VIR_FROM_XML = 5, /* Error in the XML code */ + VIR_FROM_DOM = 6, /* Error when operating on a domain */ + VIR_FROM_RPC = 7, /* Error in the XML-RPC code */ + VIR_FROM_PROXY = 8, /* Error in the proxy code; unused since + 0.8.6 */ + VIR_FROM_CONF = 9, /* Error in the configuration file handling */ + VIR_FROM_QEMU = 10, /* Error at the QEMU daemon */ + VIR_FROM_NET = 11, /* Error when operating on a network */ + VIR_FROM_TEST = 12, /* Error from test driver */ + VIR_FROM_REMOTE = 13, /* Error from remote driver */ + VIR_FROM_OPENVZ = 14, /* Error from OpenVZ driver */ + VIR_FROM_XENXM = 15, /* Error at Xen XM layer */ + VIR_FROM_STATS_LINUX = 16, /* Error in the Linux Stats code */ + VIR_FROM_LXC = 17, /* Error from Linux Container driver */ + VIR_FROM_STORAGE = 18, /* Error from storage driver */ + VIR_FROM_NETWORK = 19, /* Error from network config */ + VIR_FROM_DOMAIN = 20, /* Error from domain config */ + VIR_FROM_UML = 21, /* Error at the UML driver */ + VIR_FROM_NODEDEV = 22, /* Error from node device monitor */ + VIR_FROM_XEN_INOTIFY = 23, /* Error from xen inotify layer */ + VIR_FROM_SECURITY = 24, /* Error from security framework */ + VIR_FROM_VBOX = 25, /* Error from VirtualBox driver */ + VIR_FROM_INTERFACE = 26, /* Error when operating on an interface */ + VIR_FROM_ONE = 27, /* Error from OpenNebula driver */ + VIR_FROM_ESX = 28, /* Error from ESX driver */ + VIR_FROM_PHYP = 29, /* Error from IBM power hypervisor */ + VIR_FROM_SECRET = 30, /* Error from secret storage */ + VIR_FROM_CPU = 31, /* Error from CPU driver */ + VIR_FROM_XENAPI = 32, /* Error from XenAPI */ + VIR_FROM_NWFILTER = 33, /* Error from network filter driver */ + VIR_FROM_HOOK = 34, /* Error from Synchronous hooks */ + VIR_FROM_DOMAIN_SNAPSHOT = 35,/* Error from domain snapshot */ + VIR_FROM_AUDIT = 36, /* Error from auditing subsystem */ + VIR_FROM_SYSINFO = 37, /* Error from sysinfo/SMBIOS */ + VIR_FROM_STREAMS = 38, /* Error from I/O streams */ + VIR_FROM_VMWARE = 39, /* Error from VMware driver */ } virErrorDomain; @@ -114,82 +116,118 @@ struct _virError { * virErrorNumber: * * The full list of errors the library can generate + * + * This list should remain stable, with all additions placed at the + * end since libvirt 0.1.0. There is one exception: values added + * between libvirt 0.7.1 and libvirt 0.7.7 (VIR_WAR_NO_SECRET through + * VIR_ERROR_MIGRATE_PERSIST_FAILED) were inadvertently relocated by + * four positions in 0.8.0. If you suspect version mismatch between a + * server and client, then you can decipher values as follows: + * + * switch (err.code) { + * case 60: + * // no way to tell VIR_WAR_NO_SECRET apart from VIR_WAR_NO_NWFILTER, + * // but both are very similar warnings + * break; + * case 61: case 62: case 63: + * if (err.domain != VIR_FROM_NWFILTER) + * err.code += 4; + * break; + * case 64: + * if (err.domain == VIR_FROM_QEMU) + * err.code += 4; + * break; + * case 65: + * if (err.domain == VIR_FROM_XEN) + * err.code += 4; + * break; + * default: + * } */ typedef enum { VIR_ERR_OK = 0, - VIR_ERR_INTERNAL_ERROR, /* internal error */ - VIR_ERR_NO_MEMORY, /* memory allocation failure */ - VIR_ERR_NO_SUPPORT, /* no support for this function */ - VIR_ERR_UNKNOWN_HOST,/* could not resolve hostname */ - VIR_ERR_NO_CONNECT, /* can't connect to hypervisor */ - VIR_ERR_INVALID_CONN,/* invalid connection object */ - VIR_ERR_INVALID_DOMAIN,/* invalid domain object */ - VIR_ERR_INVALID_ARG,/* invalid function argument */ - VIR_ERR_OPERATION_FAILED,/* a command to hypervisor failed */ - VIR_ERR_GET_FAILED,/* a HTTP GET command to failed */ - VIR_ERR_POST_FAILED,/* a HTTP POST command to failed */ - VIR_ERR_HTTP_ERROR,/* unexpected HTTP error code */ - VIR_ERR_SEXPR_SERIAL,/* failure to serialize an S-Expr */ - VIR_ERR_NO_XEN,/* could not open Xen hypervisor control */ - VIR_ERR_XEN_CALL,/* failure doing an hypervisor call */ - VIR_ERR_OS_TYPE, /* unknown OS type */ - VIR_ERR_NO_KERNEL, /* missing kernel information */ - VIR_ERR_NO_ROOT, /* missing root device information */ - VIR_ERR_NO_SOURCE, /* missing source device information */ - VIR_ERR_NO_TARGET, /* missing target device information */ - VIR_ERR_NO_NAME, /* missing domain name information */ - VIR_ERR_NO_OS, /* missing domain OS information */ - VIR_ERR_NO_DEVICE, /* missing domain devices information */ - VIR_ERR_NO_XENSTORE,/* could not open Xen Store control */ - VIR_ERR_DRIVER_FULL, /* too many drivers registered */ - VIR_ERR_CALL_FAILED, /* not supported by the drivers (DEPRECATED) */ - VIR_ERR_XML_ERROR, /* an XML description is not well formed or broken */ - VIR_ERR_DOM_EXIST,/* the domain already exist */ - VIR_ERR_OPERATION_DENIED, /* operation forbidden on read-only connections */ - VIR_ERR_OPEN_FAILED, /* failed to open a conf file */ - VIR_ERR_READ_FAILED, /* failed to read a conf file */ - VIR_ERR_PARSE_FAILED, /* failed to parse a conf file */ - VIR_ERR_CONF_SYNTAX, /* failed to parse the syntax of a conf file */ - VIR_ERR_WRITE_FAILED, /* failed to write a conf file */ - VIR_ERR_XML_DETAIL, /* detail of an XML error */ - VIR_ERR_INVALID_NETWORK, /* invalid network object */ - VIR_ERR_NETWORK_EXIST, /* the network already exist */ - VIR_ERR_SYSTEM_ERROR, /* general system call failure */ - VIR_ERR_RPC, /* some sort of RPC error */ - VIR_ERR_GNUTLS_ERROR, /* error from a GNUTLS call */ - VIR_WAR_NO_NETWORK, /* failed to start network */ - VIR_ERR_NO_DOMAIN, /* domain not found or unexpectedly disappeared */ - VIR_ERR_NO_NETWORK, /* network not found */ - VIR_ERR_INVALID_MAC, /* invalid MAC address */ - VIR_ERR_AUTH_FAILED, /* authentication failed */ - VIR_ERR_INVALID_STORAGE_POOL, /* invalid storage pool object */ - VIR_ERR_INVALID_STORAGE_VOL, /* invalid storage vol object */ - VIR_WAR_NO_STORAGE, /* failed to start storage */ - VIR_ERR_NO_STORAGE_POOL, /* storage pool not found */ - VIR_ERR_NO_STORAGE_VOL, /* storage pool not found */ - VIR_WAR_NO_NODE, /* failed to start node driver */ - VIR_ERR_INVALID_NODE_DEVICE,/* invalid node device object */ - VIR_ERR_NO_NODE_DEVICE,/* node device not found */ - VIR_ERR_NO_SECURITY_MODEL, /* security model not found */ - VIR_ERR_OPERATION_INVALID, /* operation is not applicable at this time */ - VIR_WAR_NO_INTERFACE, /* failed to start interface driver */ - VIR_ERR_NO_INTERFACE, /* interface driver not running */ - VIR_ERR_INVALID_INTERFACE, /* invalid interface object */ - VIR_ERR_MULTIPLE_INTERFACES, /* more than one matching interface found */ - VIR_WAR_NO_NWFILTER, /* failed to start nwfilter driver */ - VIR_ERR_INVALID_NWFILTER, /* invalid nwfilter object */ - VIR_ERR_NO_NWFILTER, /* nw filter pool not found */ - VIR_ERR_BUILD_FIREWALL, /* nw filter pool not found */ - VIR_WAR_NO_SECRET, /* failed to start secret storage */ - VIR_ERR_INVALID_SECRET, /* invalid secret */ - VIR_ERR_NO_SECRET, /* secret not found */ - VIR_ERR_CONFIG_UNSUPPORTED, /* unsupported configuration construct */ - VIR_ERR_OPERATION_TIMEOUT, /* timeout occurred during operation */ - VIR_ERR_MIGRATE_PERSIST_FAILED, /* a migration worked, but making the - VM persist on the dest host failed */ - VIR_ERR_HOOK_SCRIPT_FAILED, /* a synchronous hook script failed */ - VIR_ERR_INVALID_DOMAIN_SNAPSHOT, /* invalid domain snapshot */ - VIR_ERR_NO_DOMAIN_SNAPSHOT, /* domain snapshot not found */ + VIR_ERR_INTERNAL_ERROR = 1, /* internal error */ + VIR_ERR_NO_MEMORY = 2, /* memory allocation failure */ + VIR_ERR_NO_SUPPORT = 3, /* no support for this function */ + VIR_ERR_UNKNOWN_HOST = 4, /* could not resolve hostname */ + VIR_ERR_NO_CONNECT = 5, /* can't connect to hypervisor */ + VIR_ERR_INVALID_CONN = 6, /* invalid connection object */ + VIR_ERR_INVALID_DOMAIN = 7, /* invalid domain object */ + VIR_ERR_INVALID_ARG = 8, /* invalid function argument */ + VIR_ERR_OPERATION_FAILED = 9, /* a command to hypervisor failed */ + VIR_ERR_GET_FAILED = 10, /* a HTTP GET command to failed */ + VIR_ERR_POST_FAILED = 11, /* a HTTP POST command to failed */ + VIR_ERR_HTTP_ERROR = 12, /* unexpected HTTP error code */ + VIR_ERR_SEXPR_SERIAL = 13, /* failure to serialize an S-Expr */ + VIR_ERR_NO_XEN = 14, /* could not open Xen hypervisor + control */ + VIR_ERR_XEN_CALL = 15, /* failure doing an hypervisor call */ + VIR_ERR_OS_TYPE = 16, /* unknown OS type */ + VIR_ERR_NO_KERNEL = 17, /* missing kernel information */ + VIR_ERR_NO_ROOT = 18, /* missing root device information */ + VIR_ERR_NO_SOURCE = 19, /* missing source device information */ + VIR_ERR_NO_TARGET = 20, /* missing target device information */ + VIR_ERR_NO_NAME = 21, /* missing domain name information */ + VIR_ERR_NO_OS = 22, /* missing domain OS information */ + VIR_ERR_NO_DEVICE = 23, /* missing domain devices information */ + VIR_ERR_NO_XENSTORE = 24, /* could not open Xen Store control */ + VIR_ERR_DRIVER_FULL = 25, /* too many drivers registered */ + VIR_ERR_CALL_FAILED = 26, /* not supported by the drivers + (DEPRECATED) */ + VIR_ERR_XML_ERROR = 27, /* an XML description is not well + formed or broken */ + VIR_ERR_DOM_EXIST = 28, /* the domain already exist */ + VIR_ERR_OPERATION_DENIED = 29, /* operation forbidden on read-only + connections */ + VIR_ERR_OPEN_FAILED = 30, /* failed to open a conf file */ + VIR_ERR_READ_FAILED = 31, /* failed to read a conf file */ + VIR_ERR_PARSE_FAILED = 32, /* failed to parse a conf file */ + VIR_ERR_CONF_SYNTAX = 33, /* failed to parse the syntax of a + conf file */ + VIR_ERR_WRITE_FAILED = 34, /* failed to write a conf file */ + VIR_ERR_XML_DETAIL = 35, /* detail of an XML error */ + VIR_ERR_INVALID_NETWORK = 36, /* invalid network object */ + VIR_ERR_NETWORK_EXIST = 37, /* the network already exist */ + VIR_ERR_SYSTEM_ERROR = 38, /* general system call failure */ + VIR_ERR_RPC = 39, /* some sort of RPC error */ + VIR_ERR_GNUTLS_ERROR = 40, /* error from a GNUTLS call */ + VIR_WAR_NO_NETWORK = 41, /* failed to start network */ + VIR_ERR_NO_DOMAIN = 42, /* domain not found or unexpectedly + disappeared */ + VIR_ERR_NO_NETWORK = 43, /* network not found */ + VIR_ERR_INVALID_MAC = 44, /* invalid MAC address */ + VIR_ERR_AUTH_FAILED = 45, /* authentication failed */ + VIR_ERR_INVALID_STORAGE_POOL = 46, /* invalid storage pool object */ + VIR_ERR_INVALID_STORAGE_VOL = 47, /* invalid storage vol object */ + VIR_WAR_NO_STORAGE = 48, /* failed to start storage */ + VIR_ERR_NO_STORAGE_POOL = 49, /* storage pool not found */ + VIR_ERR_NO_STORAGE_VOL = 50, /* storage pool not found */ + VIR_WAR_NO_NODE = 51, /* failed to start node driver */ + VIR_ERR_INVALID_NODE_DEVICE = 52, /* invalid node device object */ + VIR_ERR_NO_NODE_DEVICE = 53, /* node device not found */ + VIR_ERR_NO_SECURITY_MODEL = 54, /* security model not found */ + VIR_ERR_OPERATION_INVALID = 55, /* operation is not applicable at this + time */ + VIR_WAR_NO_INTERFACE = 56, /* failed to start interface driver */ + VIR_ERR_NO_INTERFACE = 57, /* interface driver not running */ + VIR_ERR_INVALID_INTERFACE = 58, /* invalid interface object */ + VIR_ERR_MULTIPLE_INTERFACES = 59, /* more than one matching interface + found */ + VIR_WAR_NO_NWFILTER = 60, /* failed to start nwfilter driver */ + VIR_ERR_INVALID_NWFILTER = 61, /* invalid nwfilter object */ + VIR_ERR_NO_NWFILTER = 62, /* nw filter pool not found */ + VIR_ERR_BUILD_FIREWALL = 63, /* nw filter pool not found */ + VIR_WAR_NO_SECRET = 64, /* failed to start secret storage */ + VIR_ERR_INVALID_SECRET = 65, /* invalid secret */ + VIR_ERR_NO_SECRET = 66, /* secret not found */ + VIR_ERR_CONFIG_UNSUPPORTED = 67, /* unsupported configuration + construct */ + VIR_ERR_OPERATION_TIMEOUT = 68, /* timeout occurred during operation */ + VIR_ERR_MIGRATE_PERSIST_FAILED = 69,/* a migration worked, but making the + VM persist on the dest host failed */ + VIR_ERR_HOOK_SCRIPT_FAILED = 70, /* a synchronous hook script failed */ + VIR_ERR_INVALID_DOMAIN_SNAPSHOT = 71,/* invalid domain snapshot */ + VIR_ERR_NO_DOMAIN_SNAPSHOT = 72, /* domain snapshot not found */ } virErrorNumber; /** diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index fae191c..66d3852 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -10371,8 +10371,36 @@ remoteIO(virConnectPtr conn, return -1; cleanup: - DEBUG("All done with our call %d %p %p", thiscall->proc_nr, priv->waitDispatch, thiscall); + DEBUG("All done with our call %d %p %p", thiscall->proc_nr, + priv->waitDispatch, thiscall); if (thiscall->mode == REMOTE_MODE_ERROR) { + /* Interop for virErrorNumber glitch in 0.8.0, if server is + * 0.7.1 through 0.7.7 */ + switch (thiscall->err.code) { + case VIR_WAR_NO_NWFILTER: + /* no way to tell old VIR_WAR_NO_SECRET apart from + * VIR_WAR_NO_NWFILTER, but both are very similar + * warnings, so ignore the difference */ + break; + case VIR_ERR_INVALID_NWFILTER: + case VIR_ERR_NO_NWFILTER: + case VIR_ERR_BUILD_FIREWALL: + if (thiscall->err.domain != VIR_FROM_NWFILTER) + thiscall->err.code += 4; + break; + case VIR_WAR_NO_SECRET: + if (thiscall->err.domain == VIR_FROM_QEMU) + thiscall->err.code = VIR_ERR_OPERATION_TIMEOUT; + break; + case VIR_ERR_INVALID_SECRET: + if (thiscall->err.domain == VIR_FROM_XEN) + thiscall->err.code = VIR_ERR_MIGRATE_PERSIST_FAILED; + break; + default: + /* Nothing to alter. */ + break; + } + /* See if caller asked us to keep quiet about missing RPCs * eg for interop with older servers */ if (flags & REMOTE_CALL_QUIET_MISSING_RPC && -- 1.7.3.3

On 12/21/10 - 03:12:43PM, Eric Blake wrote:
Fix glitch in commit cddd2a06 (thankfully post-0.8.6, so no released version has the glitch).
Document and try to workaround glitch in commit 46e9b0f (in 0.8.0, which invalidated 6 virErrorNumber dating back to 0.7.1).
Thankfully, my audit did not find any other glitches until pre-0.1.0 days. I'm not sure how to add a syntax-check off the top of my head, but hopefully the explicit numbering will make people think twice about renumbering in the future.
* include/libvirt/virterror.h (virErrorDomain): Avoid inserting new values in the middle, and add explicit numbering to help avoid this in the future. (virErrorNumber): Add explicit numbering, and document the snafu. * src/remote/remote_driver.c (remoteIO): Compensate for the snafu.
Thanks for looking at this, Eric.
--- include/libvirt/virterror.h | 266 ++++++++++++++++++++++++------------------ src/remote/remote_driver.c | 30 +++++- 2 files changed, 181 insertions(+), 115 deletions(-)
diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index a1f88f4..0e59c0e 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -4,7 +4,7 @@ * Description: Provides the interfaces of the libvirt library to handle * errors raised while using the library. * - * Copy: Copyright (C) 2006 Red Hat, Inc. + * Copy: Copyright (C) 2006, 2010 Red Hat, Inc. * * See COPYING.LIB for the License of this software * @@ -34,49 +34,51 @@ typedef enum { /** * virErrorDomain: * - * Indicates where an error may have come from + * Indicates where an error may have come from. This should remain + * stable, with all additions placed at the end since libvirt 0.1.0. */ typedef enum { VIR_FROM_NONE = 0, - VIR_FROM_XEN, /* Error at Xen hypervisor layer */ - VIR_FROM_XEND, /* Error at connection with xend daemon */ - VIR_FROM_XENSTORE, /* Error at connection with xen store */ - VIR_FROM_SEXPR, /* Error in the S-Expression code */ - VIR_FROM_XML, /* Error in the XML code */ - VIR_FROM_DOM, /* Error when operating on a domain */ - VIR_FROM_RPC, /* Error in the XML-RPC code */ - VIR_FROM_PROXY, /* Error in the proxy code */ /* unused since 0.8.6 */ - VIR_FROM_CONF, /* Error in the configuration file handling */ - VIR_FROM_QEMU, /* Error at the QEMU daemon */ - VIR_FROM_NET, /* Error when operating on a network */ - VIR_FROM_TEST, /* Error from test driver */ - VIR_FROM_REMOTE, /* Error from remote driver */ - VIR_FROM_OPENVZ, /* Error from OpenVZ driver */ - VIR_FROM_VMWARE, /* Error from VMware driver */ - VIR_FROM_XENXM, /* Error at Xen XM layer */ - VIR_FROM_STATS_LINUX,/* Error in the Linux Stats code */ - VIR_FROM_LXC, /* Error from Linux Container driver */ - VIR_FROM_STORAGE, /* Error from storage driver */ - VIR_FROM_NETWORK, /* Error from network config */ - VIR_FROM_DOMAIN, /* Error from domain config */ - VIR_FROM_UML, /* Error at the UML driver */ - VIR_FROM_NODEDEV, /* Error from node device monitor */ - VIR_FROM_XEN_INOTIFY,/* Error from xen inotify layer */ - VIR_FROM_SECURITY, /* Error from security framework */ - VIR_FROM_VBOX, /* Error from VirtualBox driver */ - VIR_FROM_INTERFACE, /* Error when operating on an interface */ - VIR_FROM_ONE, /* Error from OpenNebula driver */ - VIR_FROM_ESX, /* Error from ESX driver */ - VIR_FROM_PHYP, /* Error from IBM power hypervisor */ - VIR_FROM_SECRET, /* Error from secret storage */ - VIR_FROM_CPU, /* Error from CPU driver */ - VIR_FROM_XENAPI, /* Error from XenAPI */ - VIR_FROM_NWFILTER, /* Error from network filter driver */ - VIR_FROM_HOOK, /* Error from Synchronous hooks */ - VIR_FROM_DOMAIN_SNAPSHOT, /* Error from domain snapshot */ - VIR_FROM_AUDIT, /* Error from auditing subsystem */ - VIR_FROM_SYSINFO, /* Error from sysinfo/SMBIOS */ - VIR_FROM_STREAMS, /* Error from I/O streams */ + VIR_FROM_XEN = 1, /* Error at Xen hypervisor layer */ + VIR_FROM_XEND = 2, /* Error at connection with xend daemon */ + VIR_FROM_XENSTORE = 3, /* Error at connection with xen store */ + VIR_FROM_SEXPR = 4, /* Error in the S-Expression code */ + VIR_FROM_XML = 5, /* Error in the XML code */ + VIR_FROM_DOM = 6, /* Error when operating on a domain */ + VIR_FROM_RPC = 7, /* Error in the XML-RPC code */ + VIR_FROM_PROXY = 8, /* Error in the proxy code; unused since + 0.8.6 */ + VIR_FROM_CONF = 9, /* Error in the configuration file handling */ + VIR_FROM_QEMU = 10, /* Error at the QEMU daemon */ + VIR_FROM_NET = 11, /* Error when operating on a network */ + VIR_FROM_TEST = 12, /* Error from test driver */ + VIR_FROM_REMOTE = 13, /* Error from remote driver */ + VIR_FROM_OPENVZ = 14, /* Error from OpenVZ driver */ + VIR_FROM_XENXM = 15, /* Error at Xen XM layer */ + VIR_FROM_STATS_LINUX = 16, /* Error in the Linux Stats code */ + VIR_FROM_LXC = 17, /* Error from Linux Container driver */ + VIR_FROM_STORAGE = 18, /* Error from storage driver */ + VIR_FROM_NETWORK = 19, /* Error from network config */ + VIR_FROM_DOMAIN = 20, /* Error from domain config */ + VIR_FROM_UML = 21, /* Error at the UML driver */ + VIR_FROM_NODEDEV = 22, /* Error from node device monitor */ + VIR_FROM_XEN_INOTIFY = 23, /* Error from xen inotify layer */ + VIR_FROM_SECURITY = 24, /* Error from security framework */ + VIR_FROM_VBOX = 25, /* Error from VirtualBox driver */ + VIR_FROM_INTERFACE = 26, /* Error when operating on an interface */ + VIR_FROM_ONE = 27, /* Error from OpenNebula driver */ + VIR_FROM_ESX = 28, /* Error from ESX driver */ + VIR_FROM_PHYP = 29, /* Error from IBM power hypervisor */ + VIR_FROM_SECRET = 30, /* Error from secret storage */ + VIR_FROM_CPU = 31, /* Error from CPU driver */ + VIR_FROM_XENAPI = 32, /* Error from XenAPI */ + VIR_FROM_NWFILTER = 33, /* Error from network filter driver */ + VIR_FROM_HOOK = 34, /* Error from Synchronous hooks */ + VIR_FROM_DOMAIN_SNAPSHOT = 35,/* Error from domain snapshot */ + VIR_FROM_AUDIT = 36, /* Error from auditing subsystem */ + VIR_FROM_SYSINFO = 37, /* Error from sysinfo/SMBIOS */ + VIR_FROM_STREAMS = 38, /* Error from I/O streams */ + VIR_FROM_VMWARE = 39, /* Error from VMware driver */ } virErrorDomain;
@@ -114,82 +116,118 @@ struct _virError { * virErrorNumber: * * The full list of errors the library can generate + * + * This list should remain stable, with all additions placed at the + * end since libvirt 0.1.0. There is one exception: values added + * between libvirt 0.7.1 and libvirt 0.7.7 (VIR_WAR_NO_SECRET through + * VIR_ERROR_MIGRATE_PERSIST_FAILED) were inadvertently relocated by + * four positions in 0.8.0. If you suspect version mismatch between a + * server and client, then you can decipher values as follows: + * + * switch (err.code) { + * case 60: + * // no way to tell VIR_WAR_NO_SECRET apart from VIR_WAR_NO_NWFILTER, + * // but both are very similar warnings + * break; + * case 61: case 62: case 63: + * if (err.domain != VIR_FROM_NWFILTER) + * err.code += 4; + * break; + * case 64: + * if (err.domain == VIR_FROM_QEMU) + * err.code += 4; + * break; + * case 65: + * if (err.domain == VIR_FROM_XEN) + * err.code += 4; + * break; + * default: + * } */ typedef enum { VIR_ERR_OK = 0, - VIR_ERR_INTERNAL_ERROR, /* internal error */ - VIR_ERR_NO_MEMORY, /* memory allocation failure */ - VIR_ERR_NO_SUPPORT, /* no support for this function */ - VIR_ERR_UNKNOWN_HOST,/* could not resolve hostname */ - VIR_ERR_NO_CONNECT, /* can't connect to hypervisor */ - VIR_ERR_INVALID_CONN,/* invalid connection object */ - VIR_ERR_INVALID_DOMAIN,/* invalid domain object */ - VIR_ERR_INVALID_ARG,/* invalid function argument */ - VIR_ERR_OPERATION_FAILED,/* a command to hypervisor failed */ - VIR_ERR_GET_FAILED,/* a HTTP GET command to failed */ - VIR_ERR_POST_FAILED,/* a HTTP POST command to failed */ - VIR_ERR_HTTP_ERROR,/* unexpected HTTP error code */ - VIR_ERR_SEXPR_SERIAL,/* failure to serialize an S-Expr */ - VIR_ERR_NO_XEN,/* could not open Xen hypervisor control */ - VIR_ERR_XEN_CALL,/* failure doing an hypervisor call */ - VIR_ERR_OS_TYPE, /* unknown OS type */ - VIR_ERR_NO_KERNEL, /* missing kernel information */ - VIR_ERR_NO_ROOT, /* missing root device information */ - VIR_ERR_NO_SOURCE, /* missing source device information */ - VIR_ERR_NO_TARGET, /* missing target device information */ - VIR_ERR_NO_NAME, /* missing domain name information */ - VIR_ERR_NO_OS, /* missing domain OS information */ - VIR_ERR_NO_DEVICE, /* missing domain devices information */ - VIR_ERR_NO_XENSTORE,/* could not open Xen Store control */ - VIR_ERR_DRIVER_FULL, /* too many drivers registered */ - VIR_ERR_CALL_FAILED, /* not supported by the drivers (DEPRECATED) */ - VIR_ERR_XML_ERROR, /* an XML description is not well formed or broken */ - VIR_ERR_DOM_EXIST,/* the domain already exist */ - VIR_ERR_OPERATION_DENIED, /* operation forbidden on read-only connections */ - VIR_ERR_OPEN_FAILED, /* failed to open a conf file */ - VIR_ERR_READ_FAILED, /* failed to read a conf file */ - VIR_ERR_PARSE_FAILED, /* failed to parse a conf file */ - VIR_ERR_CONF_SYNTAX, /* failed to parse the syntax of a conf file */ - VIR_ERR_WRITE_FAILED, /* failed to write a conf file */ - VIR_ERR_XML_DETAIL, /* detail of an XML error */ - VIR_ERR_INVALID_NETWORK, /* invalid network object */ - VIR_ERR_NETWORK_EXIST, /* the network already exist */ - VIR_ERR_SYSTEM_ERROR, /* general system call failure */ - VIR_ERR_RPC, /* some sort of RPC error */ - VIR_ERR_GNUTLS_ERROR, /* error from a GNUTLS call */ - VIR_WAR_NO_NETWORK, /* failed to start network */ - VIR_ERR_NO_DOMAIN, /* domain not found or unexpectedly disappeared */ - VIR_ERR_NO_NETWORK, /* network not found */ - VIR_ERR_INVALID_MAC, /* invalid MAC address */ - VIR_ERR_AUTH_FAILED, /* authentication failed */ - VIR_ERR_INVALID_STORAGE_POOL, /* invalid storage pool object */ - VIR_ERR_INVALID_STORAGE_VOL, /* invalid storage vol object */ - VIR_WAR_NO_STORAGE, /* failed to start storage */ - VIR_ERR_NO_STORAGE_POOL, /* storage pool not found */ - VIR_ERR_NO_STORAGE_VOL, /* storage pool not found */ - VIR_WAR_NO_NODE, /* failed to start node driver */ - VIR_ERR_INVALID_NODE_DEVICE,/* invalid node device object */ - VIR_ERR_NO_NODE_DEVICE,/* node device not found */ - VIR_ERR_NO_SECURITY_MODEL, /* security model not found */ - VIR_ERR_OPERATION_INVALID, /* operation is not applicable at this time */ - VIR_WAR_NO_INTERFACE, /* failed to start interface driver */ - VIR_ERR_NO_INTERFACE, /* interface driver not running */ - VIR_ERR_INVALID_INTERFACE, /* invalid interface object */ - VIR_ERR_MULTIPLE_INTERFACES, /* more than one matching interface found */ - VIR_WAR_NO_NWFILTER, /* failed to start nwfilter driver */ - VIR_ERR_INVALID_NWFILTER, /* invalid nwfilter object */ - VIR_ERR_NO_NWFILTER, /* nw filter pool not found */ - VIR_ERR_BUILD_FIREWALL, /* nw filter pool not found */ - VIR_WAR_NO_SECRET, /* failed to start secret storage */ - VIR_ERR_INVALID_SECRET, /* invalid secret */ - VIR_ERR_NO_SECRET, /* secret not found */ - VIR_ERR_CONFIG_UNSUPPORTED, /* unsupported configuration construct */ - VIR_ERR_OPERATION_TIMEOUT, /* timeout occurred during operation */ - VIR_ERR_MIGRATE_PERSIST_FAILED, /* a migration worked, but making the - VM persist on the dest host failed */ - VIR_ERR_HOOK_SCRIPT_FAILED, /* a synchronous hook script failed */ - VIR_ERR_INVALID_DOMAIN_SNAPSHOT, /* invalid domain snapshot */ - VIR_ERR_NO_DOMAIN_SNAPSHOT, /* domain snapshot not found */ + VIR_ERR_INTERNAL_ERROR = 1, /* internal error */ + VIR_ERR_NO_MEMORY = 2, /* memory allocation failure */ + VIR_ERR_NO_SUPPORT = 3, /* no support for this function */ + VIR_ERR_UNKNOWN_HOST = 4, /* could not resolve hostname */ + VIR_ERR_NO_CONNECT = 5, /* can't connect to hypervisor */ + VIR_ERR_INVALID_CONN = 6, /* invalid connection object */ + VIR_ERR_INVALID_DOMAIN = 7, /* invalid domain object */ + VIR_ERR_INVALID_ARG = 8, /* invalid function argument */ + VIR_ERR_OPERATION_FAILED = 9, /* a command to hypervisor failed */ + VIR_ERR_GET_FAILED = 10, /* a HTTP GET command to failed */ + VIR_ERR_POST_FAILED = 11, /* a HTTP POST command to failed */ + VIR_ERR_HTTP_ERROR = 12, /* unexpected HTTP error code */ + VIR_ERR_SEXPR_SERIAL = 13, /* failure to serialize an S-Expr */ + VIR_ERR_NO_XEN = 14, /* could not open Xen hypervisor + control */ + VIR_ERR_XEN_CALL = 15, /* failure doing an hypervisor call */ + VIR_ERR_OS_TYPE = 16, /* unknown OS type */ + VIR_ERR_NO_KERNEL = 17, /* missing kernel information */ + VIR_ERR_NO_ROOT = 18, /* missing root device information */ + VIR_ERR_NO_SOURCE = 19, /* missing source device information */ + VIR_ERR_NO_TARGET = 20, /* missing target device information */ + VIR_ERR_NO_NAME = 21, /* missing domain name information */ + VIR_ERR_NO_OS = 22, /* missing domain OS information */ + VIR_ERR_NO_DEVICE = 23, /* missing domain devices information */ + VIR_ERR_NO_XENSTORE = 24, /* could not open Xen Store control */ + VIR_ERR_DRIVER_FULL = 25, /* too many drivers registered */ + VIR_ERR_CALL_FAILED = 26, /* not supported by the drivers + (DEPRECATED) */ + VIR_ERR_XML_ERROR = 27, /* an XML description is not well + formed or broken */ + VIR_ERR_DOM_EXIST = 28, /* the domain already exist */ + VIR_ERR_OPERATION_DENIED = 29, /* operation forbidden on read-only + connections */ + VIR_ERR_OPEN_FAILED = 30, /* failed to open a conf file */ + VIR_ERR_READ_FAILED = 31, /* failed to read a conf file */ + VIR_ERR_PARSE_FAILED = 32, /* failed to parse a conf file */ + VIR_ERR_CONF_SYNTAX = 33, /* failed to parse the syntax of a + conf file */ + VIR_ERR_WRITE_FAILED = 34, /* failed to write a conf file */ + VIR_ERR_XML_DETAIL = 35, /* detail of an XML error */ + VIR_ERR_INVALID_NETWORK = 36, /* invalid network object */ + VIR_ERR_NETWORK_EXIST = 37, /* the network already exist */ + VIR_ERR_SYSTEM_ERROR = 38, /* general system call failure */ + VIR_ERR_RPC = 39, /* some sort of RPC error */ + VIR_ERR_GNUTLS_ERROR = 40, /* error from a GNUTLS call */ + VIR_WAR_NO_NETWORK = 41, /* failed to start network */ + VIR_ERR_NO_DOMAIN = 42, /* domain not found or unexpectedly + disappeared */ + VIR_ERR_NO_NETWORK = 43, /* network not found */ + VIR_ERR_INVALID_MAC = 44, /* invalid MAC address */ + VIR_ERR_AUTH_FAILED = 45, /* authentication failed */ + VIR_ERR_INVALID_STORAGE_POOL = 46, /* invalid storage pool object */ + VIR_ERR_INVALID_STORAGE_VOL = 47, /* invalid storage vol object */ + VIR_WAR_NO_STORAGE = 48, /* failed to start storage */ + VIR_ERR_NO_STORAGE_POOL = 49, /* storage pool not found */ + VIR_ERR_NO_STORAGE_VOL = 50, /* storage pool not found */ + VIR_WAR_NO_NODE = 51, /* failed to start node driver */ + VIR_ERR_INVALID_NODE_DEVICE = 52, /* invalid node device object */ + VIR_ERR_NO_NODE_DEVICE = 53, /* node device not found */ + VIR_ERR_NO_SECURITY_MODEL = 54, /* security model not found */ + VIR_ERR_OPERATION_INVALID = 55, /* operation is not applicable at this + time */ + VIR_WAR_NO_INTERFACE = 56, /* failed to start interface driver */ + VIR_ERR_NO_INTERFACE = 57, /* interface driver not running */ + VIR_ERR_INVALID_INTERFACE = 58, /* invalid interface object */ + VIR_ERR_MULTIPLE_INTERFACES = 59, /* more than one matching interface + found */ + VIR_WAR_NO_NWFILTER = 60, /* failed to start nwfilter driver */ + VIR_ERR_INVALID_NWFILTER = 61, /* invalid nwfilter object */ + VIR_ERR_NO_NWFILTER = 62, /* nw filter pool not found */ + VIR_ERR_BUILD_FIREWALL = 63, /* nw filter pool not found */ + VIR_WAR_NO_SECRET = 64, /* failed to start secret storage */ + VIR_ERR_INVALID_SECRET = 65, /* invalid secret */ + VIR_ERR_NO_SECRET = 66, /* secret not found */ + VIR_ERR_CONFIG_UNSUPPORTED = 67, /* unsupported configuration + construct */ + VIR_ERR_OPERATION_TIMEOUT = 68, /* timeout occurred during operation */ + VIR_ERR_MIGRATE_PERSIST_FAILED = 69,/* a migration worked, but making the + VM persist on the dest host failed */ + VIR_ERR_HOOK_SCRIPT_FAILED = 70, /* a synchronous hook script failed */ + VIR_ERR_INVALID_DOMAIN_SNAPSHOT = 71,/* invalid domain snapshot */ + VIR_ERR_NO_DOMAIN_SNAPSHOT = 72, /* domain snapshot not found */ } virErrorNumber;
Definitely ACK to these two parts; moving VIR_FROM_VMWARE to the end and explicitly numbering everything. See below.
/** diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index fae191c..66d3852 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -10371,8 +10371,36 @@ remoteIO(virConnectPtr conn, return -1;
cleanup: - DEBUG("All done with our call %d %p %p", thiscall->proc_nr, priv->waitDispatch, thiscall); + DEBUG("All done with our call %d %p %p", thiscall->proc_nr, + priv->waitDispatch, thiscall); if (thiscall->mode == REMOTE_MODE_ERROR) { + /* Interop for virErrorNumber glitch in 0.8.0, if server is + * 0.7.1 through 0.7.7 */ + switch (thiscall->err.code) { + case VIR_WAR_NO_NWFILTER: + /* no way to tell old VIR_WAR_NO_SECRET apart from + * VIR_WAR_NO_NWFILTER, but both are very similar + * warnings, so ignore the difference */ + break; + case VIR_ERR_INVALID_NWFILTER: + case VIR_ERR_NO_NWFILTER: + case VIR_ERR_BUILD_FIREWALL: + if (thiscall->err.domain != VIR_FROM_NWFILTER) + thiscall->err.code += 4; + break; + case VIR_WAR_NO_SECRET: + if (thiscall->err.domain == VIR_FROM_QEMU) + thiscall->err.code = VIR_ERR_OPERATION_TIMEOUT; + break; + case VIR_ERR_INVALID_SECRET: + if (thiscall->err.domain == VIR_FROM_XEN) + thiscall->err.code = VIR_ERR_MIGRATE_PERSIST_FAILED; + break; + default: + /* Nothing to alter. */ + break; + } + /* See if caller asked us to keep quiet about missing RPCs * eg for interop with older servers */ if (flags & REMOTE_CALL_QUIET_MISSING_RPC &&
Clever. Make sure it is of the right "domain", and if not, you know you are talking to an older server. At first I thought it was confusing, but this will do the right thing in *almost* all situations, so I like it. ACK to this; as DV says, maybe we can make a "make check" or "make syntax-check" to automatically catch it in the future, but this at least fixes the current breakage. -- Chris Lalancette

On 12/22/2010 07:01 AM, Chris Lalancette wrote:
On 12/21/10 - 03:12:43PM, Eric Blake wrote:
Fix glitch in commit cddd2a06 (thankfully post-0.8.6, so no released version has the glitch).
Document and try to workaround glitch in commit 46e9b0f (in 0.8.0, which invalidated 6 virErrorNumber dating back to 0.7.1).
Thankfully, my audit did not find any other glitches until pre-0.1.0 days. I'm not sure how to add a syntax-check off the top of my head, but hopefully the explicit numbering will make people think twice about renumbering in the future.
* include/libvirt/virterror.h (virErrorDomain): Avoid inserting new values in the middle, and add explicit numbering to help avoid this in the future. (virErrorNumber): Add explicit numbering, and document the snafu. * src/remote/remote_driver.c (remoteIO): Compensate for the snafu.
Thanks for looking at this, Eric.
+++ b/src/remote/remote_driver.c @@ -10371,8 +10371,36 @@ remoteIO(virConnectPtr conn, return -1;
cleanup: - DEBUG("All done with our call %d %p %p", thiscall->proc_nr, priv->waitDispatch, thiscall); + DEBUG("All done with our call %d %p %p", thiscall->proc_nr, + priv->waitDispatch, thiscall); if (thiscall->mode == REMOTE_MODE_ERROR) { + /* Interop for virErrorNumber glitch in 0.8.0, if server is + * 0.7.1 through 0.7.7 */
I tweaked this comment to refer to the pseudocode in virterror.h,
Clever. Make sure it is of the right "domain", and if not, you know you are talking to an older server. At first I thought it was confusing, but this will do the right thing in *almost* all situations, so I like it.
ACK to this; as DV says, maybe we can make a "make check" or "make syntax-check" to automatically catch it in the future, but this at least fixes the current breakage.
then pushed the result. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

On Tue, Dec 21, 2010 at 08:50:04PM +0100, Matthias Bolte wrote:
2010/12/21 Eric Blake <eblake@redhat.com>:
On 12/21/2010 11:34 AM, Chris Lalancette wrote:
All, I'll preface this by saying that I'm not 100% sure I'm correct. But I still think there may be an API break that was introduced with the VMware player driver. In include/libvirt/virterror.h, VIR_FROM_VMWARE was added to the *middle* of the enum for virErrorDomain. If any clients of libvirt happen to be using hardcoded numbers, then they will now have the wrong number for everything after VIR_FROM_VMWARE.
virterror.h is public, we should fix it now before the next release,
Absolutely ! BTW I will send a mail about next release suggestion later today, now that my move is over and I'm back online.
because these values are passed over the wire in RPC calls, and if the server on one machine uses different values than the client on another machine, then the client can misinterpret the error values.
We might explicit write out all values of the enum members. That'll make it more obvious that adding in the middle is a bad idea.
agreed too,
Can we add a make syntax-check rule to avoid future breakage, like we have for the XDR protocol?
PS: Sorry, for not noticing this during review of the VMware driver.
Well it happens, but yes an automated extra check for all enums in the public APIs would be good, I think this could be also managed with libvirt-api.xml extracted values, assuming we put the numbers in. Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/
participants (4)
-
Chris Lalancette
-
Daniel Veillard
-
Eric Blake
-
Matthias Bolte