[libvirt] PATCH: 5/25: Locking in remote driver

Daniel P. Berrange berrange at redhat.com
Tue Jan 13 17:40:18 UTC 2009


Adds locking in the remote driver. This obtains the lock on every single
API method. This is quite poor, not giving any parallelism - that will
be added in 2 patch's time, when we drop the lock while waiting on I/O

 remote_internal.c |  523 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 481 insertions(+), 42 deletions(-)

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 {
+    virMutex 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)
+{
+    virMutexLock(&driver->lock);
+}
+
+static void remoteDriverUnlock(struct private_data *driver)
+{
+    virMutexUnlock(&driver->lock);
+}
 
 static int call (virConnectPtr conn, struct private_data *priv,
                  int flags, int proc_nr,
@@ -829,6 +841,15 @@ remoteOpen (virConnectPtr conn,
         return VIR_DRV_OPEN_ERROR;
     }
 
+    if (virMutexInit(&priv->lock) < 0) {
+        error(conn, VIR_ERR_INTERNAL_ERROR,
+              _("cannot initialize mutex"));
+        VIR_FREE(priv);
+        return VIR_DRV_OPEN_ERROR;
+    }
+    remoteDriverLock(priv);
+    priv->localUses = 1;
+
     if (flags & VIR_CONNECT_RO)
         rflags |= VIR_DRV_OPEN_REMOTE_RO;
 
@@ -883,9 +904,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 +1263,20 @@ 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);
+        virMutexDestroy(&priv->lock);
+        VIR_FREE (priv);
+    }
+    if (priv)
+        remoteDriverUnlock(priv);
 
     return ret;
 }
