[Libvir] PATCH: Fix and cleanup ref counting/ domain/network object release

Daniel P. Berrange berrange at redhat.com
Sat Jan 19 19:18:03 UTC 2008


The referencing counting code for Connect/Domain/Network objects has many
repeated codepaths, not all of which are correct. eg, the virFreeDomain 
method forgets to release networks when garbage collecting a virConnectPtr,
and the virFreeNetwork method forgets to release domains. I've also found 
it very confusing having both virFreeDomain and virDomainFree.

So I've changed the impl of the cleanup functions in hash.c to use a 
slightly different structure. There are now 6 functions:

  - virUnrefConnect
  - virReleaseConnect
  - virUnrefDomain
  - virReleaseDomain
  - virUnrefNetwork

The 'virUnref*' APIs are intended for use by the drivers to decrement the
ref count on objects they no loner need. In the virUnref* method, if the
ref count hits zero, then it calls the corresponding virRelease* method
to actually free the object's memory.  The virUnref* methods are responsible
for acquiring the connection mutex. The virRelease* method mandate that5D
the mutex is already held, and will releae it as the very last step when
deleting the object.  The virReleaseDomain/virReleaeNetwork methods will
also derecement the ref count of the connection, and call virReleaseConnection
if appropriate.  The patch for all this looks horrific but its not as bad as
it looks, so I'd recommend reviewing the final code in hash.c, rather than 
the patch.

I have also switched from xmlMutex to the POSIX standard pthread_mutex_t 
object. In theory the former may give more portability, but the patches which
follow are also going to require actual pthread_t objects, for which libxml 
has no wrappers. Thus it is pointless using the xmlMutex abstraction. The 
added plus, is that pthread_mutex_t objects do not require any memory 
allocation, merely initialization of their pre-allocated contents so it 
simplifies a little code.

Finally, the code in hash.c for dealing with ref counting seriously abused
the 'goto' statement with multiple jumps overlapping each other in a single
method. This made it very hard to follow. So I removed the use of goto in 
most places so its only used in error cleanup paths, and not for regular 
flow control.

Oh, and in cleaning up internal.h I found an odd declaration of some 
functions from xs_internal.h which could have been made static. So I made
them static.

In this version I removed the call to 'virUnrefDomain' from the libvirt.c
file's virDomainDestroy call, and likewise in virNetworkDestroy. 

Regards,
Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 
-------------- next part --------------
diff -r 1d004e448a45 src/hash.c
--- a/src/hash.c	Sat Jan 19 13:44:13 2008 -0500
+++ b/src/hash.c	Sat Jan 19 13:45:07 2008 -0500
@@ -25,8 +25,12 @@
 #include <libxml/threads.h>
 #include "internal.h"
 #include "hash.h"
+#include <pthread.h>
 
 #define MAX_HASH_LEN 8
+
+#define DEBUG(fmt,...) VIR_DEBUG(__FILE__, fmt, __VA_ARGS__)
+#define DEBUG0(msg) VIR_DEBUG(__FILE__, "%s", msg)
 
 /* #define DEBUG_GROW */
 
