[libvirt] [libvirt-glib 3/5] gobject: Fix handle leak on wrapper object creation

Christophe Fergeau cfergeau at redhat.com
Tue Nov 13 17:30:29 UTC 2012


When creating an object wrapping a libvirt object (GVirDomain,
GVirStoragePool, GVirStorageVol), libvirt-gobject gets a reference
to a libvirt object to be used as a handle, and then creates the wrapper
object by calling g_object_new(..., "handle", handle, NULL);

However, the underlying libvirt object is registered as a boxed type
with the gobject type system, and the handle setter for these object
calls g_value_dup_boxed, which in turn adds a reference on the libvirt
handle. Thus we must release the initial ref we hold on the libvirt
handle after calling g_object_new().

I noticed this bug after running in valgrind some code which calls
gvir_storage_pool_refresh and gvir_connection_fetch_storage_pools.
---
 libvirt-gobject/libvirt-gobject-connection.c   | 7 +++++++
 libvirt-gobject/libvirt-gobject-storage-pool.c | 2 +-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/libvirt-gobject/libvirt-gobject-connection.c b/libvirt-gobject/libvirt-gobject-connection.c
index e6ccfd0..3157a66 100644
--- a/libvirt-gobject/libvirt-gobject-connection.c
+++ b/libvirt-gobject/libvirt-gobject-connection.c
@@ -726,6 +726,7 @@ gboolean gvir_connection_fetch_domains(GVirConnection *conn,
         dom = GVIR_DOMAIN(g_object_new(GVIR_TYPE_DOMAIN,
                                        "handle", vdom,
                                        NULL));
+        virDomainFree(vdom);
 
         g_hash_table_insert(doms,
                             (gpointer)gvir_domain_get_uuid(dom),
@@ -744,6 +745,7 @@ gboolean gvir_connection_fetch_domains(GVirConnection *conn,
         dom = GVIR_DOMAIN(g_object_new(GVIR_TYPE_DOMAIN,
                                        "handle", vdom,
                                        NULL));
+        virDomainFree(vdom);
 
         g_hash_table_insert(doms,
                             (gpointer)gvir_domain_get_uuid(dom),
@@ -857,6 +859,7 @@ gboolean gvir_connection_fetch_storage_pools(GVirConnection *conn,
         pool = GVIR_STORAGE_POOL(g_object_new(GVIR_TYPE_STORAGE_POOL,
                                               "handle", vpool,
                                               NULL));
+        virStoragePoolFree(vpool);
 
         g_hash_table_insert(pools,
                             (gpointer)gvir_storage_pool_get_uuid(pool),
@@ -877,6 +880,7 @@ gboolean gvir_connection_fetch_storage_pools(GVirConnection *conn,
         pool = GVIR_STORAGE_POOL(g_object_new(GVIR_TYPE_STORAGE_POOL,
                                               "handle", vpool,
                                               NULL));
+        virStoragePoolFree(vpool);
 
         g_hash_table_insert(pools,
                             (gpointer)gvir_storage_pool_get_uuid(pool),
@@ -1427,6 +1431,7 @@ GVirDomain *gvir_connection_create_domain(GVirConnection *conn,
     domain = GVIR_DOMAIN(g_object_new(GVIR_TYPE_DOMAIN,
                                        "handle", handle,
                                        NULL));
+    virDomainFree(handle);
 
     g_mutex_lock(priv->lock);
     g_hash_table_insert(priv->domains,
@@ -1481,6 +1486,7 @@ GVirDomain *gvir_connection_start_domain(GVirConnection *conn,
     domain = GVIR_DOMAIN(g_object_new(GVIR_TYPE_DOMAIN,
                                        "handle", handle,
                                        NULL));
+    virDomainFree(handle);
 
     g_mutex_lock(priv->lock);
     g_hash_table_insert(priv->domains,
@@ -1532,6 +1538,7 @@ GVirStoragePool *gvir_connection_create_storage_pool
     pool = GVIR_STORAGE_POOL(g_object_new(GVIR_TYPE_STORAGE_POOL,
                                           "handle", handle,
                                           NULL));
+    virStoragePoolFree(handle);
 
     g_mutex_lock(priv->lock);
     g_hash_table_insert(priv->pools,
diff --git a/libvirt-gobject/libvirt-gobject-storage-pool.c b/libvirt-gobject/libvirt-gobject-storage-pool.c
index a380079..96670df 100644
--- a/libvirt-gobject/libvirt-gobject-storage-pool.c
+++ b/libvirt-gobject/libvirt-gobject-storage-pool.c
@@ -406,7 +406,7 @@ gboolean gvir_storage_pool_refresh(GVirStoragePool *pool,
                                                "handle", vvolume,
                                                "pool", pool,
                                                NULL));
-
+        virStorageVolFree(vvolume);
         g_hash_table_insert(vol_hash, g_strdup(volumes[i]), volume);
     }
 
-- 
1.8.0




More information about the libvir-list mailing list