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