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