@@ -677,60 +681,77 @@ virGetConnect(void) {
     ret->networks = virHashCreate(20);
     if (ret->networks == NULL)
         goto failed;
-    ret->hashes_mux = xmlNewMutex();
-    if (ret->hashes_mux == NULL)
-        goto failed;
-
-    ret->uses = 1;
+
+    pthread_mutex_init(&ret->lock, NULL);
+
+    ret->refs = 1;
     return(ret);
 
 failed:
     if (ret != NULL) {
-	if (ret->domains != NULL)
-	    virHashFree(ret->domains, (virHashDeallocator) virDomainFreeName);
-	if (ret->networks != NULL)
-	    virHashFree(ret->networks, (virHashDeallocator) virNetworkFreeName);
-	if (ret->hashes_mux != NULL)
-	    xmlFreeMutex(ret->hashes_mux);
+        if (ret->domains != NULL)
+            virHashFree(ret->domains, (virHashDeallocator) virDomainFreeName);
+        if (ret->networks != NULL)
+            virHashFree(ret->networks, (virHashDeallocator) virNetworkFreeName);
+
+        pthread_mutex_destroy(&ret->lock);
         free(ret);
     }
     return(NULL);
 }
 
 /**
- * virFreeConnect:
- * @conn: the hypervisor connection
- *
- * Release the connection. if the use count drops to zero, the structure is
- * actually freed.
- *
- * Returns the reference count or -1 in case of failure.
- */
-int	
-virFreeConnect(virConnectPtr conn) {
-    int ret;
-
-    if ((!VIR_IS_CONNECT(conn)) || (conn->hashes_mux == NULL)) {
-        virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        return(-1);
-    }
-    xmlMutexLock(conn->hashes_mux);
-    conn->uses--;
-    ret = conn->uses;
-    if (ret > 0) {
-	xmlMutexUnlock(conn->hashes_mux);
-	return(ret);
-    }
-
+ * virReleaseConnect:
+ * @conn: the hypervisor connection to release
+ *
+ * Unconditionally release all memory associated with a connection.
+ * The conn.lock mutex must be held prior to calling this, and will
+ * be released prior to this returning. The connection obj must not
+ * be used once this method returns.
+ */
+static void
+virReleaseConnect(virConnectPtr conn) {
+    DEBUG("release connection %p %s", conn, conn->name);
     if (conn->domains != NULL)
         virHashFree(conn->domains, (virHashDeallocator) virDomainFreeName);
     if (conn->networks != NULL)
         virHashFree(conn->networks, (virHashDeallocator) virNetworkFreeName);
-    if (conn->hashes_mux != NULL)
-        xmlFreeMutex(conn->hashes_mux);
     virResetError(&conn->err);
+    free(conn->name);
+
+    pthread_mutex_unlock(&conn->lock);
+    pthread_mutex_destroy(&conn->lock);
     free(conn);
-    return(0);
+}
+
+/**
+ * virUnrefConnect:
+ * @conn: the hypervisor connection to unreference
+ *
+ * Unreference the connection. If the use count drops to zero, the structure is
+ * actually freed.
+ *
+ * Returns the reference count or -1 in case of failure.
+ */
+int
+virUnrefConnect(virConnectPtr conn) {
+    int refs;
+
+    if ((!VIR_IS_CONNECT(conn))) {
+        virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return(-1);
+    }
+    pthread_mutex_lock(&conn->lock);
+    DEBUG("unref connection %p %s %d", conn, conn->name, conn->refs);
+    conn->refs--;
+    refs = conn->refs;
+    if (refs == 0) {
+        virReleaseConnect(conn);
+        /* Already unlocked mutex */
+        return (0);
+    }
+    pthread_mutex_unlock(&conn->lock);
+    return (refs);
 }
 
 /**
@@ -742,7 +763,7 @@ virFreeConnect(virConnectPtr conn) {
  * Lookup if the domain is already registered for that connection,
  * if yes return a new pointer to it, if no allocate a new structure,
  * and register it in the table. In any case a corresponding call to
- * virFreeDomain() is needed to not leak data.
+ * virUnrefDomain() is needed to not leak data.
  *
  * Returns a pointer to the domain, or NULL in case of failure
  */
@@ -750,120 +771,122 @@ __virGetDomain(virConnectPtr conn, const
 __virGetDomain(virConnectPtr conn, const char *name, const unsigned char *uuid) {
     virDomainPtr ret = NULL;
 
-    if ((!VIR_IS_CONNECT(conn)) || (name == NULL) || (uuid == NULL) ||
-        (conn->hashes_mux == NULL)) {
+    if ((!VIR_IS_CONNECT(conn)) || (name == NULL) || (uuid == NULL)) {
         virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
         return(NULL);
     }
-    xmlMutexLock(conn->hashes_mux);
+    pthread_mutex_lock(&conn->lock);
 
     /* TODO search by UUID first as they are better differenciators */
 
     ret = (virDomainPtr) virHashLookup(conn->domains, name);
+    /* TODO check the UUID */
+    if (ret == NULL) {
+        ret = (virDomainPtr) calloc(1, sizeof(*ret));
+        if (ret == NULL) {
+            virHashError(conn, VIR_ERR_NO_MEMORY, _("allocating domain"));
+            goto error;
+        }
+        ret->name = strdup(name);
+        if (ret->name == NULL) {
+            virHashError(conn, VIR_ERR_NO_MEMORY, _("allocating domain"));
+            goto error;
+        }
+        ret->magic = VIR_DOMAIN_MAGIC;
+        ret->conn = conn;
+        ret->id = -1;
+        if (uuid != NULL)
+            memcpy(&(ret->uuid[0]), uuid, VIR_UUID_BUFLEN);
+
+        if (virHashAddEntry(conn->domains, name, ret) < 0) {
+            virHashError(conn, VIR_ERR_INTERNAL_ERROR,
+                         _("failed to add domain to connection hash table"));
+            goto error;
+        }
+        conn->refs++;
+    }
+    ret->refs++;
+    pthread_mutex_unlock(&conn->lock);
+    return(ret);
+
+ error:
+    pthread_mutex_unlock(&conn->lock);
     if (ret != NULL) {
-        /* TODO check the UUID */
-	goto done;
-    }
-
-    /*
-     * not found, allocate a new one
-     */
-    ret = calloc(1, sizeof(*ret));
-    if (ret == NULL) {
-        virHashError(conn, VIR_ERR_NO_MEMORY, _("allocating domain"));
-	goto error;
-    }
-    ret->name = strdup(name);
-    if (ret->name == NULL) {
-        virHashError(conn, VIR_ERR_NO_MEMORY, _("allocating domain"));
-	goto error;
-    }
-    ret->magic = VIR_DOMAIN_MAGIC;
-    ret->conn = conn;
-    ret->id = -1;
-    if (uuid != NULL)
-        memcpy(&(ret->uuid[0]), uuid, VIR_UUID_BUFLEN);
-
-    if (virHashAddEntry(conn->domains, name, ret) < 0) {
+        if (ret->name != NULL)
+            free(ret->name );
+        free(ret);
+    }
+    return(NULL);
+}
+
+/**
+ * virReleaseDomain:
+ * @domain: the domain to release
+ *
+ * Unconditionally release all memory associated with a domain.
+ * The conn.lock mutex must be held prior to calling this, and will
+ * be released prior to this returning. The domain obj must not
+ * be used once this method returns.
+ *
+ * It will also unreference the associated connection object,
+ * which may also be released if its ref count hits zero.
+ */
+static void
+virReleaseDomain(virDomainPtr domain) {
+    virConnectPtr conn = domain->conn;
+    DEBUG("release domain %p %s", domain, domain->name);
+
+    /* TODO search by UUID first as they are better differenciators */
+    if (virHashRemoveEntry(conn->domains, domain->name, NULL) < 0)
         virHashError(conn, VIR_ERR_INTERNAL_ERROR,
-	             _("failed to add domain to connection hash table"));
-	goto error;
-    }
-    conn->uses++;
-done:
-    ret->uses++;
-    xmlMutexUnlock(conn->hashes_mux);
-    return(ret);
-
-error:
-    xmlMutexUnlock(conn->hashes_mux);
-    if (ret != NULL) {
-	if (ret->name != NULL)
-	    free(ret->name );
-	free(ret);
-    }
-    return(NULL);
-}
-
-/**
- * virFreeDomain:
- * @conn: the hypervisor connection
- * @domain: the domain to release
- *
- * Release the given domain, if the reference count drops to zero, then
- * the domain is really freed.
- *
- * Returns the reference count or -1 in case of failure.
- */
-int
-virFreeDomain(virConnectPtr conn, virDomainPtr domain) {
-    int ret = 0;
-
-    if ((!VIR_IS_CONNECT(conn)) || (!VIR_IS_CONNECTED_DOMAIN(domain)) ||
-        (domain->conn != conn) || (conn->hashes_mux == NULL)) {
-        virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        return(-1);
-    }
-    xmlMutexLock(conn->hashes_mux);
-
-    /*
-     * decrement the count for the domain
-     */
-    domain->uses--;
-    ret = domain->uses;
-    if (ret > 0)
-        goto done;
-
-    /* TODO search by UUID first as they are better differenciators */
-
-    if (virHashRemoveEntry(conn->domains, domain->name, NULL) < 0) {
-        virHashError(conn, VIR_ERR_INTERNAL_ERROR,
-	             _("domain missing from connection hash table"));
-        goto done;
-    }
+                     _("domain missing from connection hash table"));
+
     domain->magic = -1;
     domain->id = -1;
-    if (domain->name)
-        free(domain->name);
+    free(domain->name);
     free(domain);
 
-    /*
-     * decrement the count for the connection
-     */
-    conn->uses--;
-    if (conn->uses > 0)
-        goto done;
-    
-    if (conn->domains != NULL)
-        virHashFree(conn->domains, (virHashDeallocator) virDomainFreeName);
-    if (conn->hashes_mux != NULL)
-        xmlFreeMutex(conn->hashes_mux);
-    free(conn);
-    return(0);
-
-done:
-    xmlMutexUnlock(conn->hashes_mux);
-    return(ret);
+    DEBUG("unref connection %p %s %d", conn, conn->name, conn->refs);
+    conn->refs--;
+    if (conn->refs == 0) {
+        virReleaseConnect(conn);
+        /* Already unlocked mutex */
+        return;
+    }
+
+    pthread_mutex_unlock(&conn->lock);
+}
+
+
+/**
+ * virUnrefDomain:
+ * @domain: the domain to unreference
+ *
+ * Unreference the domain. If the use count drops to zero, the structure is
+ * actually freed.
+ *
+ * Returns the reference count or -1 in case of failure.
+ */
+int
+virUnrefDomain(virDomainPtr domain) {
+    int refs;
+
+    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+        virHashError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return(-1);
+    }
+    pthread_mutex_lock(&domain->conn->lock);
+    DEBUG("unref domain %p %s %d", domain, domain->name, domain->refs);
+    domain->refs--;
+    refs = domain->refs;
+    if (refs == 0) {
+        virReleaseDomain(domain);
+        /* Already unlocked mutex */
+        return (0);
+    }
+
+    pthread_mutex_lock(&domain->conn->lock);
+    return (refs);
 }
 
 /**
@@ -875,7 +898,7 @@ done:
  * Lookup if the network is already registered for that connection,
  * if yes return a new pointer to it, if no allocate a new structure,
  * and register it in the table. In any case a corresponding call to
- * virFreeNetwork() is needed to not leak data.
+ * virUnrefNetwork() is needed to not leak data.
  *
  * Returns a pointer to the network, or NULL in case of failure
  */
