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