static int storageDriverShutdown(void);
+static void storageDriverLock(virStorageDriverStatePtr driver)
+{
+ pthread_mutex_lock(&driver->lock);
+}
+static void storageDriverUnlock(virStorageDriverStatePtr driver)
+{
+ pthread_mutex_unlock(&driver->lock);
+}
static void
storageDriverAutostart(virStorageDriverStatePtr driver) {
for (i = 0 ; i < driver->pools.count ; i++) {
virStoragePoolObjPtr pool = driver->pools.objs[i];
+ virStoragePoolObjLock(pool);
if (pool->autostart &&
!virStoragePoolObjIsActive(pool)) {
virStorageBackendPtr backend;
if ((backend = virStorageBackendForType(pool->def->type)) == NULL) {
storageLog("Missing backend %d",
pool->def->type);
+ virStoragePoolObjUnlock(pool);
continue;
}
virErrorPtr err = virGetLastError();
storageLog("Failed to autostart storage pool '%s': %s",
pool->def->name, err ? err->message : NULL);
+ virStoragePoolObjUnlock(pool);
continue;
}
backend->stopPool(NULL, pool);
storageLog("Failed to autostart storage pool '%s': %s",
pool->def->name, err ? err->message : NULL);
+ virStoragePoolObjUnlock(pool);
continue;
}
pool->active = 1;
}
+ virStoragePoolObjUnlock(pool);
}
}
if (VIR_ALLOC(driverState) < 0)
return -1;
+ pthread_mutex_init(&driverState->lock, NULL);
+ storageDriverLock(driverState);
+
if (!uid) {
if ((base = strdup (SYSCONF_DIR "/libvirt")) == NULL)
goto out_of_memory;
"%s/storage/autostart", base) == -1)
goto out_of_memory;
- free(base);
- base = NULL;
+ VIR_FREE(base);
/*
if (virStorageLoadDriverConfig(driver, driverConf) < 0) {
if (virStoragePoolLoadAllConfigs(NULL,
&driverState->pools,
driverState->configDir,
- driverState->autostartDir) < 0) {
- storageDriverShutdown();
- return -1;
- }
+ driverState->autostartDir) < 0)
+ goto error;
storageDriverAutostart(driverState);
+ storageDriverUnlock(driverState);
return 0;
- out_of_memory:
+out_of_memory:
storageLog("virStorageStartup: out of memory");
- free(base);
- free(driverState);
- driverState = NULL;
+error:
+ VIR_FREE(base);
+ storageDriverUnlock(driverState);
+ storageDriverShutdown();
return -1;
}
if (!driverState)
return -1;
+ storageDriverLock(driverState);
virStoragePoolLoadAllConfigs(NULL,
&driverState->pools,
driverState->configDir,
driverState->autostartDir);
storageDriverAutostart(driverState);
+ storageDriverUnlock(driverState);
return 0;
}
static int
storageDriverActive(void) {
unsigned int i;
+ int active = 0;
if (!driverState)
return 0;
- /* If we've any active networks or guests, then we
- * mark this driver as active
- */
- for (i = 0 ; i < driverState->pools.count ; i++)
+ storageDriverLock(driverState);
+
+ for (i = 0 ; i < driverState->pools.count ; i++) {
+ virStoragePoolObjLock(driverState->pools.objs[i]);
if (virStoragePoolObjIsActive(driverState->pools.objs[i]))
- return 1;
+ active = 1;
+ virStoragePoolObjUnlock(driverState->pools.objs[i]);
+ }
- /* Otherwise we're happy to deal with a shutdown */
- return 0;
+ storageDriverUnlock(driverState);
+ return active;
}
/**
if (!driverState)
return -1;
+ storageDriverLock(driverState);
/* shutdown active pools */
for (i = 0 ; i < driverState->pools.count ; i++) {
virStoragePoolObjPtr pool = driverState->pools.objs[i];
VIR_FREE(driverState->configDir);
VIR_FREE(driverState->autostartDir);
+ storageDriverUnlock(driverState);
VIR_FREE(driverState);
return 0;
virStoragePoolObjPtr pool;
virStoragePoolPtr ret = NULL;
+ storageDriverLock(driver);
pool = virStoragePoolObjFindByUUID(&driver->pools, uuid);
+ storageDriverUnlock(driver);
+
if (!pool) {
virStorageReportError(conn, VIR_ERR_NO_STORAGE_POOL,
"%s", _("no pool with matching uuid"));
ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid);
cleanup:
+ if (pool)
+ virStoragePoolObjUnlock(pool);
return ret;
}
virStoragePoolObjPtr pool;
virStoragePoolPtr ret = NULL;
+ storageDriverLock(driver);
pool = virStoragePoolObjFindByName(&driver->pools, name);
+ storageDriverUnlock(driver);
+
if (!pool) {
virStorageReportError(conn, VIR_ERR_NO_STORAGE_POOL,
"%s", _("no pool with matching name"));
ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid);
cleanup:
+ if (pool)
+ virStoragePoolObjUnlock(pool);
return ret;
}
virStorageDriverStatePtr driver = conn->storagePrivateData;
unsigned int i, nactive = 0;
- for (i = 0 ; i < driver->pools.count ; i++)
+ storageDriverLock(driver);
+ for (i = 0 ; i < driver->pools.count ; i++) {
+ virStoragePoolObjLock(driver->pools.objs[i]);
if (virStoragePoolObjIsActive(driver->pools.objs[i]))
nactive++;
+ virStoragePoolObjUnlock(driver->pools.objs[i]);
+ }
+ storageDriverUnlock(driver);
return nactive;
}
virStorageDriverStatePtr driver = conn->storagePrivateData;
int got = 0, i;
+ storageDriverLock(driver);
for (i = 0 ; i < driver->pools.count && got < nnames ; i++) {
+ virStoragePoolObjLock(driver->pools.objs[i]);
if (virStoragePoolObjIsActive(driver->pools.objs[i])) {
if (!(names[got] = strdup(driver->pools.objs[i]->def->name))) {
+ virStoragePoolObjUnlock(driver->pools.objs[i]);
virStorageReportError(conn, VIR_ERR_NO_MEMORY,
"%s", _("names"));
goto cleanup;
}
got++;
}
+ virStoragePoolObjUnlock(driver->pools.objs[i]);
}
+ storageDriverUnlock(driver);
return got;
cleanup:
- for (i = 0 ; i < got ; i++) {
- free(names[i]);
- names[i] = NULL;
- }
+ storageDriverUnlock(driver);
+ for (i = 0 ; i < got ; i++)
+ VIR_FREE(names[i]);
memset(names, 0, nnames * sizeof(*names));
return -1;
}
virStorageDriverStatePtr driver = conn->storagePrivateData;
unsigned int i, nactive = 0;
- for (i = 0 ; i < driver->pools.count ; i++)
+ storageDriverLock(driver);
+ for (i = 0 ; i < driver->pools.count ; i++) {
+ virStoragePoolObjLock(driver->pools.objs[i]);
if (!virStoragePoolObjIsActive(driver->pools.objs[i]))
nactive++;
+ virStoragePoolObjUnlock(driver->pools.objs[i]);
+ }
+ storageDriverUnlock(driver);
return nactive;
}
virStorageDriverStatePtr driver = conn->storagePrivateData;
int got = 0, i;
+ storageDriverLock(driver);
for (i = 0 ; i < driver->pools.count && got < nnames ; i++) {
+ virStoragePoolObjLock(driver->pools.objs[i]);
if (!virStoragePoolObjIsActive(driver->pools.objs[i])) {
if (!(names[got] = strdup(driver->pools.objs[i]->def->name))) {
+ virStoragePoolObjUnlock(driver->pools.objs[i]);
virStorageReportError(conn, VIR_ERR_NO_MEMORY,
"%s", _("names"));
goto cleanup;
}
got++;
}
+ virStoragePoolObjUnlock(driver->pools.objs[i]);
}
+ storageDriverUnlock(driver);
return got;
cleanup:
+ storageDriverUnlock(driver);
for (i = 0 ; i < got ; i++) {
free(names[i]);
names[i] = NULL;
return -1;
}
+/* This method is required to be re-entrant / thread safe, so
+ uses no driver lock */
static char *
storageFindPoolSources(virConnectPtr conn,
const char *type,
unsigned int flags ATTRIBUTE_UNUSED) {
virStorageDriverStatePtr driver = conn->storagePrivateData;
virStoragePoolDefPtr def;
- virStoragePoolObjPtr pool;
+ virStoragePoolObjPtr pool = NULL;
virStoragePoolPtr ret = NULL;
virStorageBackendPtr backend;
+ storageDriverLock(driver);
if (!(def = virStoragePoolDefParse(conn, xml, NULL)))
goto cleanup;
cleanup:
virStoragePoolDefFree(def);
+ if (pool)
+ virStoragePoolObjUnlock(pool);
+ storageDriverUnlock(driver);
return ret;
}
unsigned int flags ATTRIBUTE_UNUSED) {
virStorageDriverStatePtr driver = conn->storagePrivateData;
virStoragePoolDefPtr def;
- virStoragePoolObjPtr pool;
+ virStoragePoolObjPtr pool = NULL;
virStoragePoolPtr ret = NULL;
virStorageBackendPtr backend;
+ storageDriverLock(driver);
if (!(def = virStoragePoolDefParse(conn, xml, NULL)))
goto cleanup;
cleanup:
virStoragePoolDefFree(def);
+ if (pool)
+ virStoragePoolObjUnlock(pool);
+ storageDriverUnlock(driver);
return ret;
}
virStoragePoolObjPtr pool;
int ret = -1;
+ storageDriverLock(driver);
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
if (!pool) {
virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL,
VIR_FREE(pool->autostartLink);
virStoragePoolObjRemove(&driver->pools, pool);
+ pool = NULL;
ret = 0;
cleanup:
+ if (pool)
+ virStoragePoolObjUnlock(pool);
+ storageDriverUnlock(driver);
return ret;
}
virStorageBackendPtr backend;
int ret = -1;
+ storageDriverLock(driver);
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
+ storageDriverUnlock(driver);
+
if (!pool) {
virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL,
"%s", _("no storage pool with matching uuid"));
ret = 0;
cleanup:
+ if (pool)
+ virStoragePoolObjUnlock(pool);
return ret;
}
virStorageBackendPtr backend;
int ret = -1;
+ storageDriverLock(driver);
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
+ storageDriverUnlock(driver);
+
if (!pool) {
virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL,
"%s", _("no storage pool with matching uuid"));
ret = 0;
cleanup:
+ if (pool)
+ virStoragePoolObjUnlock(pool);
return ret;
}
virStorageBackendPtr backend;
int ret = -1;
+ storageDriverLock(driver);
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
+
if (!pool) {
virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL,
"%s", _("no storage pool with matching uuid"));
pool->active = 0;
- if (pool->configFile == NULL)
+ if (pool->configFile == NULL) {
virStoragePoolObjRemove(&driver->pools, pool);
+ pool = NULL;
+ }
ret = 0;
cleanup:
+ if (pool)
+ virStoragePoolObjUnlock(pool);
+ storageDriverUnlock(driver);
return ret;
}
virStorageBackendPtr backend;
int ret = -1;
+ storageDriverLock(driver);
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
+ storageDriverUnlock(driver);
+
if (!pool) {
virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL,
"%s", _("no storage pool with matching uuid"));
ret = 0;
cleanup:
+ if (pool)
+ virStoragePoolObjUnlock(pool);
return ret;
}
virStorageBackendPtr backend;
int ret = -1;
+ storageDriverLock(driver);
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
+ storageDriverUnlock(driver);
+
if (!pool) {
virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL,
"%s", _("no storage pool with matching uuid"));
pool->active = 0;
- if (pool->configFile == NULL)
+ if (pool->configFile == NULL) {
virStoragePoolObjRemove(&driver->pools, pool);
+ pool = NULL;
+ }
goto cleanup;
}
ret = 0;
cleanup:
+ if (pool)
+ virStoragePoolObjUnlock(pool);
return ret;
}
virStorageBackendPtr backend;
int ret = -1;
+ storageDriverLock(driver);
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
+ storageDriverUnlock(driver);
+
if (!pool) {
virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL,
"%s", _("no storage pool with matching uuid"));
ret = 0;
cleanup:
+ if (pool)
+ virStoragePoolObjUnlock(pool);
return ret;
}
virStoragePoolObjPtr pool;
char *ret = NULL;
+ storageDriverLock(driver);
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
+ storageDriverUnlock(driver);
+
if (!pool) {
virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL,
"%s", _("no storage pool with matching uuid"));
ret = virStoragePoolDefFormat(obj->conn, pool->def);
cleanup:
+ if (pool)
+ virStoragePoolObjUnlock(pool);
return ret;
}
virStoragePoolObjPtr pool;
int ret = -1;
+ storageDriverLock(driver);
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
+ storageDriverUnlock(driver);
+
if (!pool) {
virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL,
"%s", _("no pool with matching uuid"));
virStoragePoolObjPtr pool;
int ret = -1;
+ storageDriverLock(driver);
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
+ storageDriverUnlock(driver);
+
if (!pool) {
virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL,
"%s", _("no pool with matching uuid"));
ret = 0;
cleanup:
+ if (pool)
+ virStoragePoolObjUnlock(pool);
return ret;
}
virStoragePoolObjPtr pool;
int ret = -1;
+ storageDriverLock(driver);
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
+ storageDriverUnlock(driver);
+
if (!pool) {
virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL,
"%s", _("no storage pool with matching uuid"));
ret = pool->volumes.count;
cleanup:
+ if (pool)
+ virStoragePoolObjUnlock(pool);
return ret;
}
memset(names, 0, maxnames * sizeof(*names));
+ storageDriverLock(driver);
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
+ storageDriverUnlock(driver);
+
if (!pool) {
virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL,
"%s", _("no storage pool with matching uuid"));
}
}
+ virStoragePoolObjUnlock(pool);
return n;
cleanup:
+ if (pool)
+ virStoragePoolObjUnlock(pool);
for (n = 0 ; n < maxnames ; n++)
VIR_FREE(names[n]);
virStorageVolDefPtr vol;
virStorageVolPtr ret = NULL;
+ storageDriverLock(driver);
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
+ storageDriverUnlock(driver);
+
if (!pool) {
virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL,
"%s", _("no storage pool with matching uuid"));
ret = virGetStorageVol(obj->conn, pool->def->name, vol->name, vol->key);
cleanup:
+ if (pool)
+ virStoragePoolObjUnlock(pool);
return ret;
}
unsigned int i;
virStorageVolPtr ret = NULL;
- for (i = 0 ; i < driver->pools.count ; i++) {
+ storageDriverLock(driver);
+ for (i = 0 ; i < driver->pools.count && !ret ; i++) {
+ virStoragePoolObjLock(driver->pools.objs[i]);
if (virStoragePoolObjIsActive(driver->pools.objs[i])) {
virStorageVolDefPtr vol =
virStorageVolDefFindByKey(driver->pools.objs[i], key);
- if (vol) {
+ if (vol)
ret = virGetStorageVol(conn,
- driver->pools.objs[i]->def->name,
- vol->name,
- vol->key);
- break;
- }
+ driver->pools.objs[i]->def->name,
+ vol->name,
+ vol->key);
}
+ virStoragePoolObjUnlock(driver->pools.objs[i]);
}
+ storageDriverUnlock(driver);
if (!ret)
virStorageReportError(conn, VIR_ERR_INVALID_STORAGE_VOL,
unsigned int i;
virStorageVolPtr ret = NULL;
- for (i = 0 ; i < driver->pools.count ; i++) {
+ storageDriverLock(driver);
+ for (i = 0 ; i < driver->pools.count && !ret ; i++) {
+ virStoragePoolObjLock(driver->pools.objs[i]);
if (virStoragePoolObjIsActive(driver->pools.objs[i])) {
virStorageVolDefPtr vol;
const char *stable_path;
* virStorageReportError if it fails; we just need to keep
* propagating the return code
*/
- if (stable_path == NULL)
+ if (stable_path == NULL) {
+ virStoragePoolObjUnlock(driver->pools.objs[i]);
goto cleanup;
+ }
vol = virStorageVolDefFindByPath(driver->pools.objs[i],
stable_path);
VIR_FREE(stable_path);
- if (vol) {
+ if (vol)
ret = virGetStorageVol(conn,
driver->pools.objs[i]->def->name,
vol->name,
vol->key);
- break;
- }
}
+ virStoragePoolObjUnlock(driver->pools.objs[i]);
}
if (!ret)
"%s", _("no storage vol with matching path"));
cleanup:
+ storageDriverUnlock(driver);
return ret;
}
virStorageVolDefPtr vol = NULL;
virStorageVolPtr ret = NULL;
+ storageDriverLock(driver);
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
+ storageDriverUnlock(driver);
+
if (!pool) {
virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL,
"%s", _("no storage pool with matching uuid"));
goto cleanup;
}
+ /* XXX ought to drop pool lock while creating instance */
if (backend->createVol(obj->conn, pool, vol) < 0) {
goto cleanup;
}
cleanup:
virStorageVolDefFree(vol);
+ if (pool)
+ virStoragePoolObjUnlock(pool);
return ret;
}
unsigned int i;
int ret = -1;
+ storageDriverLock(driver);
pool = virStoragePoolObjFindByName(&driver->pools, obj->pool);
+ storageDriverUnlock(driver);
+
if (!pool) {
virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL,
"%s", _("no storage pool with matching uuid"));
cleanup:
virStorageVolDefFree(vol);
+ if (pool)
+ virStoragePoolObjUnlock(pool);
return ret;
}
virStorageVolDefPtr vol;
int ret = -1;
+ storageDriverLock(driver);
pool = virStoragePoolObjFindByName(&driver->pools, obj->pool);
+ storageDriverUnlock(driver);
+
if (!pool) {
virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL,
"%s", _("no storage pool with matching uuid"));
ret = 0;
cleanup:
+ if (pool)
+ virStoragePoolObjUnlock(pool);
return ret;
}
virStorageVolDefPtr vol;
char *ret = NULL;
+ storageDriverLock(driver);
pool = virStoragePoolObjFindByName(&driver->pools, obj->pool);
+ storageDriverUnlock(driver);
+
if (!pool) {
virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL,
"%s", _("no storage pool with matching uuid"));
ret = virStorageVolDefFormat(obj->conn, pool->def, vol);
cleanup:
+ if (pool)
+ virStoragePoolObjUnlock(pool);
+
return ret;
}
static char *
storageVolumeGetPath(virStorageVolPtr obj) {
virStorageDriverStatePtr driver = obj->conn->storagePrivateData;
- virStoragePoolObjPtr pool = virStoragePoolObjFindByName(&driver->pools, obj->pool);
+ virStoragePoolObjPtr pool;
virStorageVolDefPtr vol;
char *ret = NULL;
+ storageDriverLock(driver);
+ pool = virStoragePoolObjFindByName(&driver->pools, obj->pool);
+ storageDriverUnlock(driver);
if (!pool) {
virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL,
"%s", _("no storage pool with matching uuid"));
virStorageReportError(obj->conn, VIR_ERR_NO_MEMORY, "%s", _("path"));
cleanup:
+ if (pool)
+ virStoragePoolObjUnlock(pool);
return ret;
}