[libvirt] PATCH 3/5: make remote driver thread safe

Daniel P. Berrange berrange at redhat.com
Tue Dec 9 12:20:34 UTC 2008


This patch makes the remote driver's internal 'struct private_data'
object thread-safe. All the driver APIs will lock & unlock this data
before accessing it. I'm also doing full reference counting on it
now, because it will shortly be shareable across multiple virConnectPtr
objects once virConnetClone is introduced.

NB, although thread safe, it is not possible to parallelize API
calls. This is because the call() method which actually does the
RPC call will block on the socket read() waiting for the RPC
reply. It holds the lock while doing this. So all threads are 
blocked for the duration of an RPC call.

Safely lifting this restriction is in fact very very hard. I do have
a plan for this which I call 'passing the buck'. More details to 
follow in a later patch for this once I actually have it working...

Even then it won't be hugely useful since the libvirtd serializes
all RPC calls from a single socket. But it will allow for receiving
events promptly.

I have of course validated this locking with Ocaml/CIL

Daniel

diff --git a/src/remote_internal.c b/src/remote_internal.c
--- a/src/remote_internal.c
+++ b/src/remote_internal.c
@@ -89,6 +89,8 @@ static int inside_daemon = 0;
 static int inside_daemon = 0;
 
 struct private_data {
+    PTHREAD_MUTEX_T(lock);
+
     int sock;                   /* Socket. */
     int watch;                  /* File handle watch */
     pid_t pid;                  /* PID of tunnel process */
@@ -119,6 +121,16 @@ enum {
     REMOTE_CALL_QUIET_MISSING_RPC = 2,
 };
 
+
+static void remoteDriverLock(struct private_data *driver)
+{
+    pthread_mutex_lock(&driver->lock);
+}
+
+static void remoteDriverUnlock(struct private_data *driver)
+{
+    pthread_mutex_unlock(&driver->lock);
+}
 
 static int call (virConnectPtr conn, struct private_data *priv,
                  int flags, int proc_nr,
@@ -829,6 +841,10 @@ remoteOpen (virConnectPtr conn,
         return VIR_DRV_OPEN_ERROR;
     }
 
+    pthread_mutex_init(&priv->lock, NULL);
+    remoteDriverLock(priv);
+    priv->localUses = 1;
+
     if (flags & VIR_CONNECT_RO)
         rflags |= VIR_DRV_OPEN_REMOTE_RO;
 
@@ -883,9 +899,11 @@ remoteOpen (virConnectPtr conn,
     ret = doRemoteOpen(conn, priv, auth, rflags);
     if (ret != VIR_DRV_OPEN_SUCCESS) {
         conn->privateData = NULL;
+        remoteDriverUnlock(priv);
         VIR_FREE(priv);
     } else {
         conn->privateData = priv;
+        remoteDriverUnlock(priv);
     }
     return ret;
 }
@@ -1240,12 +1258,19 @@ static int
 static int
 remoteClose (virConnectPtr conn)
 {
-    int ret;
-    struct private_data *priv = conn->privateData;
-
-    ret = doRemoteClose(conn, priv);
-    VIR_FREE (priv);
-    conn->privateData = NULL;
+    int ret = 0;
+    struct private_data *priv = conn->privateData;
+
+    remoteDriverLock(priv);
+    priv->localUses--;
+    if (!priv->localUses) {
+        ret = doRemoteClose(conn, priv);
+        conn->privateData = NULL;
+        remoteDriverUnlock(priv);
+        VIR_FREE (priv);
+    }
+    if (priv)
+        remoteDriverUnlock(priv);
 
     return ret;
 }
@@ -1257,6 +1282,8 @@ remoteSupportsFeature (virConnectPtr con
     remote_supports_feature_args args;
     remote_supports_feature_ret ret;
     struct private_data *priv = conn->privateData;
+
+    remoteDriverLock(priv);
 
     /* VIR_DRV_FEATURE_REMOTE* features are handled directly. */
     if (feature == VIR_DRV_FEATURE_REMOTE) {
@@ -1275,6 +1302,7 @@ remoteSupportsFeature (virConnectPtr con
     rv = ret.supported;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1293,6 +1321,8 @@ remoteType (virConnectPtr conn)
     remote_get_type_ret ret;
     struct private_data *priv = conn->privateData;
 
+    remoteDriverLock(priv);
+
     /* Cached? */
     if (priv->type) {
         rv = priv->type;
@@ -1309,6 +1339,7 @@ remoteType (virConnectPtr conn)
     rv = priv->type = ret.type;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1319,6 +1350,8 @@ remoteGetVersion (virConnectPtr conn, un
     remote_get_version_ret ret;
     struct private_data *priv = conn->privateData;
 
+    remoteDriverLock(priv);
+
     memset (&ret, 0, sizeof ret);
     if (call (conn, priv, 0, REMOTE_PROC_GET_VERSION,
               (xdrproc_t) xdr_void, (char *) NULL,
@@ -1329,6 +1362,7 @@ remoteGetVersion (virConnectPtr conn, un
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1338,6 +1372,8 @@ remoteGetHostname (virConnectPtr conn)
     char *rv = NULL;
     remote_get_hostname_ret ret;
     struct private_data *priv = conn->privateData;
+
+    remoteDriverLock(priv);
 
     memset (&ret, 0, sizeof ret);
     if (call (conn, priv, 0, REMOTE_PROC_GET_HOSTNAME,
@@ -1349,6 +1385,7 @@ remoteGetHostname (virConnectPtr conn)
     rv = ret.hostname;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1359,6 +1396,8 @@ remoteGetMaxVcpus (virConnectPtr conn, c
     remote_get_max_vcpus_args args;
     remote_get_max_vcpus_ret ret;
     struct private_data *priv = conn->privateData;
+
+    remoteDriverLock(priv);
 
     memset (&ret, 0, sizeof ret);
     args.type = type == NULL ? NULL : (char **) &type;
@@ -1370,6 +1409,7 @@ remoteGetMaxVcpus (virConnectPtr conn, c
     rv = ret.max_vcpus;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1379,6 +1419,8 @@ remoteNodeGetInfo (virConnectPtr conn, v
     int rv = -1;
     remote_node_get_info_ret ret;
     struct private_data *priv = conn->privateData;
+
+    remoteDriverLock(priv);
 
     memset (&ret, 0, sizeof ret);
     if (call (conn, priv, 0, REMOTE_PROC_NODE_GET_INFO,
@@ -1398,6 +1440,7 @@ remoteNodeGetInfo (virConnectPtr conn, v
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1407,6 +1450,8 @@ remoteGetCapabilities (virConnectPtr con
     char *rv = NULL;
     remote_get_capabilities_ret ret;
     struct private_data *priv = conn->privateData;
+
+    remoteDriverLock(priv);
 
     memset (&ret, 0, sizeof ret);
     if (call (conn, priv, 0, REMOTE_PROC_GET_CAPABILITIES,
@@ -1418,6 +1463,7 @@ remoteGetCapabilities (virConnectPtr con
     rv = ret.capabilities;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1433,6 +1479,8 @@ remoteNodeGetCellsFreeMemory(virConnectP
     int i;
     struct private_data *priv = conn->privateData;
 
+    remoteDriverLock(priv);
+
     if (maxCells > REMOTE_NODE_MAX_CELLS) {
         errorf (conn, VIR_ERR_RPC,
                 _("too many NUMA cells: %d > %d"),
@@ -1458,6 +1506,7 @@ remoteNodeGetCellsFreeMemory(virConnectP
     rv = ret.freeMems.freeMems_len;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1467,6 +1516,8 @@ remoteNodeGetFreeMemory (virConnectPtr c
     unsigned long long rv = 0; /* 0 is error value this special function*/
     remote_node_get_free_memory_ret ret;
     struct private_data *priv = conn->privateData;
+
+    remoteDriverLock(priv);
 
     memset (&ret, 0, sizeof ret);
     if (call (conn, priv, 0, REMOTE_PROC_NODE_GET_FREE_MEMORY,
@@ -1477,6 +1528,7 @@ remoteNodeGetFreeMemory (virConnectPtr c
     rv = ret.freeMem;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1489,6 +1541,8 @@ remoteListDomains (virConnectPtr conn, i
     remote_list_domains_args args;
     remote_list_domains_ret ret;
     struct private_data *priv = conn->privateData;
+
+    remoteDriverLock(priv);
 
     if (maxids > REMOTE_DOMAIN_ID_LIST_MAX) {
         errorf (conn, VIR_ERR_RPC,
@@ -1520,6 +1574,7 @@ cleanup:
     xdr_free ((xdrproc_t) xdr_remote_list_domains_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1530,6 +1585,8 @@ remoteNumOfDomains (virConnectPtr conn)
     remote_num_of_domains_ret ret;
     struct private_data *priv = conn->privateData;
 
+    remoteDriverLock(priv);
+
     memset (&ret, 0, sizeof ret);
     if (call (conn, priv, 0, REMOTE_PROC_NUM_OF_DOMAINS,
               (xdrproc_t) xdr_void, (char *) NULL,
@@ -1539,6 +1596,7 @@ remoteNumOfDomains (virConnectPtr conn)
     rv = ret.num;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1552,6 +1610,8 @@ remoteDomainCreateXML (virConnectPtr con
     remote_domain_create_xml_ret ret;
     struct private_data *priv = conn->privateData;
 
+    remoteDriverLock(priv);
+
     args.xml_desc = (char *) xmlDesc;
     args.flags = flags;
 
@@ -1565,6 +1625,7 @@ remoteDomainCreateXML (virConnectPtr con
     xdr_free ((xdrproc_t) &xdr_remote_domain_create_xml_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return dom;
 }
 
@@ -1576,6 +1637,8 @@ remoteDomainLookupByID (virConnectPtr co
     remote_domain_lookup_by_id_ret ret;
     struct private_data *priv = conn->privateData;
 
+    remoteDriverLock(priv);
+
     args.id = id;
 
     memset (&ret, 0, sizeof ret);
@@ -1588,6 +1651,7 @@ remoteDomainLookupByID (virConnectPtr co
     xdr_free ((xdrproc_t) &xdr_remote_domain_lookup_by_id_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return dom;
 }
 
@@ -1599,6 +1663,8 @@ remoteDomainLookupByUUID (virConnectPtr 
     remote_domain_lookup_by_uuid_ret ret;
     struct private_data *priv = conn->privateData;
 
+    remoteDriverLock(priv);
+
     memcpy (args.uuid, uuid, VIR_UUID_BUFLEN);
 
     memset (&ret, 0, sizeof ret);
@@ -1611,6 +1677,7 @@ remoteDomainLookupByUUID (virConnectPtr 
     xdr_free ((xdrproc_t) &xdr_remote_domain_lookup_by_uuid_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return dom;
 }
 
@@ -1622,6 +1689,8 @@ remoteDomainLookupByName (virConnectPtr 
     remote_domain_lookup_by_name_ret ret;
     struct private_data *priv = conn->privateData;
 
+    remoteDriverLock(priv);
+
     args.name = (char *) name;
 
     memset (&ret, 0, sizeof ret);
@@ -1634,6 +1703,7 @@ remoteDomainLookupByName (virConnectPtr 
     xdr_free ((xdrproc_t) &xdr_remote_domain_lookup_by_name_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return dom;
 }
 
@@ -1643,6 +1713,8 @@ remoteDomainSuspend (virDomainPtr domain
     int rv = -1;
     remote_domain_suspend_args args;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
 
@@ -1654,6 +1726,7 @@ remoteDomainSuspend (virDomainPtr domain
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1663,6 +1736,8 @@ remoteDomainResume (virDomainPtr domain)
     int rv = -1;
     remote_domain_resume_args args;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
 
@@ -1674,6 +1749,7 @@ remoteDomainResume (virDomainPtr domain)
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1683,6 +1759,8 @@ remoteDomainShutdown (virDomainPtr domai
     int rv = -1;
     remote_domain_shutdown_args args;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
 
@@ -1694,6 +1772,7 @@ remoteDomainShutdown (virDomainPtr domai
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1703,6 +1782,8 @@ remoteDomainReboot (virDomainPtr domain,
     int rv = -1;
     remote_domain_reboot_args args;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
     args.flags = flags;
@@ -1715,6 +1796,7 @@ remoteDomainReboot (virDomainPtr domain,
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1724,6 +1806,8 @@ remoteDomainDestroy (virDomainPtr domain
     int rv = -1;
     remote_domain_destroy_args args;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
 
@@ -1735,6 +1819,7 @@ remoteDomainDestroy (virDomainPtr domain
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1745,6 +1830,8 @@ remoteDomainGetOSType (virDomainPtr doma
     remote_domain_get_os_type_args args;
     remote_domain_get_os_type_ret ret;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
 
@@ -1758,6 +1845,7 @@ remoteDomainGetOSType (virDomainPtr doma
     rv = ret.type;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1769,6 +1857,8 @@ remoteDomainGetMaxMemory (virDomainPtr d
     remote_domain_get_max_memory_ret ret;
     struct private_data *priv = domain->conn->privateData;
 
+    remoteDriverLock(priv);
+
     make_nonnull_domain (&args.dom, domain);
 
     memset (&ret, 0, sizeof ret);
@@ -1780,6 +1870,7 @@ remoteDomainGetMaxMemory (virDomainPtr d
     rv = ret.memory;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1789,6 +1880,8 @@ remoteDomainSetMaxMemory (virDomainPtr d
     int rv = -1;
     remote_domain_set_max_memory_args args;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
     args.memory = memory;
@@ -1801,6 +1894,7 @@ remoteDomainSetMaxMemory (virDomainPtr d
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1810,6 +1904,8 @@ remoteDomainSetMemory (virDomainPtr doma
     int rv = -1;
     remote_domain_set_memory_args args;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
     args.memory = memory;
@@ -1822,6 +1918,7 @@ remoteDomainSetMemory (virDomainPtr doma
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1832,6 +1929,8 @@ remoteDomainGetInfo (virDomainPtr domain
     remote_domain_get_info_args args;
     remote_domain_get_info_ret ret;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
 
@@ -1850,6 +1949,7 @@ remoteDomainGetInfo (virDomainPtr domain
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1859,6 +1959,8 @@ remoteDomainSave (virDomainPtr domain, c
     int rv = -1;
     remote_domain_save_args args;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
     args.to = (char *) to;
@@ -1871,6 +1973,7 @@ remoteDomainSave (virDomainPtr domain, c
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1880,6 +1983,8 @@ remoteDomainRestore (virConnectPtr conn,
     int rv = -1;
     remote_domain_restore_args args;
     struct private_data *priv = conn->privateData;
+
+    remoteDriverLock(priv);
 
     args.from = (char *) from;
 
@@ -1891,6 +1996,7 @@ remoteDomainRestore (virConnectPtr conn,
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1900,6 +2006,8 @@ remoteDomainCoreDump (virDomainPtr domai
     int rv = -1;
     remote_domain_core_dump_args args;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
     args.to = (char *) to;
@@ -1913,6 +2021,7 @@ remoteDomainCoreDump (virDomainPtr domai
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1922,6 +2031,8 @@ remoteDomainSetVcpus (virDomainPtr domai
     int rv = -1;
     remote_domain_set_vcpus_args args;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
     args.nvcpus = nvcpus;
@@ -1934,6 +2045,7 @@ remoteDomainSetVcpus (virDomainPtr domai
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1947,6 +2059,8 @@ remoteDomainPinVcpu (virDomainPtr domain
     remote_domain_pin_vcpu_args args;
     struct private_data *priv = domain->conn->privateData;
 
+    remoteDriverLock(priv);
+
     if (maplen > REMOTE_CPUMAP_MAX) {
         errorf (domain->conn, VIR_ERR_RPC,
                 _("map length greater than maximum: %d > %d"),
@@ -1967,6 +2081,7 @@ remoteDomainPinVcpu (virDomainPtr domain
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1983,6 +2098,8 @@ remoteDomainGetVcpus (virDomainPtr domai
     remote_domain_get_vcpus_ret ret;
     struct private_data *priv = domain->conn->privateData;
 
+    remoteDriverLock(priv);
+
     if (maxinfo > REMOTE_VCPUINFO_MAX) {
         errorf (domain->conn, VIR_ERR_RPC,
                 _("vCPU count exceeds maximum: %d > %d"),
@@ -2038,6 +2155,7 @@ cleanup:
     xdr_free ((xdrproc_t) xdr_remote_domain_get_vcpus_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2048,6 +2166,8 @@ remoteDomainGetMaxVcpus (virDomainPtr do
     remote_domain_get_max_vcpus_args args;
     remote_domain_get_max_vcpus_ret ret;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
 
@@ -2060,6 +2180,7 @@ remoteDomainGetMaxVcpus (virDomainPtr do
     rv = ret.num;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2070,6 +2191,8 @@ remoteDomainDumpXML (virDomainPtr domain
     remote_domain_dump_xml_args args;
     remote_domain_dump_xml_ret ret;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
     args.flags = flags;
@@ -2084,6 +2207,7 @@ remoteDomainDumpXML (virDomainPtr domain
     rv = ret.xml;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2099,6 +2223,8 @@ remoteDomainMigratePrepare (virConnectPt
     remote_domain_migrate_prepare_ret ret;
     struct private_data *priv = dconn->privateData;
 
+    remoteDriverLock(priv);
+
     args.uri_in = uri_in == NULL ? NULL : (char **) &uri_in;
     args.flags = flags;
     args.dname = dname == NULL ? NULL : (char **) &dname;
@@ -2120,6 +2246,7 @@ remoteDomainMigratePrepare (virConnectPt
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2136,6 +2263,8 @@ remoteDomainMigratePerform (virDomainPtr
     remote_domain_migrate_perform_args args;
     struct private_data *priv = domain->conn->privateData;
 
+    remoteDriverLock(priv);
+
     make_nonnull_domain (&args.dom, domain);
     args.cookie.cookie_len = cookielen;
     args.cookie.cookie_val = (char *) cookie;
@@ -2152,6 +2281,7 @@ remoteDomainMigratePerform (virDomainPtr
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2168,6 +2298,8 @@ remoteDomainMigrateFinish (virConnectPtr
     remote_domain_migrate_finish_ret ret;
     struct private_data *priv = dconn->privateData;
 
+    remoteDriverLock(priv);
+
     args.dname = (char *) dname;
     args.cookie.cookie_len = cookielen;
     args.cookie.cookie_val = (char *) cookie;
@@ -2184,6 +2316,7 @@ remoteDomainMigrateFinish (virConnectPtr
     xdr_free ((xdrproc_t) &xdr_remote_domain_migrate_finish_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return ddom;
 }
 
@@ -2200,6 +2333,8 @@ remoteDomainMigratePrepare2 (virConnectP
     remote_domain_migrate_prepare2_ret ret;
     struct private_data *priv = dconn->privateData;
 
+    remoteDriverLock(priv);
+
     args.uri_in = uri_in == NULL ? NULL : (char **) &uri_in;
     args.flags = flags;
     args.dname = dname == NULL ? NULL : (char **) &dname;
@@ -2222,6 +2357,7 @@ remoteDomainMigratePrepare2 (virConnectP
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2239,6 +2375,8 @@ remoteDomainMigrateFinish2 (virConnectPt
     remote_domain_migrate_finish2_ret ret;
     struct private_data *priv = dconn->privateData;
 
+    remoteDriverLock(priv);
+
     args.dname = (char *) dname;
     args.cookie.cookie_len = cookielen;
     args.cookie.cookie_val = (char *) cookie;
@@ -2256,6 +2394,7 @@ remoteDomainMigrateFinish2 (virConnectPt
     xdr_free ((xdrproc_t) &xdr_remote_domain_migrate_finish2_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return ddom;
 }
 
@@ -2267,6 +2406,8 @@ remoteListDefinedDomains (virConnectPtr 
     remote_list_defined_domains_args args;
     remote_list_defined_domains_ret ret;
     struct private_data *priv = conn->privateData;
+
+    remoteDriverLock(priv);
 
     if (maxnames > REMOTE_DOMAIN_NAME_LIST_MAX) {
         errorf (conn, VIR_ERR_RPC,
@@ -2303,6 +2444,7 @@ cleanup:
     xdr_free ((xdrproc_t) xdr_remote_list_defined_domains_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2313,6 +2455,8 @@ remoteNumOfDefinedDomains (virConnectPtr
     remote_num_of_defined_domains_ret ret;
     struct private_data *priv = conn->privateData;
 
+    remoteDriverLock(priv);
+
     memset (&ret, 0, sizeof ret);
     if (call (conn, priv, 0, REMOTE_PROC_NUM_OF_DEFINED_DOMAINS,
               (xdrproc_t) xdr_void, (char *) NULL,
@@ -2322,6 +2466,7 @@ remoteNumOfDefinedDomains (virConnectPtr
     rv = ret.num;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2331,6 +2476,8 @@ remoteDomainCreate (virDomainPtr domain)
     int rv = -1;
     remote_domain_create_args args;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
 
@@ -2342,6 +2489,7 @@ remoteDomainCreate (virDomainPtr domain)
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2353,6 +2501,8 @@ remoteDomainDefineXML (virConnectPtr con
     remote_domain_define_xml_ret ret;
     struct private_data *priv = conn->privateData;
 
+    remoteDriverLock(priv);
+
     args.xml = (char *) xml;
 
     memset (&ret, 0, sizeof ret);
@@ -2365,6 +2515,7 @@ remoteDomainDefineXML (virConnectPtr con
     xdr_free ((xdrproc_t) xdr_remote_domain_define_xml_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return dom;
 }
 
@@ -2374,6 +2525,8 @@ remoteDomainUndefine (virDomainPtr domai
     int rv = -1;
     remote_domain_undefine_args args;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
 
@@ -2385,6 +2538,7 @@ remoteDomainUndefine (virDomainPtr domai
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2394,6 +2548,8 @@ remoteDomainAttachDevice (virDomainPtr d
     int rv = -1;
     remote_domain_attach_device_args args;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
     args.xml = (char *) xml;
@@ -2406,6 +2562,7 @@ remoteDomainAttachDevice (virDomainPtr d
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2415,6 +2572,8 @@ remoteDomainDetachDevice (virDomainPtr d
     int rv = -1;
     remote_domain_detach_device_args args;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
     args.xml = (char *) xml;
@@ -2427,6 +2586,7 @@ remoteDomainDetachDevice (virDomainPtr d
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2437,6 +2597,8 @@ remoteDomainGetAutostart (virDomainPtr d
     remote_domain_get_autostart_args args;
     remote_domain_get_autostart_ret ret;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
 
@@ -2450,6 +2612,7 @@ remoteDomainGetAutostart (virDomainPtr d
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2459,6 +2622,8 @@ remoteDomainSetAutostart (virDomainPtr d
     int rv = -1;
     remote_domain_set_autostart_args args;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
     args.autostart = autostart;
@@ -2471,6 +2636,7 @@ remoteDomainSetAutostart (virDomainPtr d
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2481,6 +2647,8 @@ remoteDomainGetSchedulerType (virDomainP
     remote_domain_get_scheduler_type_args args;
     remote_domain_get_scheduler_type_ret ret;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
 
@@ -2496,6 +2664,7 @@ remoteDomainGetSchedulerType (virDomainP
     rv = ret.type;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2508,6 +2677,8 @@ remoteDomainGetSchedulerParameters (virD
     remote_domain_get_scheduler_parameters_ret ret;
     int i = -1;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
     args.nparams = *nparams;
@@ -2565,6 +2736,7 @@ cleanup:
     }
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2576,6 +2748,8 @@ remoteDomainSetSchedulerParameters (virD
     remote_domain_set_scheduler_parameters_args args;
     int i, do_error;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
 
@@ -2627,6 +2801,7 @@ remoteDomainSetSchedulerParameters (virD
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2638,6 +2813,8 @@ remoteDomainBlockStats (virDomainPtr dom
     remote_domain_block_stats_args args;
     remote_domain_block_stats_ret ret;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
     args.path = (char *) path;
@@ -2658,6 +2835,7 @@ remoteDomainBlockStats (virDomainPtr dom
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2669,6 +2847,8 @@ remoteDomainInterfaceStats (virDomainPtr
     remote_domain_interface_stats_args args;
     remote_domain_interface_stats_ret ret;
     struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_domain (&args.dom, domain);
     args.path = (char *) path;
@@ -2693,6 +2873,7 @@ remoteDomainInterfaceStats (virDomainPtr
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2709,6 +2890,8 @@ remoteDomainBlockPeek (virDomainPtr doma
     remote_domain_block_peek_ret ret;
     struct private_data *priv = domain->conn->privateData;
 
+    remoteDriverLock(priv);
+
     if (size > REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX) {
         errorf (domain->conn, VIR_ERR_RPC,
                 _("block peek request too large for remote protocol, %zi > %d"),
@@ -2743,6 +2926,7 @@ cleanup:
     free (ret.buffer.buffer_val);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2758,6 +2942,8 @@ remoteDomainMemoryPeek (virDomainPtr dom
     remote_domain_memory_peek_ret ret;
     struct private_data *priv = domain->conn->privateData;
 
+    remoteDriverLock(priv);
+
     if (size > REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX) {
         errorf (domain->conn, VIR_ERR_RPC,
                 _("memory peek request too large for remote protocol, %zi > %d"),
@@ -2791,6 +2977,7 @@ cleanup:
     free (ret.buffer.buffer_val);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2807,11 +2994,17 @@ remoteNetworkOpen (virConnectPtr conn,
     if (conn &&
         conn->driver &&
         STREQ (conn->driver->name, "remote")) {
-        /* If we're here, the remote driver is already
+        struct private_data *priv;
+
+       /* If we're here, the remote driver is already
          * in use due to a) a QEMU uri, or b) a remote
          * URI. So we can re-use existing connection
          */
-        conn->networkPrivateData = conn->privateData;
+        priv = conn->privateData;
+        remoteDriverLock(priv);
+        priv->localUses++;
+        conn->networkPrivateData = priv;
+        remoteDriverUnlock(priv);
         return VIR_DRV_OPEN_SUCCESS;
     } else {
         /* Using a non-remote driver, so we need to open a
@@ -2825,6 +3018,7 @@ remoteNetworkOpen (virConnectPtr conn,
             error (conn, VIR_ERR_NO_MEMORY, _("struct private_data"));
             return VIR_DRV_OPEN_ERROR;
         }
+        pthread_mutex_init(&priv->lock, NULL);
         if (flags & VIR_CONNECT_RO)
             rflags |= VIR_DRV_OPEN_REMOTE_RO;
         rflags |= VIR_DRV_OPEN_REMOTE_UNIX;
@@ -2848,14 +3042,16 @@ remoteNetworkClose (virConnectPtr conn)
     int rv = 0;
     struct private_data *priv = conn->networkPrivateData;
 
-    if (priv->localUses) {
-        priv->localUses--;
-        if (!priv->localUses) {
-            rv = doRemoteClose(conn, priv);
-            VIR_FREE(priv);
-            conn->networkPrivateData = NULL;
-        }
-    }
+    remoteDriverLock(priv);
+    priv->localUses--;
+    if (!priv->localUses) {
+        rv = doRemoteClose(conn, priv);
+        conn->networkPrivateData = NULL;
+        remoteDriverUnlock(priv);
+        VIR_FREE(priv);
+    }
+    if (priv)
+        remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2866,6 +3062,8 @@ remoteNumOfNetworks (virConnectPtr conn)
     remote_num_of_networks_ret ret;
     struct private_data *priv = conn->networkPrivateData;
 
+    remoteDriverLock(priv);
+
     memset (&ret, 0, sizeof ret);
     if (call (conn, priv, 0, REMOTE_PROC_NUM_OF_NETWORKS,
               (xdrproc_t) xdr_void, (char *) NULL,
@@ -2875,6 +3073,7 @@ remoteNumOfNetworks (virConnectPtr conn)
     rv = ret.num;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2886,6 +3085,8 @@ remoteListNetworks (virConnectPtr conn, 
     remote_list_networks_args args;
     remote_list_networks_ret ret;
     struct private_data *priv = conn->networkPrivateData;
+
+    remoteDriverLock(priv);
 
     if (maxnames > REMOTE_NETWORK_NAME_LIST_MAX) {
         errorf (conn, VIR_ERR_RPC,
@@ -2922,6 +3123,7 @@ cleanup:
     xdr_free ((xdrproc_t) xdr_remote_list_networks_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2932,6 +3134,8 @@ remoteNumOfDefinedNetworks (virConnectPt
     remote_num_of_defined_networks_ret ret;
     struct private_data *priv = conn->networkPrivateData;
 
+    remoteDriverLock(priv);
+
     memset (&ret, 0, sizeof ret);
     if (call (conn, priv, 0, REMOTE_PROC_NUM_OF_DEFINED_NETWORKS,
               (xdrproc_t) xdr_void, (char *) NULL,
@@ -2941,6 +3145,7 @@ remoteNumOfDefinedNetworks (virConnectPt
     rv = ret.num;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2953,6 +3158,8 @@ remoteListDefinedNetworks (virConnectPtr
     remote_list_defined_networks_args args;
     remote_list_defined_networks_ret ret;
     struct private_data *priv = conn->networkPrivateData;
+
+    remoteDriverLock(priv);
 
     if (maxnames > REMOTE_NETWORK_NAME_LIST_MAX) {
         errorf (conn, VIR_ERR_RPC,
@@ -2989,6 +3196,7 @@ cleanup:
     xdr_free ((xdrproc_t) xdr_remote_list_defined_networks_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3001,6 +3209,8 @@ remoteNetworkLookupByUUID (virConnectPtr
     remote_network_lookup_by_uuid_ret ret;
     struct private_data *priv = conn->networkPrivateData;
 
+    remoteDriverLock(priv);
+
     memcpy (args.uuid, uuid, VIR_UUID_BUFLEN);
 
     memset (&ret, 0, sizeof ret);
@@ -3013,6 +3223,7 @@ remoteNetworkLookupByUUID (virConnectPtr
     xdr_free ((xdrproc_t) &xdr_remote_network_lookup_by_uuid_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return net;
 }
 
@@ -3025,6 +3236,8 @@ remoteNetworkLookupByName (virConnectPtr
     remote_network_lookup_by_name_ret ret;
     struct private_data *priv = conn->networkPrivateData;
 
+    remoteDriverLock(priv);
+
     args.name = (char *) name;
 
     memset (&ret, 0, sizeof ret);
@@ -3037,6 +3250,7 @@ remoteNetworkLookupByName (virConnectPtr
     xdr_free ((xdrproc_t) &xdr_remote_network_lookup_by_name_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return net;
 }
 
@@ -3048,6 +3262,8 @@ remoteNetworkCreateXML (virConnectPtr co
     remote_network_create_xml_ret ret;
     struct private_data *priv = conn->networkPrivateData;
 
+    remoteDriverLock(priv);
+
     args.xml = (char *) xmlDesc;
 
     memset (&ret, 0, sizeof ret);
@@ -3060,6 +3276,7 @@ remoteNetworkCreateXML (virConnectPtr co
     xdr_free ((xdrproc_t) &xdr_remote_network_create_xml_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return net;
 }
 
@@ -3071,6 +3288,8 @@ remoteNetworkDefineXML (virConnectPtr co
     remote_network_define_xml_ret ret;
     struct private_data *priv = conn->networkPrivateData;
 
+    remoteDriverLock(priv);
+
     args.xml = (char *) xml;
 
     memset (&ret, 0, sizeof ret);
@@ -3083,6 +3302,7 @@ remoteNetworkDefineXML (virConnectPtr co
     xdr_free ((xdrproc_t) &xdr_remote_network_define_xml_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return net;
 }
 
@@ -3092,6 +3312,8 @@ remoteNetworkUndefine (virNetworkPtr net
     int rv = -1;
     remote_network_undefine_args args;
     struct private_data *priv = network->conn->networkPrivateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_network (&args.net, network);
 
@@ -3103,6 +3325,7 @@ remoteNetworkUndefine (virNetworkPtr net
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3112,6 +3335,8 @@ remoteNetworkCreate (virNetworkPtr netwo
     int rv = -1;
     remote_network_create_args args;
     struct private_data *priv = network->conn->networkPrivateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_network (&args.net, network);
 
@@ -3123,6 +3348,7 @@ remoteNetworkCreate (virNetworkPtr netwo
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3132,6 +3358,8 @@ remoteNetworkDestroy (virNetworkPtr netw
     int rv = -1;
     remote_network_destroy_args args;
     struct private_data *priv = network->conn->networkPrivateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_network (&args.net, network);
 
@@ -3143,6 +3371,7 @@ remoteNetworkDestroy (virNetworkPtr netw
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3153,6 +3382,8 @@ remoteNetworkDumpXML (virNetworkPtr netw
     remote_network_dump_xml_args args;
     remote_network_dump_xml_ret ret;
     struct private_data *priv = network->conn->networkPrivateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_network (&args.net, network);
     args.flags = flags;
@@ -3167,6 +3398,7 @@ remoteNetworkDumpXML (virNetworkPtr netw
     rv = ret.xml;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3177,6 +3409,8 @@ remoteNetworkGetBridgeName (virNetworkPt
     remote_network_get_bridge_name_args args;
     remote_network_get_bridge_name_ret ret;
     struct private_data *priv = network->conn->networkPrivateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_network (&args.net, network);
 
@@ -3190,6 +3424,7 @@ remoteNetworkGetBridgeName (virNetworkPt
     rv = ret.name;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3200,6 +3435,8 @@ remoteNetworkGetAutostart (virNetworkPtr
     remote_network_get_autostart_args args;
     remote_network_get_autostart_ret ret;
     struct private_data *priv = network->conn->networkPrivateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_network (&args.net, network);
 
@@ -3214,6 +3451,7 @@ remoteNetworkGetAutostart (virNetworkPtr
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3223,6 +3461,8 @@ remoteNetworkSetAutostart (virNetworkPtr
     int rv = -1;
     remote_network_set_autostart_args args;
     struct private_data *priv = network->conn->networkPrivateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_network (&args.net, network);
     args.autostart = autostart;
@@ -3235,6 +3475,7 @@ remoteNetworkSetAutostart (virNetworkPtr
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3254,16 +3495,23 @@ remoteStorageOpen (virConnectPtr conn,
     if (conn &&
         conn->driver &&
         STREQ (conn->driver->name, "remote")) {
+        struct private_data *priv = conn->privateData;
         /* If we're here, the remote driver is already
          * in use due to a) a QEMU uri, or b) a remote
          * URI. So we can re-use existing connection
          */
-        conn->storagePrivateData = conn->privateData;
+        remoteDriverLock(priv);
+        priv->localUses++;
+        conn->storagePrivateData = priv;
+        remoteDriverUnlock(priv);
         return VIR_DRV_OPEN_SUCCESS;
     } else if (conn->networkDriver &&
                STREQ (conn->networkDriver->name, "remote")) {
-        conn->storagePrivateData = conn->networkPrivateData;
-        ((struct private_data *)conn->storagePrivateData)->localUses++;
+        struct private_data *priv = conn->networkPrivateData;
+        remoteDriverLock(priv);
+        conn->storagePrivateData = priv;
+        priv->localUses++;
+        remoteDriverUnlock(priv);
         return VIR_DRV_OPEN_SUCCESS;
     } else {
         /* Using a non-remote driver, so we need to open a
@@ -3277,6 +3525,7 @@ remoteStorageOpen (virConnectPtr conn,
             error (NULL, VIR_ERR_NO_MEMORY, _("struct private_data"));
             return VIR_DRV_OPEN_ERROR;
         }
+        pthread_mutex_init(&priv->lock, NULL);
         if (flags & VIR_CONNECT_RO)
             rflags |= VIR_DRV_OPEN_REMOTE_RO;
         rflags |= VIR_DRV_OPEN_REMOTE_UNIX;
@@ -3300,14 +3549,16 @@ remoteStorageClose (virConnectPtr conn)
     int ret = 0;
     struct private_data *priv = conn->storagePrivateData;
 
-    if (priv->localUses) {
-        priv->localUses--;
-        if (!priv->localUses) {
-            ret = doRemoteClose(conn, priv);
-            VIR_FREE(priv);
-            conn->storagePrivateData = NULL;
-        }
-    }
+    remoteDriverLock(priv);
+    priv->localUses--;
+    if (!priv->localUses) {
+        ret = doRemoteClose(conn, priv);
+        conn->storagePrivateData = NULL;
+        remoteDriverUnlock(priv);
+        VIR_FREE(priv);
+    }
+    if (priv)
+        remoteDriverUnlock(priv);
 
     return ret;
 }
@@ -3319,6 +3570,8 @@ remoteNumOfStoragePools (virConnectPtr c
     remote_num_of_storage_pools_ret ret;
     struct private_data *priv = conn->storagePrivateData;
 
+    remoteDriverLock(priv);
+
     memset (&ret, 0, sizeof ret);
     if (call (conn, priv, 0, REMOTE_PROC_NUM_OF_STORAGE_POOLS,
               (xdrproc_t) xdr_void, (char *) NULL,
@@ -3328,6 +3581,7 @@ remoteNumOfStoragePools (virConnectPtr c
     rv = ret.num;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3339,6 +3593,8 @@ remoteListStoragePools (virConnectPtr co
     remote_list_storage_pools_args args;
     remote_list_storage_pools_ret ret;
     struct private_data *priv = conn->storagePrivateData;
+
+    remoteDriverLock(priv);
 
     if (maxnames > REMOTE_STORAGE_POOL_NAME_LIST_MAX) {
         error (conn, VIR_ERR_RPC, _("too many storage pools requested"));
@@ -3371,6 +3627,7 @@ cleanup:
     xdr_free ((xdrproc_t) xdr_remote_list_storage_pools_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3381,6 +3638,8 @@ remoteNumOfDefinedStoragePools (virConne
     remote_num_of_defined_storage_pools_ret ret;
     struct private_data *priv = conn->storagePrivateData;
 
+    remoteDriverLock(priv);
+
     memset (&ret, 0, sizeof ret);
     if (call (conn, priv, 0, REMOTE_PROC_NUM_OF_DEFINED_STORAGE_POOLS,
               (xdrproc_t) xdr_void, (char *) NULL,
@@ -3390,6 +3649,7 @@ remoteNumOfDefinedStoragePools (virConne
     rv = ret.num;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3402,6 +3662,8 @@ remoteListDefinedStoragePools (virConnec
     remote_list_defined_storage_pools_args args;
     remote_list_defined_storage_pools_ret ret;
     struct private_data *priv = conn->storagePrivateData;
+
+    remoteDriverLock(priv);
 
     if (maxnames > REMOTE_STORAGE_POOL_NAME_LIST_MAX) {
         error (conn, VIR_ERR_RPC, _("too many storage pools requested"));
@@ -3434,6 +3696,7 @@ cleanup:
     xdr_free ((xdrproc_t) xdr_remote_list_defined_storage_pools_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3448,6 +3711,8 @@ remoteFindStoragePoolSources (virConnect
     remote_find_storage_pool_sources_ret ret;
     struct private_data *priv = conn->storagePrivateData;
     const char *emptyString = "";
+
+    remoteDriverLock(priv);
 
     args.type = (char*)type;
     /*
@@ -3476,6 +3741,7 @@ remoteFindStoragePoolSources (virConnect
     xdr_free ((xdrproc_t) xdr_remote_find_storage_pool_sources_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3488,6 +3754,8 @@ remoteStoragePoolLookupByUUID (virConnec
     remote_storage_pool_lookup_by_uuid_ret ret;
     struct private_data *priv = conn->storagePrivateData;
 
+    remoteDriverLock(priv);
+
     memcpy (args.uuid, uuid, VIR_UUID_BUFLEN);
 
     memset (&ret, 0, sizeof ret);
@@ -3500,6 +3768,7 @@ remoteStoragePoolLookupByUUID (virConnec
     xdr_free ((xdrproc_t) &xdr_remote_storage_pool_lookup_by_uuid_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return pool;
 }
 
@@ -3512,6 +3781,8 @@ remoteStoragePoolLookupByName (virConnec
     remote_storage_pool_lookup_by_name_ret ret;
     struct private_data *priv = conn->storagePrivateData;
 
+    remoteDriverLock(priv);
+
     args.name = (char *) name;
 
     memset (&ret, 0, sizeof ret);
@@ -3524,6 +3795,7 @@ remoteStoragePoolLookupByName (virConnec
     xdr_free ((xdrproc_t) &xdr_remote_storage_pool_lookup_by_name_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return pool;
 }
 
@@ -3535,6 +3807,8 @@ remoteStoragePoolLookupByVolume (virStor
     remote_storage_pool_lookup_by_volume_ret ret;
     struct private_data *priv = vol->conn->storagePrivateData;
 
+    remoteDriverLock(priv);
+
     make_nonnull_storage_vol (&args.vol, vol);
 
     memset (&ret, 0, sizeof ret);
@@ -3547,6 +3821,7 @@ remoteStoragePoolLookupByVolume (virStor
     xdr_free ((xdrproc_t) &xdr_remote_storage_pool_lookup_by_volume_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return pool;
 }
 
@@ -3559,6 +3834,8 @@ remoteStoragePoolCreateXML (virConnectPt
     remote_storage_pool_create_xml_ret ret;
     struct private_data *priv = conn->storagePrivateData;
 
+    remoteDriverLock(priv);
+
     args.xml = (char *) xmlDesc;
     args.flags = flags;
 
@@ -3572,6 +3849,7 @@ remoteStoragePoolCreateXML (virConnectPt
     xdr_free ((xdrproc_t) &xdr_remote_storage_pool_create_xml_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return pool;
 }
 
@@ -3583,6 +3861,8 @@ remoteStoragePoolDefineXML (virConnectPt
     remote_storage_pool_define_xml_ret ret;
     struct private_data *priv = conn->storagePrivateData;
 
+    remoteDriverLock(priv);
+
     args.xml = (char *) xml;
     args.flags = flags;
 
@@ -3596,6 +3876,7 @@ remoteStoragePoolDefineXML (virConnectPt
     xdr_free ((xdrproc_t) &xdr_remote_storage_pool_define_xml_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return pool;
 }
 
@@ -3605,6 +3886,8 @@ remoteStoragePoolUndefine (virStoragePoo
     int rv = -1;
     remote_storage_pool_undefine_args args;
     struct private_data *priv = pool->conn->storagePrivateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_storage_pool (&args.pool, pool);
 
@@ -3616,6 +3899,7 @@ remoteStoragePoolUndefine (virStoragePoo
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3625,6 +3909,8 @@ remoteStoragePoolCreate (virStoragePoolP
     int rv = -1;
     remote_storage_pool_create_args args;
     struct private_data *priv = pool->conn->storagePrivateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_storage_pool (&args.pool, pool);
     args.flags = flags;
@@ -3637,6 +3923,7 @@ remoteStoragePoolCreate (virStoragePoolP
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3648,6 +3935,8 @@ remoteStoragePoolBuild (virStoragePoolPt
     remote_storage_pool_build_args args;
     struct private_data *priv = pool->conn->storagePrivateData;
 
+    remoteDriverLock(priv);
+
     make_nonnull_storage_pool (&args.pool, pool);
     args.flags = flags;
 
@@ -3659,6 +3948,7 @@ remoteStoragePoolBuild (virStoragePoolPt
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3668,6 +3958,8 @@ remoteStoragePoolDestroy (virStoragePool
     int rv = -1;
     remote_storage_pool_destroy_args args;
     struct private_data *priv = pool->conn->storagePrivateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_storage_pool (&args.pool, pool);
 
@@ -3679,6 +3971,7 @@ remoteStoragePoolDestroy (virStoragePool
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3690,6 +3983,8 @@ remoteStoragePoolDelete (virStoragePoolP
     remote_storage_pool_delete_args args;
     struct private_data *priv = pool->conn->storagePrivateData;
 
+    remoteDriverLock(priv);
+
     make_nonnull_storage_pool (&args.pool, pool);
     args.flags = flags;
 
@@ -3701,6 +3996,7 @@ remoteStoragePoolDelete (virStoragePoolP
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3712,6 +4008,8 @@ remoteStoragePoolRefresh (virStoragePool
     remote_storage_pool_refresh_args args;
     struct private_data *priv = pool->conn->storagePrivateData;
 
+    remoteDriverLock(priv);
+
     make_nonnull_storage_pool (&args.pool, pool);
     args.flags = flags;
 
@@ -3723,6 +4021,7 @@ remoteStoragePoolRefresh (virStoragePool
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3733,6 +4032,8 @@ remoteStoragePoolGetInfo (virStoragePool
     remote_storage_pool_get_info_args args;
     remote_storage_pool_get_info_ret ret;
     struct private_data *priv = pool->conn->storagePrivateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_storage_pool (&args.pool, pool);
 
@@ -3750,6 +4051,7 @@ remoteStoragePoolGetInfo (virStoragePool
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3761,6 +4063,8 @@ remoteStoragePoolDumpXML (virStoragePool
     remote_storage_pool_dump_xml_args args;
     remote_storage_pool_dump_xml_ret ret;
     struct private_data *priv = pool->conn->storagePrivateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_storage_pool (&args.pool, pool);
     args.flags = flags;
@@ -3775,6 +4079,7 @@ remoteStoragePoolDumpXML (virStoragePool
     rv = ret.xml;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3785,6 +4090,8 @@ remoteStoragePoolGetAutostart (virStorag
     remote_storage_pool_get_autostart_args args;
     remote_storage_pool_get_autostart_ret ret;
     struct private_data *priv = pool->conn->storagePrivateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_storage_pool (&args.pool, pool);
 
@@ -3799,6 +4106,7 @@ remoteStoragePoolGetAutostart (virStorag
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3808,6 +4116,8 @@ remoteStoragePoolSetAutostart (virStorag
     int rv = -1;
     remote_storage_pool_set_autostart_args args;
     struct private_data *priv = pool->conn->storagePrivateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_storage_pool (&args.pool, pool);
     args.autostart = autostart;
@@ -3820,6 +4130,7 @@ remoteStoragePoolSetAutostart (virStorag
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3831,6 +4142,8 @@ remoteStoragePoolNumOfVolumes (virStorag
     remote_storage_pool_num_of_volumes_args args;
     remote_storage_pool_num_of_volumes_ret ret;
     struct private_data *priv = pool->conn->storagePrivateData;
+
+    remoteDriverLock(priv);
 
     make_nonnull_storage_pool(&args.pool, pool);
 
@@ -3843,6 +4156,7 @@ remoteStoragePoolNumOfVolumes (virStorag
     rv = ret.num;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3854,6 +4168,8 @@ remoteStoragePoolListVolumes (virStorage
     remote_storage_pool_list_volumes_args args;
     remote_storage_pool_list_volumes_ret ret;
     struct private_data *priv = pool->conn->storagePrivateData;
+
+    remoteDriverLock(priv);
 
     if (maxnames > REMOTE_STORAGE_VOL_NAME_LIST_MAX) {
         error (pool->conn, VIR_ERR_RPC, _("too many storage volumes requested"));
@@ -3887,6 +4203,7 @@ cleanup:
     xdr_free ((xdrproc_t) xdr_remote_storage_pool_list_volumes_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3901,6 +4218,8 @@ remoteStorageVolLookupByName (virStorage
     remote_storage_vol_lookup_by_name_ret ret;
     struct private_data *priv = pool->conn->storagePrivateData;
 
+    remoteDriverLock(priv);
+
     make_nonnull_storage_pool(&args.pool, pool);
     args.name = (char *) name;
 
@@ -3914,6 +4233,7 @@ remoteStorageVolLookupByName (virStorage
     xdr_free ((xdrproc_t) &xdr_remote_storage_vol_lookup_by_name_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return vol;
 }
 
@@ -3926,6 +4246,8 @@ remoteStorageVolLookupByKey (virConnectP
     remote_storage_vol_lookup_by_key_ret ret;
     struct private_data *priv = conn->storagePrivateData;
 
+    remoteDriverLock(priv);
+
     args.key = (char *) key;
 
     memset (&ret, 0, sizeof ret);
@@ -3938,6 +4260,7 @@ remoteStorageVolLookupByKey (virConnectP
     xdr_free ((xdrproc_t) &xdr_remote_storage_vol_lookup_by_key_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return vol;
 }
 
@@ -3950,6 +4273,8 @@ remoteStorageVolLookupByPath (virConnect
     remote_storage_vol_lookup_by_path_ret ret;
     struct private_data *priv = conn->storagePrivateData;
 
+    remoteDriverLock(priv);
+
     args.path = (char *) path;
 
     memset (&ret, 0, sizeof ret);
@@ -3962,6 +4287,7 @@ remoteStorageVolLookupByPath (virConnect
     xdr_free ((xdrproc_t) &xdr_remote_storage_vol_lookup_by_path_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return vol;
 }
 
@@ -3974,6 +4300,8 @@ remoteStorageVolCreateXML (virStoragePoo
     remote_storage_vol_create_xml_ret ret;
     struct private_data *priv = pool->conn->storagePrivateData;
 
+    remoteDriverLock(priv);
+
     make_nonnull_storage_pool (&args.pool, pool);
     args.xml = (char *) xmlDesc;
     args.flags = flags;
@@ -3988,6 +4316,7 @@ remoteStorageVolCreateXML (virStoragePoo
     xdr_free ((xdrproc_t) &xdr_remote_storage_vol_create_xml_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return vol;
 }
 
@@ -3999,6 +4328,8 @@ remoteStorageVolDelete (virStorageVolPtr
     remote_storage_vol_delete_args args;
     struct private_data *priv = vol->conn->storagePrivateData;
 
+    remoteDriverLock(priv);
+
     make_nonnull_storage_vol (&args.vol, vol);
     args.flags = flags;
 
@@ -4010,6 +4341,7 @@ remoteStorageVolDelete (virStorageVolPtr
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -4021,6 +4353,8 @@ remoteStorageVolGetInfo (virStorageVolPt
     remote_storage_vol_get_info_ret ret;
     struct private_data *priv = vol->conn->storagePrivateData;
 
+    remoteDriverLock(priv);
+
     make_nonnull_storage_vol (&args.vol, vol);
 
     memset (&ret, 0, sizeof ret);
@@ -4036,6 +4370,7 @@ remoteStorageVolGetInfo (virStorageVolPt
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -4048,6 +4383,8 @@ remoteStorageVolDumpXML (virStorageVolPt
     remote_storage_vol_dump_xml_ret ret;
     struct private_data *priv = vol->conn->storagePrivateData;
 
+    remoteDriverLock(priv);
+
     make_nonnull_storage_vol (&args.vol, vol);
     args.flags = flags;
 
@@ -4061,6 +4398,7 @@ remoteStorageVolDumpXML (virStorageVolPt
     rv = ret.xml;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -4072,6 +4410,8 @@ remoteStorageVolGetPath (virStorageVolPt
     remote_storage_vol_get_path_ret ret;
     struct private_data *priv = vol->conn->storagePrivateData;
 
+    remoteDriverLock(priv);
+
     make_nonnull_storage_vol (&args.vol, vol);
 
     memset (&ret, 0, sizeof ret);
@@ -4084,6 +4424,7 @@ remoteStorageVolGetPath (virStorageVolPt
     rv = ret.name;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -4095,19 +4436,58 @@ remoteDevMonOpen(virConnectPtr conn,
                  virConnectAuthPtr auth ATTRIBUTE_UNUSED,
                  int flags ATTRIBUTE_UNUSED)
 {
+    if (inside_daemon)
+        return VIR_DRV_OPEN_DECLINED;
+
     if (conn &&
         conn->driver &&
         STREQ (conn->driver->name, "remote")) {
+        struct private_data *priv = conn->privateData;
         /* If we're here, the remote driver is already
          * in use due to a) a QEMU uri, or b) a remote
          * URI. So we can re-use existing connection
          */
-        conn->devMonPrivateData = conn->privateData;
+        remoteDriverLock(priv);
+        priv->localUses++;
+        conn->devMonPrivateData = priv;
+        remoteDriverUnlock(priv);
         return VIR_DRV_OPEN_SUCCESS;
-    }
-
-    /* Decline open.  Will fallback to appropriate local node driver. */
-    return VIR_DRV_OPEN_DECLINED;
+    } else if (conn->networkDriver &&
+               STREQ (conn->networkDriver->name, "remote")) {
+        struct private_data *priv = conn->networkPrivateData;
+        remoteDriverLock(priv);
+        conn->devMonPrivateData = priv;
+        priv->localUses++;
+        remoteDriverUnlock(priv);
+        return VIR_DRV_OPEN_SUCCESS;
+    } else {
+        /* Using a non-remote driver, so we need to open a
+         * new connection for network APIs, forcing it to
+         * use the UNIX transport. This handles Xen driver
+         * which doesn't have its own impl of the network APIs.
+         */
+        struct private_data *priv;
+        int ret, rflags = 0;
+        if (VIR_ALLOC(priv) < 0) {
+            error (NULL, VIR_ERR_NO_MEMORY, _("struct private_data"));
+            return VIR_DRV_OPEN_ERROR;
+        }
+        pthread_mutex_init(&priv->lock, NULL);
+        if (flags & VIR_CONNECT_RO)
+            rflags |= VIR_DRV_OPEN_REMOTE_RO;
+        rflags |= VIR_DRV_OPEN_REMOTE_UNIX;
+
+        priv->sock = -1;
+        ret = doRemoteOpen(conn, priv, auth, rflags);
+        if (ret != VIR_DRV_OPEN_SUCCESS) {
+            conn->devMonPrivateData = NULL;
+            VIR_FREE(priv);
+        } else {
+            priv->localUses = 1;
+            conn->devMonPrivateData = priv;
+        }
+        return ret;
+    }
 }
 
 static int remoteDevMonClose(virConnectPtr conn)
@@ -4115,14 +4495,16 @@ static int remoteDevMonClose(virConnectP
     int ret = 0;
     struct private_data *priv = conn->devMonPrivateData;
 
-    if (priv->localUses) {
-        priv->localUses--;
-        if (!priv->localUses) {
-            ret = doRemoteClose(conn, priv);
-            VIR_FREE(priv);
-            conn->devMonPrivateData = NULL;
-        }
-    }
+    remoteDriverLock(priv);
+    priv->localUses--;
+    if (!priv->localUses) {
+        ret = doRemoteClose(conn, priv);
+        conn->devMonPrivateData = NULL;
+        remoteDriverUnlock(priv);
+        VIR_FREE(priv);
+    }
+    if (priv)
+        remoteDriverUnlock(priv);
     return ret;
 }
 
@@ -4135,6 +4517,8 @@ static int remoteNodeNumOfDevices(virCon
     remote_node_num_of_devices_ret ret;
     struct private_data *priv = conn->devMonPrivateData;
 
+    remoteDriverLock(priv);
+
     args.cap = cap ? (char **)&cap : NULL;
     args.flags = flags;
 
@@ -4147,6 +4531,7 @@ static int remoteNodeNumOfDevices(virCon
     rv = ret.num;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -4163,6 +4548,8 @@ static int remoteNodeListDevices(virConn
     remote_node_list_devices_ret ret;
     struct private_data *priv = conn->devMonPrivateData;
 
+    remoteDriverLock(priv);
+
     if (maxnames > REMOTE_NODE_DEVICE_NAME_LIST_MAX) {
         error (conn, VIR_ERR_RPC, _("too many device names requested"));
         goto done;
@@ -4196,6 +4583,7 @@ cleanup:
     xdr_free ((xdrproc_t) xdr_remote_node_list_devices_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -4208,6 +4596,8 @@ static virNodeDevicePtr remoteNodeDevice
     virNodeDevicePtr dev = NULL;
     struct private_data *priv = conn->devMonPrivateData;
 
+    remoteDriverLock(priv);
+
     args.name = (char *)name;
 
     memset (&ret, 0, sizeof ret);
@@ -4221,6 +4611,7 @@ static virNodeDevicePtr remoteNodeDevice
     xdr_free ((xdrproc_t) xdr_remote_node_device_lookup_by_name_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return dev;
 }
 
@@ -4232,6 +4623,8 @@ static char *remoteNodeDeviceDumpXML(vir
     remote_node_device_dump_xml_ret ret;
     struct private_data *priv = dev->conn->devMonPrivateData;
 
+    remoteDriverLock(priv);
+
     args.name = dev->name;
     args.flags = flags;
 
@@ -4245,6 +4638,7 @@ static char *remoteNodeDeviceDumpXML(vir
     rv = ret.xml;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -4255,6 +4649,8 @@ static char *remoteNodeDeviceGetParent(v
     remote_node_device_get_parent_ret ret;
     struct private_data *priv = dev->conn->devMonPrivateData;
 
+    remoteDriverLock(priv);
+
     args.name = dev->name;
 
     memset (&ret, 0, sizeof ret);
@@ -4267,6 +4663,7 @@ static char *remoteNodeDeviceGetParent(v
     rv = ret.parent ? *ret.parent : NULL;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -4277,6 +4674,8 @@ static int remoteNodeDeviceNumOfCaps(vir
     remote_node_device_num_of_caps_ret ret;
     struct private_data *priv = dev->conn->devMonPrivateData;
 
+    remoteDriverLock(priv);
+
     args.name = dev->name;
 
     memset (&ret, 0, sizeof ret);
@@ -4288,6 +4687,7 @@ static int remoteNodeDeviceNumOfCaps(vir
     rv = ret.num;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -4301,6 +4701,8 @@ static int remoteNodeDeviceListCaps(virN
     remote_node_device_list_caps_ret ret;
     struct private_data *priv = dev->conn->devMonPrivateData;
 
+    remoteDriverLock(priv);
+
     if (maxnames > REMOTE_NODE_DEVICE_CAPS_LIST_MAX) {
         error (dev->conn, VIR_ERR_RPC, _("too many capability names requested"));
         goto done;
@@ -4333,6 +4735,7 @@ cleanup:
     xdr_free ((xdrproc_t) xdr_remote_node_device_list_caps_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -5058,6 +5461,8 @@ static int remoteDomainEventRegister (vi
     int rv = -1;
     struct private_data *priv = conn->privateData;
 
+    remoteDriverLock(priv);
+
     if (priv->eventFlushTimer < 0) {
          error (conn, VIR_ERR_NO_SUPPORT, _("no event support"));
          goto done;
@@ -5079,6 +5484,7 @@ static int remoteDomainEventRegister (vi
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -5087,6 +5493,8 @@ static int remoteDomainEventDeregister (
 {
     int rv = -1;
     struct private_data *priv = conn->privateData;
+
+    remoteDriverLock(priv);
 
     if (virDomainEventCallbackListRemove(conn, priv->callbackList,
                                          callback) < 0) {
@@ -5105,6 +5513,7 @@ static int remoteDomainEventDeregister (
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -5897,6 +6306,8 @@ remoteDomainEventFired(int watch,
     virConnectPtr        conn = opaque;
     struct private_data *priv = conn->privateData;
 
+    remoteDriverLock(priv);
+
     DEBUG("Event fired %d %d %d %X", watch, fd, event, event);
 
     if (event & (VIR_EVENT_HANDLE_HANGUP | VIR_EVENT_HANDLE_ERROR)) {
@@ -5953,7 +6364,7 @@ remoteDomainEventFired(int watch,
     }
 
 done:
-    return;
+    remoteDriverUnlock(priv);
 }
 
 void
@@ -5961,8 +6372,12 @@ remoteDomainEventQueueFlush(int timer AT
 {
     virConnectPtr conn = opaque;
     struct private_data *priv = conn->privateData;
+
+    remoteDriverLock(priv);
 
     virDomainEventQueueDispatch(priv->domainEvents, priv->callbackList,
                                 virDomainEventDispatchDefaultFunc, NULL);
     virEventUpdateTimeout(priv->eventFlushTimer, -1);
-}
+
+    remoteDriverUnlock(priv);
+}

-- 
|: 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 :|




More information about the libvir-list mailing list