diff --git a/ChangeLog b/ChangeLog index 1d10a595b9..03e3e50247 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Tue Jan 20 11:28:53 GMT 2009 Daniel P. Berrange + + * src/remote_internal.c: Add locking to all public API entry + points + Mon Jan 19 22:50:53 CET 2009 Guido Günther daemonize qemu processes diff --git a/src/remote_internal.c b/src/remote_internal.c index 163d34eae3..24cf241060 100644 --- a/src/remote_internal.c +++ b/src/remote_internal.c @@ -89,6 +89,8 @@ 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 */ @@ -120,6 +122,16 @@ enum { }; +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, xdrproc_t args_filter, char *args, @@ -830,6 +842,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; @@ -884,9 +905,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; } @@ -1241,12 +1264,20 @@ doRemoteClose (virConnectPtr conn, struct private_data *priv) static int remoteClose (virConnectPtr conn) { - int ret; + int ret = 0; struct private_data *priv = conn->privateData; - ret = doRemoteClose(conn, priv); - VIR_FREE (priv); - conn->privateData = NULL; + 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; } @@ -1259,6 +1290,8 @@ remoteSupportsFeature (virConnectPtr conn, int feature) 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) { rv = 1; @@ -1276,6 +1309,7 @@ remoteSupportsFeature (virConnectPtr conn, int feature) rv = ret.supported; done: + remoteDriverUnlock(priv); return rv; } @@ -1294,6 +1328,8 @@ remoteType (virConnectPtr conn) remote_get_type_ret ret; struct private_data *priv = conn->privateData; + remoteDriverLock(priv); + /* Cached? */ if (priv->type) { rv = priv->type; @@ -1310,6 +1346,7 @@ remoteType (virConnectPtr conn) rv = priv->type = ret.type; done: + remoteDriverUnlock(priv); return rv; } @@ -1320,6 +1357,8 @@ remoteGetVersion (virConnectPtr conn, unsigned long *hvVer) 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, @@ -1330,6 +1369,7 @@ remoteGetVersion (virConnectPtr conn, unsigned long *hvVer) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1340,6 +1380,8 @@ remoteGetHostname (virConnectPtr conn) 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, (xdrproc_t) xdr_void, (char *) NULL, @@ -1350,6 +1392,7 @@ remoteGetHostname (virConnectPtr conn) rv = ret.hostname; done: + remoteDriverUnlock(priv); return rv; } @@ -1361,6 +1404,8 @@ remoteGetMaxVcpus (virConnectPtr conn, const char *type) 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; if (call (conn, priv, 0, REMOTE_PROC_GET_MAX_VCPUS, @@ -1371,6 +1416,7 @@ remoteGetMaxVcpus (virConnectPtr conn, const char *type) rv = ret.max_vcpus; done: + remoteDriverUnlock(priv); return rv; } @@ -1381,6 +1427,8 @@ remoteNodeGetInfo (virConnectPtr conn, virNodeInfoPtr info) 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, (xdrproc_t) xdr_void, (char *) NULL, @@ -1399,6 +1447,7 @@ remoteNodeGetInfo (virConnectPtr conn, virNodeInfoPtr info) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1409,6 +1458,8 @@ remoteGetCapabilities (virConnectPtr conn) 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, (xdrproc_t) xdr_void, (char *) NULL, @@ -1419,6 +1470,7 @@ remoteGetCapabilities (virConnectPtr conn) rv = ret.capabilities; done: + remoteDriverUnlock(priv); return rv; } @@ -1434,6 +1486,8 @@ remoteNodeGetCellsFreeMemory(virConnectPtr conn, 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"), @@ -1459,6 +1513,7 @@ remoteNodeGetCellsFreeMemory(virConnectPtr conn, rv = ret.freeMems.freeMems_len; done: + remoteDriverUnlock(priv); return rv; } @@ -1469,6 +1524,8 @@ remoteNodeGetFreeMemory (virConnectPtr conn) 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, (xdrproc_t) xdr_void, NULL, @@ -1478,6 +1535,7 @@ remoteNodeGetFreeMemory (virConnectPtr conn) rv = ret.freeMem; done: + remoteDriverUnlock(priv); return rv; } @@ -1491,6 +1549,8 @@ remoteListDomains (virConnectPtr conn, int *ids, int maxids) 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, _("too many remote domain IDs: %d > %d"), @@ -1521,6 +1581,7 @@ cleanup: xdr_free ((xdrproc_t) xdr_remote_list_domains_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return rv; } @@ -1531,6 +1592,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, @@ -1540,6 +1603,7 @@ remoteNumOfDomains (virConnectPtr conn) rv = ret.num; done: + remoteDriverUnlock(priv); return rv; } @@ -1553,6 +1617,8 @@ remoteDomainCreateXML (virConnectPtr conn, remote_domain_create_xml_ret ret; struct private_data *priv = conn->privateData; + remoteDriverLock(priv); + args.xml_desc = (char *) xmlDesc; args.flags = flags; @@ -1566,6 +1632,7 @@ remoteDomainCreateXML (virConnectPtr conn, xdr_free ((xdrproc_t) &xdr_remote_domain_create_xml_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return dom; } @@ -1577,6 +1644,8 @@ remoteDomainLookupByID (virConnectPtr conn, int id) remote_domain_lookup_by_id_ret ret; struct private_data *priv = conn->privateData; + remoteDriverLock(priv); + args.id = id; memset (&ret, 0, sizeof ret); @@ -1589,6 +1658,7 @@ remoteDomainLookupByID (virConnectPtr conn, int id) xdr_free ((xdrproc_t) &xdr_remote_domain_lookup_by_id_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return dom; } @@ -1600,6 +1670,8 @@ remoteDomainLookupByUUID (virConnectPtr conn, const unsigned char *uuid) 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); @@ -1612,6 +1684,7 @@ remoteDomainLookupByUUID (virConnectPtr conn, const unsigned char *uuid) xdr_free ((xdrproc_t) &xdr_remote_domain_lookup_by_uuid_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return dom; } @@ -1623,6 +1696,8 @@ remoteDomainLookupByName (virConnectPtr conn, const char *name) remote_domain_lookup_by_name_ret ret; struct private_data *priv = conn->privateData; + remoteDriverLock(priv); + args.name = (char *) name; memset (&ret, 0, sizeof ret); @@ -1635,6 +1710,7 @@ remoteDomainLookupByName (virConnectPtr conn, const char *name) xdr_free ((xdrproc_t) &xdr_remote_domain_lookup_by_name_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return dom; } @@ -1645,6 +1721,8 @@ remoteDomainSuspend (virDomainPtr domain) remote_domain_suspend_args args; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + make_nonnull_domain (&args.dom, domain); if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_SUSPEND, @@ -1655,6 +1733,7 @@ remoteDomainSuspend (virDomainPtr domain) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1665,6 +1744,8 @@ remoteDomainResume (virDomainPtr domain) remote_domain_resume_args args; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + make_nonnull_domain (&args.dom, domain); if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_RESUME, @@ -1675,6 +1756,7 @@ remoteDomainResume (virDomainPtr domain) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1685,6 +1767,8 @@ remoteDomainShutdown (virDomainPtr domain) remote_domain_shutdown_args args; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + make_nonnull_domain (&args.dom, domain); if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_SHUTDOWN, @@ -1695,6 +1779,7 @@ remoteDomainShutdown (virDomainPtr domain) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1705,6 +1790,8 @@ remoteDomainReboot (virDomainPtr domain, unsigned int flags) remote_domain_reboot_args args; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + make_nonnull_domain (&args.dom, domain); args.flags = flags; @@ -1716,6 +1803,7 @@ remoteDomainReboot (virDomainPtr domain, unsigned int flags) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1726,6 +1814,8 @@ remoteDomainDestroy (virDomainPtr domain) remote_domain_destroy_args args; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + make_nonnull_domain (&args.dom, domain); if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_DESTROY, @@ -1736,6 +1826,7 @@ remoteDomainDestroy (virDomainPtr domain) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1747,6 +1838,8 @@ remoteDomainGetOSType (virDomainPtr domain) remote_domain_get_os_type_ret ret; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + make_nonnull_domain (&args.dom, domain); memset (&ret, 0, sizeof ret); @@ -1759,6 +1852,7 @@ remoteDomainGetOSType (virDomainPtr domain) rv = ret.type; done: + remoteDriverUnlock(priv); return rv; } @@ -1770,6 +1864,8 @@ remoteDomainGetMaxMemory (virDomainPtr domain) 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); @@ -1781,6 +1877,7 @@ remoteDomainGetMaxMemory (virDomainPtr domain) rv = ret.memory; done: + remoteDriverUnlock(priv); return rv; } @@ -1791,6 +1888,8 @@ remoteDomainSetMaxMemory (virDomainPtr domain, unsigned long memory) 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; @@ -1802,6 +1901,7 @@ remoteDomainSetMaxMemory (virDomainPtr domain, unsigned long memory) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1812,6 +1912,8 @@ remoteDomainSetMemory (virDomainPtr domain, unsigned long memory) remote_domain_set_memory_args args; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + make_nonnull_domain (&args.dom, domain); args.memory = memory; @@ -1823,6 +1925,7 @@ remoteDomainSetMemory (virDomainPtr domain, unsigned long memory) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1834,6 +1937,8 @@ remoteDomainGetInfo (virDomainPtr domain, virDomainInfoPtr info) remote_domain_get_info_ret ret; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + make_nonnull_domain (&args.dom, domain); memset (&ret, 0, sizeof ret); @@ -1851,6 +1956,7 @@ remoteDomainGetInfo (virDomainPtr domain, virDomainInfoPtr info) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1861,6 +1967,8 @@ remoteDomainSave (virDomainPtr domain, const char *to) remote_domain_save_args args; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + make_nonnull_domain (&args.dom, domain); args.to = (char *) to; @@ -1872,6 +1980,7 @@ remoteDomainSave (virDomainPtr domain, const char *to) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1882,6 +1991,8 @@ remoteDomainRestore (virConnectPtr conn, const char *from) remote_domain_restore_args args; struct private_data *priv = conn->privateData; + remoteDriverLock(priv); + args.from = (char *) from; if (call (conn, priv, 0, REMOTE_PROC_DOMAIN_RESTORE, @@ -1892,6 +2003,7 @@ remoteDomainRestore (virConnectPtr conn, const char *from) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1902,6 +2014,8 @@ remoteDomainCoreDump (virDomainPtr domain, const char *to, int flags) 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; args.flags = flags; @@ -1914,6 +2028,7 @@ remoteDomainCoreDump (virDomainPtr domain, const char *to, int flags) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1924,6 +2039,8 @@ remoteDomainSetVcpus (virDomainPtr domain, unsigned int nvcpus) remote_domain_set_vcpus_args args; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + make_nonnull_domain (&args.dom, domain); args.nvcpus = nvcpus; @@ -1935,6 +2052,7 @@ remoteDomainSetVcpus (virDomainPtr domain, unsigned int nvcpus) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1948,6 +2066,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"), @@ -1968,6 +2088,7 @@ remoteDomainPinVcpu (virDomainPtr domain, rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1984,6 +2105,8 @@ remoteDomainGetVcpus (virDomainPtr domain, 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"), @@ -2039,6 +2162,7 @@ cleanup: xdr_free ((xdrproc_t) xdr_remote_domain_get_vcpus_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return rv; } @@ -2050,6 +2174,8 @@ remoteDomainGetMaxVcpus (virDomainPtr domain) remote_domain_get_max_vcpus_ret ret; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + make_nonnull_domain (&args.dom, domain); memset (&ret, 0, sizeof ret); @@ -2061,6 +2187,7 @@ remoteDomainGetMaxVcpus (virDomainPtr domain) rv = ret.num; done: + remoteDriverUnlock(priv); return rv; } @@ -2072,6 +2199,8 @@ remoteDomainDumpXML (virDomainPtr domain, int flags) remote_domain_dump_xml_ret ret; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + make_nonnull_domain (&args.dom, domain); args.flags = flags; @@ -2085,6 +2214,7 @@ remoteDomainDumpXML (virDomainPtr domain, int flags) rv = ret.xml; done: + remoteDriverUnlock(priv); return rv; } @@ -2100,6 +2230,8 @@ remoteDomainMigratePrepare (virConnectPtr dconn, 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; @@ -2121,6 +2253,7 @@ remoteDomainMigratePrepare (virConnectPtr dconn, rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -2137,6 +2270,8 @@ remoteDomainMigratePerform (virDomainPtr domain, 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; @@ -2153,6 +2288,7 @@ remoteDomainMigratePerform (virDomainPtr domain, rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -2169,6 +2305,8 @@ remoteDomainMigrateFinish (virConnectPtr dconn, 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; @@ -2185,6 +2323,7 @@ remoteDomainMigrateFinish (virConnectPtr dconn, xdr_free ((xdrproc_t) &xdr_remote_domain_migrate_finish_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return ddom; } @@ -2201,6 +2340,8 @@ remoteDomainMigratePrepare2 (virConnectPtr dconn, 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; @@ -2223,6 +2364,7 @@ remoteDomainMigratePrepare2 (virConnectPtr dconn, rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -2240,6 +2382,8 @@ remoteDomainMigrateFinish2 (virConnectPtr dconn, 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; @@ -2257,6 +2401,7 @@ remoteDomainMigrateFinish2 (virConnectPtr dconn, xdr_free ((xdrproc_t) &xdr_remote_domain_migrate_finish2_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return ddom; } @@ -2269,6 +2414,8 @@ remoteListDefinedDomains (virConnectPtr conn, char **const names, int maxnames) 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, _("too many remote domain names: %d > %d"), @@ -2304,6 +2451,7 @@ cleanup: xdr_free ((xdrproc_t) xdr_remote_list_defined_domains_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return rv; } @@ -2314,6 +2462,8 @@ remoteNumOfDefinedDomains (virConnectPtr conn) 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, @@ -2323,6 +2473,7 @@ remoteNumOfDefinedDomains (virConnectPtr conn) rv = ret.num; done: + remoteDriverUnlock(priv); return rv; } @@ -2333,6 +2484,8 @@ remoteDomainCreate (virDomainPtr domain) remote_domain_create_args args; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + make_nonnull_domain (&args.dom, domain); if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_CREATE, @@ -2343,6 +2496,7 @@ remoteDomainCreate (virDomainPtr domain) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -2354,6 +2508,8 @@ remoteDomainDefineXML (virConnectPtr conn, const char *xml) remote_domain_define_xml_ret ret; struct private_data *priv = conn->privateData; + remoteDriverLock(priv); + args.xml = (char *) xml; memset (&ret, 0, sizeof ret); @@ -2366,6 +2522,7 @@ remoteDomainDefineXML (virConnectPtr conn, const char *xml) xdr_free ((xdrproc_t) xdr_remote_domain_define_xml_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return dom; } @@ -2376,6 +2533,8 @@ remoteDomainUndefine (virDomainPtr domain) remote_domain_undefine_args args; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + make_nonnull_domain (&args.dom, domain); if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_UNDEFINE, @@ -2386,6 +2545,7 @@ remoteDomainUndefine (virDomainPtr domain) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -2396,6 +2556,8 @@ remoteDomainAttachDevice (virDomainPtr domain, const char *xml) 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; @@ -2407,6 +2569,7 @@ remoteDomainAttachDevice (virDomainPtr domain, const char *xml) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -2417,6 +2580,8 @@ remoteDomainDetachDevice (virDomainPtr domain, const char *xml) 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; @@ -2428,6 +2593,7 @@ remoteDomainDetachDevice (virDomainPtr domain, const char *xml) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -2439,6 +2605,8 @@ remoteDomainGetAutostart (virDomainPtr domain, int *autostart) remote_domain_get_autostart_ret ret; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + make_nonnull_domain (&args.dom, domain); memset (&ret, 0, sizeof ret); @@ -2451,6 +2619,7 @@ remoteDomainGetAutostart (virDomainPtr domain, int *autostart) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -2461,6 +2630,8 @@ remoteDomainSetAutostart (virDomainPtr domain, int autostart) remote_domain_set_autostart_args args; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + make_nonnull_domain (&args.dom, domain); args.autostart = autostart; @@ -2472,6 +2643,7 @@ remoteDomainSetAutostart (virDomainPtr domain, int autostart) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -2483,6 +2655,8 @@ remoteDomainGetSchedulerType (virDomainPtr domain, int *nparams) remote_domain_get_scheduler_type_ret ret; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + make_nonnull_domain (&args.dom, domain); memset (&ret, 0, sizeof ret); @@ -2497,6 +2671,7 @@ remoteDomainGetSchedulerType (virDomainPtr domain, int *nparams) rv = ret.type; done: + remoteDriverUnlock(priv); return rv; } @@ -2510,6 +2685,8 @@ remoteDomainGetSchedulerParameters (virDomainPtr domain, int i = -1; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + make_nonnull_domain (&args.dom, domain); args.nparams = *nparams; @@ -2561,6 +2738,7 @@ remoteDomainGetSchedulerParameters (virDomainPtr domain, cleanup: xdr_free ((xdrproc_t) xdr_remote_domain_get_scheduler_parameters_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return rv; } @@ -2573,6 +2751,8 @@ remoteDomainSetSchedulerParameters (virDomainPtr domain, int i, do_error; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + make_nonnull_domain (&args.dom, domain); /* Serialise the scheduler parameters. */ @@ -2623,6 +2803,7 @@ remoteDomainSetSchedulerParameters (virDomainPtr domain, rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -2635,6 +2816,8 @@ remoteDomainBlockStats (virDomainPtr domain, const char *path, 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; @@ -2654,6 +2837,7 @@ remoteDomainBlockStats (virDomainPtr domain, const char *path, rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -2666,6 +2850,8 @@ remoteDomainInterfaceStats (virDomainPtr domain, const char *path, 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; @@ -2689,6 +2875,7 @@ remoteDomainInterfaceStats (virDomainPtr domain, const char *path, rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -2705,6 +2892,8 @@ remoteDomainBlockPeek (virDomainPtr domain, 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"), @@ -2739,6 +2928,7 @@ cleanup: free (ret.buffer.buffer_val); done: + remoteDriverUnlock(priv); return rv; } @@ -2754,6 +2944,8 @@ remoteDomainMemoryPeek (virDomainPtr domain, 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"), @@ -2787,6 +2979,7 @@ cleanup: free (ret.buffer.buffer_val); done: + remoteDriverUnlock(priv); return rv; } @@ -2803,11 +2996,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 @@ -2821,6 +3020,12 @@ remoteNetworkOpen (virConnectPtr conn, 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) rflags |= VIR_DRV_OPEN_REMOTE_RO; rflags |= VIR_DRV_OPEN_REMOTE_UNIX; @@ -2844,14 +3049,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; } @@ -2862,6 +3070,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, @@ -2871,6 +3081,7 @@ remoteNumOfNetworks (virConnectPtr conn) rv = ret.num; done: + remoteDriverUnlock(priv); return rv; } @@ -2883,6 +3094,8 @@ remoteListNetworks (virConnectPtr conn, char **const names, int maxnames) 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, _("too many remote networks: %d > %d"), @@ -2918,6 +3131,7 @@ cleanup: xdr_free ((xdrproc_t) xdr_remote_list_networks_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return rv; } @@ -2928,6 +3142,8 @@ remoteNumOfDefinedNetworks (virConnectPtr conn) 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, @@ -2937,6 +3153,7 @@ remoteNumOfDefinedNetworks (virConnectPtr conn) rv = ret.num; done: + remoteDriverUnlock(priv); return rv; } @@ -2950,6 +3167,8 @@ remoteListDefinedNetworks (virConnectPtr conn, 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, _("too many remote networks: %d > %d"), @@ -2985,6 +3204,7 @@ cleanup: xdr_free ((xdrproc_t) xdr_remote_list_defined_networks_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return rv; } @@ -2997,6 +3217,8 @@ remoteNetworkLookupByUUID (virConnectPtr conn, 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); @@ -3009,6 +3231,7 @@ remoteNetworkLookupByUUID (virConnectPtr conn, xdr_free ((xdrproc_t) &xdr_remote_network_lookup_by_uuid_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return net; } @@ -3021,6 +3244,8 @@ remoteNetworkLookupByName (virConnectPtr conn, remote_network_lookup_by_name_ret ret; struct private_data *priv = conn->networkPrivateData; + remoteDriverLock(priv); + args.name = (char *) name; memset (&ret, 0, sizeof ret); @@ -3033,6 +3258,7 @@ remoteNetworkLookupByName (virConnectPtr conn, xdr_free ((xdrproc_t) &xdr_remote_network_lookup_by_name_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return net; } @@ -3044,6 +3270,8 @@ remoteNetworkCreateXML (virConnectPtr conn, const char *xmlDesc) remote_network_create_xml_ret ret; struct private_data *priv = conn->networkPrivateData; + remoteDriverLock(priv); + args.xml = (char *) xmlDesc; memset (&ret, 0, sizeof ret); @@ -3056,6 +3284,7 @@ remoteNetworkCreateXML (virConnectPtr conn, const char *xmlDesc) xdr_free ((xdrproc_t) &xdr_remote_network_create_xml_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return net; } @@ -3067,6 +3296,8 @@ remoteNetworkDefineXML (virConnectPtr conn, const char *xml) remote_network_define_xml_ret ret; struct private_data *priv = conn->networkPrivateData; + remoteDriverLock(priv); + args.xml = (char *) xml; memset (&ret, 0, sizeof ret); @@ -3079,6 +3310,7 @@ remoteNetworkDefineXML (virConnectPtr conn, const char *xml) xdr_free ((xdrproc_t) &xdr_remote_network_define_xml_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return net; } @@ -3089,6 +3321,8 @@ remoteNetworkUndefine (virNetworkPtr network) remote_network_undefine_args args; struct private_data *priv = network->conn->networkPrivateData; + remoteDriverLock(priv); + make_nonnull_network (&args.net, network); if (call (network->conn, priv, 0, REMOTE_PROC_NETWORK_UNDEFINE, @@ -3099,6 +3333,7 @@ remoteNetworkUndefine (virNetworkPtr network) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3109,6 +3344,8 @@ remoteNetworkCreate (virNetworkPtr network) remote_network_create_args args; struct private_data *priv = network->conn->networkPrivateData; + remoteDriverLock(priv); + make_nonnull_network (&args.net, network); if (call (network->conn, priv, 0, REMOTE_PROC_NETWORK_CREATE, @@ -3119,6 +3356,7 @@ remoteNetworkCreate (virNetworkPtr network) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3129,6 +3367,8 @@ remoteNetworkDestroy (virNetworkPtr network) remote_network_destroy_args args; struct private_data *priv = network->conn->networkPrivateData; + remoteDriverLock(priv); + make_nonnull_network (&args.net, network); if (call (network->conn, priv, 0, REMOTE_PROC_NETWORK_DESTROY, @@ -3139,6 +3379,7 @@ remoteNetworkDestroy (virNetworkPtr network) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3150,6 +3391,8 @@ remoteNetworkDumpXML (virNetworkPtr network, int flags) remote_network_dump_xml_ret ret; struct private_data *priv = network->conn->networkPrivateData; + remoteDriverLock(priv); + make_nonnull_network (&args.net, network); args.flags = flags; @@ -3163,6 +3406,7 @@ remoteNetworkDumpXML (virNetworkPtr network, int flags) rv = ret.xml; done: + remoteDriverUnlock(priv); return rv; } @@ -3174,6 +3418,8 @@ remoteNetworkGetBridgeName (virNetworkPtr network) remote_network_get_bridge_name_ret ret; struct private_data *priv = network->conn->networkPrivateData; + remoteDriverLock(priv); + make_nonnull_network (&args.net, network); memset (&ret, 0, sizeof ret); @@ -3186,6 +3432,7 @@ remoteNetworkGetBridgeName (virNetworkPtr network) rv = ret.name; done: + remoteDriverUnlock(priv); return rv; } @@ -3197,6 +3444,8 @@ remoteNetworkGetAutostart (virNetworkPtr network, int *autostart) remote_network_get_autostart_ret ret; struct private_data *priv = network->conn->networkPrivateData; + remoteDriverLock(priv); + make_nonnull_network (&args.net, network); memset (&ret, 0, sizeof ret); @@ -3210,6 +3459,7 @@ remoteNetworkGetAutostart (virNetworkPtr network, int *autostart) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3220,6 +3470,8 @@ remoteNetworkSetAutostart (virNetworkPtr network, int autostart) remote_network_set_autostart_args args; struct private_data *priv = network->conn->networkPrivateData; + remoteDriverLock(priv); + make_nonnull_network (&args.net, network); args.autostart = autostart; @@ -3231,6 +3483,7 @@ remoteNetworkSetAutostart (virNetworkPtr network, int autostart) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3250,16 +3503,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 @@ -3273,6 +3533,12 @@ remoteStorageOpen (virConnectPtr conn, 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; @@ -3296,14 +3562,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; } @@ -3315,6 +3584,8 @@ remoteNumOfStoragePools (virConnectPtr conn) 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, @@ -3324,6 +3595,7 @@ remoteNumOfStoragePools (virConnectPtr conn) rv = ret.num; done: + remoteDriverUnlock(priv); return rv; } @@ -3336,6 +3608,8 @@ remoteListStoragePools (virConnectPtr conn, char **const names, int maxnames) 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")); goto done; @@ -3367,6 +3641,7 @@ cleanup: xdr_free ((xdrproc_t) xdr_remote_list_storage_pools_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return rv; } @@ -3377,6 +3652,8 @@ remoteNumOfDefinedStoragePools (virConnectPtr conn) 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, @@ -3386,6 +3663,7 @@ remoteNumOfDefinedStoragePools (virConnectPtr conn) rv = ret.num; done: + remoteDriverUnlock(priv); return rv; } @@ -3399,6 +3677,8 @@ remoteListDefinedStoragePools (virConnectPtr conn, 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")); goto done; @@ -3430,6 +3710,7 @@ cleanup: xdr_free ((xdrproc_t) xdr_remote_list_defined_storage_pools_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return rv; } @@ -3445,6 +3726,8 @@ remoteFindStoragePoolSources (virConnectPtr conn, struct private_data *priv = conn->storagePrivateData; const char *emptyString = ""; + remoteDriverLock(priv); + args.type = (char*)type; /* * I'd think the following would work here: @@ -3472,6 +3755,7 @@ remoteFindStoragePoolSources (virConnectPtr conn, xdr_free ((xdrproc_t) xdr_remote_find_storage_pool_sources_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return rv; } @@ -3484,6 +3768,8 @@ remoteStoragePoolLookupByUUID (virConnectPtr conn, 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); @@ -3496,6 +3782,7 @@ remoteStoragePoolLookupByUUID (virConnectPtr conn, xdr_free ((xdrproc_t) &xdr_remote_storage_pool_lookup_by_uuid_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return pool; } @@ -3508,6 +3795,8 @@ remoteStoragePoolLookupByName (virConnectPtr conn, 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); @@ -3520,6 +3809,7 @@ remoteStoragePoolLookupByName (virConnectPtr conn, xdr_free ((xdrproc_t) &xdr_remote_storage_pool_lookup_by_name_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return pool; } @@ -3531,6 +3821,8 @@ remoteStoragePoolLookupByVolume (virStorageVolPtr vol) 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); @@ -3543,6 +3835,7 @@ remoteStoragePoolLookupByVolume (virStorageVolPtr vol) xdr_free ((xdrproc_t) &xdr_remote_storage_pool_lookup_by_volume_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return pool; } @@ -3555,6 +3848,8 @@ remoteStoragePoolCreateXML (virConnectPtr conn, const char *xmlDesc, unsigned in remote_storage_pool_create_xml_ret ret; struct private_data *priv = conn->storagePrivateData; + remoteDriverLock(priv); + args.xml = (char *) xmlDesc; args.flags = flags; @@ -3568,6 +3863,7 @@ remoteStoragePoolCreateXML (virConnectPtr conn, const char *xmlDesc, unsigned in xdr_free ((xdrproc_t) &xdr_remote_storage_pool_create_xml_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return pool; } @@ -3579,6 +3875,8 @@ remoteStoragePoolDefineXML (virConnectPtr conn, const char *xml, unsigned int fl remote_storage_pool_define_xml_ret ret; struct private_data *priv = conn->storagePrivateData; + remoteDriverLock(priv); + args.xml = (char *) xml; args.flags = flags; @@ -3592,6 +3890,7 @@ remoteStoragePoolDefineXML (virConnectPtr conn, const char *xml, unsigned int fl xdr_free ((xdrproc_t) &xdr_remote_storage_pool_define_xml_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return pool; } @@ -3602,6 +3901,8 @@ remoteStoragePoolUndefine (virStoragePoolPtr pool) remote_storage_pool_undefine_args args; struct private_data *priv = pool->conn->storagePrivateData; + remoteDriverLock(priv); + make_nonnull_storage_pool (&args.pool, pool); if (call (pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_UNDEFINE, @@ -3612,6 +3913,7 @@ remoteStoragePoolUndefine (virStoragePoolPtr pool) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3622,6 +3924,8 @@ remoteStoragePoolCreate (virStoragePoolPtr pool, unsigned int flags) 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; @@ -3633,6 +3937,7 @@ remoteStoragePoolCreate (virStoragePoolPtr pool, unsigned int flags) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3644,6 +3949,8 @@ remoteStoragePoolBuild (virStoragePoolPtr pool, 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; @@ -3655,6 +3962,7 @@ remoteStoragePoolBuild (virStoragePoolPtr pool, rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3665,6 +3973,8 @@ remoteStoragePoolDestroy (virStoragePoolPtr pool) remote_storage_pool_destroy_args args; struct private_data *priv = pool->conn->storagePrivateData; + remoteDriverLock(priv); + make_nonnull_storage_pool (&args.pool, pool); if (call (pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_DESTROY, @@ -3675,6 +3985,7 @@ remoteStoragePoolDestroy (virStoragePoolPtr pool) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3686,6 +3997,8 @@ remoteStoragePoolDelete (virStoragePoolPtr pool, 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; @@ -3697,6 +4010,7 @@ remoteStoragePoolDelete (virStoragePoolPtr pool, rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3708,6 +4022,8 @@ remoteStoragePoolRefresh (virStoragePoolPtr pool, 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; @@ -3719,6 +4035,7 @@ remoteStoragePoolRefresh (virStoragePoolPtr pool, rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3730,6 +4047,8 @@ remoteStoragePoolGetInfo (virStoragePoolPtr pool, virStoragePoolInfoPtr info) remote_storage_pool_get_info_ret ret; struct private_data *priv = pool->conn->storagePrivateData; + remoteDriverLock(priv); + make_nonnull_storage_pool (&args.pool, pool); memset (&ret, 0, sizeof ret); @@ -3746,6 +4065,7 @@ remoteStoragePoolGetInfo (virStoragePoolPtr pool, virStoragePoolInfoPtr info) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3758,6 +4078,8 @@ remoteStoragePoolDumpXML (virStoragePoolPtr pool, 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; @@ -3771,6 +4093,7 @@ remoteStoragePoolDumpXML (virStoragePoolPtr pool, rv = ret.xml; done: + remoteDriverUnlock(priv); return rv; } @@ -3782,6 +4105,8 @@ remoteStoragePoolGetAutostart (virStoragePoolPtr pool, int *autostart) remote_storage_pool_get_autostart_ret ret; struct private_data *priv = pool->conn->storagePrivateData; + remoteDriverLock(priv); + make_nonnull_storage_pool (&args.pool, pool); memset (&ret, 0, sizeof ret); @@ -3795,6 +4120,7 @@ remoteStoragePoolGetAutostart (virStoragePoolPtr pool, int *autostart) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3805,6 +4131,8 @@ remoteStoragePoolSetAutostart (virStoragePoolPtr pool, int autostart) 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; @@ -3816,6 +4144,7 @@ remoteStoragePoolSetAutostart (virStoragePoolPtr pool, int autostart) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3828,6 +4157,8 @@ remoteStoragePoolNumOfVolumes (virStoragePoolPtr pool) remote_storage_pool_num_of_volumes_ret ret; struct private_data *priv = pool->conn->storagePrivateData; + remoteDriverLock(priv); + make_nonnull_storage_pool(&args.pool, pool); memset (&ret, 0, sizeof ret); @@ -3839,6 +4170,7 @@ remoteStoragePoolNumOfVolumes (virStoragePoolPtr pool) rv = ret.num; done: + remoteDriverUnlock(priv); return rv; } @@ -3851,6 +4183,8 @@ remoteStoragePoolListVolumes (virStoragePoolPtr pool, char **const names, int ma 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")); goto done; @@ -3883,6 +4217,7 @@ cleanup: xdr_free ((xdrproc_t) xdr_remote_storage_pool_list_volumes_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return rv; } @@ -3897,6 +4232,8 @@ remoteStorageVolLookupByName (virStoragePoolPtr pool, 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; @@ -3910,6 +4247,7 @@ remoteStorageVolLookupByName (virStoragePoolPtr pool, xdr_free ((xdrproc_t) &xdr_remote_storage_vol_lookup_by_name_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return vol; } @@ -3922,6 +4260,8 @@ remoteStorageVolLookupByKey (virConnectPtr conn, 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); @@ -3934,6 +4274,7 @@ remoteStorageVolLookupByKey (virConnectPtr conn, xdr_free ((xdrproc_t) &xdr_remote_storage_vol_lookup_by_key_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return vol; } @@ -3946,6 +4287,8 @@ remoteStorageVolLookupByPath (virConnectPtr conn, 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); @@ -3958,6 +4301,7 @@ remoteStorageVolLookupByPath (virConnectPtr conn, xdr_free ((xdrproc_t) &xdr_remote_storage_vol_lookup_by_path_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return vol; } @@ -3970,6 +4314,8 @@ remoteStorageVolCreateXML (virStoragePoolPtr pool, const char *xmlDesc, 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; @@ -3984,6 +4330,7 @@ remoteStorageVolCreateXML (virStoragePoolPtr pool, const char *xmlDesc, xdr_free ((xdrproc_t) &xdr_remote_storage_vol_create_xml_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return vol; } @@ -3995,6 +4342,8 @@ remoteStorageVolDelete (virStorageVolPtr vol, 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; @@ -4006,6 +4355,7 @@ remoteStorageVolDelete (virStorageVolPtr vol, rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -4017,6 +4367,8 @@ remoteStorageVolGetInfo (virStorageVolPtr vol, virStorageVolInfoPtr info) 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); @@ -4032,6 +4384,7 @@ remoteStorageVolGetInfo (virStorageVolPtr vol, virStorageVolInfoPtr info) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -4044,6 +4397,8 @@ remoteStorageVolDumpXML (virStorageVolPtr vol, 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; @@ -4057,6 +4412,7 @@ remoteStorageVolDumpXML (virStorageVolPtr vol, rv = ret.xml; done: + remoteDriverUnlock(priv); return rv; } @@ -4068,6 +4424,8 @@ remoteStorageVolGetPath (virStorageVolPtr vol) 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); @@ -4080,6 +4438,7 @@ remoteStorageVolGetPath (virStorageVolPtr vol) rv = ret.name; done: + remoteDriverUnlock(priv); return rv; } @@ -4091,19 +4450,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; - } + } 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; - /* Decline open. Will fallback to appropriate local node driver. */ - return VIR_DRV_OPEN_DECLINED; + 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) @@ -4111,14 +4514,17 @@ static int remoteDevMonClose(virConnectPtr conn) 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; } @@ -4131,6 +4537,8 @@ static int remoteNodeNumOfDevices(virConnectPtr conn, remote_node_num_of_devices_ret ret; struct private_data *priv = conn->devMonPrivateData; + remoteDriverLock(priv); + args.cap = cap ? (char **)&cap : NULL; args.flags = flags; @@ -4143,6 +4551,7 @@ static int remoteNodeNumOfDevices(virConnectPtr conn, rv = ret.num; done: + remoteDriverUnlock(priv); return rv; } @@ -4159,6 +4568,8 @@ static int remoteNodeListDevices(virConnectPtr conn, 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; @@ -4192,6 +4603,7 @@ cleanup: xdr_free ((xdrproc_t) xdr_remote_node_list_devices_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return rv; } @@ -4204,6 +4616,8 @@ static virNodeDevicePtr remoteNodeDeviceLookupByName(virConnectPtr conn, virNodeDevicePtr dev = NULL; struct private_data *priv = conn->devMonPrivateData; + remoteDriverLock(priv); + args.name = (char *)name; memset (&ret, 0, sizeof ret); @@ -4217,6 +4631,7 @@ static virNodeDevicePtr remoteNodeDeviceLookupByName(virConnectPtr conn, xdr_free ((xdrproc_t) xdr_remote_node_device_lookup_by_name_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return dev; } @@ -4228,6 +4643,8 @@ static char *remoteNodeDeviceDumpXML(virNodeDevicePtr dev, remote_node_device_dump_xml_ret ret; struct private_data *priv = dev->conn->devMonPrivateData; + remoteDriverLock(priv); + args.name = dev->name; args.flags = flags; @@ -4241,6 +4658,7 @@ static char *remoteNodeDeviceDumpXML(virNodeDevicePtr dev, rv = ret.xml; done: + remoteDriverUnlock(priv); return rv; } @@ -4251,6 +4669,8 @@ static char *remoteNodeDeviceGetParent(virNodeDevicePtr dev) 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); @@ -4263,6 +4683,7 @@ static char *remoteNodeDeviceGetParent(virNodeDevicePtr dev) rv = ret.parent ? *ret.parent : NULL; done: + remoteDriverUnlock(priv); return rv; } @@ -4273,6 +4694,8 @@ static int remoteNodeDeviceNumOfCaps(virNodeDevicePtr dev) 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); @@ -4284,6 +4707,7 @@ static int remoteNodeDeviceNumOfCaps(virNodeDevicePtr dev) rv = ret.num; done: + remoteDriverUnlock(priv); return rv; } @@ -4297,6 +4721,8 @@ static int remoteNodeDeviceListCaps(virNodeDevicePtr dev, 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; @@ -4329,6 +4755,7 @@ cleanup: xdr_free ((xdrproc_t) xdr_remote_node_device_list_caps_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return rv; } @@ -5054,6 +5481,8 @@ static int remoteDomainEventRegister (virConnectPtr conn, 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; @@ -5075,6 +5504,7 @@ static int remoteDomainEventRegister (virConnectPtr conn, rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -5084,6 +5514,8 @@ static int remoteDomainEventDeregister (virConnectPtr conn, struct private_data *priv = conn->privateData; int rv = -1; + remoteDriverLock(priv); + if (virDomainEventCallbackListRemove(conn, priv->callbackList, callback) < 0) { error (conn, VIR_ERR_RPC, _("removing cb fron list")); @@ -5101,6 +5533,7 @@ static int remoteDomainEventDeregister (virConnectPtr conn, rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -5891,6 +6324,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)) { @@ -5947,7 +6382,7 @@ remoteDomainEventFired(int watch, } done: - return; + remoteDriverUnlock(priv); } void @@ -5956,7 +6391,11 @@ remoteDomainEventQueueFlush(int timer ATTRIBUTE_UNUSED, void *opaque) virConnectPtr conn = opaque; struct private_data *priv = conn->privateData; + remoteDriverLock(priv); + virDomainEventQueueDispatch(priv->domainEvents, priv->callbackList, virDomainEventDispatchDefaultFunc, NULL); virEventUpdateTimeout(priv->eventFlushTimer, -1); + + remoteDriverUnlock(priv); }