@@ -883,120 +906,127 @@ __virGetNetwork(virConnectPtr conn, cons
 __virGetNetwork(virConnectPtr conn, const char *name, const unsigned char *uuid) {
     virNetworkPtr ret = NULL;
 
-    if ((!VIR_IS_CONNECT(conn)) || (name == NULL) || (uuid == NULL) ||
-        (conn->hashes_mux == NULL)) {
+    if ((!VIR_IS_CONNECT(conn)) || (name == NULL) || (uuid == NULL)) {
         virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
         return(NULL);
     }
-    xmlMutexLock(conn->hashes_mux);
+    pthread_mutex_lock(&conn->lock);
 
     /* TODO search by UUID first as they are better differenciators */
 
     ret = (virNetworkPtr) virHashLookup(conn->networks, name);
+    /* TODO check the UUID */
+    if (ret == NULL) {
+        ret = (virNetworkPtr) calloc(1, sizeof(*ret));
+        if (ret == NULL) {
+            virHashError(conn, VIR_ERR_NO_MEMORY, _("allocating network"));
+            goto error;
+        }
+        ret->name = strdup(name);
+        if (ret->name == NULL) {
+            virHashError(conn, VIR_ERR_NO_MEMORY, _("allocating network"));
+            goto error;
+        }
+        ret->magic = VIR_NETWORK_MAGIC;
+        ret->conn = conn;
+        if (uuid != NULL)
+            memcpy(&(ret->uuid[0]), uuid, VIR_UUID_BUFLEN);
+
+        if (virHashAddEntry(conn->networks, name, ret) < 0) {
+            virHashError(conn, VIR_ERR_INTERNAL_ERROR,
+                         _("failed to add network to connection hash table"));
+            goto error;
+        }
+        conn->refs++;
+    }
+    ret->refs++;
+    pthread_mutex_unlock(&conn->lock);
+    return(ret);
+
+ error:
+    pthread_mutex_unlock(&conn->lock);
     if (ret != NULL) {
-        /* TODO check the UUID */
-	goto done;
-    }
-
-    /*
-     * not found, allocate a new one
-     */
-    ret = calloc(1, sizeof(*ret));
-    if (ret == NULL) {
-        virHashError(conn, VIR_ERR_NO_MEMORY, _("allocating network"));
-	goto error;
-    }
-    ret->name = strdup(name);
-    if (ret->name == NULL) {
-        virHashError(conn, VIR_ERR_NO_MEMORY, _("allocating network"));
-	goto error;
-    }
-    ret->magic = VIR_NETWORK_MAGIC;
-    ret->conn = conn;
-    if (uuid != NULL)
-        memcpy(&(ret->uuid[0]), uuid, VIR_UUID_BUFLEN);
-
-    if (virHashAddEntry(conn->networks, name, ret) < 0) {
+        if (ret->name != NULL)
+            free(ret->name );
+        free(ret);
+    }
+    return(NULL);
+}
+
+/**
+ * virReleaseNetwork:
+ * @network: the network to release
+ *
+ * Unconditionally release all memory associated with a network.
+ * The conn.lock mutex must be held prior to calling this, and will
+ * be released prior to this returning. The network obj must not
+ * be used once this method returns.
+ *
+ * It will also unreference the associated connection object,
+ * which may also be released if its ref count hits zero.
+ */
+static void
+virReleaseNetwork(virNetworkPtr network) {
+    virConnectPtr conn = network->conn;
+    DEBUG("release network %p %s", network, network->name);
+
+    /* TODO search by UUID first as they are better differenciators */
+    if (virHashRemoveEntry(conn->networks, network->name, NULL) < 0)
         virHashError(conn, VIR_ERR_INTERNAL_ERROR,
-	             _("failed to add network to connection hash table"));
-	goto error;
-    }
-    conn->uses++;
-done:
-    ret->uses++;
-    xmlMutexUnlock(conn->hashes_mux);
-    return(ret);
-
-error:
-    xmlMutexUnlock(conn->hashes_mux);
-    if (ret != NULL) {
-	if (ret->name != NULL)
-	    free(ret->name );
-	free(ret);
-    }
-    return(NULL);
-}
-
-/**
- * virFreeNetwork:
- * @conn: the hypervisor connection
- * @network: the network to release
- *
- * Release the given network, if the reference count drops to zero, then
- * the network is really freed.
+                     _("network missing from connection hash table"));
+
+    network->magic = -1;
+    free(network->name);
+    free(network);
+
+    DEBUG("unref connection %p %s %d", conn, conn->name, conn->refs);
+    conn->refs--;
+    if (conn->refs == 0) {
+        virReleaseConnect(conn);
+        /* Already unlocked mutex */
+        return;
+    }
+
+    pthread_mutex_unlock(&conn->lock);
+}
+
+
+/**
+ * virUnrefNetwork:
+ * @network: the network to unreference
+ *
+ * Unreference the network. If the use count drops to zero, the structure is
+ * actually freed.
  *
  * Returns the reference count or -1 in case of failure.
  */
 int
