diff --git a/ChangeLog b/ChangeLog index 5e3e38952076d9b8541e301dc624f5f0c7e23965..88a433a42b4f0160f5cd0e113da393c3b6c83acd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Fri Oct 10 15:39:00 BST 2008 Daniel P. Berrange + + * src/storage_conf.c, src/storage_conf.h, src/storage_driver.c, + src/storage_backend_disk.c, src/storage_backend_fs.c, + src/storage_backend_iscsi.c, src/storage_backend_logical.c: + Switch storage objects to array instead of linked list + Fri Oct 10 15:39:00 BST 2008 Daniel P. Berrange * src/network_conf.c, src/network_conf.h, src/network_driver.c, diff --git a/src/storage_backend_disk.c b/src/storage_backend_disk.c index e9c94462917fba9f04138dd038a716afd017dde5..bb134c7ed4f96f22e67737c267109e9d7953b3ed 100644 --- a/src/storage_backend_disk.c +++ b/src/storage_backend_disk.c @@ -182,9 +182,13 @@ virStorageBackendDiskMakeDataVol(virConnectPtr conn, return -1; } - vol->next = pool->volumes; - pool->volumes = vol; - pool->nvolumes++; + if (VIR_REALLOC_N(pool->volumes.objs, + pool->volumes.count+1) < 0) { + virStorageReportError(conn, VIR_ERR_NO_MEMORY, _("volume")); + virStorageVolDefFree(vol); + return -1; + } + pool->volumes.objs[pool->volumes.count++] = vol; /* Prepended path will be same for all partitions, so we can * strip the path to form a reasonable pool-unique name diff --git a/src/storage_backend_fs.c b/src/storage_backend_fs.c index dd4c79ce2933e352e13866a66eed980dbf49906d..d3f41962afb4304a2794388648bffa37e781c7ac 100644 --- a/src/storage_backend_fs.c +++ b/src/storage_backend_fs.c @@ -822,6 +822,7 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn, DIR *dir; struct dirent *ent; struct statvfs sb; + virStorageVolDefPtr vol = NULL; if (!(dir = opendir(pool->def->target.path))) { virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, @@ -831,61 +832,42 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn, } while ((ent = readdir(dir)) != NULL) { - virStorageVolDefPtr vol; int ret; - if (VIR_ALLOC(vol) < 0) { - virStorageReportError(conn, VIR_ERR_NO_MEMORY, - "%s", _("volume")); - goto cleanup; - } + if (VIR_ALLOC(vol) < 0) + goto no_memory; - vol->name = strdup(ent->d_name); - if (vol->name == NULL) { - VIR_FREE(vol); - virStorageReportError(conn, VIR_ERR_NO_MEMORY, - "%s", _("volume name")); - goto cleanup; - } + if ((vol->name = strdup(ent->d_name)) == NULL) + goto no_memory; vol->target.format = VIR_STORAGE_VOL_RAW; /* Real value is filled in during probe */ if (VIR_ALLOC_N(vol->target.path, strlen(pool->def->target.path) + - 1 + strlen(vol->name) + 1) < 0) { - VIR_FREE(vol->target.path); - VIR_FREE(vol); - virStorageReportError(conn, VIR_ERR_NO_MEMORY, - "%s", _("volume name")); - goto cleanup; - } + 1 + strlen(vol->name) + 1) < 0) + goto no_memory; + strcpy(vol->target.path, pool->def->target.path); strcat(vol->target.path, "/"); strcat(vol->target.path, vol->name); - if ((vol->key = strdup(vol->target.path)) == NULL) { - VIR_FREE(vol->name); - VIR_FREE(vol->target.path); - VIR_FREE(vol); - virStorageReportError(conn, VIR_ERR_NO_MEMORY, - "%s", _("volume key")); - goto cleanup; - } + if ((vol->key = strdup(vol->target.path)) == NULL) + goto no_memory; if ((ret = virStorageBackendProbeFile(conn, vol) < 0)) { - VIR_FREE(vol->key); - VIR_FREE(vol->name); - VIR_FREE(vol->target.path); - VIR_FREE(vol); if (ret == -1) - goto cleanup; - else + goto no_memory; + else { /* Silently ignore non-regular files, * eg '.' '..', 'lost+found' */ + virStorageVolDefFree(vol); + vol = NULL; continue; + } } - vol->next = pool->volumes; - pool->volumes = vol; - pool->nvolumes++; - continue; + if (VIR_REALLOC_N(pool->volumes.objs, + pool->volumes.count+1) < 0) + goto no_memory; + pool->volumes.objs[pool->volumes.count++] = vol; + vol = NULL; } closedir(dir); @@ -904,8 +886,13 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn, return 0; +no_memory: + virStorageReportError(conn, VIR_ERR_NO_MEMORY, NULL); + /* fallthrough */ + cleanup: closedir(dir); + virStorageVolDefFree(vol); virStoragePoolObjClearVols(pool); return -1; } diff --git a/src/storage_backend_iscsi.c b/src/storage_backend_iscsi.c index 4f1906a051be4297d60828ff0d55d9c0e5bfb012..a556361fd8672bafd7e77b9a6b37493f4ab46d0f 100644 --- a/src/storage_backend_iscsi.c +++ b/src/storage_backend_iscsi.c @@ -236,9 +236,12 @@ virStorageBackendISCSINewLun(virConnectPtr conn, virStoragePoolObjPtr pool, pool->def->capacity += vol->capacity; pool->def->allocation += vol->allocation; - vol->next = pool->volumes; - pool->volumes = vol; - pool->nvolumes++; + if (VIR_REALLOC_N(pool->volumes.objs, + pool->volumes.count+1) < 0) { + virStorageReportError(conn, VIR_ERR_NO_MEMORY, NULL); + goto cleanup; + } + pool->volumes.objs[pool->volumes.count++] = vol; close(fd); diff --git a/src/storage_backend_logical.c b/src/storage_backend_logical.c index 1212c672d5a9c77013d274e4576d659ac2cd72c4..c549f26b7bc004f877b36c8a4229bc07c4aef71e 100644 --- a/src/storage_backend_logical.c +++ b/src/storage_backend_logical.c @@ -119,12 +119,17 @@ virStorageBackendLogicalMakeVol(virConnectPtr conn, if ((vol->name = strdup(groups[0])) == NULL) { virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("volume")); + virStorageVolDefFree(vol); return -1; } - vol->next = pool->volumes; - pool->volumes = vol; - pool->nvolumes++; + if (VIR_REALLOC_N(pool->volumes.objs, + pool->volumes.count + 1)) { + virStorageReportError(conn, VIR_ERR_NO_MEMORY, NULL); + virStorageVolDefFree(vol); + return -1; + } + pool->volumes.objs[pool->volumes.count++] = vol; } if (vol->target.path == NULL) { diff --git a/src/storage_conf.c b/src/storage_conf.c index 5884e9c6ce4c63064a0aa85ac69d9caa8ddc827c..4398ccfb24b03ed904c7bdd1cd5dbe388f44e7ab 100644 --- a/src/storage_conf.c +++ b/src/storage_conf.c @@ -52,6 +52,10 @@ void virStorageVolDefFree(virStorageVolDefPtr def) { int i; + + if (!def) + return; + VIR_FREE(def->name); VIR_FREE(def->key); @@ -69,6 +73,9 @@ void virStoragePoolDefFree(virStoragePoolDefPtr def) { int i; + if (!def) + return; + VIR_FREE(def->name); VIR_FREE(def->source.host.name); for (i = 0 ; i < def->source.ndevice ; i++) { @@ -92,38 +99,48 @@ virStoragePoolDefFree(virStoragePoolDefPtr def) { void virStoragePoolObjFree(virStoragePoolObjPtr obj) { - if (obj->def) - virStoragePoolDefFree(obj->def); - if (obj->newDef) - virStoragePoolDefFree(obj->newDef); + if (!obj) + return; + + virStoragePoolDefFree(obj->def); + virStoragePoolDefFree(obj->newDef); VIR_FREE(obj->configFile); VIR_FREE(obj->autostartLink); VIR_FREE(obj); } +void virStoragePoolObjListFree(virStoragePoolObjListPtr pools) +{ + unsigned int i; + for (i = 0 ; i < pools->count ; i++) + virStoragePoolObjFree(pools->objs[i]); + VIR_FREE(pools->objs); + pools->count = 0; +} + void -virStoragePoolObjRemove(virStorageDriverStatePtr driver, +virStoragePoolObjRemove(virStoragePoolObjListPtr pools, virStoragePoolObjPtr pool) { - virStoragePoolObjPtr prev = NULL, curr; + unsigned int i; - curr = driver->pools; - while (curr != pool) { - prev = curr; - curr = curr->next; - } + for (i = 0 ; i < pools->count ; i++) { + if (pools->objs[i] == pool) { + virStoragePoolObjFree(pools->objs[i]); - if (curr) { - if (prev) - prev->next = curr->next; - else - driver->pools = curr->next; + if (i < (pools->count - 1)) + memmove(pools->objs + i, pools->objs + i + 1, + sizeof(*(pools->objs)) * (pools->count - (i + 1))); - driver->ninactivePools--; - } + if (VIR_REALLOC_N(pools->objs, pools->count - 1) < 0) { + ; /* Failure to reduce memory allocation isn't fatal */ + } + pools->count--; - virStoragePoolObjFree(pool); + break; + } + } } @@ -906,29 +923,25 @@ virStorageVolDefFormat(virConnectPtr conn, virStoragePoolObjPtr -virStoragePoolObjFindByUUID(virStorageDriverStatePtr driver, +virStoragePoolObjFindByUUID(virStoragePoolObjListPtr pools, const unsigned char *uuid) { - virStoragePoolObjPtr pool = driver->pools; + unsigned int i; - while (pool) { - if (!memcmp(pool->def->uuid, uuid, VIR_UUID_BUFLEN)) - return pool; - pool = pool->next; - } + for (i = 0 ; i < pools->count ; i++) + if (!memcmp(pools->objs[i]->def->uuid, uuid, VIR_UUID_BUFLEN)) + return pools->objs[i]; return NULL; } virStoragePoolObjPtr -virStoragePoolObjFindByName(virStorageDriverStatePtr driver, +virStoragePoolObjFindByName(virStoragePoolObjListPtr pools, const char *name) { - virStoragePoolObjPtr pool = driver->pools; + unsigned int i; - while (pool) { - if (STREQ(pool->def->name, name)) - return pool; - pool = pool->next; - } + for (i = 0 ; i < pools->count ; i++) + if (STREQ(pools->objs[i]->def->name, name)) + return pools->objs[i]; return NULL; } @@ -936,26 +949,22 @@ virStoragePoolObjFindByName(virStorageDriverStatePtr driver, void virStoragePoolObjClearVols(virStoragePoolObjPtr pool) { - virStorageVolDefPtr vol = pool->volumes; - while (vol) { - virStorageVolDefPtr next = vol->next; - virStorageVolDefFree(vol); - vol = next; - } - pool->volumes = NULL; - pool->nvolumes = 0; + unsigned int i; + for (i = 0 ; i < pool->volumes.count ; i++) + virStorageVolDefFree(pool->volumes.objs[i]); + + VIR_FREE(pool->volumes.objs); + pool->volumes.count = 0; } virStorageVolDefPtr virStorageVolDefFindByKey(virStoragePoolObjPtr pool, const char *key) { - virStorageVolDefPtr vol = pool->volumes; + unsigned int i; - while (vol) { - if (STREQ(vol->key, key)) - return vol; - vol = vol->next; - } + for (i = 0 ; i < pool->volumes.count ; i++) + if (STREQ(pool->volumes.objs[i]->key, key)) + return pool->volumes.objs[i]; return NULL; } @@ -963,13 +972,11 @@ virStorageVolDefFindByKey(virStoragePoolObjPtr pool, virStorageVolDefPtr virStorageVolDefFindByPath(virStoragePoolObjPtr pool, const char *path) { - virStorageVolDefPtr vol = pool->volumes; + unsigned int i; - while (vol) { - if (STREQ(vol->target.path, path)) - return vol; - vol = vol->next; - } + for (i = 0 ; i < pool->volumes.count ; i++) + if (STREQ(pool->volumes.objs[i]->target.path, path)) + return pool->volumes.objs[i]; return NULL; } @@ -977,24 +984,22 @@ virStorageVolDefFindByPath(virStoragePoolObjPtr pool, virStorageVolDefPtr virStorageVolDefFindByName(virStoragePoolObjPtr pool, const char *name) { - virStorageVolDefPtr vol = pool->volumes; + unsigned int i; - while (vol) { - if (STREQ(vol->name, name)) - return vol; - vol = vol->next; - } + for (i = 0 ; i < pool->volumes.count ; i++) + if (STREQ(pool->volumes.objs[i]->name, name)) + return pool->volumes.objs[i]; return NULL; } virStoragePoolObjPtr virStoragePoolObjAssignDef(virConnectPtr conn, - virStorageDriverStatePtr driver, + virStoragePoolObjListPtr pools, virStoragePoolDefPtr def) { virStoragePoolObjPtr pool; - if ((pool = virStoragePoolObjFindByName(driver, def->name))) { + if ((pool = virStoragePoolObjFindByName(pools, def->name))) { if (!virStoragePoolObjIsActive(pool)) { virStoragePoolDefFree(pool->def); pool->def = def; @@ -1014,16 +1019,21 @@ virStoragePoolObjAssignDef(virConnectPtr conn, pool->active = 0; pool->def = def; - pool->next = driver->pools; - driver->pools = pool; - driver->ninactivePools++; + if (VIR_REALLOC_N(pools->objs, pools->count+1) < 0) { + pool->def = NULL; + virStoragePoolObjFree(pool); + virStorageReportError(conn, VIR_ERR_NO_MEMORY, NULL); + return NULL; + } + pools->objs[pools->count++] = pool; return pool; } static virStoragePoolObjPtr -virStoragePoolObjLoad(virStorageDriverStatePtr driver, +virStoragePoolObjLoad(virConnectPtr conn, + virStoragePoolObjListPtr pools, const char *file, const char *path, const char *xml, @@ -1045,7 +1055,7 @@ virStoragePoolObjLoad(virStorageDriverStatePtr driver, return NULL; } - if (!(pool = virStoragePoolObjAssignDef(NULL, driver, def))) { + if (!(pool = virStoragePoolObjAssignDef(conn, pools, def))) { virStorageLog("Failed to load storage pool config '%s': out of memory", path); virStoragePoolDefFree(def); return NULL; @@ -1072,15 +1082,18 @@ virStoragePoolObjLoad(virStorageDriverStatePtr driver, int -virStoragePoolObjScanConfigs(virStorageDriverStatePtr driver) { +virStoragePoolLoadAllConfigs(virConnectPtr conn, + virStoragePoolObjListPtr pools, + const char *configDir, + const char *autostartDir) { DIR *dir; struct dirent *entry; - if (!(dir = opendir(driver->configDir))) { + if (!(dir = opendir(configDir))) { if (errno == ENOENT) return 0; virStorageLog("Failed to open dir '%s': %s", - driver->configDir, strerror(errno)); + configDir, strerror(errno)); return -1; } @@ -1095,24 +1108,24 @@ virStoragePoolObjScanConfigs(virStorageDriverStatePtr driver) { if (!virFileHasSuffix(entry->d_name, ".xml")) continue; - if (virFileBuildPath(driver->configDir, entry->d_name, + if (virFileBuildPath(configDir, entry->d_name, NULL, path, PATH_MAX) < 0) { virStorageLog("Config filename '%s/%s' is too long", - driver->configDir, entry->d_name); + configDir, entry->d_name); continue; } - if (virFileBuildPath(driver->autostartDir, entry->d_name, + if (virFileBuildPath(autostartDir, entry->d_name, NULL, autostartLink, PATH_MAX) < 0) { virStorageLog("Autostart link path '%s/%s' is too long", - driver->autostartDir, entry->d_name); + autostartDir, entry->d_name); continue; } if (virFileReadAll(path, 8192, &xml) < 0) continue; - virStoragePoolObjLoad(driver, entry->d_name, path, xml, autostartLink); + virStoragePoolObjLoad(conn, pools, entry->d_name, path, xml, autostartLink); VIR_FREE(xml); } diff --git a/src/storage_conf.h b/src/storage_conf.h index c86bf4b520b4c1fafcfa88e44b95e169259576c7..e321a8af5b526ed9b3978dd789f0fd1be1196dac 100644 --- a/src/storage_conf.h +++ b/src/storage_conf.h @@ -87,10 +87,14 @@ struct _virStorageVolDef { virStorageVolSource source; virStorageVolTarget target; - - virStorageVolDefPtr next; }; +typedef struct _virStorageVolDefList virStorageVolDefList; +typedef virStorageVolDefList *virStorageVolDefListPtr; +struct _virStorageVolDefList { + unsigned int count; + virStorageVolDefPtr *objs; +}; @@ -222,10 +226,14 @@ struct _virStoragePoolObj { virStoragePoolDefPtr def; virStoragePoolDefPtr newDef; - int nvolumes; - virStorageVolDefPtr volumes; + virStorageVolDefList volumes; +}; - virStoragePoolObjPtr next; +typedef struct _virStoragePoolObjList virStoragePoolObjList; +typedef virStoragePoolObjList *virStoragePoolObjListPtr; +struct _virStoragePoolObjList { + unsigned int count; + virStoragePoolObjPtr *objs; }; @@ -235,9 +243,8 @@ typedef struct _virStorageDriverState virStorageDriverState; typedef virStorageDriverState *virStorageDriverStatePtr; struct _virStorageDriverState { - int nactivePools; - int ninactivePools; - virStoragePoolObjPtr pools; + virStoragePoolObjList pools; + char *configDir; char *autostartDir; }; @@ -251,11 +258,14 @@ static inline int virStoragePoolObjIsActive(virStoragePoolObjPtr pool) { __virReportErrorHelper(conn, VIR_FROM_STORAGE, code, __FILE__, \ __FUNCTION__, __LINE__, fmt) -int virStoragePoolObjScanConfigs(virStorageDriverStatePtr driver); +int virStoragePoolLoadAllConfigs(virConnectPtr conn, + virStoragePoolObjListPtr pools, + const char *configDir, + const char *autostartDir); -virStoragePoolObjPtr virStoragePoolObjFindByUUID(virStorageDriverStatePtr driver, +virStoragePoolObjPtr virStoragePoolObjFindByUUID(virStoragePoolObjListPtr pools, const unsigned char *uuid); -virStoragePoolObjPtr virStoragePoolObjFindByName(virStorageDriverStatePtr driver, +virStoragePoolObjPtr virStoragePoolObjFindByName(virStoragePoolObjListPtr pools, const char *name); virStorageVolDefPtr virStorageVolDefFindByKey(virStoragePoolObjPtr pool, @@ -282,7 +292,7 @@ char *virStorageVolDefFormat(virConnectPtr conn, virStorageVolDefPtr def); virStoragePoolObjPtr virStoragePoolObjAssignDef(virConnectPtr conn, - virStorageDriverStatePtr driver, + virStoragePoolObjListPtr pools, virStoragePoolDefPtr def); int virStoragePoolObjSaveDef(virConnectPtr conn, @@ -295,7 +305,8 @@ int virStoragePoolObjDeleteDef(virConnectPtr conn, void virStorageVolDefFree(virStorageVolDefPtr def); void virStoragePoolDefFree(virStoragePoolDefPtr def); void virStoragePoolObjFree(virStoragePoolObjPtr pool); -void virStoragePoolObjRemove(virStorageDriverStatePtr driver, +void virStoragePoolObjListFree(virStoragePoolObjListPtr pools); +void virStoragePoolObjRemove(virStoragePoolObjListPtr pools, virStoragePoolObjPtr pool); #endif /* __VIR_STORAGE_DRIVER_H__ */ diff --git a/src/storage_driver.c b/src/storage_driver.c index 221bdecbf470453a0480dcc95c558cb20adb01b0..e0d97e1fb16ade75c88ec8dd604f9c7a305ce70f 100644 --- a/src/storage_driver.c +++ b/src/storage_driver.c @@ -49,11 +49,10 @@ static int storageDriverShutdown(void); static void storageDriverAutostart(virStorageDriverStatePtr driver) { - virStoragePoolObjPtr pool; + unsigned int i; - pool = driver->pools; - while (pool != NULL) { - virStoragePoolObjPtr next = pool->next; + for (i = 0 ; i < driver->pools.count ; i++) { + virStoragePoolObjPtr pool = driver->pools.objs[i]; if (pool->autostart && !virStoragePoolObjIsActive(pool)) { @@ -61,7 +60,6 @@ storageDriverAutostart(virStorageDriverStatePtr driver) { if ((backend = virStorageBackendForType(pool->def->type)) == NULL) { storageLog("Missing backend %d", pool->def->type); - pool = next; continue; } @@ -70,7 +68,6 @@ storageDriverAutostart(virStorageDriverStatePtr driver) { virErrorPtr err = virGetLastError(); storageLog("Failed to autostart storage pool '%s': %s", pool->def->name, err ? err->message : NULL); - pool = next; continue; } @@ -80,15 +77,10 @@ storageDriverAutostart(virStorageDriverStatePtr driver) { backend->stopPool(NULL, pool); storageLog("Failed to autostart storage pool '%s': %s", pool->def->name, err ? err->message : NULL); - pool = next; continue; } pool->active = 1; - driver->nactivePools++; - driver->ninactivePools--; } - - pool = next; } } @@ -149,7 +141,10 @@ storageDriverStartup(void) { } */ - if (virStoragePoolObjScanConfigs(driverState) < 0) { + if (virStoragePoolLoadAllConfigs(NULL, + &driverState->pools, + driverState->configDir, + driverState->autostartDir) < 0) { storageDriverShutdown(); return -1; } @@ -173,7 +168,13 @@ storageDriverStartup(void) { */ static int storageDriverReload(void) { - virStoragePoolObjScanConfigs(driverState); + if (!driverState) + return -1; + + virStoragePoolLoadAllConfigs(NULL, + &driverState->pools, + driverState->configDir, + driverState->autostartDir); storageDriverAutostart(driverState); return 0; @@ -188,11 +189,17 @@ storageDriverReload(void) { */ static int storageDriverActive(void) { + unsigned int i; + + if (!driverState) + return 0; + /* If we've any active networks or guests, then we * mark this driver as active */ - if (driverState->nactivePools) - return 1; + for (i = 0 ; i < driverState->pools.count ; i++) + if (virStoragePoolObjIsActive(driverState->pools.objs[i])) + return 1; /* Otherwise we're happy to deal with a shutdown */ return 0; @@ -205,15 +212,15 @@ storageDriverActive(void) { */ static int storageDriverShutdown(void) { - virStoragePoolObjPtr pool; + unsigned int i; if (!driverState) return -1; /* shutdown active pools */ - pool = driverState->pools; - while (pool) { - virStoragePoolObjPtr next = pool->next; + for (i = 0 ; i < driverState->pools.count ; i++) { + virStoragePoolObjPtr pool = driverState->pools.objs[i]; + if (virStoragePoolObjIsActive(pool)) { virStorageBackendPtr backend; if ((backend = virStorageBackendForType(pool->def->type)) == NULL) { @@ -229,24 +236,14 @@ storageDriverShutdown(void) { } virStoragePoolObjClearVols(pool); } - pool = next; } /* free inactive pools */ - pool = driverState->pools; - while (pool) { - virStoragePoolObjPtr next = pool->next; - virStoragePoolObjFree(pool); - pool = next; - } - driverState->pools = NULL; - driverState->nactivePools = 0; - driverState->ninactivePools = 0; - - free(driverState->configDir); - free(driverState->autostartDir); - free(driverState); - driverState = NULL; + virStoragePoolObjListFree(&driverState->pools); + + VIR_FREE(driverState->configDir); + VIR_FREE(driverState->autostartDir); + VIR_FREE(driverState); return 0; } @@ -258,7 +255,7 @@ storagePoolLookupByUUID(virConnectPtr conn, const unsigned char *uuid) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)conn->storagePrivateData; - virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(driver, uuid); + virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(&driver->pools, uuid); virStoragePoolPtr ret; if (!pool) { @@ -276,7 +273,7 @@ storagePoolLookupByName(virConnectPtr conn, const char *name) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)conn->storagePrivateData; - virStoragePoolObjPtr pool = virStoragePoolObjFindByName(driver, name); + virStoragePoolObjPtr pool = virStoragePoolObjFindByName(&driver->pools, name); virStoragePoolPtr ret; if (!pool) { @@ -316,7 +313,13 @@ static int storageNumPools(virConnectPtr conn) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)conn->storagePrivateData; - return driver->nactivePools; + unsigned int i, nactive = 0; + + for (i = 0 ; i < driver->pools.count ; i++) + if (virStoragePoolObjIsActive(driver->pools.objs[i])) + nactive++; + + return nactive; } static int @@ -325,18 +328,17 @@ storageListPools(virConnectPtr conn, int nnames) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)conn->storagePrivateData; - virStoragePoolObjPtr pool = driver->pools; int got = 0, i; - while (pool && got < nnames) { - if (virStoragePoolObjIsActive(pool)) { - if (!(names[got] = strdup(pool->def->name))) { + + for (i = 0 ; i < driver->pools.count && got < nnames ; i++) { + if (virStoragePoolObjIsActive(driver->pools.objs[i])) { + if (!(names[got] = strdup(driver->pools.objs[i]->def->name))) { virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("names")); goto cleanup; } got++; } - pool = pool->next; } return got; @@ -353,7 +355,13 @@ static int storageNumDefinedPools(virConnectPtr conn) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)conn->storagePrivateData; - return driver->ninactivePools; + unsigned int i, nactive = 0; + + for (i = 0 ; i < driver->pools.count ; i++) + if (!virStoragePoolObjIsActive(driver->pools.objs[i])) + nactive++; + + return nactive; } static int @@ -362,18 +370,17 @@ storageListDefinedPools(virConnectPtr conn, int nnames) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)conn->storagePrivateData; - virStoragePoolObjPtr pool = driver->pools; int got = 0, i; - while (pool && got < nnames) { - if (!virStoragePoolObjIsActive(pool)) { - if (!(names[got] = strdup(pool->def->name))) { + + for (i = 0 ; i < driver->pools.count && got < nnames ; i++) { + if (!virStoragePoolObjIsActive(driver->pools.objs[i])) { + if (!(names[got] = strdup(driver->pools.objs[i]->def->name))) { virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("names")); goto cleanup; } got++; } - pool = pool->next; } return got; @@ -424,8 +431,8 @@ storagePoolCreate(virConnectPtr conn, if (!(def = virStoragePoolDefParse(conn, xml, NULL))) return NULL; - if (virStoragePoolObjFindByUUID(driver, def->uuid) || - virStoragePoolObjFindByName(driver, def->name)) { + if (virStoragePoolObjFindByUUID(&driver->pools, def->uuid) || + virStoragePoolObjFindByName(&driver->pools, def->name)) { virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", _("storage pool already exists")); virStoragePoolDefFree(def); @@ -437,7 +444,7 @@ storagePoolCreate(virConnectPtr conn, return NULL; } - if (!(pool = virStoragePoolObjAssignDef(conn, driver, def))) { + if (!(pool = virStoragePoolObjAssignDef(conn, &driver->pools, def))) { virStoragePoolDefFree(def); return NULL; } @@ -451,8 +458,6 @@ storagePoolCreate(virConnectPtr conn, return NULL; } pool->active = 1; - driver->nactivePools++; - driver->ninactivePools--; ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid); @@ -478,13 +483,13 @@ storagePoolDefine(virConnectPtr conn, return NULL; } - if (!(pool = virStoragePoolObjAssignDef(conn, driver, def))) { + if (!(pool = virStoragePoolObjAssignDef(conn, &driver->pools, def))) { virStoragePoolDefFree(def); return NULL; } if (virStoragePoolObjSaveDef(conn, driver, pool, def) < 0) { - virStoragePoolObjRemove(driver, pool); + virStoragePoolObjRemove(&driver->pools, pool); return NULL; } @@ -496,7 +501,7 @@ static int storagePoolUndefine(virStoragePoolPtr obj) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)obj->conn->storagePrivateData; - virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(driver, obj->uuid); + virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid); if (!pool) { virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL, @@ -517,12 +522,10 @@ storagePoolUndefine(virStoragePoolPtr obj) { storageLog("Failed to delete autostart link '%s': %s", pool->autostartLink, strerror(errno)); - free(pool->configFile); - pool->configFile = NULL; - free(pool->autostartLink); - pool->autostartLink = NULL; + VIR_FREE(pool->configFile); + VIR_FREE(pool->autostartLink); - virStoragePoolObjRemove(driver, pool); + virStoragePoolObjRemove(&driver->pools, pool); return 0; } @@ -532,7 +535,7 @@ storagePoolStart(virStoragePoolPtr obj, unsigned int flags ATTRIBUTE_UNUSED) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)obj->conn->storagePrivateData; - virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(driver, obj->uuid); + virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid); virStorageBackendPtr backend; if (!pool) { @@ -560,8 +563,6 @@ storagePoolStart(virStoragePoolPtr obj, } pool->active = 1; - driver->nactivePools++; - driver->ninactivePools--; return 0; } @@ -571,7 +572,7 @@ storagePoolBuild(virStoragePoolPtr obj, unsigned int flags) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)obj->conn->storagePrivateData; - virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(driver, obj->uuid); + virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid); virStorageBackendPtr backend; if (!pool) { @@ -602,7 +603,7 @@ static int storagePoolDestroy(virStoragePoolPtr obj) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)obj->conn->storagePrivateData; - virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(driver, obj->uuid); + virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid); virStorageBackendPtr backend; if (!pool) { @@ -628,11 +629,9 @@ storagePoolDestroy(virStoragePoolPtr obj) { virStoragePoolObjClearVols(pool); pool->active = 0; - driver->nactivePools--; - driver->ninactivePools++; if (pool->configFile == NULL) - virStoragePoolObjRemove(driver, pool); + virStoragePoolObjRemove(&driver->pools, pool); return 0; } @@ -643,7 +642,7 @@ storagePoolDelete(virStoragePoolPtr obj, unsigned int flags) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)obj->conn->storagePrivateData; - virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(driver, obj->uuid); + virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid); virStorageBackendPtr backend; if (!pool) { @@ -679,7 +678,7 @@ storagePoolRefresh(virStoragePoolPtr obj, unsigned int flags ATTRIBUTE_UNUSED) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)obj->conn->storagePrivateData; - virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(driver, obj->uuid); + virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid); virStorageBackendPtr backend; int ret = 0; @@ -705,11 +704,9 @@ storagePoolRefresh(virStoragePoolPtr obj, backend->stopPool(obj->conn, pool); pool->active = 0; - driver->nactivePools--; - driver->ninactivePools++; if (pool->configFile == NULL) - virStoragePoolObjRemove(driver, pool); + virStoragePoolObjRemove(&driver->pools, pool); } return ret; @@ -721,7 +718,7 @@ storagePoolGetInfo(virStoragePoolPtr obj, virStoragePoolInfoPtr info) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)obj->conn->storagePrivateData; - virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(driver, obj->uuid); + virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid); virStorageBackendPtr backend; if (!pool) { @@ -751,7 +748,7 @@ storagePoolDumpXML(virStoragePoolPtr obj, unsigned int flags ATTRIBUTE_UNUSED) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)obj->conn->storagePrivateData; - virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(driver, obj->uuid); + virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid); if (!pool) { virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL, @@ -767,7 +764,7 @@ storagePoolGetAutostart(virStoragePoolPtr obj, int *autostart) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)obj->conn->storagePrivateData; - virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(driver, obj->uuid); + virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid); if (!pool) { virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL, @@ -789,7 +786,7 @@ storagePoolSetAutostart(virStoragePoolPtr obj, int autostart) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)obj->conn->storagePrivateData; - virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(driver, obj->uuid); + virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid); if (!pool) { virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL, @@ -845,7 +842,7 @@ static int storagePoolNumVolumes(virStoragePoolPtr obj) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)obj->conn->storagePrivateData; - virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(driver, obj->uuid); + virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid); if (!pool) { virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL, @@ -859,7 +856,7 @@ storagePoolNumVolumes(virStoragePoolPtr obj) { return -1; } - return pool->nvolumes; + return pool->volumes.count; } static int @@ -868,9 +865,8 @@ storagePoolListVolumes(virStoragePoolPtr obj, int maxnames) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)obj->conn->storagePrivateData; - virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(driver, obj->uuid); - int i = 0; - virStorageVolDefPtr vol; + virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid); + int i, n = 0; if (!pool) { virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL, @@ -885,25 +881,20 @@ storagePoolListVolumes(virStoragePoolPtr obj, } memset(names, 0, maxnames); - vol = pool->volumes; - while (vol && i < maxnames) { - names[i] = strdup(vol->name); - if (names[i] == NULL) { + for (i = 0 ; i < pool->volumes.count && n < maxnames ; i++) { + if ((names[n++] = strdup(pool->volumes.objs[i]->name)) == NULL) { virStorageReportError(obj->conn, VIR_ERR_NO_MEMORY, "%s", _("name")); goto cleanup; } - vol = vol->next; - i++; } - return i; + return n; cleanup: - for (i = 0 ; i < maxnames ; i++) { - free(names[i]); - names[i] = NULL; - } + for (n = 0 ; n < maxnames ; n++) + VIR_FREE(names[i]); + memset(names, 0, maxnames); return -1; } @@ -914,7 +905,7 @@ storageVolumeLookupByName(virStoragePoolPtr obj, const char *name) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)obj->conn->storagePrivateData; - virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(driver, obj->uuid); + virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid); virStorageVolDefPtr vol; if (!pool) { @@ -946,19 +937,19 @@ storageVolumeLookupByKey(virConnectPtr conn, const char *key) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)conn->storagePrivateData; - virStoragePoolObjPtr pool = driver->pools; + unsigned int i; - while (pool) { - if (virStoragePoolObjIsActive(pool)) { - virStorageVolDefPtr vol = virStorageVolDefFindByKey(pool, key); + for (i = 0 ; i < driver->pools.count ; i++) { + if (virStoragePoolObjIsActive(driver->pools.objs[i])) { + virStorageVolDefPtr vol = + virStorageVolDefFindByKey(driver->pools.objs[i], key); if (vol) return virGetStorageVol(conn, - pool->def->name, + driver->pools.objs[i]->def->name, vol->name, vol->key); } - pool = pool->next; } virStorageReportError(conn, VIR_ERR_INVALID_STORAGE_VOL, @@ -971,19 +962,19 @@ storageVolumeLookupByPath(virConnectPtr conn, const char *path) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)conn->storagePrivateData; - virStoragePoolObjPtr pool = driver->pools; + unsigned int i; - while (pool) { - if (virStoragePoolObjIsActive(pool)) { - virStorageVolDefPtr vol = virStorageVolDefFindByPath(pool, path); + for (i = 0 ; i < driver->pools.count ; i++) { + if (virStoragePoolObjIsActive(driver->pools.objs[i])) { + virStorageVolDefPtr vol = + virStorageVolDefFindByPath(driver->pools.objs[i], path); if (vol) return virGetStorageVol(conn, - pool->def->name, + driver->pools.objs[i]->def->name, vol->name, vol->key); } - pool = pool->next; } virStorageReportError(conn, VIR_ERR_INVALID_STORAGE_VOL, @@ -997,7 +988,7 @@ storageVolumeCreateXML(virStoragePoolPtr obj, unsigned int flags ATTRIBUTE_UNUSED) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)obj->conn->storagePrivateData; - virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(driver, obj->uuid); + virStoragePoolObjPtr pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid); virStorageBackendPtr backend; virStorageVolDefPtr vol; @@ -1027,6 +1018,13 @@ storageVolumeCreateXML(virStoragePoolPtr obj, return NULL; } + if (VIR_REALLOC_N(pool->volumes.objs, + pool->volumes.count+1) < 0) { + virStorageReportError(obj->conn, VIR_ERR_NO_MEMORY, NULL); + virStorageVolDefFree(vol); + return NULL; + } + if (!backend->createVol) { virStorageReportError(obj->conn, VIR_ERR_NO_SUPPORT, "%s", _("storage pool does not support volume creation")); @@ -1039,9 +1037,7 @@ storageVolumeCreateXML(virStoragePoolPtr obj, return NULL; } - vol->next = pool->volumes; - pool->volumes = vol; - pool->nvolumes++; + pool->volumes.objs[pool->volumes.count++] = vol; return virGetStorageVol(obj->conn, pool->def->name, vol->name, vol->key); } @@ -1051,9 +1047,10 @@ storageVolumeDelete(virStorageVolPtr obj, unsigned int flags) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)obj->conn->storagePrivateData; - virStoragePoolObjPtr pool = virStoragePoolObjFindByName(driver, obj->pool); + virStoragePoolObjPtr pool = virStoragePoolObjFindByName(&driver->pools, obj->pool); virStorageBackendPtr backend; - virStorageVolDefPtr vol, tmp, prev; + virStorageVolDefPtr vol; + unsigned int i; if (!pool) { virStorageReportError(obj->conn, VIR_ERR_INVALID_STORAGE_POOL, @@ -1089,22 +1086,22 @@ storageVolumeDelete(virStorageVolPtr obj, return -1; } - prev = NULL; - tmp = pool->volumes; - while (tmp) { - if (tmp == vol) { + for (i = 0 ; i < pool->volumes.count ; i++) { + if (pool->volumes.objs[i] == vol) { + virStorageVolDefFree(vol); + + if (i < (pool->volumes.count - 1)) + memmove(pool->volumes.objs + i, pool->volumes.objs + i + 1, + sizeof(*(pool->volumes.objs)) * (pool->volumes.count - (i + 1))); + + if (VIR_REALLOC_N(pool->volumes.objs, pool->volumes.count - 1) < 0) { + ; /* Failure to reduce memory allocation isn't fatal */ + } + pool->volumes.count--; + break; } - prev = tmp; - tmp = tmp->next; - } - if (prev) { - prev->next = vol->next; - } else { - pool->volumes = vol->next; } - pool->nvolumes--; - virStorageVolDefFree(vol); return 0; } @@ -1114,7 +1111,7 @@ storageVolumeGetInfo(virStorageVolPtr obj, virStorageVolInfoPtr info) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)obj->conn->storagePrivateData; - virStoragePoolObjPtr pool = virStoragePoolObjFindByName(driver, obj->pool); + virStoragePoolObjPtr pool = virStoragePoolObjFindByName(&driver->pools, obj->pool); virStorageBackendPtr backend; virStorageVolDefPtr vol; @@ -1158,7 +1155,7 @@ storageVolumeGetXMLDesc(virStorageVolPtr obj, unsigned int flags ATTRIBUTE_UNUSED) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)obj->conn->storagePrivateData; - virStoragePoolObjPtr pool = virStoragePoolObjFindByName(driver, obj->pool); + virStoragePoolObjPtr pool = virStoragePoolObjFindByName(&driver->pools, obj->pool); virStorageBackendPtr backend; virStorageVolDefPtr vol; @@ -1192,7 +1189,7 @@ static char * storageVolumeGetPath(virStorageVolPtr obj) { virStorageDriverStatePtr driver = (virStorageDriverStatePtr)obj->conn->storagePrivateData; - virStoragePoolObjPtr pool = virStoragePoolObjFindByName(driver, obj->pool); + virStoragePoolObjPtr pool = virStoragePoolObjFindByName(&driver->pools, obj->pool); virStorageVolDefPtr vol; char *ret;