commit f44bfb7fb978c9313ce050a1c4149bf04aa0a670
Author: Jiri Denemark <jdenemar@redhat.com>
Date:   Wed Mar 23 16:00:58 2011 +0100

    Make error reporting in libvirtd thread safe
    
    Bug https://bugzilla.redhat.com/show_bug.cgi?id=689374 reported libvirtd
    crash during error dispatch.
    
    The reason is that libvirtd uses remoteDispatchConnError() with non-NULL
    conn parameter which means that virConnGetLastError() is used instead of
    its thread safe replacement virGetLastError().
    
    So when several libvirtd threads are reporting errors at the same time,
    the errors can get mixed or corrupted or in case of bad luck libvirtd
    itself crashes.
    
    Since Daniel B. is going to rewrite this code from scratch on top of his
    RPC infrastructure, I tried to come up with a minimal fix. Thus,
    remoteDispatchConnError() now just ignores its conn argument and always
    calls virGetLastError(). However, several callers had to be touched as
    well, since no libvirt API is allowed to be called before dispatching
    the error. Doing so would reset the error and we would have nothing to
    dispatch. As a result of that, the code is not very nice but that
    doesn't really make daemon/remote.c worse than it is now :-) And it will
    all die soon, which is good.
    
    The bug report also contains a reproducer in C which detects both mixed
    up error messages and libvirtd crash. Before this patch, I was able to
    crash libvirtd in about 20 seconds up to 3 minutes depending on number
    of CPU cores (more is better) and luck.