-virFreeNetwork(virConnectPtr conn, virNetworkPtr network) {
-    int ret = 0;
-
-    if ((!VIR_IS_CONNECT(conn)) || (!VIR_IS_CONNECTED_NETWORK(network)) ||
-        (network->conn != conn) || (conn->hashes_mux == NULL)) {
-        virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+virUnrefNetwork(virNetworkPtr network) {
+    int refs;
+
+    if (!VIR_IS_CONNECTED_NETWORK(network)) {
+        virHashError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
         return(-1);
     }
-    xmlMutexLock(conn->hashes_mux);
-
-    /*
-     * decrement the count for the network
-     */
-    network->uses--;
-    ret = network->uses;
-    if (ret > 0)
-        goto done;
-
-    /* TODO search by UUID first as they are better differenciators */
-
-    if (virHashRemoveEntry(conn->networks, network->name, NULL) < 0) {
-        virHashError(conn, VIR_ERR_INTERNAL_ERROR,
-	             _("network missing from connection hash table"));
-        goto done;
-    }
-    network->magic = -1;
-    if (network->name)
-        free(network->name);
-    free(network);
-
-    /*
-     * decrement the count for the connection
-     */
-    conn->uses--;
-    if (conn->uses > 0)
-        goto done;
-
-    if (conn->networks != NULL)
-        virHashFree(conn->networks, (virHashDeallocator) virNetworkFreeName);
-    if (conn->hashes_mux != NULL)
-        xmlFreeMutex(conn->hashes_mux);
-    free(conn);
-    return(0);
-
-done:
-    xmlMutexUnlock(conn->hashes_mux);
-    return(ret);
-}
-
+    pthread_mutex_lock(&network->conn->lock);
+    DEBUG("unref network %p %s %d", network, network->name, network->refs);
+    network->refs--;
+    refs = network->refs;
+    if (refs == 0) {
+        virReleaseNetwork(network);
+        /* Already unlocked mutex */
+        return (0);
+    }
+
+    pthread_mutex_lock(&network->conn->lock);
+    return (refs);
+}
+
+/*
+ * vim: set tabstop=4:
+ * vim: set shiftwidth=4:
+ * vim: set expandtab:
+ */
 /*
  * Local variables:
  *  indent-tabs-mode: nil
diff -r 1d004e448a45 src/internal.h
--- a/src/internal.h	Sat Jan 19 13:44:13 2008 -0500
+++ b/src/internal.h	Sat Jan 19 13:45:07 2008 -0500
@@ -149,8 +149,8 @@ extern int debugFlag;
  */
 struct _virConnect {
     unsigned int magic;     /* specific value to check */
-
-    int uses;               /* reference count */
+    int flags;              /* a set of connection flags */
+    char *name;                 /* connection URI */
 
     /* The underlying hypervisor driver and network driver. */
     virDriverPtr      driver;
@@ -168,12 +168,16 @@ struct _virConnect {
     virErrorFunc handler;   /* associated handlet */
     void *userData;         /* the user data */
 
-    /* misc */
-    xmlMutexPtr hashes_mux;/* a mutex to protect the domain and networks hash tables */
-    virHashTablePtr domains;/* hash table for known domains */
-    virHashTablePtr networks;/* hash table for known domains */
-    int flags;              /* a set of connection flags */
-    char *name;                 /* connection URI */
+    /*
+     * The lock mutex must be acquired before accessing/changing
+     * any of members following this point, or changing the ref
+     * count of any virDomain/virNetwork object associated with
+     * this connection
+     */
+    pthread_mutex_t lock;
+    virHashTablePtr domains;  /* hash table for known domains */
+    virHashTablePtr networks; /* hash table for known domains */
+    int refs;                 /* reference count */
 };
 
 /**
@@ -183,7 +187,7 @@ struct _virConnect {
 */
 struct _virDomain {
     unsigned int magic;                  /* specific value to check */
-    int uses;                            /* reference count */
+    int refs;                            /* reference count */
     virConnectPtr conn;                  /* pointer back to the connection */
     char *name;                          /* the domain external name */
     int id;                              /* the domain ID */
@@ -197,18 +201,12 @@ struct _virDomain {
 */
 struct _virNetwork {
     unsigned int magic;                  /* specific value to check */
-    int uses;                            /* reference count */
+    int refs;                            /* reference count */
     virConnectPtr conn;                  /* pointer back to the connection */
     char *name;                          /* the network external name */
     unsigned char uuid[VIR_UUID_BUFLEN]; /* the network unique identifier */
 };
 
-/*
-* Internal routines
-*/
-char *virDomainGetVM(virDomainPtr domain);
-char *virDomainGetVMInfo(virDomainPtr domain,
-			 const char *vm, const char *name);
 
 /************************************************************************
  *									*
@@ -234,18 +232,16 @@ const char *__virErrorMsg(virErrorNumber
  *									*
  ************************************************************************/
 
-virConnectPtr	virGetConnect	(void);
-int		virFreeConnect	(virConnectPtr conn);
-virDomainPtr	__virGetDomain	(virConnectPtr conn,
-				 const char *name,
-				 const unsigned char *uuid);
-int		virFreeDomain	(virConnectPtr conn,
-				 virDomainPtr domain);
-virNetworkPtr	__virGetNetwork	(virConnectPtr conn,
-				 const char *name,
-				 const unsigned char *uuid);
-int		virFreeNetwork	(virConnectPtr conn,
-				 virNetworkPtr domain);
+virConnectPtr  virGetConnect   (void);
+int            virUnrefConnect (virConnectPtr conn);
+virDomainPtr   __virGetDomain  (virConnectPtr conn,
+                                const char *name,
+                                const unsigned char *uuid);
+int            virUnrefDomain  (virDomainPtr domain);
+virNetworkPtr  __virGetNetwork (virConnectPtr conn,
+                                const char *name,
+                                const unsigned char *uuid);
+int           virUnrefNetwork  (virNetworkPtr network);
 
 #define virGetDomain(c,n,u) __virGetDomain((c),(n),(u))
 #define virGetNetwork(c,n,u) __virGetNetwork((c),(n),(u))
diff -r 1d004e448a45 src/libvirt.c
--- a/src/libvirt.c	Sat Jan 19 13:44:13 2008 -0500
+++ b/src/libvirt.c	Sat Jan 19 13:45:07 2008 -0500
@@ -616,7 +616,7 @@ failed:
     if (ret->name) free (ret->name);
     if (ret->driver) ret->driver->close (ret);
     if (uri) xmlFreeURI(uri);
-	virFreeConnect(ret);
+	virUnrefConnect(ret);
     return NULL;
 }
 
@@ -703,9 +703,7 @@ virConnectClose(virConnectPtr conn)
         conn->networkDriver->close (conn);
     conn->driver->close (conn);
 
-    if (conn->name) free (conn->name);
-
-    if (virFreeConnect(conn) < 0)
+    if (virUnrefConnect(conn) < 0)
         return (-1);
     return (0);
 }
@@ -1209,7 +1207,7 @@ virDomainFree(virDomainPtr domain)
         virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
         return (-1);
     }
-    if (virFreeDomain(domain->conn, domain) < 0)
+    if (virUnrefDomain(domain) < 0)
         return (-1);
     return(0);
 }
