On Fri, Dec 12, 2008 at 01:31:24PM +0100, Daniel Veillard wrote:
On Fri, Dec 12, 2008 at 10:51:33AM +0000, Daniel P. Berrange wrote:
> On Fri, Dec 12, 2008 at 09:46:14AM +0100, Daniel Veillard wrote:
> > On Thu, Dec 11, 2008 at 08:16:36PM +0000, Daniel P. Berrange wrote:
> > > The current public API for error reporting consists of
> > >
> > > - A global error object
> > > - A per-connection error object
> > >
> > > Some functions always set errors on the global object. Other functions
> > > always set errors on the per-connection object, except when they set
> > > errors on the global object. Both have built-in race conditions if they
> > > are accessed from multiple threads because of the time between the API
> > > call raising the error, and the caller querying it.
> > >
> > > The solution to this is to do away with all of the existing error objects
> > > and replace them with a per-thread error object. Well, except we
can't
> > > do away with existing objects because of ABI compatability. This turns
> > > out to not be such a bad problem after all....
> > >
> > > So with this patch...
> > >
> > >
> > > virterror.c gets ability to track a per-thread virErrorPtr instance. This
> > > object is stored in a thread local variable via
pthread_{get,set}specific.
> > > It is allocated when first required, and deleted when the thread exits
> > >
> > > Every single API will *always* set the virErrorPtr object associated
with
> > > its current thread.
> > >
> > > In the public virterror.h we add
> > >
> > > virErrorPtr virThreadGetLastError (void);
> > > int virThreadCopyLastError (virErrorPtr to);
> > > void virThreadResetLastError (void);
> > >
> > > This provides a guarenteed thread-safe public API for fetching error
> > > information. All the other existing APIs have docs updated to recommend
> > > against their use.
> >
> > I understand the problem but I don't understand the way you expect to
> > fix it. Historically this copies the libxml2 error APIs, but in libxml2
> > the error data are stored in thread safe local storage. Until now
> > basically libvirt could not be used in a threaded way or at least not
> > without lot of constraints. Now we are getting thread safe, I suggest to
> > just retrofit thread safety into the exiting API, since they have the
> > exact same signature I see no reason to annoy the application writer
> > with extra API and deprecated ones.
> > If the application is single threaded nothing changes for them in
> > practice.
> > If the application is multi-threaded the old behaviour wasn't making
> > sense, could not be trusted and the new code does basically "the
> > right thing" now.
>
>
> Yes, I guess that does atually make sense.
>
> So I'll make the global virGetLastError() thread-safe, and then there's
> no need for the new APIs, and also no need for anyone to call the
> virConnGetLastError(), though I'll make sure that still syncs to
> whatever error is stored in the global location anyway.
okay, cool !
Try out this patch. The virConn*Error methods are left as is, and the
global vir*Error methods are made to use a thread local
Daniel
diff --git a/src/datatypes.c b/src/datatypes.c
--- a/src/datatypes.c
+++ b/src/datatypes.c
@@ -192,8 +192,6 @@ virReleaseConnect(virConnectPtr conn) {
virHashFree(conn->nodeDevices, (virHashDeallocator) virNodeDeviceFree);
virResetError(&conn->err);
- if (virLastErr.conn == conn)
- virLastErr.conn = NULL;
xmlFreeURI(conn->uri);
@@ -216,7 +214,7 @@ virUnrefConnect(virConnectPtr conn) {
int refs;
if ((!VIR_IS_CONNECT(conn))) {
- virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(-1);
}
pthread_mutex_lock(&conn->lock);
@@ -250,7 +248,7 @@ virGetDomain(virConnectPtr conn, const c
virDomainPtr ret = NULL;
if ((!VIR_IS_CONNECT(conn)) || (name == NULL) || (uuid == NULL)) {
- virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(NULL);
}
pthread_mutex_lock(&conn->lock);
@@ -320,10 +318,6 @@ virReleaseDomain(virDomainPtr domain) {
virLibConnError(conn, VIR_ERR_INTERNAL_ERROR,
_("domain missing from connection hash table"));
- if (conn->err.dom == domain)
- conn->err.dom = NULL;
- if (virLastErr.dom == domain)
- virLastErr.dom = NULL;
domain->magic = -1;
domain->id = -1;
VIR_FREE(domain->name);
@@ -355,7 +349,7 @@ virUnrefDomain(virDomainPtr domain) {
int refs;
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
- virLibConnError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(-1);
}
pthread_mutex_lock(&domain->conn->lock);
@@ -390,7 +384,7 @@ virGetNetwork(virConnectPtr conn, const
virNetworkPtr ret = NULL;
if ((!VIR_IS_CONNECT(conn)) || (name == NULL) || (uuid == NULL)) {
- virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(NULL);
}
pthread_mutex_lock(&conn->lock);
@@ -456,11 +450,6 @@ virReleaseNetwork(virNetworkPtr network)
virLibConnError(conn, VIR_ERR_INTERNAL_ERROR,
_("network missing from connection hash table"));
- if (
conn->err.net == network)
-
conn->err.net = NULL;
- if (
virLastErr.net == network)
-
virLastErr.net = NULL;
-
network->magic = -1;
VIR_FREE(network->name);
VIR_FREE(network);
@@ -491,7 +480,7 @@ virUnrefNetwork(virNetworkPtr network) {
int refs;
if (!VIR_IS_CONNECTED_NETWORK(network)) {
- virLibConnError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(-1);
}
pthread_mutex_lock(&network->conn->lock);
@@ -527,7 +516,7 @@ virGetStoragePool(virConnectPtr conn, co
virStoragePoolPtr ret = NULL;
if ((!VIR_IS_CONNECT(conn)) || (name == NULL) || (uuid == NULL)) {
- virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(NULL);
}
pthread_mutex_lock(&conn->lock);
@@ -624,7 +613,7 @@ virUnrefStoragePool(virStoragePoolPtr po
int refs;
if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
- virLibConnError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(-1);
}
pthread_mutex_lock(&pool->conn->lock);
@@ -661,7 +650,7 @@ virGetStorageVol(virConnectPtr conn, con
virStorageVolPtr ret = NULL;
if ((!VIR_IS_CONNECT(conn)) || (name == NULL) || (key == NULL)) {
- virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(NULL);
}
pthread_mutex_lock(&conn->lock);
@@ -762,7 +751,7 @@ virUnrefStorageVol(virStorageVolPtr vol)
int refs;
if (!VIR_IS_CONNECTED_STORAGE_VOL(vol)) {
- virLibConnError(vol->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(-1);
}
pthread_mutex_lock(&vol->conn->lock);
@@ -798,7 +787,7 @@ virGetNodeDevice(virConnectPtr conn, con
virNodeDevicePtr ret = NULL;
if ((!VIR_IS_CONNECT(conn)) || (name == NULL)) {
- virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(NULL);
}
pthread_mutex_lock(&conn->lock);
diff --git a/src/datatypes.h b/src/datatypes.h
--- a/src/datatypes.h
+++ b/src/datatypes.h
@@ -95,6 +95,10 @@
* Internal structure associated to a connection
*/
struct _virConnect {
+ /* All the variables from here, until the 'lock' declaration
+ * are setup at time of connection open, and never changed
+ * since. Thus no need to lock when accessing them
+ */
unsigned int magic; /* specific value to check */
int flags; /* a set of connection flags */
xmlURIPtr uri; /* connection URI */
@@ -114,11 +118,6 @@ struct _virConnect {
void * storagePrivateData;
void * devMonPrivateData;
- /* Per-connection error. */
- virError err; /* the last error */
- virErrorFunc handler; /* associated handlet */
- void *userData; /* the user data */
-
/*
* The lock mutex must be acquired before accessing/changing
* any of members following this point, or changing the ref
@@ -126,6 +125,12 @@ struct _virConnect {
* this connection
*/
PTHREAD_MUTEX_T (lock);
+
+ /* Per-connection error. */
+ virError err; /* the last error */
+ virErrorFunc handler; /* associated handlet */
+ void *userData; /* the user data */
+
virHashTablePtr domains; /* hash table for known domains */
virHashTablePtr networks; /* hash table for known domains */
virHashTablePtr storagePools;/* hash table for known storage pools */
diff --git a/src/libvirt.c b/src/libvirt.c
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -791,6 +791,8 @@ do_open (const char *name,
{
int i, res;
virConnectPtr ret;
+
+ virResetLastError();
ret = virGetConnect();
if (ret == NULL)
@@ -945,17 +947,8 @@ failed:
failed:
if (ret->driver) ret->driver->close (ret);
- /* If no global error was set, copy any error set
- in the connection object we're about to dispose of */
- if (virLastErr.code == VIR_ERR_OK) {
- memcpy(&virLastErr, &ret->err, sizeof(ret->err));
- memset(&ret->err, 0, sizeof(ret->err));
- }
-
- /* Still no error set, then raise a generic error */
- if (virLastErr.code == VIR_ERR_OK)
- virLibConnError (NULL, VIR_ERR_INTERNAL_ERROR,
- _("unable to open connection"));
+ /* Ensure a global error is set in case driver forgot */
+ virSetGlobalError();
virUnrefConnect(ret);
@@ -1050,8 +1043,12 @@ virConnectClose(virConnectPtr conn)
{
DEBUG("conn=%p", conn);
- if (!VIR_IS_CONNECT(conn))
- return (-1);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (-1);
+ }
if (conn->networkDriver)
conn->networkDriver->close (conn);
@@ -1073,12 +1070,20 @@ int
int
virDrvSupportsFeature (virConnectPtr conn, int feature)
{
+ int ret;
DEBUG("conn=%p, feature=%d", conn, feature);
- if (!VIR_IS_CONNECT(conn))
- return (-1);
-
- return VIR_DRV_SUPPORTS_FEATURE (conn->driver, conn, feature);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (-1);
+ }
+
+ ret = VIR_DRV_SUPPORTS_FEATURE (conn->driver, conn, feature);
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
+ return ret;
}
/**
@@ -1097,6 +1102,8 @@ virConnectGetType(virConnectPtr conn)
{
const char *ret;
DEBUG("conn=%p", conn);
+
+ virResetLastError();
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
@@ -1128,20 +1135,30 @@ virConnectGetVersion(virConnectPtr conn,
{
DEBUG("conn=%p, hvVer=%p", conn, hvVer);
- if (!VIR_IS_CONNECT(conn)) {
- virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
- return (-1);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return -1;
}
if (hvVer == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
- }
-
- if (conn->driver->version)
- return conn->driver->version (conn, hvVer);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->version) {
+ int ret = conn->driver->version (conn, hvVer);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return -1;
}
@@ -1162,15 +1179,25 @@ virConnectGetHostname (virConnectPtr con
{
DEBUG("conn=%p", conn);
- if (!VIR_IS_CONNECT(conn)) {
- virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
- return NULL;
- }
-
- if (conn->driver->getHostname)
- return conn->driver->getHostname (conn);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return NULL;
+ }
+
+ if (conn->driver->getHostname) {
+ char *ret = conn->driver->getHostname (conn);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return NULL;
}
@@ -1193,8 +1220,9 @@ virConnectGetURI (virConnectPtr conn)
virConnectGetURI (virConnectPtr conn)
{
char *name;
-
- DEBUG("conn=%p", conn);
+ DEBUG("conn=%p", conn);
+
+ virResetLastError();
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
@@ -1204,15 +1232,23 @@ virConnectGetURI (virConnectPtr conn)
/* Drivers may override getURI, but if they don't then
* we provide a default implementation.
*/
- if (conn->driver->getURI)
- return conn->driver->getURI (conn);
+ if (conn->driver->getURI) {
+ name = conn->driver->getURI (conn);
+ if (!name)
+ goto error;
+ }
name = (char *)xmlSaveUri(conn->uri);
if (!name) {
virLibConnError (conn, VIR_ERR_NO_MEMORY, __FUNCTION__);
- return NULL;
+ goto error;
}
return name;
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
+ return NULL;
}
/**
@@ -1232,15 +1268,24 @@ virConnectGetMaxVcpus(virConnectPtr conn
{
DEBUG("conn=%p, type=%s", conn, type);
- if (!VIR_IS_CONNECT(conn)) {
- virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
- return (-1);
- }
-
- if (conn->driver->getMaxVcpus)
- return conn->driver->getMaxVcpus (conn, type);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return -1;
+ }
+
+ if (conn->driver->getMaxVcpus) {
+ int ret = conn->driver->getMaxVcpus (conn, type);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return -1;
}
@@ -1259,20 +1304,29 @@ virConnectListDomains(virConnectPtr conn
{
DEBUG("conn=%p, ids=%p, maxids=%d", conn, ids, maxids);
- if (!VIR_IS_CONNECT(conn)) {
- virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
- return (-1);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return -1;
}
if ((ids == NULL) || (maxids < 0)) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
- }
-
- if (conn->driver->listDomains)
- return conn->driver->listDomains (conn, ids, maxids);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->listDomains) {
+ int ret = conn->driver->listDomains (conn, ids, maxids);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return -1;
}
@@ -1289,15 +1343,24 @@ virConnectNumOfDomains(virConnectPtr con
{
DEBUG("conn=%p", conn);
- if (!VIR_IS_CONNECT(conn)) {
- virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
- return (-1);
- }
-
- if (conn->driver->numOfDomains)
- return conn->driver->numOfDomains (conn);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->numOfDomains) {
+ int ret = conn->driver->numOfDomains (conn);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return -1;
}
@@ -1320,7 +1383,9 @@ virDomainGetConnect (virDomainPtr dom)
{
DEBUG("dom=%p", dom);
- if (!VIR_IS_DOMAIN (dom)) {
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN (dom)) {
virLibDomainError (NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
return NULL;
}
@@ -1348,23 +1413,33 @@ virDomainCreateXML(virConnectPtr conn, c
{
DEBUG("conn=%p, xmlDesc=%s, flags=%d", conn, xmlDesc, flags);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (NULL);
}
if (xmlDesc == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
+ goto error;
}
if (conn->flags & VIR_CONNECT_RO) {
virLibConnError(conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (NULL);
- }
-
- if (conn->driver->domainCreateXML)
- return conn->driver->domainCreateXML (conn, xmlDesc, flags);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->domainCreateXML) {
+ virDomainPtr ret;
+ ret = conn->driver->domainCreateXML (conn, xmlDesc, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return NULL;
}
@@ -1404,19 +1479,30 @@ virDomainLookupByID(virConnectPtr conn,
{
DEBUG("conn=%p, id=%d", conn, id);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (NULL);
}
if (id < 0) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
- }
-
- if (conn->driver->domainLookupByID)
- return conn->driver->domainLookupByID (conn, id);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->domainLookupByID) {
+ virDomainPtr ret;
+ ret = conn->driver->domainLookupByID (conn, id);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return NULL;
}
@@ -1435,19 +1521,30 @@ virDomainLookupByUUID(virConnectPtr conn
{
DEBUG("conn=%p, uuid=%s", conn, uuid);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (NULL);
}
if (uuid == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
- }
-
- if (conn->driver->domainLookupByUUID)
- return conn->driver->domainLookupByUUID (conn, uuid);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->domainLookupByUUID) {
+ virDomainPtr ret;
+ ret = conn->driver->domainLookupByUUID (conn, uuid);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return NULL;
}
@@ -1470,14 +1567,15 @@ virDomainLookupByUUIDString(virConnectPt
DEBUG("conn=%p, uuidstr=%s", conn, uuidstr);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (NULL);
}
if (uuidstr == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
-
+ goto error;
}
/* XXX: sexpr_uuid() also supports 'xxxx-xxxx-xxxx-xxxx' format.
* We needn't it here. Right?
@@ -1495,12 +1593,17 @@ virDomainLookupByUUIDString(virConnectPt
if (ret!=VIR_UUID_BUFLEN) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
+ goto error;
}
for (i = 0; i < VIR_UUID_BUFLEN; i++)
uuid[i] = raw[i] & 0xFF;
return virDomainLookupByUUID(conn, &uuid[0]);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
+ return NULL;
}
/**
@@ -1518,19 +1621,30 @@ virDomainLookupByName(virConnectPtr conn
{
DEBUG("conn=%p, name=%s", conn, name);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (NULL);
}
if (name == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
- }
-
- if (conn->driver->domainLookupByName)
- return conn->driver->domainLookupByName (conn, name);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->domainLookupByName) {
+ virDomainPtr dom;
+ dom = conn->driver->domainLookupByName (conn, name);
+ if (!dom)
+ goto error;
+ return dom;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return NULL;
}
@@ -1552,21 +1666,32 @@ virDomainDestroy(virDomainPtr domain)
DEBUG("domain=%p", domain);
- if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
- virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
- return (-1);
- }
-
- conn = domain->conn;
- if (conn->flags & VIR_CONNECT_RO) {
- virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
- }
-
- if (conn->driver->domainDestroy)
- return conn->driver->domainDestroy (domain);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return (-1);
+ }
+
+ conn = domain->conn;
+ if (conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->domainDestroy) {
+ int ret;
+ ret = conn->driver->domainDestroy (domain);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return -1;
}
@@ -1584,12 +1709,14 @@ virDomainFree(virDomainPtr domain)
{
DEBUG("domain=%p", domain);
- if (!VIR_IS_DOMAIN(domain)) {
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
return (-1);
}
if (virUnrefDomain(domain) < 0)
- return (-1);
+ return -1;
return(0);
}
@@ -1611,21 +1738,32 @@ virDomainSuspend(virDomainPtr domain)
virConnectPtr conn;
DEBUG("domain=%p", domain);
- if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
- virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
- return (-1);
- }
- if (domain->conn->flags & VIR_CONNECT_RO) {
- virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
- }
-
- conn = domain->conn;
-
- if (conn->driver->domainSuspend)
- return conn->driver->domainSuspend (domain);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return (-1);
+ }
+ if (domain->conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ conn = domain->conn;
+
+ if (conn->driver->domainSuspend) {
+ int ret;
+ ret = conn->driver->domainSuspend (domain);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return -1;
}
@@ -1645,21 +1783,32 @@ virDomainResume(virDomainPtr domain)
virConnectPtr conn;
DEBUG("domain=%p", domain);
- if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
- virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
- return (-1);
- }
- if (domain->conn->flags & VIR_CONNECT_RO) {
- virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
- }
-
- conn = domain->conn;
-
- if (conn->driver->domainResume)
- return conn->driver->domainResume (domain);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return (-1);
+ }
+ if (domain->conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ conn = domain->conn;
+
+ if (conn->driver->domainResume) {
+ int ret;
+ ret = conn->driver->domainResume (domain);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return -1;
}
@@ -1682,18 +1831,20 @@ virDomainSave(virDomainPtr domain, const
virConnectPtr conn;
DEBUG("domain=%p, to=%s", domain, to);
- if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
- virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
- return (-1);
- }
- if (domain->conn->flags & VIR_CONNECT_RO) {
- virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return (-1);
+ }
+ if (domain->conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
}
conn = domain->conn;
if (to == NULL) {
virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
+ goto error;
}
/*
@@ -1716,10 +1867,19 @@ virDomainSave(virDomainPtr domain, const
}
- if (conn->driver->domainSave)
- return conn->driver->domainSave (domain, to);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ if (conn->driver->domainSave) {
+ int ret;
+ ret = conn->driver->domainSave (domain, to);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return -1;
}
@@ -1738,17 +1898,19 @@ virDomainRestore(virConnectPtr conn, con
char filepath[4096];
DEBUG("conn=%p, from=%s", conn, from);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (-1);
}
if (conn->flags & VIR_CONNECT_RO) {
virLibConnError(conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
+ goto error;
}
if (from == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
+ goto error;
}
/*
@@ -1759,21 +1921,36 @@ virDomainRestore(virConnectPtr conn, con
unsigned int len, t;
t = strlen(from);
- if (getcwd(filepath, sizeof(filepath) - (t + 3)) == NULL)
- return (-1);
+ if (getcwd(filepath, sizeof(filepath) - (t + 3)) == NULL) {
+ virLibConnError(conn, VIR_ERR_SYSTEM_ERROR,
+ _("cannot get working directory"));
+ goto error;
+ }
len = strlen(filepath);
/* that should be covered by getcwd() semantic, but be 100% sure */
- if (len > sizeof(filepath) - (t + 3))
- return (-1);
+ if (len > sizeof(filepath) - (t + 3)) {
+ virLibConnError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("path too long"));
+ goto error;
+ }
filepath[len] = '/';
strcpy(&filepath[len + 1], from);
from = &filepath[0];
}
- if (conn->driver->domainRestore)
- return conn->driver->domainRestore (conn, from);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ if (conn->driver->domainRestore) {
+ int ret;
+ ret = conn->driver->domainRestore (conn, from);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return -1;
}
@@ -1796,18 +1973,20 @@ virDomainCoreDump(virDomainPtr domain, c
virConnectPtr conn;
DEBUG("domain=%p, to=%s, flags=%d", domain, to, flags);
- if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
- virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
- return (-1);
- }
- if (domain->conn->flags & VIR_CONNECT_RO) {
- virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return (-1);
+ }
+ if (domain->conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
}
conn = domain->conn;
if (to == NULL) {
virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
+ goto error;
}
/*
@@ -1818,22 +1997,37 @@ virDomainCoreDump(virDomainPtr domain, c
unsigned int len, t;
t = strlen(to);
- if (getcwd(filepath, sizeof(filepath) - (t + 3)) == NULL)
- return (-1);
+ if (getcwd(filepath, sizeof(filepath) - (t + 3)) == NULL) {
+ virLibDomainError(domain, VIR_ERR_SYSTEM_ERROR,
+ _("cannot get current directory"));
+ goto error;
+ }
len = strlen(filepath);
/* that should be covered by getcwd() semantic, but be 100% sure */
- if (len > sizeof(filepath) - (t + 3))
- return (-1);
+ if (len > sizeof(filepath) - (t + 3)) {
+ virLibDomainError(domain, VIR_ERR_INTERNAL_ERROR,
+ _("path too long"));
+ goto error;
+ }
filepath[len] = '/';
strcpy(&filepath[len + 1], to);
to = &filepath[0];
}
- if (conn->driver->domainCoreDump)
- return conn->driver->domainCoreDump (domain, to, flags);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ if (conn->driver->domainCoreDump) {
+ int ret;
+ ret = conn->driver->domainCoreDump (domain, to, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return -1;
}
@@ -1856,21 +2050,32 @@ virDomainShutdown(virDomainPtr domain)
virConnectPtr conn;
DEBUG("domain=%p", domain);
- if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
- virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
- return (-1);
- }
- if (domain->conn->flags & VIR_CONNECT_RO) {
- virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
- }
-
- conn = domain->conn;
-
- if (conn->driver->domainShutdown)
- return conn->driver->domainShutdown (domain);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return (-1);
+ }
+ if (domain->conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ conn = domain->conn;
+
+ if (conn->driver->domainShutdown) {
+ int ret;
+ ret = conn->driver->domainShutdown (domain);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return -1;
}
@@ -1891,21 +2096,32 @@ virDomainReboot(virDomainPtr domain, uns
virConnectPtr conn;
DEBUG("domain=%p, flags=%u", domain, flags);
- if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
- virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
- return (-1);
- }
- if (domain->conn->flags & VIR_CONNECT_RO) {
- virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
- }
-
- conn = domain->conn;
-
- if (conn->driver->domainReboot)
- return conn->driver->domainReboot (domain, flags);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return (-1);
+ }
+ if (domain->conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ conn = domain->conn;
+
+ if (conn->driver->domainReboot) {
+ int ret;
+ ret = conn->driver->domainReboot (domain, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return -1;
}
@@ -1923,6 +2139,8 @@ virDomainGetName(virDomainPtr domain)
{
DEBUG("domain=%p", domain);
+ virResetLastError();
+
if (!VIR_IS_DOMAIN(domain)) {
virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
return (NULL);
@@ -1944,12 +2162,16 @@ virDomainGetUUID(virDomainPtr domain, un
{
DEBUG("domain=%p, uuid=%p", domain, uuid);
+ virResetLastError();
+
if (!VIR_IS_DOMAIN(domain)) {
virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
return (-1);
}
if (uuid == NULL) {
virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return (-1);
}
@@ -1974,20 +2196,27 @@ virDomainGetUUIDString(virDomainPtr doma
unsigned char uuid[VIR_UUID_BUFLEN];
DEBUG("domain=%p, buf=%p", domain, buf);
+ virResetLastError();
+
if (!VIR_IS_DOMAIN(domain)) {
virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
return (-1);
}
if (buf == NULL) {
virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
+ goto error;
}
if (virDomainGetUUID(domain, &uuid[0]))
- return (-1);
+ goto error;
virUUIDFormat(uuid, buf);
return (0);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
+ return -1;
}
/**
@@ -2003,6 +2232,8 @@ virDomainGetID(virDomainPtr domain)
{
DEBUG("domain=%p", domain);
+ virResetLastError();
+
if (!VIR_IS_DOMAIN(domain)) {
virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
return ((unsigned int) -1);
@@ -2025,17 +2256,28 @@ virDomainGetOSType(virDomainPtr domain)
virConnectPtr conn;
DEBUG("domain=%p", domain);
- if (!VIR_IS_DOMAIN(domain)) {
- virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
- return (NULL);
- }
-
- conn = domain->conn;
-
- if (conn->driver->domainGetOSType)
- return conn->driver->domainGetOSType (domain);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return (NULL);
+ }
+
+ conn = domain->conn;
+
+ if (conn->driver->domainGetOSType) {
+ char *ret;
+ ret = conn->driver->domainGetOSType (domain);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return NULL;
}
@@ -2055,6 +2297,8 @@ virDomainGetMaxMemory(virDomainPtr domai
virConnectPtr conn;
DEBUG("domain=%p", domain);
+ virResetLastError();
+
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
return (0);
@@ -2062,10 +2306,19 @@ virDomainGetMaxMemory(virDomainPtr domai
conn = domain->conn;
- if (conn->driver->domainGetMaxMemory)
- return conn->driver->domainGetMaxMemory (domain);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ if (conn->driver->domainGetMaxMemory) {
+ unsigned long ret;
+ ret = conn->driver->domainGetMaxMemory (domain);
+ if (ret == 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return 0;
}
@@ -2087,28 +2340,35 @@ virDomainSetMaxMemory(virDomainPtr domai
virConnectPtr conn;
DEBUG("domain=%p, memory=%lu", domain, memory);
- if (domain == NULL) {
- TODO
- return (-1);
- }
- if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
- virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
- return (-1);
- }
- if (domain->conn->flags & VIR_CONNECT_RO) {
- virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return (-1);
+ }
+ if (domain->conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
}
if (memory < 4096) {
virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
- }
- conn = domain->conn;
-
- if (conn->driver->domainSetMaxMemory)
- return conn->driver->domainSetMaxMemory (domain, memory);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+ conn = domain->conn;
+
+ if (conn->driver->domainSetMaxMemory) {
+ int ret;
+ ret = conn->driver->domainSetMaxMemory (domain, memory);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return -1;
}
@@ -2130,29 +2390,36 @@ virDomainSetMemory(virDomainPtr domain,
virConnectPtr conn;
DEBUG("domain=%p, memory=%lu", domain, memory);
- if (domain == NULL) {
- TODO
- return (-1);
- }
- if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
- virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
- return (-1);
- }
- if (domain->conn->flags & VIR_CONNECT_RO) {
- virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return (-1);
+ }
+ if (domain->conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
}
if (memory < 4096) {
virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
- }
-
- conn = domain->conn;
-
- if (conn->driver->domainSetMemory)
- return conn->driver->domainSetMemory (domain, memory);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ conn = domain->conn;
+
+ if (conn->driver->domainSetMemory) {
+ int ret;
+ ret = conn->driver->domainSetMemory (domain, memory);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return -1;
}
@@ -2173,23 +2440,34 @@ virDomainGetInfo(virDomainPtr domain, vi
virConnectPtr conn;
DEBUG("domain=%p, info=%p", domain, info);
+ virResetLastError();
+
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
return (-1);
}
if (info == NULL) {
virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
+ goto error;
}
memset(info, 0, sizeof(virDomainInfo));
conn = domain->conn;
- if (conn->driver->domainGetInfo)
- return conn->driver->domainGetInfo (domain, info);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ if (conn->driver->domainGetInfo) {
+ int ret;
+ ret = conn->driver->domainGetInfo (domain, info);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return -1;
}
@@ -2210,17 +2488,28 @@ virDomainGetXMLDesc(virDomainPtr domain,
virConnectPtr conn;
DEBUG("domain=%p, flags=%d", domain, flags);
- if (!VIR_IS_DOMAIN(domain)) {
- virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
- return (NULL);
- }
-
- conn = domain->conn;
-
- if (conn->driver->domainDumpXML)
- return conn->driver->domainDumpXML (domain, flags);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return (NULL);
+ }
+
+ conn = domain->conn;
+
+ if (conn->driver->domainDumpXML) {
+ char *ret;
+ ret = conn->driver->domainDumpXML (domain, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return NULL;
}
@@ -2289,14 +2578,16 @@ virDomainMigrate (virDomainPtr domain,
DEBUG("domain=%p, dconn=%p, flags=%lu, dname=%s, uri=%s, bandwidth=%lu",
domain, dconn, flags, dname, uri, bandwidth);
- if (!VIR_IS_DOMAIN (domain)) {
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN (domain)) {
virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
return NULL;
}
conn = domain->conn; /* Source connection. */
if (!VIR_IS_CONNECT (dconn)) {
virLibConnError (conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
- return NULL;
+ goto error;
}
/* Check that migration is supported by both drivers. */
@@ -2312,7 +2603,7 @@ virDomainMigrate (virDomainPtr domain,
version = 2;
else {
virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
- return NULL;
+ goto error;
}
/* Prepare the migration.
@@ -2347,13 +2638,13 @@ virDomainMigrate (virDomainPtr domain,
*/
if (!conn->driver->domainDumpXML) {
virLibConnError (conn, VIR_ERR_INTERNAL_ERROR, __FUNCTION__);
- return NULL;
+ goto error;
}
dom_xml = conn->driver->domainDumpXML (domain,
VIR_DOMAIN_XML_SECURE);
if (!dom_xml)
- return NULL;
+ goto error;
ret = dconn->driver->domainMigratePrepare2
(dconn, &cookie, &cookielen, uri, &uri_out, flags, dname,
@@ -2403,6 +2694,11 @@ virDomainMigrate (virDomainPtr domain,
free (uri_out);
free (cookie);
return ddomain;
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
+ return NULL;
}
/*
@@ -2421,17 +2717,28 @@ virDomainMigratePrepare (virConnectPtr d
{
DEBUG("dconn=%p, cookie=%p, cookielen=%p, uri_in=%s, uri_out=%p, flags=%lu,
dname=%s, bandwidth=%lu", dconn, cookie, cookielen, uri_in, uri_out, flags, dname,
bandwidth);
+ virResetLastError();
+
if (!VIR_IS_CONNECT (dconn)) {
virLibConnError (NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return -1;
}
- if (dconn->driver->domainMigratePrepare)
- return dconn->driver->domainMigratePrepare (dconn, cookie, cookielen,
- uri_in, uri_out,
- flags, dname, bandwidth);
+ if (dconn->driver->domainMigratePrepare) {
+ int ret;
+ ret = dconn->driver->domainMigratePrepare (dconn, cookie, cookielen,
+ uri_in, uri_out,
+ flags, dname, bandwidth);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
virLibConnError (dconn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(dconn);
return -1;
}
@@ -2451,18 +2758,29 @@ virDomainMigratePerform (virDomainPtr do
virConnectPtr conn;
DEBUG("domain=%p, cookie=%p, cookielen=%d, uri=%s, flags=%lu, dname=%s,
bandwidth=%lu", domain, cookie, cookielen, uri, flags, dname, bandwidth);
- if (!VIR_IS_DOMAIN (domain)) {
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN (domain)) {
virLibDomainError (NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
return -1;
}
conn = domain->conn;
- if (conn->driver->domainMigratePerform)
- return conn->driver->domainMigratePerform (domain, cookie, cookielen,
- uri,
- flags, dname, bandwidth);
+ if (conn->driver->domainMigratePerform) {
+ int ret;
+ ret = conn->driver->domainMigratePerform (domain, cookie, cookielen,
+ uri,
+ flags, dname, bandwidth);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
virLibDomainError (domain, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return -1;
}
@@ -2480,17 +2798,28 @@ virDomainMigrateFinish (virConnectPtr dc
{
DEBUG("dconn=%p, dname=%s, cookie=%p, cookielen=%d, uri=%s, flags=%lu",
dconn, dname, cookie, cookielen, uri, flags);
+ virResetLastError();
+
if (!VIR_IS_CONNECT (dconn)) {
virLibConnError (NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return NULL;
}
- if (dconn->driver->domainMigrateFinish)
- return dconn->driver->domainMigrateFinish (dconn, dname,
- cookie, cookielen,
- uri, flags);
+ if (dconn->driver->domainMigrateFinish) {
+ virDomainPtr ret;
+ ret = dconn->driver->domainMigrateFinish (dconn, dname,
+ cookie, cookielen,
+ uri, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
virLibConnError (dconn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(dconn);
return NULL;
}
@@ -2512,18 +2841,29 @@ virDomainMigratePrepare2 (virConnectPtr
{
DEBUG("dconn=%p, cookie=%p, cookielen=%p, uri_in=%s, uri_out=%p, flags=%lu,
dname=%s, bandwidth=%lu, dom_xml=%s", dconn, cookie, cookielen, uri_in, uri_out,
flags, dname, bandwidth, dom_xml);
+ virResetLastError();
+
if (!VIR_IS_CONNECT (dconn)) {
virLibConnError (NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return -1;
}
- if (dconn->driver->domainMigratePrepare2)
- return dconn->driver->domainMigratePrepare2 (dconn, cookie, cookielen,
- uri_in, uri_out,
- flags, dname, bandwidth,
- dom_xml);
+ if (dconn->driver->domainMigratePrepare2) {
+ int ret;
+ ret = dconn->driver->domainMigratePrepare2 (dconn, cookie, cookielen,
+ uri_in, uri_out,
+ flags, dname, bandwidth,
+ dom_xml);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
virLibConnError (dconn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(dconn);
return -1;
}
@@ -2542,18 +2882,29 @@ virDomainMigrateFinish2 (virConnectPtr d
{
DEBUG("dconn=%p, dname=%s, cookie=%p, cookielen=%d, uri=%s, flags=%lu,
retcode=%d", dconn, dname, cookie, cookielen, uri, flags, retcode);
+ virResetLastError();
+
if (!VIR_IS_CONNECT (dconn)) {
virLibConnError (NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return NULL;
}
- if (dconn->driver->domainMigrateFinish2)
- return dconn->driver->domainMigrateFinish2 (dconn, dname,
- cookie, cookielen,
- uri, flags,
- retcode);
+ if (dconn->driver->domainMigrateFinish2) {
+ virDomainPtr ret;
+ ret = dconn->driver->domainMigrateFinish2 (dconn, dname,
+ cookie, cookielen,
+ uri, flags,
+ retcode);
+ if (!ret)
+ goto error;
+ return ret;
+ }
virLibConnError (dconn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(dconn);
return NULL;
}
@@ -2572,19 +2923,30 @@ virNodeGetInfo(virConnectPtr conn, virNo
{
DEBUG("conn=%p, info=%p", conn, info);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (-1);
}
if (info == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
- }
-
- if (conn->driver->nodeGetInfo)
- return conn->driver->nodeGetInfo (conn, info);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->nodeGetInfo) {
+ int ret;
+ ret = conn->driver->nodeGetInfo (conn, info);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return -1;
}
@@ -2603,15 +2965,26 @@ virConnectGetCapabilities (virConnectPtr
{
DEBUG("conn=%p", conn);
+ virResetLastError();
+
if (!VIR_IS_CONNECT (conn)) {
virLibConnError (NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return NULL;
}
- if (conn->driver->getCapabilities)
- return conn->driver->getCapabilities (conn);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ if (conn->driver->getCapabilities) {
+ char *ret;
+ ret = conn->driver->getCapabilities (conn);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return NULL;
}
@@ -2627,16 +3000,27 @@ virNodeGetFreeMemory(virConnectPtr conn)
virNodeGetFreeMemory(virConnectPtr conn)
{
DEBUG("conn=%p", conn);
+
+ virResetLastError();
if (!VIR_IS_CONNECT (conn)) {
virLibConnError (NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return 0;
}
- if (conn->driver->getFreeMemory)
- return conn->driver->getFreeMemory (conn);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ if (conn->driver->getFreeMemory) {
+ unsigned long long ret;
+ ret = conn->driver->getFreeMemory (conn);
+ if (ret == 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return 0;
}
@@ -2656,6 +3040,8 @@ virDomainGetSchedulerType(virDomainPtr d
char *schedtype;
DEBUG("domain=%p, nparams=%p", domain, nparams);
+ virResetLastError();
+
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
return NULL;
@@ -2664,10 +3050,16 @@ virDomainGetSchedulerType(virDomainPtr d
if (conn->driver->domainGetSchedulerType){
schedtype = conn->driver->domainGetSchedulerType (domain, nparams);
+ if (!schedtype)
+ goto error;
return schedtype;
}
virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return NULL;
}
@@ -2693,16 +3085,27 @@ virDomainGetSchedulerParameters(virDomai
virConnectPtr conn;
DEBUG("domain=%p, params=%p, nparams=%p", domain, params, nparams);
- if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
- virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
- return -1;
- }
- conn = domain->conn;
-
- if (conn->driver->domainGetSchedulerParameters)
- return conn->driver->domainGetSchedulerParameters (domain, params,
nparams);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return -1;
+ }
+ conn = domain->conn;
+
+ if (conn->driver->domainGetSchedulerParameters) {
+ int ret;
+ ret = conn->driver->domainGetSchedulerParameters (domain, params,
nparams);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return -1;
}
@@ -2725,20 +3128,31 @@ virDomainSetSchedulerParameters(virDomai
virConnectPtr conn;
DEBUG("domain=%p, params=%p, nparams=%d", domain, params, nparams);
- if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
- virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
- return -1;
- }
- if (domain->conn->flags & VIR_CONNECT_RO) {
- virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return -1;
- }
- conn = domain->conn;
-
- if (conn->driver->domainSetSchedulerParameters)
- return conn->driver->domainSetSchedulerParameters (domain, params,
nparams);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return -1;
+ }
+ if (domain->conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+ conn = domain->conn;
+
+ if (conn->driver->domainSetSchedulerParameters) {
+ int ret;
+ ret = conn->driver->domainSetSchedulerParameters (domain, params,
nparams);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return -1;
}
@@ -2774,25 +3188,31 @@ virDomainBlockStats (virDomainPtr dom, c
struct _virDomainBlockStats stats2 = { -1, -1, -1, -1, -1 };
DEBUG("domain=%p, path=%s, stats=%p, size=%zi", dom, path, stats, size);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN (dom)) {
+ virLibDomainError (NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return -1;
+ }
if (!stats || size > sizeof stats2) {
virLibDomainError (dom, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return -1;
- }
- if (!VIR_IS_CONNECTED_DOMAIN (dom)) {
- virLibDomainError (NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
- return -1;
+ goto error;
}
conn = dom->conn;
if (conn->driver->domainBlockStats) {
if (conn->driver->domainBlockStats (dom, path, &stats2) == -1)
- return -1;
+ goto error;
memcpy (stats, &stats2, size);
return 0;
}
virLibDomainError (dom, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(dom->conn);
return -1;
}
@@ -2826,25 +3246,31 @@ virDomainInterfaceStats (virDomainPtr do
-1, -1, -1, -1 };
DEBUG("domain=%p, path=%s, stats=%p, size=%zi", dom, path, stats, size);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN (dom)) {
+ virLibDomainError (NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return -1;
+ }
if (!stats || size > sizeof stats2) {
virLibDomainError (dom, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return -1;
- }
- if (!VIR_IS_CONNECTED_DOMAIN (dom)) {
- virLibDomainError (NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
- return -1;
+ goto error;
}
conn = dom->conn;
if (conn->driver->domainInterfaceStats) {
if (conn->driver->domainInterfaceStats (dom, path, &stats2) == -1)
- return -1;
+ goto error;
memcpy (stats, &stats2, size);
return 0;
}
virLibDomainError (dom, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(dom->conn);
return -1;
}
@@ -2899,6 +3325,8 @@ virDomainBlockPeek (virDomainPtr dom,
DEBUG("domain=%p, path=%s, offset=%lld, size=%zi, buffer=%p",
dom, path, offset, size, buffer);
+ virResetLastError();
+
if (!VIR_IS_CONNECTED_DOMAIN (dom)) {
virLibDomainError (NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
return -1;
@@ -2908,27 +3336,36 @@ virDomainBlockPeek (virDomainPtr dom,
if (!path) {
virLibDomainError (dom, VIR_ERR_INVALID_ARG,
_("path is NULL"));
- return -1;
+ goto error;
}
if (flags != 0) {
virLibDomainError (dom, VIR_ERR_INVALID_ARG,
_("flags must be zero"));
- return -1;
+ goto error;
}
/* Allow size == 0 as an access test. */
if (size > 0 && !buffer) {
virLibDomainError (dom, VIR_ERR_INVALID_ARG,
_("buffer is NULL"));
- return -1;
- }
-
- if (conn->driver->domainBlockPeek)
- return conn->driver->domainBlockPeek (dom, path, offset, size,
- buffer, flags);
+ goto error;
+ }
+
+ if (conn->driver->domainBlockPeek) {
+ int ret;
+ ret =conn->driver->domainBlockPeek (dom, path, offset, size,
+ buffer, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
virLibDomainError (dom, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(dom->conn);
return -1;
}
@@ -2973,6 +3410,8 @@ virDomainMemoryPeek (virDomainPtr dom,
virConnectPtr conn;
DEBUG ("domain=%p, start=%lld, size=%zi, buffer=%p, flags=%d",
dom, start, size, buffer, flags);
+
+ virResetLastError();
if (!VIR_IS_CONNECTED_DOMAIN (dom)) {
virLibDomainError (NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
@@ -3004,21 +3443,30 @@ virDomainMemoryPeek (virDomainPtr dom,
if (flags != VIR_MEMORY_VIRTUAL) {
virLibDomainError (dom, VIR_ERR_INVALID_ARG,
_("flags parameter must be VIR_MEMORY_VIRTUAL"));
- return -1;
+ goto error;
}
/* Allow size == 0 as an access test. */
if (size > 0 && !buffer) {
virLibDomainError (dom, VIR_ERR_INVALID_ARG,
_("buffer is NULL but size is non-zero"));
- return -1;
- }
-
- if (conn->driver->domainMemoryPeek)
- return conn->driver->domainMemoryPeek (dom, start, size,
- buffer, flags);
+ goto error;
+ }
+
+ if (conn->driver->domainMemoryPeek) {
+ int ret;
+ ret = conn->driver->domainMemoryPeek (dom, start, size,
+ buffer, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
virLibDomainError (dom, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(dom->conn);
return -1;
}
@@ -3044,23 +3492,34 @@ virDomainDefineXML(virConnectPtr conn, c
virDomainDefineXML(virConnectPtr conn, const char *xml) {
DEBUG("conn=%p, xml=%s", conn, xml);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (NULL);
}
if (conn->flags & VIR_CONNECT_RO) {
virLibConnError(conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (NULL);
+ goto error;
}
if (xml == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
- }
-
- if (conn->driver->domainDefineXML)
- return conn->driver->domainDefineXML (conn, xml);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->domainDefineXML) {
+ virDomainPtr ret;
+ ret = conn->driver->domainDefineXML (conn, xml);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return NULL;
}
@@ -3077,20 +3536,31 @@ virDomainUndefine(virDomainPtr domain) {
virConnectPtr conn;
DEBUG("domain=%p", domain);
- if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
- virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
- return (-1);
- }
- conn = domain->conn;
- if (conn->flags & VIR_CONNECT_RO) {
- virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
- }
-
- if (conn->driver->domainUndefine)
- return conn->driver->domainUndefine (domain);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return (-1);
+ }
+ conn = domain->conn;
+ if (conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->domainUndefine) {
+ int ret;
+ ret = conn->driver->domainUndefine (domain);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return -1;
}
@@ -3107,15 +3577,26 @@ virConnectNumOfDefinedDomains(virConnect
{
DEBUG("conn=%p", conn);
- if (!VIR_IS_CONNECT(conn)) {
- virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
- return (-1);
- }
-
- if (conn->driver->numOfDefinedDomains)
- return conn->driver->numOfDefinedDomains (conn);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (-1);
+ }
+
+ if (conn->driver->numOfDefinedDomains) {
+ int ret;
+ ret = conn->driver->numOfDefinedDomains (conn);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return -1;
}
@@ -3135,6 +3616,8 @@ virConnectListDefinedDomains(virConnectP
int maxnames) {
DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (-1);
@@ -3142,13 +3625,22 @@ virConnectListDefinedDomains(virConnectP
if ((names == NULL) || (maxnames < 0)) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
- }
-
- if (conn->driver->listDefinedDomains)
- return conn->driver->listDefinedDomains (conn, names, maxnames);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->listDefinedDomains) {
+ int ret;
+ ret = conn->driver->listDefinedDomains (conn, names, maxnames);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return -1;
}
@@ -3166,24 +3658,31 @@ virDomainCreate(virDomainPtr domain) {
virConnectPtr conn;
DEBUG("domain=%p", domain);
- if (domain == NULL) {
- TODO
- return (-1);
- }
- if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
- virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
- return (-1);
- }
- conn = domain->conn;
- if (conn->flags & VIR_CONNECT_RO) {
- virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
- }
-
- if (conn->driver->domainCreate)
- return conn->driver->domainCreate (domain);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return (-1);
+ }
+ conn = domain->conn;
+ if (conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->domainCreate) {
+ int ret;
+ ret = conn->driver->domainCreate (domain);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return -1;
}
@@ -3205,21 +3704,32 @@ virDomainGetAutostart(virDomainPtr domai
virConnectPtr conn;
DEBUG("domain=%p, autostart=%p", domain, autostart);
- if (!VIR_IS_DOMAIN(domain)) {
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
return (-1);
}
if (!autostart) {
virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
- }
-
- conn = domain->conn;
-
- if (conn->driver->domainGetAutostart)
- return conn->driver->domainGetAutostart (domain, autostart);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ conn = domain->conn;
+
+ if (conn->driver->domainGetAutostart) {
+ int ret;
+ ret = conn->driver->domainGetAutostart (domain, autostart);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return -1;
}
@@ -3240,17 +3750,28 @@ virDomainSetAutostart(virDomainPtr domai
virConnectPtr conn;
DEBUG("domain=%p, autostart=%d", domain, autostart);
- if (!VIR_IS_DOMAIN(domain)) {
- virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
- return (-1);
- }
-
- conn = domain->conn;
-
- if (conn->driver->domainSetAutostart)
- return conn->driver->domainSetAutostart (domain, autostart);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return (-1);
+ }
+
+ conn = domain->conn;
+
+ if (conn->driver->domainSetAutostart) {
+ int ret;
+ ret = conn->driver->domainSetAutostart (domain, autostart);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return -1;
}
@@ -3273,29 +3794,36 @@ virDomainSetVcpus(virDomainPtr domain, u
virConnectPtr conn;
DEBUG("domain=%p, nvcpus=%u", domain, nvcpus);
- if (domain == NULL) {
- TODO
- return (-1);
- }
- if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
- virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
- return (-1);
- }
- if (domain->conn->flags & VIR_CONNECT_RO) {
- virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return (-1);
+ }
+ if (domain->conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
}
if (nvcpus < 1) {
virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
- }
- conn = domain->conn;
-
- if (conn->driver->domainSetVcpus)
- return conn->driver->domainSetVcpus (domain, nvcpus);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+ conn = domain->conn;
+
+ if (conn->driver->domainSetVcpus) {
+ int ret;
+ ret = conn->driver->domainSetVcpus (domain, nvcpus);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return -1;
}
@@ -3324,30 +3852,37 @@ virDomainPinVcpu(virDomainPtr domain, un
virConnectPtr conn;
DEBUG("domain=%p, vcpu=%u, cpumap=%p, maplen=%d", domain, vcpu, cpumap,
maplen);
- if (domain == NULL) {
- TODO
- return (-1);
- }
- if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
- virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
- return (-1);
- }
- if (domain->conn->flags & VIR_CONNECT_RO) {
- virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return (-1);
+ }
+ if (domain->conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
}
if ((vcpu > 32000) || (cpumap == NULL) || (maplen < 1)) {
virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
- }
-
- conn = domain->conn;
-
- if (conn->driver->domainPinVcpu)
- return conn->driver->domainPinVcpu (domain, vcpu, cpumap, maplen);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ conn = domain->conn;
+
+ if (conn->driver->domainPinVcpu) {
+ int ret;
+ ret = conn->driver->domainPinVcpu (domain, vcpu, cpumap, maplen);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return -1;
}
@@ -3379,30 +3914,37 @@ virDomainGetVcpus(virDomainPtr domain, v
virConnectPtr conn;
DEBUG("domain=%p, info=%p, maxinfo=%d, cpumaps=%p, maplen=%d", domain,
info, maxinfo, cpumaps, maplen);
- if (domain == NULL) {
- TODO
- return (-1);
- }
+ virResetLastError();
+
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
return (-1);
}
if ((info == NULL) || (maxinfo < 1)) {
virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
+ goto error;
}
if (cpumaps != NULL && maplen < 1) {
virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
- }
-
- conn = domain->conn;
-
- if (conn->driver->domainGetVcpus)
- return conn->driver->domainGetVcpus (domain, info, maxinfo,
- cpumaps, maplen);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ conn = domain->conn;
+
+ if (conn->driver->domainGetVcpus) {
+ int ret;
+ ret = conn->driver->domainGetVcpus (domain, info, maxinfo,
+ cpumaps, maplen);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return -1;
}
@@ -3424,17 +3966,28 @@ virDomainGetMaxVcpus(virDomainPtr domain
virConnectPtr conn;
DEBUG("domain=%p", domain);
- if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
- virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
- return (-1);
- }
-
- conn = domain->conn;
-
- if (conn->driver->domainGetMaxVcpus)
- return conn->driver->domainGetMaxVcpus (domain);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return (-1);
+ }
+
+ conn = domain->conn;
+
+ if (conn->driver->domainGetMaxVcpus) {
+ int ret;
+ ret = conn->driver->domainGetMaxVcpus (domain);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return -1;
}
@@ -3454,20 +4007,31 @@ virDomainAttachDevice(virDomainPtr domai
virConnectPtr conn;
DEBUG("domain=%p, xml=%s", domain, xml);
- if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
- virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
- return (-1);
- }
- if (domain->conn->flags & VIR_CONNECT_RO) {
- virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
- }
- conn = domain->conn;
-
- if (conn->driver->domainAttachDevice)
- return conn->driver->domainAttachDevice (domain, xml);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return (-1);
+ }
+ if (domain->conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+ conn = domain->conn;
+
+ if (conn->driver->domainAttachDevice) {
+ int ret;
+ ret = conn->driver->domainAttachDevice (domain, xml);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return -1;
}
@@ -3486,20 +4050,31 @@ virDomainDetachDevice(virDomainPtr domai
virConnectPtr conn;
DEBUG("domain=%p, xml=%s", domain, xml);
- if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
- virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
- return (-1);
- }
- if (domain->conn->flags & VIR_CONNECT_RO) {
- virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
- }
- conn = domain->conn;
-
- if (conn->driver->domainDetachDevice)
- return conn->driver->domainDetachDevice (domain, xml);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return (-1);
+ }
+ if (domain->conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+ conn = domain->conn;
+
+ if (conn->driver->domainDetachDevice) {
+ int ret;
+ ret = conn->driver->domainDetachDevice (domain, xml);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(domain->conn);
return -1;
}
@@ -3528,6 +4103,8 @@ virNodeGetCellsFreeMemory(virConnectPtr
DEBUG("conn=%p, freeMems=%p, startCell=%d, maxCells=%d",
conn, freeMems, startCell, maxCells);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (-1);
@@ -3535,13 +4112,22 @@ virNodeGetCellsFreeMemory(virConnectPtr
if ((freeMems == NULL) || (maxCells <= 0) || (startCell < 0)) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
- }
-
- if (conn->driver->nodeGetCellsFreeMemory)
- return conn->driver->nodeGetCellsFreeMemory (conn, freeMems, startCell,
maxCells);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->nodeGetCellsFreeMemory) {
+ int ret;
+ ret = conn->driver->nodeGetCellsFreeMemory (conn, freeMems, startCell,
maxCells);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return -1;
}
@@ -3564,7 +4150,9 @@ virNetworkGetConnect (virNetworkPtr net)
{
DEBUG("net=%p", net);
- if (!VIR_IS_NETWORK (net)) {
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_NETWORK (net)) {
virLibNetworkError (NULL, VIR_ERR_INVALID_NETWORK, __FUNCTION__);
return NULL;
}
@@ -3584,15 +4172,26 @@ virConnectNumOfNetworks(virConnectPtr co
{
DEBUG("conn=%p", conn);
- if (!VIR_IS_CONNECT(conn)) {
- virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
- return (-1);
- }
-
- if (conn->networkDriver && conn->networkDriver->numOfNetworks)
- return conn->networkDriver->numOfNetworks (conn);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (-1);
+ }
+
+ if (conn->networkDriver && conn->networkDriver->numOfNetworks) {
+ int ret;
+ ret = conn->networkDriver->numOfNetworks (conn);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return -1;
}
@@ -3611,6 +4210,8 @@ virConnectListNetworks(virConnectPtr con
{
DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (-1);
@@ -3618,13 +4219,22 @@ virConnectListNetworks(virConnectPtr con
if ((names == NULL) || (maxnames < 0)) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
- }
-
- if (conn->networkDriver && conn->networkDriver->listNetworks)
- return conn->networkDriver->listNetworks (conn, names, maxnames);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->networkDriver && conn->networkDriver->listNetworks) {
+ int ret;
+ ret = conn->networkDriver->listNetworks (conn, names, maxnames);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return -1;
}
@@ -3641,15 +4251,26 @@ virConnectNumOfDefinedNetworks(virConnec
{
DEBUG("conn=%p", conn);
- if (!VIR_IS_CONNECT(conn)) {
- virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
- return (-1);
- }
-
- if (conn->networkDriver &&
conn->networkDriver->numOfDefinedNetworks)
- return conn->networkDriver->numOfDefinedNetworks (conn);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (-1);
+ }
+
+ if (conn->networkDriver &&
conn->networkDriver->numOfDefinedNetworks) {
+ int ret;
+ ret = conn->networkDriver->numOfDefinedNetworks (conn);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return -1;
}
@@ -3669,6 +4290,8 @@ virConnectListDefinedNetworks(virConnect
{
DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (-1);
@@ -3676,14 +4299,23 @@ virConnectListDefinedNetworks(virConnect
if ((names == NULL) || (maxnames < 0)) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
- }
-
- if (conn->networkDriver &&
conn->networkDriver->listDefinedNetworks)
- return conn->networkDriver->listDefinedNetworks (conn,
- names, maxnames);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->networkDriver && conn->networkDriver->listDefinedNetworks)
{
+ int ret;
+ ret = conn->networkDriver->listDefinedNetworks (conn,
+ names, maxnames);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return -1;
}
@@ -3702,19 +4334,30 @@ virNetworkLookupByName(virConnectPtr con
{
DEBUG("conn=%p, name=%s", conn, name);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (NULL);
}
if (name == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
- }
-
- if (conn->networkDriver &&
conn->networkDriver->networkLookupByName)
- return conn->networkDriver->networkLookupByName (conn, name);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->networkDriver && conn->networkDriver->networkLookupByName)
{
+ virNetworkPtr ret;
+ ret = conn->networkDriver->networkLookupByName (conn, name);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return NULL;
}
@@ -3733,19 +4376,30 @@ virNetworkLookupByUUID(virConnectPtr con
{
DEBUG("conn=%p, uuid=%s", conn, uuid);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (NULL);
}
if (uuid == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
- }
-
- if (conn->networkDriver &&
conn->networkDriver->networkLookupByUUID)
- return conn->networkDriver->networkLookupByUUID (conn, uuid);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->networkDriver &&
conn->networkDriver->networkLookupByUUID){
+ virNetworkPtr ret;
+ ret = conn->networkDriver->networkLookupByUUID (conn, uuid);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return NULL;
}
@@ -3767,13 +4421,15 @@ virNetworkLookupByUUIDString(virConnectP
int ret;
DEBUG("conn=%p, uuidstr=%s", conn, uuidstr);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (NULL);
}
if (uuidstr == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
+ goto error;
}
/* XXX: sexpr_uuid() also supports 'xxxx-xxxx-xxxx-xxxx' format.
@@ -3792,12 +4448,17 @@ virNetworkLookupByUUIDString(virConnectP
if (ret!=VIR_UUID_BUFLEN) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
+ goto error;
}
for (i = 0; i < VIR_UUID_BUFLEN; i++)
uuid[i] = raw[i] & 0xFF;
return virNetworkLookupByUUID(conn, &uuid[0]);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
+ return NULL;
}
/**
@@ -3815,23 +4476,34 @@ virNetworkCreateXML(virConnectPtr conn,
{
DEBUG("conn=%p, xmlDesc=%s", conn, xmlDesc);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (NULL);
}
if (xmlDesc == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
+ goto error;
}
if (conn->flags & VIR_CONNECT_RO) {
virLibConnError(conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (NULL);
- }
-
- if (conn->networkDriver && conn->networkDriver->networkCreateXML)
- return conn->networkDriver->networkCreateXML (conn, xmlDesc);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->networkDriver && conn->networkDriver->networkCreateXML) {
+ virNetworkPtr ret;
+ ret = conn->networkDriver->networkCreateXML (conn, xmlDesc);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return NULL;
}
@@ -3849,23 +4521,34 @@ virNetworkDefineXML(virConnectPtr conn,
{
DEBUG("conn=%p, xml=%s", conn, xml);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (NULL);
}
if (conn->flags & VIR_CONNECT_RO) {
virLibConnError(conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (NULL);
+ goto error;
}
if (xml == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
- }
-
- if (conn->networkDriver && conn->networkDriver->networkDefineXML)
- return conn->networkDriver->networkDefineXML (conn, xml);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->networkDriver && conn->networkDriver->networkDefineXML) {
+ virNetworkPtr ret;
+ ret = conn->networkDriver->networkDefineXML (conn, xml);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return NULL;
}
@@ -3882,6 +4565,8 @@ virNetworkUndefine(virNetworkPtr network
virConnectPtr conn;
DEBUG("network=%p", network);
+ virResetLastError();
+
if (!VIR_IS_CONNECTED_NETWORK(network)) {
virLibNetworkError(NULL, VIR_ERR_INVALID_NETWORK, __FUNCTION__);
return (-1);
@@ -3889,13 +4574,22 @@ virNetworkUndefine(virNetworkPtr network
conn = network->conn;
if (conn->flags & VIR_CONNECT_RO) {
virLibNetworkError(network, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
- }
-
- if (conn->networkDriver && conn->networkDriver->networkUndefine)
- return conn->networkDriver->networkUndefine (network);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->networkDriver && conn->networkDriver->networkUndefine) {
+ int ret;
+ ret = conn->networkDriver->networkUndefine (network);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(network->conn);
return -1;
}
@@ -3914,10 +4608,8 @@ virNetworkCreate(virNetworkPtr network)
virConnectPtr conn;
DEBUG("network=%p", network);
- if (network == NULL) {
- TODO
- return (-1);
- }
+ virResetLastError();
+
if (!VIR_IS_CONNECTED_NETWORK(network)) {
virLibNetworkError(NULL, VIR_ERR_INVALID_NETWORK, __FUNCTION__);
return (-1);
@@ -3925,13 +4617,22 @@ virNetworkCreate(virNetworkPtr network)
conn = network->conn;
if (conn->flags & VIR_CONNECT_RO) {
virLibNetworkError(network, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
- }
-
- if (conn->networkDriver && conn->networkDriver->networkCreate)
- return conn->networkDriver->networkCreate (network);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->networkDriver && conn->networkDriver->networkCreate) {
+ int ret;
+ ret = conn->networkDriver->networkCreate (network);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(network->conn);
return -1;
}
@@ -3952,6 +4653,8 @@ virNetworkDestroy(virNetworkPtr network)
virConnectPtr conn;
DEBUG("network=%p", network);
+ virResetLastError();
+
if (!VIR_IS_CONNECTED_NETWORK(network)) {
virLibNetworkError(NULL, VIR_ERR_INVALID_NETWORK, __FUNCTION__);
return (-1);
@@ -3960,13 +4663,22 @@ virNetworkDestroy(virNetworkPtr network)
conn = network->conn;
if (conn->flags & VIR_CONNECT_RO) {
virLibNetworkError(network, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
- }
-
- if (conn->networkDriver && conn->networkDriver->networkDestroy)
- return conn->networkDriver->networkDestroy (network);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->networkDriver && conn->networkDriver->networkDestroy) {
+ int ret;
+ ret = conn->networkDriver->networkDestroy (network);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(network->conn);
return -1;
}
@@ -3984,7 +4696,9 @@ virNetworkFree(virNetworkPtr network)
{
DEBUG("network=%p", network);
- if (!VIR_IS_NETWORK(network)) {
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_NETWORK(network)) {
virLibNetworkError(NULL, VIR_ERR_INVALID_NETWORK, __FUNCTION__);
return (-1);
}
@@ -4007,6 +4721,8 @@ virNetworkGetName(virNetworkPtr network)
{
DEBUG("network=%p", network);
+ virResetLastError();
+
if (!VIR_IS_NETWORK(network)) {
virLibNetworkError(NULL, VIR_ERR_INVALID_NETWORK, __FUNCTION__);
return (NULL);
@@ -4027,6 +4743,8 @@ virNetworkGetUUID(virNetworkPtr network,
virNetworkGetUUID(virNetworkPtr network, unsigned char *uuid)
{
DEBUG("network=%p, uuid=%p", network, uuid);
+
+ virResetLastError();
if (!VIR_IS_NETWORK(network)) {
virLibNetworkError(NULL, VIR_ERR_INVALID_NETWORK, __FUNCTION__);
@@ -4034,12 +4752,17 @@ virNetworkGetUUID(virNetworkPtr network,
}
if (uuid == NULL) {
virLibNetworkError(network, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
+ goto error;
}
memcpy(uuid, &network->uuid[0], VIR_UUID_BUFLEN);
return (0);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(network->conn);
+ return -1;
}
/**
@@ -4058,13 +4781,15 @@ virNetworkGetUUIDString(virNetworkPtr ne
unsigned char uuid[VIR_UUID_BUFLEN];
DEBUG("network=%p, buf=%p", network, buf);
+ virResetLastError();
+
if (!VIR_IS_NETWORK(network)) {
virLibNetworkError(NULL, VIR_ERR_INVALID_NETWORK, __FUNCTION__);
return (-1);
}
if (buf == NULL) {
virLibNetworkError(network, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
+ goto error;
}
if (virNetworkGetUUID(network, &uuid[0]))
@@ -4072,6 +4797,11 @@ virNetworkGetUUIDString(virNetworkPtr ne
virUUIDFormat(uuid, buf);
return (0);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(network->conn);
+ return -1;
}
/**
@@ -4091,21 +4821,32 @@ virNetworkGetXMLDesc(virNetworkPtr netwo
virConnectPtr conn;
DEBUG("network=%p, flags=%d", network, flags);
- if (!VIR_IS_NETWORK(network)) {
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_NETWORK(network)) {
virLibNetworkError(NULL, VIR_ERR_INVALID_NETWORK, __FUNCTION__);
return (NULL);
}
if (flags != 0) {
virLibNetworkError(network, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
+ goto error;
}
conn = network->conn;
- if (conn->networkDriver && conn->networkDriver->networkDumpXML)
- return conn->networkDriver->networkDumpXML (network, flags);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ if (conn->networkDriver && conn->networkDriver->networkDumpXML) {
+ char *ret;
+ ret = conn->networkDriver->networkDumpXML (network, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(network->conn);
return NULL;
}
@@ -4125,17 +4866,28 @@ virNetworkGetBridgeName(virNetworkPtr ne
virConnectPtr conn;
DEBUG("network=%p", network);
- if (!VIR_IS_NETWORK(network)) {
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_NETWORK(network)) {
virLibNetworkError(NULL, VIR_ERR_INVALID_NETWORK, __FUNCTION__);
return (NULL);
}
conn = network->conn;
- if (conn->networkDriver &&
conn->networkDriver->networkGetBridgeName)
- return conn->networkDriver->networkGetBridgeName (network);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ if (conn->networkDriver &&
conn->networkDriver->networkGetBridgeName) {
+ char *ret;
+ ret = conn->networkDriver->networkGetBridgeName (network);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(network->conn);
return NULL;
}
@@ -4157,21 +4909,32 @@ virNetworkGetAutostart(virNetworkPtr net
virConnectPtr conn;
DEBUG("network=%p, autostart=%p", network, autostart);
- if (!VIR_IS_NETWORK(network)) {
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_NETWORK(network)) {
virLibNetworkError(NULL, VIR_ERR_INVALID_NETWORK, __FUNCTION__);
return (-1);
}
if (!autostart) {
virLibNetworkError(network, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
+ goto error;
}
conn = network->conn;
- if (conn->networkDriver &&
conn->networkDriver->networkGetAutostart)
- return conn->networkDriver->networkGetAutostart (network, autostart);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ if (conn->networkDriver && conn->networkDriver->networkGetAutostart)
{
+ int ret;
+ ret = conn->networkDriver->networkGetAutostart (network, autostart);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(network->conn);
return -1;
}
@@ -4192,17 +4955,28 @@ virNetworkSetAutostart(virNetworkPtr net
virConnectPtr conn;
DEBUG("network=%p, autostart=%d", network, autostart);
- if (!VIR_IS_NETWORK(network)) {
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_NETWORK(network)) {
virLibNetworkError(NULL, VIR_ERR_INVALID_NETWORK, __FUNCTION__);
return (-1);
}
conn = network->conn;
- if (conn->networkDriver &&
conn->networkDriver->networkSetAutostart)
- return conn->networkDriver->networkSetAutostart (network, autostart);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ if (conn->networkDriver && conn->networkDriver->networkSetAutostart)
{
+ int ret;
+ ret = conn->networkDriver->networkSetAutostart (network, autostart);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(network->conn);
return -1;
}
@@ -4226,7 +5000,9 @@ virStoragePoolGetConnect (virStoragePool
{
DEBUG("pool=%p", pool);
- if (!VIR_IS_STORAGE_POOL (pool)) {
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_STORAGE_POOL (pool)) {
virLibStoragePoolError (NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
return NULL;
}
@@ -4246,15 +5022,26 @@ virConnectNumOfStoragePools (virConnectP
{
DEBUG("conn=%p", conn);
- if (!VIR_IS_CONNECT(conn)) {
- virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
- return (-1);
- }
-
- if (conn->storageDriver && conn->storageDriver->numOfPools)
- return conn->storageDriver->numOfPools (conn);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (-1);
+ }
+
+ if (conn->storageDriver && conn->storageDriver->numOfPools) {
+ int ret;
+ ret = conn->storageDriver->numOfPools (conn);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return -1;
}
@@ -4277,6 +5064,8 @@ virConnectListStoragePools (virConnectPt
{
DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (-1);
@@ -4284,15 +5073,23 @@ virConnectListStoragePools (virConnectPt
if ((names == NULL) || (maxnames < 0)) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
- }
-
- if (conn->storageDriver && conn->storageDriver->listPools)
- return conn->storageDriver->listPools (conn, names, maxnames);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
- return -1;
-
+ goto error;
+ }
+
+ if (conn->storageDriver && conn->storageDriver->listPools) {
+ int ret;
+ ret = conn->storageDriver->listPools (conn, names, maxnames);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
+ return -1;
}
@@ -4309,15 +5106,26 @@ virConnectNumOfDefinedStoragePools(virCo
{
DEBUG("conn=%p", conn);
- if (!VIR_IS_CONNECT(conn)) {
- virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
- return (-1);
- }
-
- if (conn->storageDriver && conn->storageDriver->numOfDefinedPools)
- return conn->storageDriver->numOfDefinedPools (conn);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (-1);
+ }
+
+ if (conn->storageDriver && conn->storageDriver->numOfDefinedPools)
{
+ int ret;
+ ret = conn->storageDriver->numOfDefinedPools (conn);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return -1;
}
@@ -4341,6 +5149,8 @@ virConnectListDefinedStoragePools(virCon
{
DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (-1);
@@ -4348,13 +5158,22 @@ virConnectListDefinedStoragePools(virCon
if ((names == NULL) || (maxnames < 0)) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
- }
-
- if (conn->storageDriver && conn->storageDriver->listDefinedPools)
- return conn->storageDriver->listDefinedPools (conn, names, maxnames);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->storageDriver && conn->storageDriver->listDefinedPools) {
+ int ret;
+ ret = conn->storageDriver->listDefinedPools (conn, names, maxnames);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return -1;
}
@@ -4386,19 +5205,32 @@ virConnectFindStoragePoolSources(virConn
const char *srcSpec,
unsigned int flags)
{
+ DEBUG("conn=%p, type=%s, src=%s, flags=%u", conn, type ? type :
"", srcSpec ? srcSpec : "", flags);
+
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return NULL;
}
if (type == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return NULL;
- }
-
- if (conn->storageDriver && conn->storageDriver->findPoolSources)
- return conn->storageDriver->findPoolSources(conn, type, srcSpec, flags);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->storageDriver && conn->storageDriver->findPoolSources) {
+ char *ret;
+ ret = conn->storageDriver->findPoolSources(conn, type, srcSpec, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return NULL;
}
@@ -4418,19 +5250,30 @@ virStoragePoolLookupByName(virConnectPtr
{
DEBUG("conn=%p, name=%s", conn, name);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (NULL);
}
if (name == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
- }
-
- if (conn->storageDriver && conn->storageDriver->poolLookupByName)
- return conn->storageDriver->poolLookupByName (conn, name);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->storageDriver && conn->storageDriver->poolLookupByName) {
+ virStoragePoolPtr ret;
+ ret = conn->storageDriver->poolLookupByName (conn, name);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return NULL;
}
@@ -4450,21 +5293,31 @@ virStoragePoolLookupByUUID(virConnectPtr
{
DEBUG("conn=%p, uuid=%s", conn, uuid);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (NULL);
}
if (uuid == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
- }
-
- if (conn->storageDriver && conn->storageDriver->poolLookupByUUID)
- return conn->storageDriver->poolLookupByUUID (conn, uuid);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
- return NULL;
-
+ goto error;
+ }
+
+ if (conn->storageDriver && conn->storageDriver->poolLookupByUUID) {
+ virStoragePoolPtr ret;
+ ret = conn->storageDriver->poolLookupByUUID (conn, uuid);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
+ return NULL;
}
@@ -4479,26 +5332,33 @@ virStoragePoolLookupByUUID(virConnectPtr
*/
virStoragePoolPtr
virStoragePoolLookupByUUIDString(virConnectPtr conn,
- const char *uuidstr)
+ const char *uuidstr)
{
unsigned char uuid[VIR_UUID_BUFLEN];
DEBUG("conn=%p, uuidstr=%s", conn, uuidstr);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (NULL);
}
if (uuidstr == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
+ goto error;
}
if (virUUIDParse(uuidstr, uuid) < 0) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
+ goto error;
}
return virStoragePoolLookupByUUID(conn, uuid);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
+ return NULL;
}
@@ -4515,17 +5375,27 @@ virStoragePoolLookupByVolume(virStorageV
{
DEBUG("vol=%p", vol);
- if (!VIR_IS_STORAGE_VOL(vol)) {
- virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
- return (NULL);
- }
-
- if (vol->conn->storageDriver &&
vol->conn->storageDriver->poolLookupByVolume)
- return vol->conn->storageDriver->poolLookupByVolume (vol);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_STORAGE_VOL(vol)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (NULL);
+ }
+
+ if (vol->conn->storageDriver &&
vol->conn->storageDriver->poolLookupByVolume) {
+ virStoragePoolPtr ret;
+ ret = vol->conn->storageDriver->poolLookupByVolume (vol);
+ if (!ret)
+ goto error;
+ return ret;
+ }
virLibConnError (vol->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
- return NULL;
-
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(vol->conn);
+ return NULL;
}
/**
@@ -4547,23 +5417,34 @@ virStoragePoolCreateXML(virConnectPtr co
{
DEBUG("conn=%p, xmlDesc=%s", conn, xmlDesc);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (NULL);
}
if (xmlDesc == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
+ goto error;
}
if (conn->flags & VIR_CONNECT_RO) {
virLibConnError(conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (NULL);
- }
-
- if (conn->storageDriver && conn->storageDriver->poolCreateXML)
- return conn->storageDriver->poolCreateXML (conn, xmlDesc, flags);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->storageDriver && conn->storageDriver->poolCreateXML) {
+ virStoragePoolPtr ret;
+ ret = conn->storageDriver->poolCreateXML (conn, xmlDesc, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return NULL;
}
@@ -4585,25 +5466,35 @@ virStoragePoolDefineXML(virConnectPtr co
{
DEBUG("conn=%p, xml=%s", conn, xml);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (NULL);
}
if (conn->flags & VIR_CONNECT_RO) {
virLibConnError(conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (NULL);
+ goto error;
}
if (xml == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
- }
-
- if (conn->storageDriver && conn->storageDriver->poolDefineXML)
- return conn->storageDriver->poolDefineXML (conn, xml, flags);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
- return NULL;
-
+ goto error;
+ }
+
+ if (conn->storageDriver && conn->storageDriver->poolDefineXML) {
+ virStoragePoolPtr ret;
+ ret = conn->storageDriver->poolDefineXML (conn, xml, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
+ return NULL;
}
/**
@@ -4622,6 +5513,8 @@ virStoragePoolBuild(virStoragePoolPtr po
virConnectPtr conn;
DEBUG("pool=%p, flags=%u", pool, flags);
+ virResetLastError();
+
if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
virLibStoragePoolError(NULL, VIR_ERR_INVALID_NETWORK, __FUNCTION__);
return (-1);
@@ -4629,15 +5522,23 @@ virStoragePoolBuild(virStoragePoolPtr po
conn = pool->conn;
if (conn->flags & VIR_CONNECT_RO) {
virLibStoragePoolError(pool, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
- }
-
- if (conn->storageDriver && conn->storageDriver->poolBuild)
- return conn->storageDriver->poolBuild (pool, flags);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
- return -1;
-
+ goto error;
+ }
+
+ if (conn->storageDriver && conn->storageDriver->poolBuild) {
+ int ret;
+ ret = conn->storageDriver->poolBuild (pool, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(pool->conn);
+ return -1;
}
@@ -4655,6 +5556,8 @@ virStoragePoolUndefine(virStoragePoolPtr
virConnectPtr conn;
DEBUG("pool=%p", pool);
+ virResetLastError();
+
if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
virLibStoragePoolError(NULL, VIR_ERR_INVALID_NETWORK, __FUNCTION__);
return (-1);
@@ -4662,15 +5565,23 @@ virStoragePoolUndefine(virStoragePoolPtr
conn = pool->conn;
if (conn->flags & VIR_CONNECT_RO) {
virLibStoragePoolError(pool, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
- }
-
- if (conn->storageDriver && conn->storageDriver->poolUndefine)
- return conn->storageDriver->poolUndefine (pool);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
- return -1;
-
+ goto error;
+ }
+
+ if (conn->storageDriver && conn->storageDriver->poolUndefine) {
+ int ret;
+ ret = conn->storageDriver->poolUndefine (pool);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(pool->conn);
+ return -1;
}
@@ -4690,10 +5601,8 @@ virStoragePoolCreate(virStoragePoolPtr p
virConnectPtr conn;
DEBUG("pool=%p", pool);
- if (pool == NULL) {
- TODO;
- return (-1);
- }
+ virResetLastError();
+
if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
return (-1);
@@ -4701,15 +5610,23 @@ virStoragePoolCreate(virStoragePoolPtr p
conn = pool->conn;
if (conn->flags & VIR_CONNECT_RO) {
virLibStoragePoolError(pool, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
- }
-
- if (conn->storageDriver && conn->storageDriver->poolCreate)
- return conn->storageDriver->poolCreate (pool, flags);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
- return -1;
-
+ goto error;
+ }
+
+ if (conn->storageDriver && conn->storageDriver->poolCreate) {
+ int ret;
+ ret = conn->storageDriver->poolCreate (pool, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(pool->conn);
+ return -1;
}
@@ -4731,6 +5648,8 @@ virStoragePoolDestroy(virStoragePoolPtr
virConnectPtr conn;
DEBUG("pool=%p", pool);
+ virResetLastError();
+
if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
return (-1);
@@ -4739,13 +5658,22 @@ virStoragePoolDestroy(virStoragePoolPtr
conn = pool->conn;
if (conn->flags & VIR_CONNECT_RO) {
virLibStoragePoolError(pool, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
- }
-
- if (conn->storageDriver && conn->storageDriver->poolDestroy)
- return conn->storageDriver->poolDestroy (pool);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->storageDriver && conn->storageDriver->poolDestroy) {
+ int ret;
+ ret = conn->storageDriver->poolDestroy (pool);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(pool->conn);
return -1;
}
@@ -4767,6 +5695,8 @@ virStoragePoolDelete(virStoragePoolPtr p
virConnectPtr conn;
DEBUG("pool=%p, flags=%u", pool, flags);
+ virResetLastError();
+
if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
return (-1);
@@ -4775,13 +5705,22 @@ virStoragePoolDelete(virStoragePoolPtr p
conn = pool->conn;
if (conn->flags & VIR_CONNECT_RO) {
virLibStoragePoolError(pool, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
- }
-
- if (conn->storageDriver && conn->storageDriver->poolDelete)
- return conn->storageDriver->poolDelete (pool, flags);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->storageDriver && conn->storageDriver->poolDelete) {
+ int ret;
+ ret = conn->storageDriver->poolDelete (pool, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(pool->conn);
return -1;
}
@@ -4800,7 +5739,9 @@ virStoragePoolFree(virStoragePoolPtr poo
{
DEBUG("pool=%p", pool);
- if (!VIR_IS_STORAGE_POOL(pool)) {
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
return (-1);
}
@@ -4829,6 +5770,8 @@ virStoragePoolRefresh(virStoragePoolPtr
virConnectPtr conn;
DEBUG("pool=%p flags=%u", pool, flags);
+ virResetLastError();
+
if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
return (-1);
@@ -4837,13 +5780,22 @@ virStoragePoolRefresh(virStoragePoolPtr
conn = pool->conn;
if (conn->flags & VIR_CONNECT_RO) {
virLibStoragePoolError(pool, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
- }
-
- if (conn->storageDriver && conn->storageDriver->poolRefresh)
- return conn->storageDriver->poolRefresh (pool, flags);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->storageDriver && conn->storageDriver->poolRefresh) {
+ int ret;
+ ret = conn->storageDriver->poolRefresh (pool, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(pool->conn);
return -1;
}
@@ -4861,12 +5813,13 @@ virStoragePoolGetName(virStoragePoolPtr
{
DEBUG("pool=%p", pool);
+ virResetLastError();
+
if (!VIR_IS_STORAGE_POOL(pool)) {
virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
return (NULL);
}
return (pool->name);
-
}
@@ -4885,19 +5838,25 @@ virStoragePoolGetUUID(virStoragePoolPtr
{
DEBUG("pool=%p, uuid=%p", pool, uuid);
+ virResetLastError();
+
if (!VIR_IS_STORAGE_POOL(pool)) {
virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
return (-1);
}
if (uuid == NULL) {
virLibStoragePoolError(pool, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
+ goto error;
}
memcpy(uuid, &pool->uuid[0], VIR_UUID_BUFLEN);
return (0);
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(pool->conn);
+ return -1;
}
/**
@@ -4916,21 +5875,27 @@ virStoragePoolGetUUIDString(virStoragePo
unsigned char uuid[VIR_UUID_BUFLEN];
DEBUG("pool=%p, buf=%p", pool, buf);
+ virResetLastError();
+
if (!VIR_IS_STORAGE_POOL(pool)) {
virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
return (-1);
}
if (buf == NULL) {
virLibStoragePoolError(pool, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
+ goto error;
}
if (virStoragePoolGetUUID(pool, &uuid[0]))
- return (-1);
+ goto error;
virUUIDFormat(uuid, buf);
return (0);
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(pool->conn);
+ return -1;
}
@@ -4951,25 +5916,35 @@ virStoragePoolGetInfo(virStoragePoolPtr
virConnectPtr conn;
DEBUG("pool=%p, info=%p", pool, info);
+ virResetLastError();
+
if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
return (-1);
}
if (info == NULL) {
virLibStoragePoolError(pool, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
+ goto error;
}
memset(info, 0, sizeof(virStoragePoolInfo));
conn = pool->conn;
- if (conn->storageDriver->poolGetInfo)
- return conn->storageDriver->poolGetInfo (pool, info);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
- return -1;
-
+ if (conn->storageDriver->poolGetInfo) {
+ int ret;
+ ret = conn->storageDriver->poolGetInfo (pool, info);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(pool->conn);
+ return -1;
}
@@ -4991,23 +5966,33 @@ virStoragePoolGetXMLDesc(virStoragePoolP
virConnectPtr conn;
DEBUG("pool=%p, flags=%u", pool, flags);
- if (!VIR_IS_STORAGE_POOL(pool)) {
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
return (NULL);
}
if (flags != 0) {
virLibStoragePoolError(pool, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
- }
-
- conn = pool->conn;
-
- if (conn->storageDriver && conn->storageDriver->poolGetXMLDesc)
- return conn->storageDriver->poolGetXMLDesc (pool, flags);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
- return NULL;
-
+ goto error;
+ }
+
+ conn = pool->conn;
+
+ if (conn->storageDriver && conn->storageDriver->poolGetXMLDesc) {
+ char *ret;
+ ret = conn->storageDriver->poolGetXMLDesc (pool, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(pool->conn);
+ return NULL;
}
@@ -5028,21 +6013,32 @@ virStoragePoolGetAutostart(virStoragePoo
virConnectPtr conn;
DEBUG("pool=%p, autostart=%p", pool, autostart);
- if (!VIR_IS_STORAGE_POOL(pool)) {
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
return (-1);
}
if (!autostart) {
virLibStoragePoolError(pool, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
- }
-
- conn = pool->conn;
-
- if (conn->storageDriver && conn->storageDriver->poolGetAutostart)
- return conn->storageDriver->poolGetAutostart (pool, autostart);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ conn = pool->conn;
+
+ if (conn->storageDriver && conn->storageDriver->poolGetAutostart) {
+ int ret;
+ ret = conn->storageDriver->poolGetAutostart (pool, autostart);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(pool->conn);
return -1;
}
@@ -5063,17 +6059,28 @@ virStoragePoolSetAutostart(virStoragePoo
virConnectPtr conn;
DEBUG("pool=%p, autostart=%d", pool, autostart);
- if (!VIR_IS_STORAGE_POOL(pool)) {
- virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
- return (-1);
- }
-
- conn = pool->conn;
-
- if (conn->storageDriver && conn->storageDriver->poolSetAutostart)
- return conn->storageDriver->poolSetAutostart (pool, autostart);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
+ virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
+ return (-1);
+ }
+
+ conn = pool->conn;
+
+ if (conn->storageDriver && conn->storageDriver->poolSetAutostart) {
+ int ret;
+ ret = conn->storageDriver->poolSetAutostart (pool, autostart);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(pool->conn);
return -1;
}
@@ -5090,16 +6097,27 @@ virStoragePoolNumOfVolumes(virStoragePoo
virStoragePoolNumOfVolumes(virStoragePoolPtr pool)
{
DEBUG("pool=%p", pool);
+
+ virResetLastError();
if (!VIR_IS_STORAGE_POOL(pool)) {
virLibConnError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
return (-1);
}
- if (pool->conn->storageDriver &&
pool->conn->storageDriver->poolNumOfVolumes)
- return pool->conn->storageDriver->poolNumOfVolumes (pool);
+ if (pool->conn->storageDriver &&
pool->conn->storageDriver->poolNumOfVolumes) {
+ int ret;
+ ret = pool->conn->storageDriver->poolNumOfVolumes (pool);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
virLibConnError (pool->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(pool->conn);
return -1;
}
@@ -5122,6 +6140,8 @@ virStoragePoolListVolumes(virStoragePool
{
DEBUG("pool=%p, names=%p, maxnames=%d", pool, names, maxnames);
+ virResetLastError();
+
if (!VIR_IS_STORAGE_POOL(pool)) {
virLibConnError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
return (-1);
@@ -5129,13 +6149,22 @@ virStoragePoolListVolumes(virStoragePool
if ((names == NULL) || (maxnames < 0)) {
virLibConnError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
- }
-
- if (pool->conn->storageDriver &&
pool->conn->storageDriver->poolListVolumes)
- return pool->conn->storageDriver->poolListVolumes (pool, names,
maxnames);
+ goto error;
+ }
+
+ if (pool->conn->storageDriver &&
pool->conn->storageDriver->poolListVolumes) {
+ int ret;
+ ret = pool->conn->storageDriver->poolListVolumes (pool, names,
maxnames);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
virLibConnError (pool->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(pool->conn);
return -1;
}
@@ -5159,6 +6188,8 @@ virStorageVolGetConnect (virStorageVolPt
{
DEBUG("vol=%p", vol);
+ virResetLastError();
+
if (!VIR_IS_STORAGE_VOL (vol)) {
virLibStoragePoolError (NULL, VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
return NULL;
@@ -5183,19 +6214,30 @@ virStorageVolLookupByName(virStoragePool
{
DEBUG("pool=%p, name=%s", pool, name);
+ virResetLastError();
+
if (!VIR_IS_STORAGE_POOL(pool)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (NULL);
}
if (name == NULL) {
virLibConnError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
- }
-
- if (pool->conn->storageDriver &&
pool->conn->storageDriver->volLookupByName)
- return pool->conn->storageDriver->volLookupByName (pool, name);
+ goto error;
+ }
+
+ if (pool->conn->storageDriver &&
pool->conn->storageDriver->volLookupByName) {
+ virStorageVolPtr ret;
+ ret = pool->conn->storageDriver->volLookupByName (pool, name);
+ if (!ret)
+ goto error;
+ return ret;
+ }
virLibConnError (pool->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(pool->conn);
return NULL;
}
@@ -5217,19 +6259,30 @@ virStorageVolLookupByKey(virConnectPtr c
{
DEBUG("conn=%p, key=%s", conn, key);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (NULL);
}
if (key == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
- }
-
- if (conn->storageDriver && conn->storageDriver->volLookupByKey)
- return conn->storageDriver->volLookupByKey (conn, key);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->storageDriver && conn->storageDriver->volLookupByKey) {
+ virStorageVolPtr ret;
+ ret = conn->storageDriver->volLookupByKey (conn, key);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return NULL;
}
@@ -5249,19 +6302,30 @@ virStorageVolLookupByPath(virConnectPtr
{
DEBUG("conn=%p, path=%s", conn, path);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (NULL);
}
if (path == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
- }
-
- if (conn->storageDriver && conn->storageDriver->volLookupByPath)
- return conn->storageDriver->volLookupByPath (conn, path);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->storageDriver && conn->storageDriver->volLookupByPath) {
+ virStorageVolPtr ret;
+ ret = conn->storageDriver->volLookupByPath (conn, path);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return NULL;
}
@@ -5279,6 +6343,8 @@ virStorageVolGetName(virStorageVolPtr vo
virStorageVolGetName(virStorageVolPtr vol)
{
DEBUG("vol=%p", vol);
+
+ virResetLastError();
if (!VIR_IS_STORAGE_VOL(vol)) {
virLibStorageVolError(NULL, VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
@@ -5302,6 +6368,8 @@ virStorageVolGetKey(virStorageVolPtr vol
virStorageVolGetKey(virStorageVolPtr vol)
{
DEBUG("vol=%p", vol);
+
+ virResetLastError();
if (!VIR_IS_STORAGE_VOL(vol)) {
virLibStorageVolError(NULL, VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
@@ -5330,6 +6398,8 @@ virStorageVolCreateXML(virStoragePoolPtr
{
DEBUG("pool=%p, flags=%u", pool, flags);
+ virResetLastError();
+
if (!VIR_IS_STORAGE_POOL(pool)) {
virLibConnError(NULL, VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
return (NULL);
@@ -5337,13 +6407,22 @@ virStorageVolCreateXML(virStoragePoolPtr
if (pool->conn->flags & VIR_CONNECT_RO) {
virLibConnError(pool->conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (NULL);
- }
-
- if (pool->conn->storageDriver &&
pool->conn->storageDriver->volCreateXML)
- return pool->conn->storageDriver->volCreateXML (pool, xmldesc, flags);
+ goto error;
+ }
+
+ if (pool->conn->storageDriver &&
pool->conn->storageDriver->volCreateXML) {
+ virStorageVolPtr ret;
+ ret = pool->conn->storageDriver->volCreateXML (pool, xmldesc, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
virLibConnError (pool->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(pool->conn);
return NULL;
}
@@ -5364,6 +6443,8 @@ virStorageVolDelete(virStorageVolPtr vol
virConnectPtr conn;
DEBUG("vol=%p, flags=%u", vol, flags);
+ virResetLastError();
+
if (!VIR_IS_CONNECTED_STORAGE_VOL(vol)) {
virLibStorageVolError(NULL, VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
return (-1);
@@ -5372,13 +6453,22 @@ virStorageVolDelete(virStorageVolPtr vol
conn = vol->conn;
if (conn->flags & VIR_CONNECT_RO) {
virLibStorageVolError(vol, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- return (-1);
- }
-
- if (conn->storageDriver && conn->storageDriver->volDelete)
- return conn->storageDriver->volDelete (vol, flags);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->storageDriver && conn->storageDriver->volDelete) {
+ int ret;
+ ret = conn->storageDriver->volDelete (vol, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(vol->conn);
return -1;
}
@@ -5397,6 +6487,8 @@ virStorageVolFree(virStorageVolPtr vol)
{
DEBUG("vol=%p", vol);
+ virResetLastError();
+
if (!VIR_IS_STORAGE_VOL(vol)) {
virLibStorageVolError(NULL, VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
return (-1);
@@ -5424,23 +6516,34 @@ virStorageVolGetInfo(virStorageVolPtr vo
virConnectPtr conn;
DEBUG("vol=%p, info=%p", vol, info);
+ virResetLastError();
+
if (!VIR_IS_CONNECTED_STORAGE_VOL(vol)) {
virLibStorageVolError(NULL, VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
return (-1);
}
if (info == NULL) {
virLibStorageVolError(vol, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
+ goto error;
}
memset(info, 0, sizeof(virStorageVolInfo));
conn = vol->conn;
- if (conn->storageDriver->volGetInfo)
- return conn->storageDriver->volGetInfo (vol, info);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ if (conn->storageDriver->volGetInfo){
+ int ret;
+ ret = conn->storageDriver->volGetInfo (vol, info);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(vol->conn);
return -1;
}
@@ -5462,23 +6565,33 @@ virStorageVolGetXMLDesc(virStorageVolPtr
virConnectPtr conn;
DEBUG("vol=%p, flags=%u", vol, flags);
+ virResetLastError();
+
if (!VIR_IS_STORAGE_VOL(vol)) {
virLibStorageVolError(NULL, VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
return (NULL);
}
if (flags != 0) {
virLibStorageVolError(vol, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (NULL);
+ goto error;
}
conn = vol->conn;
- if (conn->storageDriver && conn->storageDriver->volGetXMLDesc)
- return conn->storageDriver->volGetXMLDesc (vol, flags);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
- return NULL;
-
+ if (conn->storageDriver && conn->storageDriver->volGetXMLDesc) {
+ char *ret;
+ ret = conn->storageDriver->volGetXMLDesc (vol, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(vol->conn);
+ return NULL;
}
@@ -5500,6 +6613,8 @@ virStorageVolGetPath(virStorageVolPtr vo
virConnectPtr conn;
DEBUG("vol=%p", vol);
+ virResetLastError();
+
if (!VIR_IS_STORAGE_VOL(vol)) {
virLibStorageVolError(NULL, VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
return (NULL);
@@ -5507,10 +6622,19 @@ virStorageVolGetPath(virStorageVolPtr vo
conn = vol->conn;
- if (conn->storageDriver && conn->storageDriver->volGetPath)
- return conn->storageDriver->volGetPath (vol);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ if (conn->storageDriver && conn->storageDriver->volGetPath) {
+ char *ret;
+ ret = conn->storageDriver->volGetPath (vol);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(vol->conn);
return NULL;
}
@@ -5535,19 +6659,30 @@ virNodeNumOfDevices(virConnectPtr conn,
{
DEBUG("conn=%p, cap=%s, flags=%d", conn, cap, flags);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (-1);
}
if (flags != 0) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
- }
-
- if (conn->deviceMonitor && conn->deviceMonitor->numOfDevices)
- return conn->deviceMonitor->numOfDevices (conn, cap, flags);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->deviceMonitor && conn->deviceMonitor->numOfDevices) {
+ int ret;
+ ret = conn->deviceMonitor->numOfDevices (conn, cap, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return -1;
}
@@ -5576,19 +6711,30 @@ virNodeListDevices(virConnectPtr conn,
DEBUG("conn=%p, cap=%s, names=%p, maxnames=%d, flags=%d",
conn, cap, names, maxnames, flags);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (-1);
}
if ((flags != 0) || (names == NULL) || (maxnames < 0)) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
- }
-
- if (conn->deviceMonitor && conn->deviceMonitor->listDevices)
- return conn->deviceMonitor->listDevices (conn, cap, names, maxnames,
flags);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->deviceMonitor && conn->deviceMonitor->listDevices) {
+ int ret;
+ ret = conn->deviceMonitor->listDevices (conn, cap, names, maxnames,
flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return -1;
}
@@ -5606,6 +6752,8 @@ virNodeDevicePtr virNodeDeviceLookupByNa
{
DEBUG("conn=%p, name=%p", conn, name);
+ virResetLastError();
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return NULL;
@@ -5613,13 +6761,22 @@ virNodeDevicePtr virNodeDeviceLookupByNa
if (name == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return NULL;
- }
-
- if (conn->deviceMonitor && conn->deviceMonitor->deviceLookupByName)
- return conn->deviceMonitor->deviceLookupByName (conn, name);
-
- virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->deviceMonitor && conn->deviceMonitor->deviceLookupByName)
{
+ virNodeDevicePtr ret;
+ ret = conn->deviceMonitor->deviceLookupByName (conn, name);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return NULL;
}
@@ -5638,15 +6795,26 @@ char *virNodeDeviceGetXMLDesc(virNodeDev
{
DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL);
+ virResetLastError();
+
if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
virLibNodeDeviceError(NULL, VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
return NULL;
}
- if (dev->conn->deviceMonitor &&
dev->conn->deviceMonitor->deviceDumpXML)
- return dev->conn->deviceMonitor->deviceDumpXML (dev, flags);
+ if (dev->conn->deviceMonitor &&
dev->conn->deviceMonitor->deviceDumpXML) {
+ char *ret;
+ ret = dev->conn->deviceMonitor->deviceDumpXML (dev, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
virLibConnError (dev->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(dev->conn);
return NULL;
}
@@ -5683,6 +6851,8 @@ const char *virNodeDeviceGetParent(virNo
const char *virNodeDeviceGetParent(virNodeDevicePtr dev)
{
DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL);
+
+ virResetLastError();
if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
virLibNodeDeviceError(NULL, VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
@@ -5694,6 +6864,7 @@ const char *virNodeDeviceGetParent(virNo
dev->parent = dev->conn->deviceMonitor->deviceGetParent (dev);
} else {
virLibConnError (dev->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ virSetConnError(dev->conn);
return NULL;
}
}
@@ -5712,15 +6883,26 @@ int virNodeDeviceNumOfCaps(virNodeDevice
{
DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL);
+ virResetLastError();
+
if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
virLibNodeDeviceError(NULL, VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
return -1;
}
- if (dev->conn->deviceMonitor &&
dev->conn->deviceMonitor->deviceNumOfCaps)
- return dev->conn->deviceMonitor->deviceNumOfCaps (dev);
+ if (dev->conn->deviceMonitor &&
dev->conn->deviceMonitor->deviceNumOfCaps) {
+ int ret;
+ ret = dev->conn->deviceMonitor->deviceNumOfCaps (dev);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
virLibConnError (dev->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(dev->conn);
return -1;
}
@@ -5741,15 +6923,26 @@ int virNodeDeviceListCaps(virNodeDeviceP
DEBUG("dev=%p, conn=%p, names=%p, maxnames=%d",
dev, dev ? dev->conn : NULL, names, maxnames);
+ virResetLastError();
+
if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
virLibNodeDeviceError(NULL, VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
return -1;
}
- if (dev->conn->deviceMonitor &&
dev->conn->deviceMonitor->deviceListCaps)
- return dev->conn->deviceMonitor->deviceListCaps (dev, names, maxnames);
+ if (dev->conn->deviceMonitor &&
dev->conn->deviceMonitor->deviceListCaps) {
+ int ret;
+ ret = dev->conn->deviceMonitor->deviceListCaps (dev, names, maxnames);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
virLibConnError (dev->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(dev->conn);
return -1;
}
@@ -5766,6 +6959,8 @@ int virNodeDeviceFree(virNodeDevicePtr d
int virNodeDeviceFree(virNodeDevicePtr dev)
{
DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL);
+
+ virResetLastError();
if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
virLibNodeDeviceError(NULL, VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
@@ -5799,6 +6994,8 @@ virConnectDomainEventRegister(virConnect
void *opaque,
virFreeCallback freecb)
{
+ DEBUG("conn=%p, cb=%p, opaque=%p, freecb=%p", conn, cb, opaque, freecb);
+ virResetLastError();
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
@@ -5806,11 +7003,21 @@ virConnectDomainEventRegister(virConnect
}
if (cb == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
- }
-
- if ((conn->driver) && (conn->driver->domainEventRegister))
- return conn->driver->domainEventRegister (conn, cb, opaque, freecb);
+ goto error;
+ }
+
+ if ((conn->driver) && (conn->driver->domainEventRegister)) {
+ int ret;
+ ret = conn->driver->domainEventRegister (conn, cb, opaque, freecb);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError(conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
return -1;
}
@@ -5829,6 +7036,9 @@ virConnectDomainEventDeregister(virConne
virConnectDomainEventDeregister(virConnectPtr conn,
virConnectDomainEventCallback cb)
{
+ DEBUG("conn=%p, cb=%p", conn, cb);
+
+ virResetLastError();
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
@@ -5836,12 +7046,21 @@ virConnectDomainEventDeregister(virConne
}
if (cb == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
- }
- if ((conn->driver) && (conn->driver->domainEventDeregister))
- return conn->driver->domainEventDeregister (conn, cb);
-
- return -1;
-}
-
-
+ goto error;
+ }
+ if ((conn->driver) && (conn->driver->domainEventDeregister)) {
+ int ret;
+ ret = conn->driver->domainEventDeregister (conn, cb);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError(conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
+ return -1;
+}
+
+
diff --git a/src/libvirt_sym.version.in b/src/libvirt_sym.version.in
--- a/src/libvirt_sym.version.in
+++ b/src/libvirt_sym.version.in
@@ -249,7 +249,7 @@ LIBVIRT_0.5.0 {
} LIBVIRT_0.4.5;
-/* no new entry point in 0.5.1 */
+
/* .... define new API here using predicted next version number .... */
diff --git a/src/virterror.c b/src/virterror.c
--- a/src/virterror.c
+++ b/src/virterror.c
@@ -17,11 +17,18 @@
#include "virterror_internal.h"
#include "datatypes.h"
+#include "memory.h"
-virError virLastErr = /* the last error */
+#ifdef HAVE_PTHREAD_H
+pthread_once_t virLastErrInit = PTHREAD_ONCE_INIT;
+pthread_key_t virLastErr;
+#else
+static virError virLastErr = /* the last error */
{ .code = 0, .domain = 0, .message = NULL, .level = VIR_ERR_NONE,
.conn = NULL, .dom = NULL, .str1 = NULL, .str2 = NULL, .str3 = NULL,
.int1 = 0, .int2 = 0, .net = NULL };
+#endif
+
virErrorFunc virErrorHandler = NULL; /* global error handler */
void *virUserData = NULL; /* associated data */
@@ -62,28 +69,129 @@ void *virUserData = NULL; /* asso
}} \
}
+
+#ifdef HAVE_PTHREAD_H
/*
+ * Internal helper that is called when a thread exits, to
+ * release the error object stored in the thread local
+ */
+static void
+virLastErrFreeData(void *data)
+{
+ virErrorPtr err = data;
+ if (!err)
+ return;
+ virResetError(err);
+ VIR_FREE(err);
+}
+
+
+/*
+ * Internal helper called *once* by pthread_once() to create the
+ * thread local field we store errors in
+ */
+static void
+virLastErrCreate(void)
+{
+ pthread_key_create(&virLastErr, virLastErrFreeData);
+}
+#endif
+
+
+/*
+ * Internal helper to ensure a generic error code is stored
+ * in case where API returns failure, but forgot to set an
+ * error
+ */
+static void
+virErrorGenericFailure(virErrorPtr err)
+{
+ err->code = VIR_ERR_INTERNAL_ERROR;
+ err->domain = VIR_FROM_NONE;
+ err->level = VIR_ERR_ERROR;
+ err->message = strdup(_("Unknown failure"));
+}
+
+
+/*
+ * Internal helper to perform a deep copy of the an error
+ */
+static int
+virCopyError(virErrorPtr from,
+ virErrorPtr to)
+{
+ int ret = 0;
+ if (!to)
+ return 0;
+ virResetError(to);
+ if (!from)
+ return 0;
+ to->code = from->code;
+ to->domain = from->domain;
+ to->level = from->level;
+ if (from->message && !(to->message = strdup(from->message)))
+ ret = -1;
+ if (from->str1 && !(to->str1 = strdup(from->str1)))
+ ret = -1;
+ if (from->str2 && !(to->str2 = strdup(from->str2)))
+ ret = -1;
+ if (from->str3 && !(to->str3 = strdup(from->str3)))
+ ret = -1;
+ to->int1 = from->int1;
+ to->int2 = from->int2;
+ /*
+ * Delibrately not setting 'conn', 'dom', 'net' references
+ */
+ return ret;
+}
+
+static virErrorPtr
+virLastErrorObject(void)
+{
+ virErrorPtr err;
+#ifdef HAVE_PTHREAD_H
+ pthread_once(&virLastErrInit, virLastErrCreate);
+ err = pthread_getspecific(virLastErr);
+ if (!err) {
+ if (VIR_ALLOC(err) < 0)
+ return NULL;
+ pthread_setspecific(virLastErr, err);
+ }
+#else
+ err = &virLastErr;
+#endif
+ return err;
+}
+
+
+/**
* virGetLastError:
*
* Provide a pointer to the last error caught at the library level
- * Simpler but may not be suitable for multithreaded accesses, in which
- * case use virCopyLastError()
+ *
+ * The error object is kept in thread local storage, so separate
+ * threads can safely access this concurrently.
*
* Returns a pointer to the last error or NULL if none occurred.
*/
virErrorPtr
virGetLastError(void)
{
- if (virLastErr.code == VIR_ERR_OK)
- return (NULL);
- return (&virLastErr);
+ virErrorPtr err = virLastErrorObject();
+ if (!err || err->code == VIR_ERR_OK)
+ return NULL;
+ return err;
}
-/*
+/**
* virCopyLastError:
* @to: target to receive the copy
*
* Copy the content of the last error caught at the library level
+ *
+ * The error object is kept in thread local storage, so separate
+ * threads can safely access this concurrently.
+ *
* One will need to free the result with virResetError()
*
* Returns 0 if no error was found and the error code otherwise and -1 in case
@@ -92,12 +200,12 @@ int
int
virCopyLastError(virErrorPtr to)
{
- if (to == NULL)
- return (-1);
- if (virLastErr.code == VIR_ERR_OK)
- return (0);
- memcpy(to, &virLastErr, sizeof(virError));
- return (virLastErr.code);
+ virErrorPtr err = virLastErrorObject();
+ if (err)
+ virCopyError(err, to);
+ else
+ virResetError(to);
+ return to->code;
}
/**
@@ -118,15 +226,22 @@ virResetError(virErrorPtr err)
memset(err, 0, sizeof(virError));
}
+
/**
* virResetLastError:
*
* Reset the last error caught at the library level.
+ *
+ * The error object is kept in thread local storage, so separate
+ * threads can safely access this concurrently, only resetting
+ * their own error object.
*/
void
virResetLastError(void)
{
- virResetError(&virLastErr);
+ virErrorPtr err = virLastErrorObject();
+ if (err)
+ virResetError(err);
}
/**
@@ -134,8 +249,20 @@ virResetLastError(void)
* @conn: pointer to the hypervisor connection
*
* Provide a pointer to the last error caught on that connection
- * Simpler but may not be suitable for multithreaded accesses, in which
- * case use virConnCopyLastError()
+ *
+ * This method is not protected against access from multiple
+ * threads. In a multi-threaded application, always use the
+ * global virGetLastError() API which is backed by thread
+ * local storage.
+ *
+ * If the connection object was discovered to be invalid by
+ * an API call, then the error will be reported against the
+ * global error object.
+ *
+ * Since 0.6.0, all errors reported in the per-connection object
+ * are also duplicated in the global error object. As such an
+ * application can always use virGetLastError(). This method
+ * remains for backwards compatability.
*
* Returns a pointer to the last error or NULL if none occurred.
*/
@@ -143,8 +270,8 @@ virConnGetLastError(virConnectPtr conn)
virConnGetLastError(virConnectPtr conn)
{
if (conn == NULL)
- return (NULL);
- return (&conn->err);
+ return NULL;
+ return &conn->err;
}
/**
@@ -153,6 +280,21 @@ virConnGetLastError(virConnectPtr conn)
* @to: target to receive the copy
*
* Copy the content of the last error caught on that connection
+ *
+ * This method is not protected against access from multiple
+ * threads. In a multi-threaded application, always use the
+ * global virGetLastError() API which is backed by thread
+ * local storage.
+ *
+ * If the connection object was discovered to be invalid by
+ * an API call, then the error will be reported against the
+ * global error object.
+ *
+ * Since 0.6.0, all errors reported in the per-connection object
+ * are also duplicated in the global error object. As such an
+ * application can always use virGetLastError(). This method
+ * remains for backwards compatability.
+ *
* One will need to free the result with virResetError()
*
* Returns 0 if no error was found and the error code otherwise and -1 in case
@@ -162,18 +304,22 @@ virConnCopyLastError(virConnectPtr conn,
virConnCopyLastError(virConnectPtr conn, virErrorPtr to)
{
if (conn == NULL)
- return (-1);
- if (to == NULL)
- return (-1);
+ return -1;
+ pthread_mutex_lock(&conn->lock);
if (conn->err.code == VIR_ERR_OK)
- return (0);
- memcpy(to, &conn->err, sizeof(virError));
- return (conn->err.code);
+ virResetError(to);
+ else
+ virCopyError(&conn->err, to);
+ pthread_mutex_unlock(&conn->lock);
+ return to->code;
}
/**
* virConnResetLastError:
* @conn: pointer to the hypervisor connection
+ *
+ * The error object is kept in thread local storage, so separate
+ * threads can safely access this concurrently.
*
* Reset the last error caught on that connection
*/
@@ -182,7 +328,9 @@ virConnResetLastError(virConnectPtr conn
{
if (conn == NULL)
return;
+ pthread_mutex_lock(&conn->lock);
virResetError(&conn->err);
+ pthread_mutex_unlock(&conn->lock);
}
/**
@@ -217,8 +365,10 @@ virConnSetErrorFunc(virConnectPtr conn,
{
if (conn == NULL)
return;
+ pthread_mutex_lock(&conn->lock);
conn->handler = handler;
conn->userData = userData;
+ pthread_mutex_unlock(&conn->lock);
}
/**
@@ -338,6 +488,44 @@ virDefaultErrorFunc(virErrorPtr err)
dom, lvl, domain, network, err->message);
}
+/*
+ * Internal helper to ensure the global error object
+ * is initialized with a generic message if not already
+ * set.
+ */
+void
+virSetGlobalError(void)
+{
+ virErrorPtr err = virLastErrorObject();
+
+ if (err && err->code == VIR_ERR_OK)
+ virErrorGenericFailure(err);
+}
+
+/*
+ * Internal helper to ensure the connection error object
+ * is initialized from the global object.
+ */
+void
+virSetConnError(virConnectPtr conn)
+{
+ virErrorPtr err = virLastErrorObject();
+
+ if (err && err->code == VIR_ERR_OK)
+ virErrorGenericFailure(err);
+
+ if (conn) {
+ pthread_mutex_lock(&conn->lock);
+ if (err)
+ virCopyError(err, &conn->err);
+ else
+ virErrorGenericFailure(&conn->err);
+ pthread_mutex_unlock(&conn->lock);
+ }
+}
+
+
+
/**
* virRaiseError:
* @conn: the connection to the hypervisor if available
@@ -358,15 +546,28 @@ virDefaultErrorFunc(virErrorPtr err)
* immediately if a callback is found and store it for later handling.
*/
void
-virRaiseError(virConnectPtr conn, virDomainPtr dom, virNetworkPtr net,
+virRaiseError(virConnectPtr conn,
+ virDomainPtr dom ATTRIBUTE_UNUSED,
+ virNetworkPtr net ATTRIBUTE_UNUSED,
int domain, int code, virErrorLevel level,
const char *str1, const char *str2, const char *str3,
int int1, int int2, const char *msg, ...)
{
- virErrorPtr to = &virLastErr;
+ virErrorPtr to;
void *userData = virUserData;
virErrorFunc handler = virErrorHandler;
char *str;
+
+ /*
+ * All errors are recorded in thread local storage
+ * For compatability, public API calls will copy them
+ * to the per-connection error object when neccessary
+ */
+ to = virGetLastError();
+ if (!to)
+ return; /* Hit OOM allocating thread error object, sod all we can do now */
+
+ virResetError(to);
if (code == VIR_ERR_OK)
return;
@@ -375,11 +576,12 @@ virRaiseError(virConnectPtr conn, virDom
* try to find the best place to save and report the error
*/
if (conn != NULL) {
- to = &conn->err;
+ pthread_mutex_lock(&conn->lock);
if (conn->handler != NULL) {
handler = conn->handler;
userData = conn->userData;
}
+ pthread_mutex_unlock(&conn->lock);
}
/*
@@ -395,9 +597,10 @@ virRaiseError(virConnectPtr conn, virDom
* Save the information about the error
*/
virResetError(to);
- to->conn = conn;
- to->dom = dom;
- to->net = net;
+ /*
+ * Delibrately not setting conn, dom & net fields since
+ * they're utterly unsafe
+ */
to->domain = domain;
to->code = code;
to->message = str;
@@ -787,3 +990,5 @@ void virReportErrorHelper(virConnectPtr
virerr, errorMessage, NULL, -1, -1, virerr, errorMessage);
}
+
+
diff --git a/src/virterror_internal.h b/src/virterror_internal.h
--- a/src/virterror_internal.h
+++ b/src/virterror_internal.h
@@ -24,7 +24,6 @@
#include "internal.h"
-extern virError virLastErr;
extern virErrorFunc virErrorHandler;
extern void *virUserData;
@@ -53,4 +52,7 @@ void virReportErrorHelper(virConnectPtr
ATTRIBUTE_FORMAT(printf, 7, 8);
+void virSetGlobalError(void);
+void virSetConnError(virConnectPtr conn);
+
#endif
--
|: Red Hat, Engineering, London -o-
http://people.redhat.com/berrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org -o-
http://ovirt.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|