Adds locking in the remote driver. This obtains the lock on every single API method. This is quite poor, not giving any parallelism - that will be added in 2 patch's time, when we drop the lock while waiting on I/O remote_internal.c | 523 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 481 insertions(+), 42 deletions(-) Daniel diff --git a/src/remote_internal.c b/src/remote_internal.c --- a/src/remote_internal.c +++ b/src/remote_internal.c @@ -89,6 +89,8 @@ static int inside_daemon = 0; static int inside_daemon = 0; struct private_data { + virMutex lock; + int sock; /* Socket. */ int watch; /* File handle watch */ pid_t pid; /* PID of tunnel process */ @@ -119,6 +121,16 @@ enum { REMOTE_CALL_QUIET_MISSING_RPC = 2, }; + +static void remoteDriverLock(struct private_data *driver) +{ + virMutexLock(&driver->lock); +} + +static void remoteDriverUnlock(struct private_data *driver) +{ + virMutexUnlock(&driver->lock); +} static int call (virConnectPtr conn, struct private_data *priv, int flags, int proc_nr, @@ -829,6 +841,15 @@ remoteOpen (virConnectPtr conn, return VIR_DRV_OPEN_ERROR; } + if (virMutexInit(&priv->lock) < 0) { + error(conn, VIR_ERR_INTERNAL_ERROR, + _("cannot initialize mutex")); + VIR_FREE(priv); + return VIR_DRV_OPEN_ERROR; + } + remoteDriverLock(priv); + priv->localUses = 1; + if (flags & VIR_CONNECT_RO) rflags |= VIR_DRV_OPEN_REMOTE_RO; @@ -883,9 +904,11 @@ remoteOpen (virConnectPtr conn, ret = doRemoteOpen(conn, priv, auth, rflags); if (ret != VIR_DRV_OPEN_SUCCESS) { conn->privateData = NULL; + remoteDriverUnlock(priv); VIR_FREE(priv); } else { conn->privateData = priv; + remoteDriverUnlock(priv); } return ret; } @@ -1240,12 +1263,20 @@ static int static int remoteClose (virConnectPtr conn) { - int ret; - struct private_data *priv = conn->privateData; - - ret = doRemoteClose(conn, priv); - VIR_FREE (priv); - conn->privateData = NULL; + int ret = 0; + struct private_data *priv = conn->privateData; + + remoteDriverLock(priv); + priv->localUses--; + if (!priv->localUses) { + ret = doRemoteClose(conn, priv); + conn->privateData = NULL; + remoteDriverUnlock(priv); + virMutexDestroy(&priv->lock); + VIR_FREE (priv); + } + if (priv) + remoteDriverUnlock(priv); return ret; } @@ -1257,6 +1288,8 @@ remoteSupportsFeature (virConnectPtr con remote_supports_feature_args args; remote_supports_feature_ret ret; struct private_data *priv = conn->privateData; + + remoteDriverLock(priv); /* VIR_DRV_FEATURE_REMOTE* features are handled directly. */ if (feature == VIR_DRV_FEATURE_REMOTE) { @@ -1275,6 +1308,7 @@ remoteSupportsFeature (virConnectPtr con rv = ret.supported; done: + remoteDriverUnlock(priv); return rv; } @@ -1293,6 +1327,8 @@ remoteType (virConnectPtr conn) remote_get_type_ret ret; struct private_data *priv = conn->privateData; + remoteDriverLock(priv); + /* Cached? */ if (priv->type) { rv = priv->type; @@ -1309,6 +1345,7 @@ remoteType (virConnectPtr conn) rv = priv->type = ret.type; done: + remoteDriverUnlock(priv); return rv; } @@ -1319,6 +1356,8 @@ remoteGetVersion (virConnectPtr conn, un remote_get_version_ret ret; struct private_data *priv = conn->privateData; + remoteDriverLock(priv); + memset (&ret, 0, sizeof ret); if (call (conn, priv, 0, REMOTE_PROC_GET_VERSION, (xdrproc_t) xdr_void, (char *) NULL, @@ -1329,6 +1368,7 @@ remoteGetVersion (virConnectPtr conn, un rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1338,6 +1378,8 @@ remoteGetHostname (virConnectPtr conn) char *rv = NULL; remote_get_hostname_ret ret; struct private_data *priv = conn->privateData; + + remoteDriverLock(priv); memset (&ret, 0, sizeof ret); if (call (conn, priv, 0, REMOTE_PROC_GET_HOSTNAME, @@ -1349,6 +1391,7 @@ remoteGetHostname (virConnectPtr conn) rv = ret.hostname; done: + remoteDriverUnlock(priv); return rv; } @@ -1359,6 +1402,8 @@ remoteGetMaxVcpus (virConnectPtr conn, c remote_get_max_vcpus_args args; remote_get_max_vcpus_ret ret; struct private_data *priv = conn->privateData; + + remoteDriverLock(priv); memset (&ret, 0, sizeof ret); args.type = type == NULL ? NULL : (char **) &type; @@ -1370,6 +1415,7 @@ remoteGetMaxVcpus (virConnectPtr conn, c rv = ret.max_vcpus; done: + remoteDriverUnlock(priv); return rv; } @@ -1379,6 +1425,8 @@ remoteNodeGetInfo (virConnectPtr conn, v int rv = -1; remote_node_get_info_ret ret; struct private_data *priv = conn->privateData; + + remoteDriverLock(priv); memset (&ret, 0, sizeof ret); if (call (conn, priv, 0, REMOTE_PROC_NODE_GET_INFO, @@ -1398,6 +1446,7 @@ remoteNodeGetInfo (virConnectPtr conn, v rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1407,6 +1456,8 @@ remoteGetCapabilities (virConnectPtr con char *rv = NULL; remote_get_capabilities_ret ret; struct private_data *priv = conn->privateData; + + remoteDriverLock(priv); memset (&ret, 0, sizeof ret); if (call (conn, priv, 0, REMOTE_PROC_GET_CAPABILITIES, @@ -1418,6 +1469,7 @@ remoteGetCapabilities (virConnectPtr con rv = ret.capabilities; done: + remoteDriverUnlock(priv); return rv; } @@ -1433,6 +1485,8 @@ remoteNodeGetCellsFreeMemory(virConnectP int i; struct private_data *priv = conn->privateData; + remoteDriverLock(priv); + if (maxCells > REMOTE_NODE_MAX_CELLS) { errorf (conn, VIR_ERR_RPC, _("too many NUMA cells: %d > %d"), @@ -1458,6 +1512,7 @@ remoteNodeGetCellsFreeMemory(virConnectP rv = ret.freeMems.freeMems_len; done: + remoteDriverUnlock(priv); return rv; } @@ -1467,6 +1522,8 @@ remoteNodeGetFreeMemory (virConnectPtr c unsigned long long rv = 0; /* 0 is error value this special function*/ remote_node_get_free_memory_ret ret; struct private_data *priv = conn->privateData; + + remoteDriverLock(priv); memset (&ret, 0, sizeof ret); if (call (conn, priv, 0, REMOTE_PROC_NODE_GET_FREE_MEMORY, @@ -1477,6 +1534,7 @@ remoteNodeGetFreeMemory (virConnectPtr c rv = ret.freeMem; done: + remoteDriverUnlock(priv); return rv; } @@ -1489,6 +1547,8 @@ remoteListDomains (virConnectPtr conn, i remote_list_domains_args args; remote_list_domains_ret ret; struct private_data *priv = conn->privateData; + + remoteDriverLock(priv); if (maxids > REMOTE_DOMAIN_ID_LIST_MAX) { errorf (conn, VIR_ERR_RPC, @@ -1520,6 +1580,7 @@ cleanup: xdr_free ((xdrproc_t) xdr_remote_list_domains_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return rv; } @@ -1530,6 +1591,8 @@ remoteNumOfDomains (virConnectPtr conn) remote_num_of_domains_ret ret; struct private_data *priv = conn->privateData; + remoteDriverLock(priv); + memset (&ret, 0, sizeof ret); if (call (conn, priv, 0, REMOTE_PROC_NUM_OF_DOMAINS, (xdrproc_t) xdr_void, (char *) NULL, @@ -1539,6 +1602,7 @@ remoteNumOfDomains (virConnectPtr conn) rv = ret.num; done: + remoteDriverUnlock(priv); return rv; } @@ -1552,6 +1616,8 @@ remoteDomainCreateXML (virConnectPtr con remote_domain_create_xml_ret ret; struct private_data *priv = conn->privateData; + remoteDriverLock(priv); + args.xml_desc = (char *) xmlDesc; args.flags = flags; @@ -1565,6 +1631,7 @@ remoteDomainCreateXML (virConnectPtr con xdr_free ((xdrproc_t) &xdr_remote_domain_create_xml_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return dom; } @@ -1576,6 +1643,8 @@ remoteDomainLookupByID (virConnectPtr co remote_domain_lookup_by_id_ret ret; struct private_data *priv = conn->privateData; + remoteDriverLock(priv); + args.id = id; memset (&ret, 0, sizeof ret); @@ -1588,6 +1657,7 @@ remoteDomainLookupByID (virConnectPtr co xdr_free ((xdrproc_t) &xdr_remote_domain_lookup_by_id_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return dom; } @@ -1599,6 +1669,8 @@ remoteDomainLookupByUUID (virConnectPtr remote_domain_lookup_by_uuid_ret ret; struct private_data *priv = conn->privateData; + remoteDriverLock(priv); + memcpy (args.uuid, uuid, VIR_UUID_BUFLEN); memset (&ret, 0, sizeof ret); @@ -1611,6 +1683,7 @@ remoteDomainLookupByUUID (virConnectPtr xdr_free ((xdrproc_t) &xdr_remote_domain_lookup_by_uuid_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return dom; } @@ -1622,6 +1695,8 @@ remoteDomainLookupByName (virConnectPtr remote_domain_lookup_by_name_ret ret; struct private_data *priv = conn->privateData; + remoteDriverLock(priv); + args.name = (char *) name; memset (&ret, 0, sizeof ret); @@ -1634,6 +1709,7 @@ remoteDomainLookupByName (virConnectPtr xdr_free ((xdrproc_t) &xdr_remote_domain_lookup_by_name_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return dom; } @@ -1643,6 +1719,8 @@ remoteDomainSuspend (virDomainPtr domain int rv = -1; remote_domain_suspend_args args; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); @@ -1654,6 +1732,7 @@ remoteDomainSuspend (virDomainPtr domain rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1663,6 +1742,8 @@ remoteDomainResume (virDomainPtr domain) int rv = -1; remote_domain_resume_args args; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); @@ -1674,6 +1755,7 @@ remoteDomainResume (virDomainPtr domain) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1683,6 +1765,8 @@ remoteDomainShutdown (virDomainPtr domai int rv = -1; remote_domain_shutdown_args args; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); @@ -1694,6 +1778,7 @@ remoteDomainShutdown (virDomainPtr domai rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1703,6 +1788,8 @@ remoteDomainReboot (virDomainPtr domain, int rv = -1; remote_domain_reboot_args args; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); args.flags = flags; @@ -1715,6 +1802,7 @@ remoteDomainReboot (virDomainPtr domain, rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1724,6 +1812,8 @@ remoteDomainDestroy (virDomainPtr domain int rv = -1; remote_domain_destroy_args args; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); @@ -1735,6 +1825,7 @@ remoteDomainDestroy (virDomainPtr domain rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1745,6 +1836,8 @@ remoteDomainGetOSType (virDomainPtr doma remote_domain_get_os_type_args args; remote_domain_get_os_type_ret ret; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); @@ -1758,6 +1851,7 @@ remoteDomainGetOSType (virDomainPtr doma rv = ret.type; done: + remoteDriverUnlock(priv); return rv; } @@ -1769,6 +1863,8 @@ remoteDomainGetMaxMemory (virDomainPtr d remote_domain_get_max_memory_ret ret; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + make_nonnull_domain (&args.dom, domain); memset (&ret, 0, sizeof ret); @@ -1780,6 +1876,7 @@ remoteDomainGetMaxMemory (virDomainPtr d rv = ret.memory; done: + remoteDriverUnlock(priv); return rv; } @@ -1789,6 +1886,8 @@ remoteDomainSetMaxMemory (virDomainPtr d int rv = -1; remote_domain_set_max_memory_args args; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); args.memory = memory; @@ -1801,6 +1900,7 @@ remoteDomainSetMaxMemory (virDomainPtr d rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1810,6 +1910,8 @@ remoteDomainSetMemory (virDomainPtr doma int rv = -1; remote_domain_set_memory_args args; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); args.memory = memory; @@ -1822,6 +1924,7 @@ remoteDomainSetMemory (virDomainPtr doma rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1832,6 +1935,8 @@ remoteDomainGetInfo (virDomainPtr domain remote_domain_get_info_args args; remote_domain_get_info_ret ret; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); @@ -1850,6 +1955,7 @@ remoteDomainGetInfo (virDomainPtr domain rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1859,6 +1965,8 @@ remoteDomainSave (virDomainPtr domain, c int rv = -1; remote_domain_save_args args; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); args.to = (char *) to; @@ -1871,6 +1979,7 @@ remoteDomainSave (virDomainPtr domain, c rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1880,6 +1989,8 @@ remoteDomainRestore (virConnectPtr conn, int rv = -1; remote_domain_restore_args args; struct private_data *priv = conn->privateData; + + remoteDriverLock(priv); args.from = (char *) from; @@ -1891,6 +2002,7 @@ remoteDomainRestore (virConnectPtr conn, rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1900,6 +2012,8 @@ remoteDomainCoreDump (virDomainPtr domai int rv = -1; remote_domain_core_dump_args args; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); args.to = (char *) to; @@ -1913,6 +2027,7 @@ remoteDomainCoreDump (virDomainPtr domai rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1922,6 +2037,8 @@ remoteDomainSetVcpus (virDomainPtr domai int rv = -1; remote_domain_set_vcpus_args args; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); args.nvcpus = nvcpus; @@ -1934,6 +2051,7 @@ remoteDomainSetVcpus (virDomainPtr domai rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1947,6 +2065,8 @@ remoteDomainPinVcpu (virDomainPtr domain remote_domain_pin_vcpu_args args; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + if (maplen > REMOTE_CPUMAP_MAX) { errorf (domain->conn, VIR_ERR_RPC, _("map length greater than maximum: %d > %d"), @@ -1967,6 +2087,7 @@ remoteDomainPinVcpu (virDomainPtr domain rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -1983,6 +2104,8 @@ remoteDomainGetVcpus (virDomainPtr domai remote_domain_get_vcpus_ret ret; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + if (maxinfo > REMOTE_VCPUINFO_MAX) { errorf (domain->conn, VIR_ERR_RPC, _("vCPU count exceeds maximum: %d > %d"), @@ -2038,6 +2161,7 @@ cleanup: xdr_free ((xdrproc_t) xdr_remote_domain_get_vcpus_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return rv; } @@ -2048,6 +2172,8 @@ remoteDomainGetMaxVcpus (virDomainPtr do remote_domain_get_max_vcpus_args args; remote_domain_get_max_vcpus_ret ret; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); @@ -2060,6 +2186,7 @@ remoteDomainGetMaxVcpus (virDomainPtr do rv = ret.num; done: + remoteDriverUnlock(priv); return rv; } @@ -2070,6 +2197,8 @@ remoteDomainDumpXML (virDomainPtr domain remote_domain_dump_xml_args args; remote_domain_dump_xml_ret ret; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); args.flags = flags; @@ -2084,6 +2213,7 @@ remoteDomainDumpXML (virDomainPtr domain rv = ret.xml; done: + remoteDriverUnlock(priv); return rv; } @@ -2099,6 +2229,8 @@ remoteDomainMigratePrepare (virConnectPt remote_domain_migrate_prepare_ret ret; struct private_data *priv = dconn->privateData; + remoteDriverLock(priv); + args.uri_in = uri_in == NULL ? NULL : (char **) &uri_in; args.flags = flags; args.dname = dname == NULL ? NULL : (char **) &dname; @@ -2120,6 +2252,7 @@ remoteDomainMigratePrepare (virConnectPt rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -2136,6 +2269,8 @@ remoteDomainMigratePerform (virDomainPtr remote_domain_migrate_perform_args args; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + make_nonnull_domain (&args.dom, domain); args.cookie.cookie_len = cookielen; args.cookie.cookie_val = (char *) cookie; @@ -2152,6 +2287,7 @@ remoteDomainMigratePerform (virDomainPtr rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -2168,6 +2304,8 @@ remoteDomainMigrateFinish (virConnectPtr remote_domain_migrate_finish_ret ret; struct private_data *priv = dconn->privateData; + remoteDriverLock(priv); + args.dname = (char *) dname; args.cookie.cookie_len = cookielen; args.cookie.cookie_val = (char *) cookie; @@ -2184,6 +2322,7 @@ remoteDomainMigrateFinish (virConnectPtr xdr_free ((xdrproc_t) &xdr_remote_domain_migrate_finish_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return ddom; } @@ -2200,6 +2339,8 @@ remoteDomainMigratePrepare2 (virConnectP remote_domain_migrate_prepare2_ret ret; struct private_data *priv = dconn->privateData; + remoteDriverLock(priv); + args.uri_in = uri_in == NULL ? NULL : (char **) &uri_in; args.flags = flags; args.dname = dname == NULL ? NULL : (char **) &dname; @@ -2222,6 +2363,7 @@ remoteDomainMigratePrepare2 (virConnectP rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -2239,6 +2381,8 @@ remoteDomainMigrateFinish2 (virConnectPt remote_domain_migrate_finish2_ret ret; struct private_data *priv = dconn->privateData; + remoteDriverLock(priv); + args.dname = (char *) dname; args.cookie.cookie_len = cookielen; args.cookie.cookie_val = (char *) cookie; @@ -2256,6 +2400,7 @@ remoteDomainMigrateFinish2 (virConnectPt xdr_free ((xdrproc_t) &xdr_remote_domain_migrate_finish2_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return ddom; } @@ -2267,6 +2412,8 @@ remoteListDefinedDomains (virConnectPtr remote_list_defined_domains_args args; remote_list_defined_domains_ret ret; struct private_data *priv = conn->privateData; + + remoteDriverLock(priv); if (maxnames > REMOTE_DOMAIN_NAME_LIST_MAX) { errorf (conn, VIR_ERR_RPC, @@ -2303,6 +2450,7 @@ cleanup: xdr_free ((xdrproc_t) xdr_remote_list_defined_domains_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return rv; } @@ -2313,6 +2461,8 @@ remoteNumOfDefinedDomains (virConnectPtr remote_num_of_defined_domains_ret ret; struct private_data *priv = conn->privateData; + remoteDriverLock(priv); + memset (&ret, 0, sizeof ret); if (call (conn, priv, 0, REMOTE_PROC_NUM_OF_DEFINED_DOMAINS, (xdrproc_t) xdr_void, (char *) NULL, @@ -2322,6 +2472,7 @@ remoteNumOfDefinedDomains (virConnectPtr rv = ret.num; done: + remoteDriverUnlock(priv); return rv; } @@ -2331,6 +2482,8 @@ remoteDomainCreate (virDomainPtr domain) int rv = -1; remote_domain_create_args args; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); @@ -2342,6 +2495,7 @@ remoteDomainCreate (virDomainPtr domain) rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -2353,6 +2507,8 @@ remoteDomainDefineXML (virConnectPtr con remote_domain_define_xml_ret ret; struct private_data *priv = conn->privateData; + remoteDriverLock(priv); + args.xml = (char *) xml; memset (&ret, 0, sizeof ret); @@ -2365,6 +2521,7 @@ remoteDomainDefineXML (virConnectPtr con xdr_free ((xdrproc_t) xdr_remote_domain_define_xml_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return dom; } @@ -2374,6 +2531,8 @@ remoteDomainUndefine (virDomainPtr domai int rv = -1; remote_domain_undefine_args args; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); @@ -2385,6 +2544,7 @@ remoteDomainUndefine (virDomainPtr domai rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -2394,6 +2554,8 @@ remoteDomainAttachDevice (virDomainPtr d int rv = -1; remote_domain_attach_device_args args; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); args.xml = (char *) xml; @@ -2406,6 +2568,7 @@ remoteDomainAttachDevice (virDomainPtr d rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -2415,6 +2578,8 @@ remoteDomainDetachDevice (virDomainPtr d int rv = -1; remote_domain_detach_device_args args; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); args.xml = (char *) xml; @@ -2427,6 +2592,7 @@ remoteDomainDetachDevice (virDomainPtr d rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -2437,6 +2603,8 @@ remoteDomainGetAutostart (virDomainPtr d remote_domain_get_autostart_args args; remote_domain_get_autostart_ret ret; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); @@ -2450,6 +2618,7 @@ remoteDomainGetAutostart (virDomainPtr d rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -2459,6 +2628,8 @@ remoteDomainSetAutostart (virDomainPtr d int rv = -1; remote_domain_set_autostart_args args; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); args.autostart = autostart; @@ -2471,6 +2642,7 @@ remoteDomainSetAutostart (virDomainPtr d rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -2481,6 +2653,8 @@ remoteDomainGetSchedulerType (virDomainP remote_domain_get_scheduler_type_args args; remote_domain_get_scheduler_type_ret ret; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); @@ -2496,6 +2670,7 @@ remoteDomainGetSchedulerType (virDomainP rv = ret.type; done: + remoteDriverUnlock(priv); return rv; } @@ -2508,6 +2683,8 @@ remoteDomainGetSchedulerParameters (virD remote_domain_get_scheduler_parameters_ret ret; int i = -1; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); args.nparams = *nparams; @@ -2565,6 +2742,7 @@ cleanup: } done: + remoteDriverUnlock(priv); return rv; } @@ -2576,6 +2754,8 @@ remoteDomainSetSchedulerParameters (virD remote_domain_set_scheduler_parameters_args args; int i, do_error; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); @@ -2627,6 +2807,7 @@ remoteDomainSetSchedulerParameters (virD rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -2638,6 +2819,8 @@ remoteDomainBlockStats (virDomainPtr dom remote_domain_block_stats_args args; remote_domain_block_stats_ret ret; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); args.path = (char *) path; @@ -2658,6 +2841,7 @@ remoteDomainBlockStats (virDomainPtr dom rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -2669,6 +2853,8 @@ remoteDomainInterfaceStats (virDomainPtr remote_domain_interface_stats_args args; remote_domain_interface_stats_ret ret; struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); make_nonnull_domain (&args.dom, domain); args.path = (char *) path; @@ -2693,6 +2879,7 @@ remoteDomainInterfaceStats (virDomainPtr rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -2709,6 +2896,8 @@ remoteDomainBlockPeek (virDomainPtr doma remote_domain_block_peek_ret ret; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + if (size > REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX) { errorf (domain->conn, VIR_ERR_RPC, _("block peek request too large for remote protocol, %zi > %d"), @@ -2743,6 +2932,7 @@ cleanup: free (ret.buffer.buffer_val); done: + remoteDriverUnlock(priv); return rv; } @@ -2758,6 +2948,8 @@ remoteDomainMemoryPeek (virDomainPtr dom remote_domain_memory_peek_ret ret; struct private_data *priv = domain->conn->privateData; + remoteDriverLock(priv); + if (size > REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX) { errorf (domain->conn, VIR_ERR_RPC, _("memory peek request too large for remote protocol, %zi > %d"), @@ -2791,6 +2983,7 @@ cleanup: free (ret.buffer.buffer_val); done: + remoteDriverUnlock(priv); return rv; } @@ -2807,11 +3000,17 @@ remoteNetworkOpen (virConnectPtr conn, if (conn && conn->driver && STREQ (conn->driver->name, "remote")) { - /* If we're here, the remote driver is already + struct private_data *priv; + + /* If we're here, the remote driver is already * in use due to a) a QEMU uri, or b) a remote * URI. So we can re-use existing connection */ - conn->networkPrivateData = conn->privateData; + priv = conn->privateData; + remoteDriverLock(priv); + priv->localUses++; + conn->networkPrivateData = priv; + remoteDriverUnlock(priv); return VIR_DRV_OPEN_SUCCESS; } else { /* Using a non-remote driver, so we need to open a @@ -2823,6 +3022,12 @@ remoteNetworkOpen (virConnectPtr conn, int ret, rflags = 0; if (VIR_ALLOC(priv) < 0) { error (conn, VIR_ERR_NO_MEMORY, _("struct private_data")); + return VIR_DRV_OPEN_ERROR; + } + if (virMutexInit(&priv->lock) < 0) { + error(conn, VIR_ERR_INTERNAL_ERROR, + _("cannot initialize mutex")); + VIR_FREE(priv); return VIR_DRV_OPEN_ERROR; } if (flags & VIR_CONNECT_RO) @@ -2848,14 +3053,17 @@ remoteNetworkClose (virConnectPtr conn) int rv = 0; struct private_data *priv = conn->networkPrivateData; - if (priv->localUses) { - priv->localUses--; - if (!priv->localUses) { - rv = doRemoteClose(conn, priv); - VIR_FREE(priv); - conn->networkPrivateData = NULL; - } - } + remoteDriverLock(priv); + priv->localUses--; + if (!priv->localUses) { + rv = doRemoteClose(conn, priv); + conn->networkPrivateData = NULL; + remoteDriverUnlock(priv); + virMutexDestroy(&priv->lock); + VIR_FREE(priv); + } + if (priv) + remoteDriverUnlock(priv); return rv; } @@ -2866,6 +3074,8 @@ remoteNumOfNetworks (virConnectPtr conn) remote_num_of_networks_ret ret; struct private_data *priv = conn->networkPrivateData; + remoteDriverLock(priv); + memset (&ret, 0, sizeof ret); if (call (conn, priv, 0, REMOTE_PROC_NUM_OF_NETWORKS, (xdrproc_t) xdr_void, (char *) NULL, @@ -2875,6 +3085,7 @@ remoteNumOfNetworks (virConnectPtr conn) rv = ret.num; done: + remoteDriverUnlock(priv); return rv; } @@ -2886,6 +3097,8 @@ remoteListNetworks (virConnectPtr conn, remote_list_networks_args args; remote_list_networks_ret ret; struct private_data *priv = conn->networkPrivateData; + + remoteDriverLock(priv); if (maxnames > REMOTE_NETWORK_NAME_LIST_MAX) { errorf (conn, VIR_ERR_RPC, @@ -2922,6 +3135,7 @@ cleanup: xdr_free ((xdrproc_t) xdr_remote_list_networks_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return rv; } @@ -2932,6 +3146,8 @@ remoteNumOfDefinedNetworks (virConnectPt remote_num_of_defined_networks_ret ret; struct private_data *priv = conn->networkPrivateData; + remoteDriverLock(priv); + memset (&ret, 0, sizeof ret); if (call (conn, priv, 0, REMOTE_PROC_NUM_OF_DEFINED_NETWORKS, (xdrproc_t) xdr_void, (char *) NULL, @@ -2941,6 +3157,7 @@ remoteNumOfDefinedNetworks (virConnectPt rv = ret.num; done: + remoteDriverUnlock(priv); return rv; } @@ -2953,6 +3170,8 @@ remoteListDefinedNetworks (virConnectPtr remote_list_defined_networks_args args; remote_list_defined_networks_ret ret; struct private_data *priv = conn->networkPrivateData; + + remoteDriverLock(priv); if (maxnames > REMOTE_NETWORK_NAME_LIST_MAX) { errorf (conn, VIR_ERR_RPC, @@ -2989,6 +3208,7 @@ cleanup: xdr_free ((xdrproc_t) xdr_remote_list_defined_networks_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return rv; } @@ -3001,6 +3221,8 @@ remoteNetworkLookupByUUID (virConnectPtr remote_network_lookup_by_uuid_ret ret; struct private_data *priv = conn->networkPrivateData; + remoteDriverLock(priv); + memcpy (args.uuid, uuid, VIR_UUID_BUFLEN); memset (&ret, 0, sizeof ret); @@ -3013,6 +3235,7 @@ remoteNetworkLookupByUUID (virConnectPtr xdr_free ((xdrproc_t) &xdr_remote_network_lookup_by_uuid_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return net; } @@ -3025,6 +3248,8 @@ remoteNetworkLookupByName (virConnectPtr remote_network_lookup_by_name_ret ret; struct private_data *priv = conn->networkPrivateData; + remoteDriverLock(priv); + args.name = (char *) name; memset (&ret, 0, sizeof ret); @@ -3037,6 +3262,7 @@ remoteNetworkLookupByName (virConnectPtr xdr_free ((xdrproc_t) &xdr_remote_network_lookup_by_name_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return net; } @@ -3048,6 +3274,8 @@ remoteNetworkCreateXML (virConnectPtr co remote_network_create_xml_ret ret; struct private_data *priv = conn->networkPrivateData; + remoteDriverLock(priv); + args.xml = (char *) xmlDesc; memset (&ret, 0, sizeof ret); @@ -3060,6 +3288,7 @@ remoteNetworkCreateXML (virConnectPtr co xdr_free ((xdrproc_t) &xdr_remote_network_create_xml_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return net; } @@ -3071,6 +3300,8 @@ remoteNetworkDefineXML (virConnectPtr co remote_network_define_xml_ret ret; struct private_data *priv = conn->networkPrivateData; + remoteDriverLock(priv); + args.xml = (char *) xml; memset (&ret, 0, sizeof ret); @@ -3083,6 +3314,7 @@ remoteNetworkDefineXML (virConnectPtr co xdr_free ((xdrproc_t) &xdr_remote_network_define_xml_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return net; } @@ -3092,6 +3324,8 @@ remoteNetworkUndefine (virNetworkPtr net int rv = -1; remote_network_undefine_args args; struct private_data *priv = network->conn->networkPrivateData; + + remoteDriverLock(priv); make_nonnull_network (&args.net, network); @@ -3103,6 +3337,7 @@ remoteNetworkUndefine (virNetworkPtr net rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3112,6 +3347,8 @@ remoteNetworkCreate (virNetworkPtr netwo int rv = -1; remote_network_create_args args; struct private_data *priv = network->conn->networkPrivateData; + + remoteDriverLock(priv); make_nonnull_network (&args.net, network); @@ -3123,6 +3360,7 @@ remoteNetworkCreate (virNetworkPtr netwo rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3132,6 +3370,8 @@ remoteNetworkDestroy (virNetworkPtr netw int rv = -1; remote_network_destroy_args args; struct private_data *priv = network->conn->networkPrivateData; + + remoteDriverLock(priv); make_nonnull_network (&args.net, network); @@ -3143,6 +3383,7 @@ remoteNetworkDestroy (virNetworkPtr netw rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3153,6 +3394,8 @@ remoteNetworkDumpXML (virNetworkPtr netw remote_network_dump_xml_args args; remote_network_dump_xml_ret ret; struct private_data *priv = network->conn->networkPrivateData; + + remoteDriverLock(priv); make_nonnull_network (&args.net, network); args.flags = flags; @@ -3167,6 +3410,7 @@ remoteNetworkDumpXML (virNetworkPtr netw rv = ret.xml; done: + remoteDriverUnlock(priv); return rv; } @@ -3177,6 +3421,8 @@ remoteNetworkGetBridgeName (virNetworkPt remote_network_get_bridge_name_args args; remote_network_get_bridge_name_ret ret; struct private_data *priv = network->conn->networkPrivateData; + + remoteDriverLock(priv); make_nonnull_network (&args.net, network); @@ -3190,6 +3436,7 @@ remoteNetworkGetBridgeName (virNetworkPt rv = ret.name; done: + remoteDriverUnlock(priv); return rv; } @@ -3200,6 +3447,8 @@ remoteNetworkGetAutostart (virNetworkPtr remote_network_get_autostart_args args; remote_network_get_autostart_ret ret; struct private_data *priv = network->conn->networkPrivateData; + + remoteDriverLock(priv); make_nonnull_network (&args.net, network); @@ -3214,6 +3463,7 @@ remoteNetworkGetAutostart (virNetworkPtr rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3223,6 +3473,8 @@ remoteNetworkSetAutostart (virNetworkPtr int rv = -1; remote_network_set_autostart_args args; struct private_data *priv = network->conn->networkPrivateData; + + remoteDriverLock(priv); make_nonnull_network (&args.net, network); args.autostart = autostart; @@ -3235,6 +3487,7 @@ remoteNetworkSetAutostart (virNetworkPtr rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3254,16 +3507,23 @@ remoteStorageOpen (virConnectPtr conn, if (conn && conn->driver && STREQ (conn->driver->name, "remote")) { + struct private_data *priv = conn->privateData; /* If we're here, the remote driver is already * in use due to a) a QEMU uri, or b) a remote * URI. So we can re-use existing connection */ - conn->storagePrivateData = conn->privateData; + remoteDriverLock(priv); + priv->localUses++; + conn->storagePrivateData = priv; + remoteDriverUnlock(priv); return VIR_DRV_OPEN_SUCCESS; } else if (conn->networkDriver && STREQ (conn->networkDriver->name, "remote")) { - conn->storagePrivateData = conn->networkPrivateData; - ((struct private_data *)conn->storagePrivateData)->localUses++; + struct private_data *priv = conn->networkPrivateData; + remoteDriverLock(priv); + conn->storagePrivateData = priv; + priv->localUses++; + remoteDriverUnlock(priv); return VIR_DRV_OPEN_SUCCESS; } else { /* Using a non-remote driver, so we need to open a @@ -3275,6 +3535,12 @@ remoteStorageOpen (virConnectPtr conn, int ret, rflags = 0; if (VIR_ALLOC(priv) < 0) { error (NULL, VIR_ERR_NO_MEMORY, _("struct private_data")); + return VIR_DRV_OPEN_ERROR; + } + if (virMutexInit(&priv->lock) < 0) { + error(conn, VIR_ERR_INTERNAL_ERROR, + _("cannot initialize mutex")); + VIR_FREE(priv); return VIR_DRV_OPEN_ERROR; } if (flags & VIR_CONNECT_RO) @@ -3300,14 +3566,17 @@ remoteStorageClose (virConnectPtr conn) int ret = 0; struct private_data *priv = conn->storagePrivateData; - if (priv->localUses) { - priv->localUses--; - if (!priv->localUses) { - ret = doRemoteClose(conn, priv); - VIR_FREE(priv); - conn->storagePrivateData = NULL; - } - } + remoteDriverLock(priv); + priv->localUses--; + if (!priv->localUses) { + ret = doRemoteClose(conn, priv); + conn->storagePrivateData = NULL; + remoteDriverUnlock(priv); + virMutexDestroy(&priv->lock); + VIR_FREE(priv); + } + if (priv) + remoteDriverUnlock(priv); return ret; } @@ -3319,6 +3588,8 @@ remoteNumOfStoragePools (virConnectPtr c remote_num_of_storage_pools_ret ret; struct private_data *priv = conn->storagePrivateData; + remoteDriverLock(priv); + memset (&ret, 0, sizeof ret); if (call (conn, priv, 0, REMOTE_PROC_NUM_OF_STORAGE_POOLS, (xdrproc_t) xdr_void, (char *) NULL, @@ -3328,6 +3599,7 @@ remoteNumOfStoragePools (virConnectPtr c rv = ret.num; done: + remoteDriverUnlock(priv); return rv; } @@ -3339,6 +3611,8 @@ remoteListStoragePools (virConnectPtr co remote_list_storage_pools_args args; remote_list_storage_pools_ret ret; struct private_data *priv = conn->storagePrivateData; + + remoteDriverLock(priv); if (maxnames > REMOTE_STORAGE_POOL_NAME_LIST_MAX) { error (conn, VIR_ERR_RPC, _("too many storage pools requested")); @@ -3371,6 +3645,7 @@ cleanup: xdr_free ((xdrproc_t) xdr_remote_list_storage_pools_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return rv; } @@ -3381,6 +3656,8 @@ remoteNumOfDefinedStoragePools (virConne remote_num_of_defined_storage_pools_ret ret; struct private_data *priv = conn->storagePrivateData; + remoteDriverLock(priv); + memset (&ret, 0, sizeof ret); if (call (conn, priv, 0, REMOTE_PROC_NUM_OF_DEFINED_STORAGE_POOLS, (xdrproc_t) xdr_void, (char *) NULL, @@ -3390,6 +3667,7 @@ remoteNumOfDefinedStoragePools (virConne rv = ret.num; done: + remoteDriverUnlock(priv); return rv; } @@ -3402,6 +3680,8 @@ remoteListDefinedStoragePools (virConnec remote_list_defined_storage_pools_args args; remote_list_defined_storage_pools_ret ret; struct private_data *priv = conn->storagePrivateData; + + remoteDriverLock(priv); if (maxnames > REMOTE_STORAGE_POOL_NAME_LIST_MAX) { error (conn, VIR_ERR_RPC, _("too many storage pools requested")); @@ -3434,6 +3714,7 @@ cleanup: xdr_free ((xdrproc_t) xdr_remote_list_defined_storage_pools_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return rv; } @@ -3448,6 +3729,8 @@ remoteFindStoragePoolSources (virConnect remote_find_storage_pool_sources_ret ret; struct private_data *priv = conn->storagePrivateData; const char *emptyString = ""; + + remoteDriverLock(priv); args.type = (char*)type; /* @@ -3476,6 +3759,7 @@ remoteFindStoragePoolSources (virConnect xdr_free ((xdrproc_t) xdr_remote_find_storage_pool_sources_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return rv; } @@ -3488,6 +3772,8 @@ remoteStoragePoolLookupByUUID (virConnec remote_storage_pool_lookup_by_uuid_ret ret; struct private_data *priv = conn->storagePrivateData; + remoteDriverLock(priv); + memcpy (args.uuid, uuid, VIR_UUID_BUFLEN); memset (&ret, 0, sizeof ret); @@ -3500,6 +3786,7 @@ remoteStoragePoolLookupByUUID (virConnec xdr_free ((xdrproc_t) &xdr_remote_storage_pool_lookup_by_uuid_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return pool; } @@ -3512,6 +3799,8 @@ remoteStoragePoolLookupByName (virConnec remote_storage_pool_lookup_by_name_ret ret; struct private_data *priv = conn->storagePrivateData; + remoteDriverLock(priv); + args.name = (char *) name; memset (&ret, 0, sizeof ret); @@ -3524,6 +3813,7 @@ remoteStoragePoolLookupByName (virConnec xdr_free ((xdrproc_t) &xdr_remote_storage_pool_lookup_by_name_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return pool; } @@ -3535,6 +3825,8 @@ remoteStoragePoolLookupByVolume (virStor remote_storage_pool_lookup_by_volume_ret ret; struct private_data *priv = vol->conn->storagePrivateData; + remoteDriverLock(priv); + make_nonnull_storage_vol (&args.vol, vol); memset (&ret, 0, sizeof ret); @@ -3547,6 +3839,7 @@ remoteStoragePoolLookupByVolume (virStor xdr_free ((xdrproc_t) &xdr_remote_storage_pool_lookup_by_volume_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return pool; } @@ -3559,6 +3852,8 @@ remoteStoragePoolCreateXML (virConnectPt remote_storage_pool_create_xml_ret ret; struct private_data *priv = conn->storagePrivateData; + remoteDriverLock(priv); + args.xml = (char *) xmlDesc; args.flags = flags; @@ -3572,6 +3867,7 @@ remoteStoragePoolCreateXML (virConnectPt xdr_free ((xdrproc_t) &xdr_remote_storage_pool_create_xml_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return pool; } @@ -3583,6 +3879,8 @@ remoteStoragePoolDefineXML (virConnectPt remote_storage_pool_define_xml_ret ret; struct private_data *priv = conn->storagePrivateData; + remoteDriverLock(priv); + args.xml = (char *) xml; args.flags = flags; @@ -3596,6 +3894,7 @@ remoteStoragePoolDefineXML (virConnectPt xdr_free ((xdrproc_t) &xdr_remote_storage_pool_define_xml_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return pool; } @@ -3605,6 +3904,8 @@ remoteStoragePoolUndefine (virStoragePoo int rv = -1; remote_storage_pool_undefine_args args; struct private_data *priv = pool->conn->storagePrivateData; + + remoteDriverLock(priv); make_nonnull_storage_pool (&args.pool, pool); @@ -3616,6 +3917,7 @@ remoteStoragePoolUndefine (virStoragePoo rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3625,6 +3927,8 @@ remoteStoragePoolCreate (virStoragePoolP int rv = -1; remote_storage_pool_create_args args; struct private_data *priv = pool->conn->storagePrivateData; + + remoteDriverLock(priv); make_nonnull_storage_pool (&args.pool, pool); args.flags = flags; @@ -3637,6 +3941,7 @@ remoteStoragePoolCreate (virStoragePoolP rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3648,6 +3953,8 @@ remoteStoragePoolBuild (virStoragePoolPt remote_storage_pool_build_args args; struct private_data *priv = pool->conn->storagePrivateData; + remoteDriverLock(priv); + make_nonnull_storage_pool (&args.pool, pool); args.flags = flags; @@ -3659,6 +3966,7 @@ remoteStoragePoolBuild (virStoragePoolPt rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3668,6 +3976,8 @@ remoteStoragePoolDestroy (virStoragePool int rv = -1; remote_storage_pool_destroy_args args; struct private_data *priv = pool->conn->storagePrivateData; + + remoteDriverLock(priv); make_nonnull_storage_pool (&args.pool, pool); @@ -3679,6 +3989,7 @@ remoteStoragePoolDestroy (virStoragePool rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3690,6 +4001,8 @@ remoteStoragePoolDelete (virStoragePoolP remote_storage_pool_delete_args args; struct private_data *priv = pool->conn->storagePrivateData; + remoteDriverLock(priv); + make_nonnull_storage_pool (&args.pool, pool); args.flags = flags; @@ -3701,6 +4014,7 @@ remoteStoragePoolDelete (virStoragePoolP rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3712,6 +4026,8 @@ remoteStoragePoolRefresh (virStoragePool remote_storage_pool_refresh_args args; struct private_data *priv = pool->conn->storagePrivateData; + remoteDriverLock(priv); + make_nonnull_storage_pool (&args.pool, pool); args.flags = flags; @@ -3723,6 +4039,7 @@ remoteStoragePoolRefresh (virStoragePool rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3733,6 +4050,8 @@ remoteStoragePoolGetInfo (virStoragePool remote_storage_pool_get_info_args args; remote_storage_pool_get_info_ret ret; struct private_data *priv = pool->conn->storagePrivateData; + + remoteDriverLock(priv); make_nonnull_storage_pool (&args.pool, pool); @@ -3750,6 +4069,7 @@ remoteStoragePoolGetInfo (virStoragePool rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3761,6 +4081,8 @@ remoteStoragePoolDumpXML (virStoragePool remote_storage_pool_dump_xml_args args; remote_storage_pool_dump_xml_ret ret; struct private_data *priv = pool->conn->storagePrivateData; + + remoteDriverLock(priv); make_nonnull_storage_pool (&args.pool, pool); args.flags = flags; @@ -3775,6 +4097,7 @@ remoteStoragePoolDumpXML (virStoragePool rv = ret.xml; done: + remoteDriverUnlock(priv); return rv; } @@ -3785,6 +4108,8 @@ remoteStoragePoolGetAutostart (virStorag remote_storage_pool_get_autostart_args args; remote_storage_pool_get_autostart_ret ret; struct private_data *priv = pool->conn->storagePrivateData; + + remoteDriverLock(priv); make_nonnull_storage_pool (&args.pool, pool); @@ -3799,6 +4124,7 @@ remoteStoragePoolGetAutostart (virStorag rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3808,6 +4134,8 @@ remoteStoragePoolSetAutostart (virStorag int rv = -1; remote_storage_pool_set_autostart_args args; struct private_data *priv = pool->conn->storagePrivateData; + + remoteDriverLock(priv); make_nonnull_storage_pool (&args.pool, pool); args.autostart = autostart; @@ -3820,6 +4148,7 @@ remoteStoragePoolSetAutostart (virStorag rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -3831,6 +4160,8 @@ remoteStoragePoolNumOfVolumes (virStorag remote_storage_pool_num_of_volumes_args args; remote_storage_pool_num_of_volumes_ret ret; struct private_data *priv = pool->conn->storagePrivateData; + + remoteDriverLock(priv); make_nonnull_storage_pool(&args.pool, pool); @@ -3843,6 +4174,7 @@ remoteStoragePoolNumOfVolumes (virStorag rv = ret.num; done: + remoteDriverUnlock(priv); return rv; } @@ -3854,6 +4186,8 @@ remoteStoragePoolListVolumes (virStorage remote_storage_pool_list_volumes_args args; remote_storage_pool_list_volumes_ret ret; struct private_data *priv = pool->conn->storagePrivateData; + + remoteDriverLock(priv); if (maxnames > REMOTE_STORAGE_VOL_NAME_LIST_MAX) { error (pool->conn, VIR_ERR_RPC, _("too many storage volumes requested")); @@ -3887,6 +4221,7 @@ cleanup: xdr_free ((xdrproc_t) xdr_remote_storage_pool_list_volumes_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return rv; } @@ -3901,6 +4236,8 @@ remoteStorageVolLookupByName (virStorage remote_storage_vol_lookup_by_name_ret ret; struct private_data *priv = pool->conn->storagePrivateData; + remoteDriverLock(priv); + make_nonnull_storage_pool(&args.pool, pool); args.name = (char *) name; @@ -3914,6 +4251,7 @@ remoteStorageVolLookupByName (virStorage xdr_free ((xdrproc_t) &xdr_remote_storage_vol_lookup_by_name_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return vol; } @@ -3926,6 +4264,8 @@ remoteStorageVolLookupByKey (virConnectP remote_storage_vol_lookup_by_key_ret ret; struct private_data *priv = conn->storagePrivateData; + remoteDriverLock(priv); + args.key = (char *) key; memset (&ret, 0, sizeof ret); @@ -3938,6 +4278,7 @@ remoteStorageVolLookupByKey (virConnectP xdr_free ((xdrproc_t) &xdr_remote_storage_vol_lookup_by_key_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return vol; } @@ -3950,6 +4291,8 @@ remoteStorageVolLookupByPath (virConnect remote_storage_vol_lookup_by_path_ret ret; struct private_data *priv = conn->storagePrivateData; + remoteDriverLock(priv); + args.path = (char *) path; memset (&ret, 0, sizeof ret); @@ -3962,6 +4305,7 @@ remoteStorageVolLookupByPath (virConnect xdr_free ((xdrproc_t) &xdr_remote_storage_vol_lookup_by_path_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return vol; } @@ -3974,6 +4318,8 @@ remoteStorageVolCreateXML (virStoragePoo remote_storage_vol_create_xml_ret ret; struct private_data *priv = pool->conn->storagePrivateData; + remoteDriverLock(priv); + make_nonnull_storage_pool (&args.pool, pool); args.xml = (char *) xmlDesc; args.flags = flags; @@ -3988,6 +4334,7 @@ remoteStorageVolCreateXML (virStoragePoo xdr_free ((xdrproc_t) &xdr_remote_storage_vol_create_xml_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return vol; } @@ -3999,6 +4346,8 @@ remoteStorageVolDelete (virStorageVolPtr remote_storage_vol_delete_args args; struct private_data *priv = vol->conn->storagePrivateData; + remoteDriverLock(priv); + make_nonnull_storage_vol (&args.vol, vol); args.flags = flags; @@ -4010,6 +4359,7 @@ remoteStorageVolDelete (virStorageVolPtr rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -4021,6 +4371,8 @@ remoteStorageVolGetInfo (virStorageVolPt remote_storage_vol_get_info_ret ret; struct private_data *priv = vol->conn->storagePrivateData; + remoteDriverLock(priv); + make_nonnull_storage_vol (&args.vol, vol); memset (&ret, 0, sizeof ret); @@ -4036,6 +4388,7 @@ remoteStorageVolGetInfo (virStorageVolPt rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -4048,6 +4401,8 @@ remoteStorageVolDumpXML (virStorageVolPt remote_storage_vol_dump_xml_ret ret; struct private_data *priv = vol->conn->storagePrivateData; + remoteDriverLock(priv); + make_nonnull_storage_vol (&args.vol, vol); args.flags = flags; @@ -4061,6 +4416,7 @@ remoteStorageVolDumpXML (virStorageVolPt rv = ret.xml; done: + remoteDriverUnlock(priv); return rv; } @@ -4072,6 +4428,8 @@ remoteStorageVolGetPath (virStorageVolPt remote_storage_vol_get_path_ret ret; struct private_data *priv = vol->conn->storagePrivateData; + remoteDriverLock(priv); + make_nonnull_storage_vol (&args.vol, vol); memset (&ret, 0, sizeof ret); @@ -4084,6 +4442,7 @@ remoteStorageVolGetPath (virStorageVolPt rv = ret.name; done: + remoteDriverUnlock(priv); return rv; } @@ -4095,19 +4454,63 @@ remoteDevMonOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED) { + if (inside_daemon) + return VIR_DRV_OPEN_DECLINED; + if (conn && conn->driver && STREQ (conn->driver->name, "remote")) { + struct private_data *priv = conn->privateData; /* If we're here, the remote driver is already * in use due to a) a QEMU uri, or b) a remote * URI. So we can re-use existing connection */ - conn->devMonPrivateData = conn->privateData; + remoteDriverLock(priv); + priv->localUses++; + conn->devMonPrivateData = priv; + remoteDriverUnlock(priv); return VIR_DRV_OPEN_SUCCESS; - } - - /* Decline open. Will fallback to appropriate local node driver. */ - return VIR_DRV_OPEN_DECLINED; + } else if (conn->networkDriver && + STREQ (conn->networkDriver->name, "remote")) { + struct private_data *priv = conn->networkPrivateData; + remoteDriverLock(priv); + conn->devMonPrivateData = priv; + priv->localUses++; + remoteDriverUnlock(priv); + return VIR_DRV_OPEN_SUCCESS; + } else { + /* Using a non-remote driver, so we need to open a + * new connection for network APIs, forcing it to + * use the UNIX transport. This handles Xen driver + * which doesn't have its own impl of the network APIs. + */ + struct private_data *priv; + int ret, rflags = 0; + if (VIR_ALLOC(priv) < 0) { + error (NULL, VIR_ERR_NO_MEMORY, _("struct private_data")); + return VIR_DRV_OPEN_ERROR; + } + if (virMutexInit(&priv->lock) < 0) { + error(conn, VIR_ERR_INTERNAL_ERROR, + _("cannot initialize mutex")); + VIR_FREE(priv); + return VIR_DRV_OPEN_ERROR; + } + if (flags & VIR_CONNECT_RO) + rflags |= VIR_DRV_OPEN_REMOTE_RO; + rflags |= VIR_DRV_OPEN_REMOTE_UNIX; + + priv->sock = -1; + ret = doRemoteOpen(conn, priv, auth, rflags); + if (ret != VIR_DRV_OPEN_SUCCESS) { + conn->devMonPrivateData = NULL; + VIR_FREE(priv); + } else { + priv->localUses = 1; + conn->devMonPrivateData = priv; + } + return ret; + } } static int remoteDevMonClose(virConnectPtr conn) @@ -4115,14 +4518,17 @@ static int remoteDevMonClose(virConnectP int ret = 0; struct private_data *priv = conn->devMonPrivateData; - if (priv->localUses) { - priv->localUses--; - if (!priv->localUses) { - ret = doRemoteClose(conn, priv); - VIR_FREE(priv); - conn->devMonPrivateData = NULL; - } - } + remoteDriverLock(priv); + priv->localUses--; + if (!priv->localUses) { + ret = doRemoteClose(conn, priv); + conn->devMonPrivateData = NULL; + remoteDriverUnlock(priv); + virMutexDestroy(&priv->lock); + VIR_FREE(priv); + } + if (priv) + remoteDriverUnlock(priv); return ret; } @@ -4135,6 +4541,8 @@ static int remoteNodeNumOfDevices(virCon remote_node_num_of_devices_ret ret; struct private_data *priv = conn->devMonPrivateData; + remoteDriverLock(priv); + args.cap = cap ? (char **)&cap : NULL; args.flags = flags; @@ -4147,6 +4555,7 @@ static int remoteNodeNumOfDevices(virCon rv = ret.num; done: + remoteDriverUnlock(priv); return rv; } @@ -4163,6 +4572,8 @@ static int remoteNodeListDevices(virConn remote_node_list_devices_ret ret; struct private_data *priv = conn->devMonPrivateData; + remoteDriverLock(priv); + if (maxnames > REMOTE_NODE_DEVICE_NAME_LIST_MAX) { error (conn, VIR_ERR_RPC, _("too many device names requested")); goto done; @@ -4196,6 +4607,7 @@ cleanup: xdr_free ((xdrproc_t) xdr_remote_node_list_devices_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return rv; } @@ -4208,6 +4620,8 @@ static virNodeDevicePtr remoteNodeDevice virNodeDevicePtr dev = NULL; struct private_data *priv = conn->devMonPrivateData; + remoteDriverLock(priv); + args.name = (char *)name; memset (&ret, 0, sizeof ret); @@ -4221,6 +4635,7 @@ static virNodeDevicePtr remoteNodeDevice xdr_free ((xdrproc_t) xdr_remote_node_device_lookup_by_name_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return dev; } @@ -4232,6 +4647,8 @@ static char *remoteNodeDeviceDumpXML(vir remote_node_device_dump_xml_ret ret; struct private_data *priv = dev->conn->devMonPrivateData; + remoteDriverLock(priv); + args.name = dev->name; args.flags = flags; @@ -4245,6 +4662,7 @@ static char *remoteNodeDeviceDumpXML(vir rv = ret.xml; done: + remoteDriverUnlock(priv); return rv; } @@ -4255,6 +4673,8 @@ static char *remoteNodeDeviceGetParent(v remote_node_device_get_parent_ret ret; struct private_data *priv = dev->conn->devMonPrivateData; + remoteDriverLock(priv); + args.name = dev->name; memset (&ret, 0, sizeof ret); @@ -4267,6 +4687,7 @@ static char *remoteNodeDeviceGetParent(v rv = ret.parent ? *ret.parent : NULL; done: + remoteDriverUnlock(priv); return rv; } @@ -4277,6 +4698,8 @@ static int remoteNodeDeviceNumOfCaps(vir remote_node_device_num_of_caps_ret ret; struct private_data *priv = dev->conn->devMonPrivateData; + remoteDriverLock(priv); + args.name = dev->name; memset (&ret, 0, sizeof ret); @@ -4288,6 +4711,7 @@ static int remoteNodeDeviceNumOfCaps(vir rv = ret.num; done: + remoteDriverUnlock(priv); return rv; } @@ -4301,6 +4725,8 @@ static int remoteNodeDeviceListCaps(virN remote_node_device_list_caps_ret ret; struct private_data *priv = dev->conn->devMonPrivateData; + remoteDriverLock(priv); + if (maxnames > REMOTE_NODE_DEVICE_CAPS_LIST_MAX) { error (dev->conn, VIR_ERR_RPC, _("too many capability names requested")); goto done; @@ -4333,6 +4759,7 @@ cleanup: xdr_free ((xdrproc_t) xdr_remote_node_device_list_caps_ret, (char *) &ret); done: + remoteDriverUnlock(priv); return rv; } @@ -5058,6 +5485,10 @@ static int remoteDomainEventRegister (vi int rv = -1; struct private_data *priv = conn->privateData; + remoteDriverLock(priv); + + remoteDriverLock(priv); + if (priv->eventFlushTimer < 0) { error (conn, VIR_ERR_NO_SUPPORT, _("no event support")); goto done; @@ -5079,6 +5510,7 @@ static int remoteDomainEventRegister (vi rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -5105,6 +5537,7 @@ static int remoteDomainEventDeregister ( rv = 0; done: + remoteDriverUnlock(priv); return rv; } @@ -5895,6 +6328,8 @@ remoteDomainEventFired(int watch, virConnectPtr conn = opaque; struct private_data *priv = conn->privateData; + remoteDriverLock(priv); + DEBUG("Event fired %d %d %d %X", watch, fd, event, event); if (event & (VIR_EVENT_HANDLE_HANGUP | VIR_EVENT_HANDLE_ERROR)) { @@ -5951,7 +6386,7 @@ remoteDomainEventFired(int watch, } done: - return; + remoteDriverUnlock(priv); } void @@ -5959,8 +6394,12 @@ remoteDomainEventQueueFlush(int timer AT { virConnectPtr conn = opaque; struct private_data *priv = conn->privateData; + + remoteDriverLock(priv); virDomainEventQueueDispatch(priv->domainEvents, priv->callbackList, virDomainEventDispatchDefaultFunc, NULL); virEventUpdateTimeout(priv->eventFlushTimer, -1); -} + + remoteDriverUnlock(priv); +} -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list