@@ -3322,7 +3320,7 @@ virNetworkFree(virNetworkPtr network)
         virLibNetworkError(NULL, VIR_ERR_INVALID_NETWORK, __FUNCTION__);
         return (-1);
     }
-    if (virFreeNetwork(network->conn, network) < 0)
+    if (virUnrefNetwork(network) < 0)
         return (-1);
     return(0);
 }
diff -r 1d004e448a45 src/qemu_driver.c
--- a/src/qemu_driver.c	Sat Jan 19 13:44:13 2008 -0500
+++ b/src/qemu_driver.c	Sat Jan 19 13:45:07 2008 -0500
@@ -1888,7 +1888,7 @@ static int qemudDomainDestroy(virDomainP
     qemudShutdownVMDaemon(dom->conn, driver, vm);
     if (!vm->configFile[0])
         qemudRemoveInactiveVM(driver, vm);
-    virFreeDomain(dom->conn, dom);
+
     return 0;
 }
 
@@ -2763,8 +2763,6 @@ static int qemudNetworkDestroy(virNetwor
     }
 
     ret = qemudShutdownNetworkDaemon(net->conn, driver, network);
-
-    virFreeNetwork(net->conn, net);
 
     return ret;
 }
diff -r 1d004e448a45 src/xend_internal.c
--- a/src/xend_internal.c	Sat Jan 19 13:44:13 2008 -0500
+++ b/src/xend_internal.c	Sat Jan 19 13:45:07 2008 -0500
@@ -2032,7 +2032,7 @@ error:
     virXendError(conn, VIR_ERR_INTERNAL_ERROR,
                  _("failed to parse Xend domain information"));
     if (ret != NULL)