Index: libvirt-0.7.6/daemon/dispatch.c
===================================================================
--- libvirt-0.7.6.orig/daemon/dispatch.c
+++ libvirt-0.7.6/daemon/dispatch.c
@@ -109,14 +109,10 @@ void remoteDispatchOOMError (remote_erro
 
 
 void remoteDispatchConnError (remote_error *rerr,
-                              virConnectPtr conn)
+                              virConnectPtr conn ATTRIBUTE_UNUSED)
 {
-    virErrorPtr verr;
+    virErrorPtr verr = virGetLastError();
 
-    if (conn)
-        verr = virConnGetLastError(conn);
-    else
-        verr = virGetLastError();
     if (verr)
         remoteDispatchCopyError(rerr, verr);
     else
Index: libvirt-0.7.6/daemon/remote.c
===================================================================
--- libvirt-0.7.6.orig/daemon/remote.c
+++ libvirt-0.7.6/daemon/remote.c
@@ -471,8 +471,8 @@ remoteDispatchDomainGetSchedulerType (st
 
     type = virDomainGetSchedulerType (dom, &nparams);
     if (type == NULL) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
 
@@ -515,9 +515,9 @@ remoteDispatchDomainGetSchedulerParamete
 
     r = virDomainGetSchedulerParameters (dom, params, &nparams);
     if (r == -1) {
+        remoteDispatchConnError(rerr, conn);
         virDomainFree(dom);
         VIR_FREE(params);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -622,12 +622,13 @@ remoteDispatchDomainSetSchedulerParamete
     }
 
     r = virDomainSetSchedulerParameters (dom, params, nparams);
-    virDomainFree(dom);
     VIR_FREE(params);
     if (r == -1) {
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
+    virDomainFree(dom);
 
     return 0;
 }
@@ -653,8 +654,8 @@ remoteDispatchDomainBlockStats (struct q
     path = args->path;
 
     if (virDomainBlockStats (dom, path, &stats, sizeof stats) == -1) {
-        virDomainFree (dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree (dom);
         return -1;
     }
     virDomainFree (dom);
@@ -689,8 +690,8 @@ remoteDispatchDomainInterfaceStats (stru
     path = args->path;
 
     if (virDomainInterfaceStats (dom, path, &stats, sizeof stats) == -1) {
-        virDomainFree (dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree (dom);
         return -1;
     }
     virDomainFree (dom);
@@ -739,12 +740,13 @@ remoteDispatchDomainMemoryStats (struct
      }
 
     nr_stats = virDomainMemoryStats (dom, stats, args->maxStats, 0);
-    virDomainFree (dom);
     if (nr_stats == -1) {
         VIR_FREE(stats);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree (dom);
         return -1;
     }
+    virDomainFree (dom);
 
     /* Allocate return buffer */
     if (VIR_ALLOC_N(ret->stats.stats_val, args->maxStats) < 0) {
@@ -805,8 +807,8 @@ remoteDispatchDomainBlockPeek (struct qe
     if (virDomainBlockPeek (dom, path, offset, size,
                             ret->buffer.buffer_val, flags) == -1) {
         /* free (ret->buffer.buffer_val); - caller frees */
-        virDomainFree (dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree (dom);
         return -1;
     }
     virDomainFree (dom);
@@ -854,8 +856,8 @@ remoteDispatchDomainMemoryPeek (struct q
     if (virDomainMemoryPeek (dom, offset, size,
                              ret->buffer.buffer_val, flags) == -1) {
         /* free (ret->buffer.buffer_val); - caller frees */
-        virDomainFree (dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree (dom);
         return -1;
     }
     virDomainFree (dom);
@@ -881,8 +883,8 @@ remoteDispatchDomainAttachDevice (struct
     }
 
     if (virDomainAttachDevice (dom, args->xml) == -1) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
     virDomainFree(dom);
@@ -907,8 +909,8 @@ remoteDispatchDomainAttachDeviceFlags (s
     }
 
     if (virDomainAttachDeviceFlags (dom, args->xml, args->flags) == -1) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
     virDomainFree(dom);
@@ -933,8 +935,8 @@ remoteDispatchDomainCreate (struct qemud
     }
 
     if (virDomainCreate (dom) == -1) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
     virDomainFree(dom);
@@ -1005,8 +1007,8 @@ remoteDispatchDomainDestroy (struct qemu
     }
 
     if (virDomainDestroy (dom) == -1) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
     virDomainFree(dom);
@@ -1031,8 +1033,8 @@ remoteDispatchDomainDetachDevice (struct
     }
 
     if (virDomainDetachDevice (dom, args->xml) == -1) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
 
@@ -1058,8 +1060,8 @@ remoteDispatchDomainDetachDeviceFlags (s
     }
 
     if (virDomainDetachDeviceFlags (dom, args->xml, args->flags) == -1) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
 
@@ -1087,8 +1089,8 @@ remoteDispatchDomainDumpXml (struct qemu
     /* remoteDispatchClientRequest will free this. */
     ret->xml = virDomainGetXMLDesc (dom, args->flags);
     if (!ret->xml) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
     virDomainFree(dom);
@@ -1156,8 +1158,8 @@ remoteDispatchDomainGetAutostart (struct
     }
 
     if (virDomainGetAutostart (dom, &ret->autostart) == -1) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
     virDomainFree(dom);
@@ -1183,8 +1185,8 @@ remoteDispatchDomainGetInfo (struct qemu
     }
 
     if (virDomainGetInfo (dom, &info) == -1) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
 
@@ -1218,8 +1220,8 @@ remoteDispatchDomainGetMaxMemory (struct
 
     ret->memory = virDomainGetMaxMemory (dom);
     if (ret->memory == 0) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
     virDomainFree(dom);
@@ -1245,8 +1247,8 @@ remoteDispatchDomainGetMaxVcpus (struct
 
     ret->num = virDomainGetMaxVcpus (dom);
     if (ret->num == -1) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
     virDomainFree(dom);
@@ -1273,8 +1275,8 @@ remoteDispatchDomainGetSecurityLabel(str
 
     memset(&seclabel, 0, sizeof seclabel);
     if (virDomainGetSecurityLabel(dom, &seclabel) == -1) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
 
@@ -1345,8 +1347,8 @@ remoteDispatchDomainGetOsType (struct qe
     /* remoteDispatchClientRequest will free this */
     ret->type = virDomainGetOSType (dom);
     if (ret->type == NULL) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
     virDomainFree(dom);
@@ -1396,10 +1398,10 @@ remoteDispatchDomainGetVcpus (struct qem
                                   info, args->maxinfo,
                                   cpumaps, args->maplen);
     if (info_len == -1) {
+        remoteDispatchConnError(rerr, conn);
         VIR_FREE(info);
         VIR_FREE(cpumaps);
         virDomainFree(dom);
-        remoteDispatchConnError(rerr, conn);
         return -1;
     }
 
@@ -1509,11 +1511,12 @@ remoteDispatchDomainMigratePerform (stru
                                  args->cookie.cookie_len,
                                  args->uri,
                                  args->flags, dname, args->resource);
-    virDomainFree (dom);
     if (r == -1) {
         remoteDispatchConnError(rerr, conn);
+        virDomainFree (dom);
         return -1;
     }
+    virDomainFree (dom);
 
     return 0;
 }
@@ -1644,8 +1647,8 @@ remoteDispatchDomainMigratePrepareTunnel
                                       args->flags, dname, args->resource,
                                       args->dom_xml);
     if (r == -1) {
-        remoteFreeClientStream(client, stream);
         remoteDispatchConnError(rerr, conn);
+        remoteFreeClientStream(client, stream);
         return -1;
     }
 
@@ -1806,8 +1809,8 @@ remoteDispatchDomainPinVcpu (struct qemu
                            (unsigned char *) args->cpumap.cpumap_val,
                            args->cpumap.cpumap_len);
     if (rv == -1) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
     virDomainFree(dom);
@@ -1832,8 +1835,8 @@ remoteDispatchDomainReboot (struct qemud
     }
 
     if (virDomainReboot (dom, args->flags) == -1) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
     virDomainFree(dom);
@@ -1876,8 +1879,8 @@ remoteDispatchDomainResume (struct qemud
     }
 
     if (virDomainResume (dom) == -1) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
     virDomainFree(dom);
@@ -1902,8 +1905,8 @@ remoteDispatchDomainSave (struct qemud_s
     }
 
     if (virDomainSave (dom, args->to) == -1) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
     virDomainFree(dom);
@@ -1928,8 +1931,8 @@ remoteDispatchDomainCoreDump (struct qem
     }
 
     if (virDomainCoreDump (dom, args->to, args->flags) == -1) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
     virDomainFree(dom);
@@ -1954,8 +1957,8 @@ remoteDispatchDomainSetAutostart (struct
     }
 
     if (virDomainSetAutostart (dom, args->autostart) == -1) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
     virDomainFree(dom);
@@ -1980,8 +1983,8 @@ remoteDispatchDomainSetMaxMemory (struct
     }
 
     if (virDomainSetMaxMemory (dom, args->memory) == -1) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
     virDomainFree(dom);
@@ -2006,8 +2009,8 @@ remoteDispatchDomainSetMemory (struct qe
     }
 
     if (virDomainSetMemory (dom, args->memory) == -1) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
     virDomainFree(dom);
@@ -2032,8 +2035,8 @@ remoteDispatchDomainSetVcpus (struct qem
     }
 
     if (virDomainSetVcpus (dom, args->nvcpus) == -1) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
     virDomainFree(dom);
@@ -2058,8 +2061,8 @@ remoteDispatchDomainShutdown (struct qem
     }
 
     if (virDomainShutdown (dom) == -1) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
     virDomainFree(dom);
@@ -2084,8 +2087,8 @@ remoteDispatchDomainSuspend (struct qemu
     }
 
     if (virDomainSuspend (dom) == -1) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
     virDomainFree(dom);
@@ -2110,8 +2113,8 @@ remoteDispatchDomainUndefine (struct qem
     }
 
     if (virDomainUndefine (dom) == -1) {
-        virDomainFree(dom);
         remoteDispatchConnError(rerr, conn);
+        virDomainFree(dom);
         return -1;
     }
     virDomainFree(dom);
@@ -2237,8 +2240,8 @@ remoteDispatchNetworkCreate (struct qemu
     }
 
     if (virNetworkCreate (net) == -1) {
-        virNetworkFree(net);
         remoteDispatchConnError(rerr, conn);
+        virNetworkFree(net);
         return -1;
     }
     virNetworkFree(net);
@@ -2307,8 +2310,8 @@ remoteDispatchNetworkDestroy (struct qem
     }
 
     if (virNetworkDestroy (net) == -1) {
-        virNetworkFree(net);
         remoteDispatchConnError(rerr, conn);
+        virNetworkFree(net);
         return -1;
     }
     virNetworkFree(net);
@@ -2335,8 +2338,8 @@ remoteDispatchNetworkDumpXml (struct qem
     /* remoteDispatchClientRequest will free this. */
     ret->xml = virNetworkGetXMLDesc (net, args->flags);
     if (!ret->xml) {
-        virNetworkFree(net);
         remoteDispatchConnError(rerr, conn);
+        virNetworkFree(net);
         return -1;
     }
     virNetworkFree(net);
@@ -2361,8 +2364,8 @@ remoteDispatchNetworkGetAutostart (struc
     }
 
     if (virNetworkGetAutostart (net, &ret->autostart) == -1) {
-        virNetworkFree(net);
         remoteDispatchConnError(rerr, conn);
+        virNetworkFree(net);
         return -1;
     }
     virNetworkFree(net);
@@ -2389,8 +2392,8 @@ remoteDispatchNetworkGetBridgeName (stru
     /* remoteDispatchClientRequest will free this. */
     ret->name = virNetworkGetBridgeName (net);
     if (!ret->name) {
-        virNetworkFree(net);
         remoteDispatchConnError(rerr, conn);
+        virNetworkFree(net);
         return -1;
     }
     virNetworkFree(net);
@@ -2459,8 +2462,8 @@ remoteDispatchNetworkSetAutostart (struc
     }
 
     if (virNetworkSetAutostart (net, args->autostart) == -1) {
-        virNetworkFree(net);
         remoteDispatchConnError(rerr, conn);
+        virNetworkFree(net);
         return -1;
     }
     virNetworkFree(net);
@@ -2485,8 +2488,8 @@ remoteDispatchNetworkUndefine (struct qe
     }
 
     if (virNetworkUndefine (net) == -1) {
-        virNetworkFree(net);
         remoteDispatchConnError(rerr, conn);
+        virNetworkFree(net);
         return -1;
     }
     virNetworkFree(net);
@@ -2722,8 +2725,8 @@ remoteDispatchInterfaceGetXmlDesc (struc
     /* remoteDispatchClientRequest will free this. */
     ret->xml = virInterfaceGetXMLDesc (iface, args->flags);
     if (!ret->xml) {
-        virInterfaceFree(iface);
         remoteDispatchConnError(rerr, conn);
+        virInterfaceFree(iface);
         return -1;
     }
     virInterfaceFree(iface);
@@ -2770,8 +2773,8 @@ remoteDispatchInterfaceUndefine (struct
     }
 
     if (virInterfaceUndefine (iface) == -1) {
-        virInterfaceFree(iface);
         remoteDispatchConnError(rerr, conn);
+        virInterfaceFree(iface);
         return -1;
     }
     virInterfaceFree(iface);
@@ -2796,8 +2799,8 @@ remoteDispatchInterfaceCreate (struct qe
     }
 
     if (virInterfaceCreate (iface, args->flags) == -1) {
-        virInterfaceFree(iface);
         remoteDispatchConnError(rerr, conn);
+        virInterfaceFree(iface);
         return -1;
     }
     virInterfaceFree(iface);
@@ -2822,8 +2825,8 @@ remoteDispatchInterfaceDestroy (struct q
     }
 
     if (virInterfaceDestroy (iface, args->flags) == -1) {
-        virInterfaceFree(iface);
         remoteDispatchConnError(rerr, conn);
+        virInterfaceFree(iface);
         return -1;
     }
     virInterfaceFree(iface);
@@ -3689,8 +3692,8 @@ remoteDispatchStoragePoolCreate (struct
     }
 
     if (virStoragePoolCreate (pool, args->flags) == -1) {
-        virStoragePoolFree(pool);
         remoteDispatchConnError(rerr, conn);
+        virStoragePoolFree(pool);
         return -1;
     }
     virStoragePoolFree(pool);
@@ -3759,8 +3762,8 @@ remoteDispatchStoragePoolBuild (struct q
     }
 
     if (virStoragePoolBuild (pool, args->flags) == -1) {
-        virStoragePoolFree(pool);
         remoteDispatchConnError(rerr, conn);
+        virStoragePoolFree(pool);
         return -1;
     }
     virStoragePoolFree(pool);
@@ -3786,8 +3789,8 @@ remoteDispatchStoragePoolDestroy (struct
     }
 
     if (virStoragePoolDestroy (pool) == -1) {
-        virStoragePoolFree(pool);
         remoteDispatchConnError(rerr, conn);
+        virStoragePoolFree(pool);
         return -1;
     }
     virStoragePoolFree(pool);
@@ -3812,8 +3815,8 @@ remoteDispatchStoragePoolDelete (struct
     }
 
     if (virStoragePoolDelete (pool, args->flags) == -1) {
-        virStoragePoolFree(pool);
         remoteDispatchConnError(rerr, conn);
+        virStoragePoolFree(pool);
         return -1;
     }
     virStoragePoolFree(pool);
@@ -3838,8 +3841,8 @@ remoteDispatchStoragePoolRefresh (struct
     }
 
     if (virStoragePoolRefresh (pool, args->flags) == -1) {
-        virStoragePoolFree(pool);
         remoteDispatchConnError(rerr, conn);
+        virStoragePoolFree(pool);
         return -1;
     }
     virStoragePoolFree(pool);
@@ -3865,8 +3868,8 @@ remoteDispatchStoragePoolGetInfo (struct
     }
 
     if (virStoragePoolGetInfo (pool, &info) == -1) {
-        virStoragePoolFree(pool);
         remoteDispatchConnError(rerr, conn);
+        virStoragePoolFree(pool);
         return -1;
     }
 
@@ -3900,8 +3903,8 @@ remoteDispatchStoragePoolDumpXml (struct
     /* remoteDispatchClientRequest will free this. */
     ret->xml = virStoragePoolGetXMLDesc (pool, args->flags);
     if (!ret->xml) {
-        virStoragePoolFree(pool);
         remoteDispatchConnError(rerr, conn);
+        virStoragePoolFree(pool);
         return -1;
     }
     virStoragePoolFree(pool);
@@ -3926,8 +3929,8 @@ remoteDispatchStoragePoolGetAutostart (s
     }
 
     if (virStoragePoolGetAutostart (pool, &ret->autostart) == -1) {
-        virStoragePoolFree(pool);
         remoteDispatchConnError(rerr, conn);
+        virStoragePoolFree(pool);
         return -1;
     }
     virStoragePoolFree(pool);
@@ -3998,11 +4001,12 @@ remoteDispatchStoragePoolLookupByVolume
     }
 
     pool = virStoragePoolLookupByVolume (vol);
-    virStorageVolFree(vol);
     if (pool == NULL) {
         remoteDispatchConnError(rerr, conn);
+        virStorageVolFree(vol);
         return -1;
     }
+    virStorageVolFree(vol);
 
     make_nonnull_storage_pool (&ret->pool, pool);
     virStoragePoolFree(pool);
@@ -4027,8 +4031,8 @@ remoteDispatchStoragePoolSetAutostart (s
     }
 
     if (virStoragePoolSetAutostart (pool, args->autostart) == -1) {
-        virStoragePoolFree(pool);
         remoteDispatchConnError(rerr, conn);
+        virStoragePoolFree(pool);
         return -1;
     }
     virStoragePoolFree(pool);
@@ -4053,8 +4057,8 @@ remoteDispatchStoragePoolUndefine (struc
     }
 
     if (virStoragePoolUndefine (pool) == -1) {
-        virStoragePoolFree(pool);
         remoteDispatchConnError(rerr, conn);
+        virStoragePoolFree(pool);
         return -1;
     }
     virStoragePoolFree(pool);
@@ -4196,11 +4200,12 @@ remoteDispatchStorageVolCreateXml (struc
     }
 
     vol = virStorageVolCreateXML (pool, args->xml, args->flags);
-    virStoragePoolFree(pool);
     if (vol == NULL) {
         remoteDispatchConnError(rerr, conn);
+        virStoragePoolFree(pool);
         return -1;
     }
+    virStoragePoolFree(pool);
 
     make_nonnull_storage_vol (&ret->vol, vol);
     virStorageVolFree(vol);
@@ -4227,19 +4232,21 @@ remoteDispatchStorageVolCreateXmlFrom (s
 
     clonevol = get_nonnull_storage_vol (conn, args->clonevol);
     if (clonevol == NULL) {
-        virStoragePoolFree(pool);
         remoteDispatchConnError(rerr, conn);
+        virStoragePoolFree(pool);
         return -1;
     }
 
     newvol = virStorageVolCreateXMLFrom (pool, args->xml, clonevol,
                                          args->flags);
-    virStorageVolFree(clonevol);
-    virStoragePoolFree(pool);
     if (newvol == NULL) {
         remoteDispatchConnError(rerr, conn);
+        virStorageVolFree(clonevol);
+        virStoragePoolFree(pool);
         return -1;
     }
+    virStorageVolFree(clonevol);
+    virStoragePoolFree(pool);
 
     make_nonnull_storage_vol (&ret->vol, newvol);
     virStorageVolFree(newvol);
@@ -4264,8 +4271,8 @@ remoteDispatchStorageVolDelete (struct q
     }
 
     if (virStorageVolDelete (vol, args->flags) == -1) {
-        virStorageVolFree(vol);
         remoteDispatchConnError(rerr, conn);
+        virStorageVolFree(vol);
         return -1;
     }
     virStorageVolFree(vol);
@@ -4291,8 +4298,8 @@ remoteDispatchStorageVolGetInfo (struct
     }
 
     if (virStorageVolGetInfo (vol, &info) == -1) {
-        virStorageVolFree(vol);
         remoteDispatchConnError(rerr, conn);
+        virStorageVolFree(vol);
         return -1;
     }
 
@@ -4325,8 +4332,8 @@ remoteDispatchStorageVolDumpXml (struct
     /* remoteDispatchClientRequest will free this. */
     ret->xml = virStorageVolGetXMLDesc (vol, args->flags);
     if (!ret->xml) {
-        virStorageVolFree(vol);
         remoteDispatchConnError(rerr, conn);
+        virStorageVolFree(vol);
         return -1;
     }
     virStorageVolFree(vol);
@@ -4354,8 +4361,8 @@ remoteDispatchStorageVolGetPath (struct
     /* remoteDispatchClientRequest will free this. */
     ret->name = virStorageVolGetPath (vol);
     if (!ret->name) {
-        virStorageVolFree(vol);
         remoteDispatchConnError(rerr, conn);
+        virStorageVolFree(vol);
         return -1;
     }
     virStorageVolFree(vol);
@@ -4382,11 +4389,12 @@ remoteDispatchStorageVolLookupByName (st
     }
 
     vol = virStorageVolLookupByName (pool, args->name);
-    virStoragePoolFree(pool);
     if (vol == NULL) {
         remoteDispatchConnError(rerr, conn);
+        virStoragePoolFree(pool);
         return -1;
     }
+    virStoragePoolFree(pool);
 
     make_nonnull_storage_vol (&ret->vol, vol);
     virStorageVolFree(vol);
@@ -4622,6 +4630,7 @@ remoteDispatchNodeDeviceNumOfCaps (struc
     ret->num = virNodeDeviceNumOfCaps(dev);
     if (ret->num < 0) {
         remoteDispatchConnError(rerr, conn);
+        virNodeDeviceFree(dev);
         return -1;
     }
 
@@ -4665,6 +4674,7 @@ remoteDispatchNodeDeviceListCaps (struct
                                args->maxnames);
     if (ret->names.names_len == -1) {
         remoteDispatchConnError(rerr, conn);
+        virNodeDeviceFree(dev);
         VIR_FREE(ret->names.names_val);
         return -1;
     }
@@ -4693,6 +4703,7 @@ remoteDispatchNodeDeviceDettach (struct
 
     if (virNodeDeviceDettach(dev) == -1) {
         remoteDispatchConnError(rerr, conn);
+        virNodeDeviceFree(dev);
         return -1;
     }
 
@@ -4720,6 +4731,7 @@ remoteDispatchNodeDeviceReAttach (struct
 
     if (virNodeDeviceReAttach(dev) == -1) {
         remoteDispatchConnError(rerr, conn);
+        virNodeDeviceFree(dev);
         return -1;
     }
 
@@ -4747,6 +4759,7 @@ remoteDispatchNodeDeviceReset (struct qe
 
     if (virNodeDeviceReset(dev) == -1) {
         remoteDispatchConnError(rerr, conn);
+        virNodeDeviceFree(dev);
         return -1;
     }
 
@@ -4797,6 +4810,7 @@ remoteDispatchNodeDeviceDestroy(struct q
 
     if (virNodeDeviceDestroy(dev) == -1) {
         remoteDispatchConnError(rerr, conn);
+        virNodeDeviceFree(dev);
         return -1;
     }
 
@@ -5161,6 +5175,7 @@ static int remoteDispatchDomainIsActive(
 
     if (ret->active < 0) {
         remoteDispatchConnError(err, conn);
+        virDomainFree(domain);
         return -1;
     }
 
@@ -5187,6 +5202,7 @@ static int remoteDispatchDomainIsPersist
 
     if (ret->persistent < 0) {
         remoteDispatchConnError(err, conn);
+        virDomainFree(domain);
         return -1;
     }
 
@@ -5213,6 +5229,7 @@ static int remoteDispatchInterfaceIsActi
 
     if (ret->active < 0) {
         remoteDispatchConnError(err, conn);
+        virInterfaceFree(iface);
         return -1;
     }
 
@@ -5239,6 +5256,7 @@ static int remoteDispatchNetworkIsActive
 
     if (ret->active < 0) {
         remoteDispatchConnError(err, conn);
+        virNetworkFree(network);
         return -1;
     }
 
@@ -5265,6 +5283,7 @@ static int remoteDispatchNetworkIsPersis
 
     if (ret->persistent < 0) {
         remoteDispatchConnError(err, conn);
+        virNetworkFree(network);
         return -1;
     }
 
@@ -5291,6 +5310,7 @@ static int remoteDispatchStoragePoolIsAc
 
     if (ret->active < 0) {
         remoteDispatchConnError(err, conn);
+        virStoragePoolFree(pool);
         return -1;
     }
 
@@ -5317,6 +5337,7 @@ static int remoteDispatchStoragePoolIsPe
 
     if (ret->persistent < 0) {
         remoteDispatchConnError(err, conn);
+        virStoragePoolFree(pool);
         return -1;
     }
 