@@ -1257,6 +1288,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 +1308,7 @@ remoteSupportsFeature (virConnectPtr con
     rv = ret.supported;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1293,6 +1327,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 +1345,7 @@ remoteType (virConnectPtr conn)
     rv = priv->type = ret.type;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1319,6 +1356,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 +1368,7 @@ remoteGetVersion (virConnectPtr conn, un
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1338,6 +1378,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 +1391,7 @@ remoteGetHostname (virConnectPtr conn)
     rv = ret.hostname;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1359,6 +1402,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 +1415,7 @@ remoteGetMaxVcpus (virConnectPtr conn, c
     rv = ret.max_vcpus;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1379,6 +1425,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 +1446,7 @@ remoteNodeGetInfo (virConnectPtr conn, v
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1407,6 +1456,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 +1469,7 @@ remoteGetCapabilities (virConnectPtr con
     rv = ret.capabilities;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1433,6 +1485,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 +1512,7 @@ remoteNodeGetCellsFreeMemory(virConnectP
     rv = ret.freeMems.freeMems_len;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1467,6 +1522,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 +1534,7 @@ remoteNodeGetFreeMemory (virConnectPtr c
     rv = ret.freeMem;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1489,6 +1547,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 +1580,7 @@ cleanup:
     xdr_free ((xdrproc_t) xdr_remote_list_domains_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1530,6 +1591,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 +1602,7 @@ remoteNumOfDomains (virConnectPtr conn)
     rv = ret.num;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1552,6 +1616,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 +1631,7 @@ remoteDomainCreateXML (virConnectPtr con
     xdr_free ((xdrproc_t) &xdr_remote_domain_create_xml_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return dom;
 }
 
@@ -1576,6 +1643,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 +1657,7 @@ remoteDomainLookupByID (virConnectPtr co
     xdr_free ((xdrproc_t) &xdr_remote_domain_lookup_by_id_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return dom;
 }
 
@@ -1599,6 +1669,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 +1683,7 @@ remoteDomainLookupByUUID (virConnectPtr 
     xdr_free ((xdrproc_t) &xdr_remote_domain_lookup_by_uuid_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return dom;
 }
 
@@ -1622,6 +1695,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 +1709,7 @@ remoteDomainLookupByName (virConnectPtr 
     xdr_free ((xdrproc_t) &xdr_remote_domain_lookup_by_name_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return dom;
 }
 
@@ -1643,6 +1719,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 +1732,7 @@ remoteDomainSuspend (virDomainPtr domain
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1663,6 +1742,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 +1755,7 @@ remoteDomainResume (virDomainPtr domain)
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1683,6 +1765,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 +1778,7 @@ remoteDomainShutdown (virDomainPtr domai
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1703,6 +1788,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 +1802,7 @@ remoteDomainReboot (virDomainPtr domain,
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1724,6 +1812,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 +1825,7 @@ remoteDomainDestroy (virDomainPtr domain
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1745,6 +1836,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 +1851,7 @@ remoteDomainGetOSType (virDomainPtr doma
     rv = ret.type;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1769,6 +1863,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 +1876,7 @@ remoteDomainGetMaxMemory (virDomainPtr d
     rv = ret.memory;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1789,6 +1886,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 +1900,7 @@ remoteDomainSetMaxMemory (virDomainPtr d
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1810,6 +1910,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 +1924,7 @@ remoteDomainSetMemory (virDomainPtr doma
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1832,6 +1935,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 +1955,7 @@ remoteDomainGetInfo (virDomainPtr domain
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1859,6 +1965,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 +1979,7 @@ remoteDomainSave (virDomainPtr domain, c
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1880,6 +1989,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 +2002,7 @@ remoteDomainRestore (virConnectPtr conn,
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1900,6 +2012,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 +2027,7 @@ remoteDomainCoreDump (virDomainPtr domai
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1922,6 +2037,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 +2051,7 @@ remoteDomainSetVcpus (virDomainPtr domai
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1947,6 +2065,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 +2087,7 @@ remoteDomainPinVcpu (virDomainPtr domain
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -1983,6 +2104,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 +2161,7 @@ cleanup:
     xdr_free ((xdrproc_t) xdr_remote_domain_get_vcpus_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2048,6 +2172,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 +2186,7 @@ remoteDomainGetMaxVcpus (virDomainPtr do
     rv = ret.num;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2070,6 +2197,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 +2213,7 @@ remoteDomainDumpXML (virDomainPtr domain
     rv = ret.xml;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2099,6 +2229,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 +2252,7 @@ remoteDomainMigratePrepare (virConnectPt
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2136,6 +2269,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 +2287,7 @@ remoteDomainMigratePerform (virDomainPtr
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2168,6 +2304,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 +2322,7 @@ remoteDomainMigrateFinish (virConnectPtr
     xdr_free ((xdrproc_t) &xdr_remote_domain_migrate_finish_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return ddom;
 }
 
@@ -2200,6 +2339,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 +2363,7 @@ remoteDomainMigratePrepare2 (virConnectP
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2239,6 +2381,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 +2400,7 @@ remoteDomainMigrateFinish2 (virConnectPt
     xdr_free ((xdrproc_t) &xdr_remote_domain_migrate_finish2_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return ddom;
 }
 
@@ -2267,6 +2412,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 +2450,7 @@ cleanup:
     xdr_free ((xdrproc_t) xdr_remote_list_defined_domains_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2313,6 +2461,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 +2472,7 @@ remoteNumOfDefinedDomains (virConnectPtr
     rv = ret.num;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2331,6 +2482,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 +2495,7 @@ remoteDomainCreate (virDomainPtr domain)
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2353,6 +2507,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 +2521,7 @@ remoteDomainDefineXML (virConnectPtr con
     xdr_free ((xdrproc_t) xdr_remote_domain_define_xml_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return dom;
 }
 
@@ -2374,6 +2531,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 +2544,7 @@ remoteDomainUndefine (virDomainPtr domai
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2394,6 +2554,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 +2568,7 @@ remoteDomainAttachDevice (virDomainPtr d
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2415,6 +2578,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 +2592,7 @@ remoteDomainDetachDevice (virDomainPtr d
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2437,6 +2603,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 +2618,7 @@ remoteDomainGetAutostart (virDomainPtr d
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2459,6 +2628,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 +2642,7 @@ remoteDomainSetAutostart (virDomainPtr d
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2481,6 +2653,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 +2670,7 @@ remoteDomainGetSchedulerType (virDomainP
     rv = ret.type;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2508,6 +2683,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 +2742,7 @@ cleanup:
     }
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2576,6 +2754,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 +2807,7 @@ remoteDomainSetSchedulerParameters (virD
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2638,6 +2819,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 +2841,7 @@ remoteDomainBlockStats (virDomainPtr dom
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2669,6 +2853,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 +2879,7 @@ remoteDomainInterfaceStats (virDomainPtr
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2709,6 +2896,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 +2932,7 @@ cleanup:
     free (ret.buffer.buffer_val);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2758,6 +2948,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 +2983,7 @@ cleanup:
     free (ret.buffer.buffer_val);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2807,11 +3000,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
@@ -2823,6 +3022,12 @@ remoteNetworkOpen (virConnectPtr conn,
         int ret, rflags = 0;
         if (VIR_ALLOC(priv) < 0) {
             error (conn, VIR_ERR_NO_MEMORY, _("struct private_data"));
+            return VIR_DRV_OPEN_ERROR;
+        }
+        if (virMutexInit(&priv->lock) < 0) {
+            error(conn, VIR_ERR_INTERNAL_ERROR,
+                  _("cannot initialize mutex"));
+            VIR_FREE(priv);
             return VIR_DRV_OPEN_ERROR;
         }
         if (flags & VIR_CONNECT_RO)
@@ -2848,14 +3053,17 @@ 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);
+        virMutexDestroy(&priv->lock);
+        VIR_FREE(priv);
+    }
+    if (priv)
+        remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2866,6 +3074,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 +3085,7 @@ remoteNumOfNetworks (virConnectPtr conn)
     rv = ret.num;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2886,6 +3097,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 +3135,7 @@ cleanup:
     xdr_free ((xdrproc_t) xdr_remote_list_networks_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2932,6 +3146,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 +3157,7 @@ remoteNumOfDefinedNetworks (virConnectPt
     rv = ret.num;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -2953,6 +3170,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 +3208,7 @@ cleanup:
     xdr_free ((xdrproc_t) xdr_remote_list_defined_networks_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3001,6 +3221,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 +3235,7 @@ remoteNetworkLookupByUUID (virConnectPtr
     xdr_free ((xdrproc_t) &xdr_remote_network_lookup_by_uuid_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return net;
 }
 
@@ -3025,6 +3248,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 +3262,7 @@ remoteNetworkLookupByName (virConnectPtr
     xdr_free ((xdrproc_t) &xdr_remote_network_lookup_by_name_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return net;
 }
 
@@ -3048,6 +3274,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 +3288,7 @@ remoteNetworkCreateXML (virConnectPtr co
     xdr_free ((xdrproc_t) &xdr_remote_network_create_xml_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return net;
 }
 
@@ -3071,6 +3300,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 +3314,7 @@ remoteNetworkDefineXML (virConnectPtr co
     xdr_free ((xdrproc_t) &xdr_remote_network_define_xml_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return net;
 }
 
@@ -3092,6 +3324,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 +3337,7 @@ remoteNetworkUndefine (virNetworkPtr net
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3112,6 +3347,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 +3360,7 @@ remoteNetworkCreate (virNetworkPtr netwo
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3132,6 +3370,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 +3383,7 @@ remoteNetworkDestroy (virNetworkPtr netw
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3153,6 +3394,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 +3410,7 @@ remoteNetworkDumpXML (virNetworkPtr netw
     rv = ret.xml;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3177,6 +3421,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 +3436,7 @@ remoteNetworkGetBridgeName (virNetworkPt
     rv = ret.name;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3200,6 +3447,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 +3463,7 @@ remoteNetworkGetAutostart (virNetworkPtr
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3223,6 +3473,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 +3487,7 @@ remoteNetworkSetAutostart (virNetworkPtr
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3254,16 +3507,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
@@ -3275,6 +3535,12 @@ remoteStorageOpen (virConnectPtr conn,
         int ret, rflags = 0;
         if (VIR_ALLOC(priv) < 0) {
             error (NULL, VIR_ERR_NO_MEMORY, _("struct private_data"));
+            return VIR_DRV_OPEN_ERROR;
+        }
+        if (virMutexInit(&priv->lock) < 0) {
+            error(conn, VIR_ERR_INTERNAL_ERROR,
+                  _("cannot initialize mutex"));
+            VIR_FREE(priv);
             return VIR_DRV_OPEN_ERROR;
         }
         if (flags & VIR_CONNECT_RO)
@@ -3300,14 +3566,17 @@ 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);
+        virMutexDestroy(&priv->lock);
+        VIR_FREE(priv);
+    }
+    if (priv)
+        remoteDriverUnlock(priv);
 
     return ret;
 }
@@ -3319,6 +3588,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 +3599,7 @@ remoteNumOfStoragePools (virConnectPtr c
     rv = ret.num;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3339,6 +3611,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 +3645,7 @@ cleanup:
     xdr_free ((xdrproc_t) xdr_remote_list_storage_pools_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3381,6 +3656,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 +3667,7 @@ remoteNumOfDefinedStoragePools (virConne
     rv = ret.num;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3402,6 +3680,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 +3714,7 @@ cleanup:
     xdr_free ((xdrproc_t) xdr_remote_list_defined_storage_pools_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3448,6 +3729,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 +3759,7 @@ remoteFindStoragePoolSources (virConnect
     xdr_free ((xdrproc_t) xdr_remote_find_storage_pool_sources_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3488,6 +3772,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 +3786,7 @@ remoteStoragePoolLookupByUUID (virConnec
     xdr_free ((xdrproc_t) &xdr_remote_storage_pool_lookup_by_uuid_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return pool;
 }
 
@@ -3512,6 +3799,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 +3813,7 @@ remoteStoragePoolLookupByName (virConnec
     xdr_free ((xdrproc_t) &xdr_remote_storage_pool_lookup_by_name_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return pool;
 }
 
@@ -3535,6 +3825,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 +3839,7 @@ remoteStoragePoolLookupByVolume (virStor
     xdr_free ((xdrproc_t) &xdr_remote_storage_pool_lookup_by_volume_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return pool;
 }
 
@@ -3559,6 +3852,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 +3867,7 @@ remoteStoragePoolCreateXML (virConnectPt
     xdr_free ((xdrproc_t) &xdr_remote_storage_pool_create_xml_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return pool;
 }
 
@@ -3583,6 +3879,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 +3894,7 @@ remoteStoragePoolDefineXML (virConnectPt
     xdr_free ((xdrproc_t) &xdr_remote_storage_pool_define_xml_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return pool;
 }
 
@@ -3605,6 +3904,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 +3917,7 @@ remoteStoragePoolUndefine (virStoragePoo
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3625,6 +3927,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 +3941,7 @@ remoteStoragePoolCreate (virStoragePoolP
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3648,6 +3953,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 +3966,7 @@ remoteStoragePoolBuild (virStoragePoolPt
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3668,6 +3976,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 +3989,7 @@ remoteStoragePoolDestroy (virStoragePool
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3690,6 +4001,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 +4014,7 @@ remoteStoragePoolDelete (virStoragePoolP
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3712,6 +4026,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 +4039,7 @@ remoteStoragePoolRefresh (virStoragePool
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3733,6 +4050,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 +4069,7 @@ remoteStoragePoolGetInfo (virStoragePool
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3761,6 +4081,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 +4097,7 @@ remoteStoragePoolDumpXML (virStoragePool
     rv = ret.xml;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3785,6 +4108,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 +4124,7 @@ remoteStoragePoolGetAutostart (virStorag
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3808,6 +4134,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 +4148,7 @@ remoteStoragePoolSetAutostart (virStorag
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3831,6 +4160,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 +4174,7 @@ remoteStoragePoolNumOfVolumes (virStorag
     rv = ret.num;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3854,6 +4186,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 +4221,7 @@ cleanup:
     xdr_free ((xdrproc_t) xdr_remote_storage_pool_list_volumes_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -3901,6 +4236,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 +4251,7 @@ remoteStorageVolLookupByName (virStorage
     xdr_free ((xdrproc_t) &xdr_remote_storage_vol_lookup_by_name_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return vol;
 }
 
@@ -3926,6 +4264,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 +4278,7 @@ remoteStorageVolLookupByKey (virConnectP
     xdr_free ((xdrproc_t) &xdr_remote_storage_vol_lookup_by_key_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return vol;
 }
 
@@ -3950,6 +4291,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 +4305,7 @@ remoteStorageVolLookupByPath (virConnect
     xdr_free ((xdrproc_t) &xdr_remote_storage_vol_lookup_by_path_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return vol;
 }
 
@@ -3974,6 +4318,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 +4334,7 @@ remoteStorageVolCreateXML (virStoragePoo
     xdr_free ((xdrproc_t) &xdr_remote_storage_vol_create_xml_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return vol;
 }
 
@@ -3999,6 +4346,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 +4359,7 @@ remoteStorageVolDelete (virStorageVolPtr
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -4021,6 +4371,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 +4388,7 @@ remoteStorageVolGetInfo (virStorageVolPt
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -4048,6 +4401,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 +4416,7 @@ remoteStorageVolDumpXML (virStorageVolPt
     rv = ret.xml;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -4072,6 +4428,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 +4442,7 @@ remoteStorageVolGetPath (virStorageVolPt
     rv = ret.name;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -4095,19 +4454,63 @@ 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;
+        }
+        if (virMutexInit(&priv->lock) < 0) {
+            error(conn, VIR_ERR_INTERNAL_ERROR,
+                  _("cannot initialize mutex"));
+            VIR_FREE(priv);
+            return VIR_DRV_OPEN_ERROR;
+        }
+        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 +4518,17 @@ 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);
+        virMutexDestroy(&priv->lock);
+        VIR_FREE(priv);
+    }
+    if (priv)
+        remoteDriverUnlock(priv);
     return ret;
 }
 
@@ -4135,6 +4541,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 +4555,7 @@ static int remoteNodeNumOfDevices(virCon
     rv = ret.num;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -4163,6 +4572,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 +4607,7 @@ cleanup:
     xdr_free ((xdrproc_t) xdr_remote_node_list_devices_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -4208,6 +4620,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 +4635,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 +4647,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 +4662,7 @@ static char *remoteNodeDeviceDumpXML(vir
     rv = ret.xml;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -4255,6 +4673,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 +4687,7 @@ static char *remoteNodeDeviceGetParent(v
     rv = ret.parent ? *ret.parent : NULL;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -4277,6 +4698,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 +4711,7 @@ static int remoteNodeDeviceNumOfCaps(vir
     rv = ret.num;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -4301,6 +4725,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 +4759,7 @@ cleanup:
     xdr_free ((xdrproc_t) xdr_remote_node_device_list_caps_ret, (char *) &ret);
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -5058,6 +5485,10 @@ static int remoteDomainEventRegister (vi
     int rv = -1;
     struct private_data *priv = conn->privateData;
 
+    remoteDriverLock(priv);
+
+    remoteDriverLock(priv);
+
     if (priv->eventFlushTimer < 0) {
          error (conn, VIR_ERR_NO_SUPPORT, _("no event support"));
          goto done;
@@ -5079,6 +5510,7 @@ static int remoteDomainEventRegister (vi
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -5105,6 +5537,7 @@ static int remoteDomainEventDeregister (
     rv = 0;
 
 done:
+    remoteDriverUnlock(priv);
     return rv;
 }
 
@@ -5895,6 +6328,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)) {
@@ -5951,7 +6386,7 @@ remoteDomainEventFired(int watch,
     }
 
 done:
-    return;
+    remoteDriverUnlock(priv);
 }
 
 void
@@ -5959,8 +6394,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