-        virFreeDomain(conn, ret);
+        virUnrefDomain(ret);
     return(NULL);
 }
 #endif /* !PROXY */
@@ -3179,7 +3179,7 @@ xenDaemonCreateLinux(virConnectPtr conn,
     /* Make sure we don't leave a still-born domain around */
     if (dom != NULL) {
         xenDaemonDomainDestroy(dom);
-        virFreeDomain(dom->conn, dom);
+        virUnrefDomain(dom);
     }
     if (name != NULL)
         free(name);
diff -r 1d004e448a45 src/xs_internal.c
--- a/src/xs_internal.c	Sat Jan 19 13:44:13 2008 -0500
+++ b/src/xs_internal.c	Sat Jan 19 13:45:07 2008 -0500
@@ -227,7 +227,7 @@ virDomainDoStoreWrite(virDomainPtr domai
  *
  * Returns the new string or NULL in case of error
  */
-char *
+static char *
 virDomainGetVM(virDomainPtr domain)
 {
     char *vm;
@@ -261,7 +261,7 @@ virDomainGetVM(virDomainPtr domain)
  *
  * Returns the new string or NULL in case of error
  */
-char *
+static char *
 virDomainGetVMInfo(virDomainPtr domain, const char *vm, const char *name)
 {
     char s[256];
@@ -284,30 +284,6 @@ virDomainGetVMInfo(virDomainPtr domain, 
     return (ret);
 }
 
-#if 0
-/**
- * virConnectCheckStoreID:
- * @conn: pointer to the hypervisor connection
- * @id: the id number as returned from Xenstore
- *
- * the xenstore sometimes list non-running domains, double check
- * from the hypervisor if we have direct access
- *
- * Returns -1 if the check failed, 0 if successful or not possible to check
- */
-static int
-virConnectCheckStoreID(virConnectPtr conn, int id)
-{
-    if (conn->id >= 0) {
-        int tmp;
-
-        tmp = xenHypervisorCheckID(conn, id);
-        if (tmp < 0)
-            return (-1);
-    }
-    return (0);
-}
-#endif
 #endif /* ! PROXY */
 
 /************************************************************************


More information about the libvir-list mailing list