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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list