void virStoragePoolObjDispose(void *opaque) { virStoragePoolObjPtr obj = opaque; if (!obj) return; virStoragePoolObjClearVols(obj); virStoragePoolDefFree(obj->def); virStoragePoolDefFree(obj->newDef); VIR_FREE(obj->configFile); VIR_FREE(obj->autostartLink); }
static int virStorageBackendRBDRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool) { size_t max_size = 1024; int ret = -1; int len = -1; int i; char *name, *names = NULL; virStorageBackendRBDStatePtr ptr; ptr.cluster = NULL; ptr.ioctx = NULL; if (virStorageBackendRBDOpenRADOSConn(&ptr, conn, pool) < 0) { goto cleanup; } if (rados_ioctx_create(ptr.cluster, pool->def->source.name, &ptr.ioctx) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to create the RBD IoCTX. Does the pool '%s' exist?"), pool->def->source.name); goto cleanup; } struct rados_cluster_stat_t stat; if (rados_cluster_stat(ptr.cluster, &stat) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("failed to stat the RADOS cluster")); goto cleanup; } struct rados_pool_stat_t poolstat; if (rados_ioctx_pool_stat(ptr.ioctx, &poolstat) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to stat the RADOS pool '%s'"), pool->def->source.name); goto cleanup; } pool->def->capacity = stat.kb * 1024; pool->def->available = stat.kb_avail * 1024; pool->def->allocation = poolstat.num_bytes; VIR_DEBUG("Utilization of RBD pool %s: (kb: %llu kb_avail: %llu num_bytes: %llu)", pool->def->source.name, (unsigned long long)stat.kb, (unsigned long long)stat.kb_avail, (unsigned long long)poolstat.num_bytes); while (true) { if (VIR_ALLOC_N(names, max_size) < 0) goto out_of_memory; len = rbd_list(ptr.ioctx, names, &max_size); if (len >= 0) break; if (len != -ERANGE) { VIR_WARN("%s", _("A problem occurred while listing RBD images")); goto cleanup; } VIR_FREE(names); } for (i = 0, name = names; name < names + max_size; i++) { virStorageVolDefPtr vol; if (VIR_REALLOC_N(pool->volumes.objs, pool->volumes.count + 1) < 0) { virStoragePoolObjClearVols(pool); goto out_of_memory; } if (STREQ(name, "")) break; if (VIR_ALLOC(vol) < 0) goto out_of_memory; vol->name = strdup(name); if (vol->name == NULL) { VIR_FREE(vol); goto out_of_memory; } name += strlen(name) + 1; if (volStorageBackendRBDRefreshVolInfo(vol, pool, ptr) < 0) { virStorageVolDefFree(vol); goto cleanup; } pool->volumes.objs[pool->volumes.count++] = vol; } VIR_DEBUG("Found %d images in RBD pool %s", pool->volumes.count, pool->def->source.name); ret = 0; cleanup: VIR_FREE(names); virStorageBackendRBDCloseRADOSConn(ptr); return ret; out_of_memory: virReportOOMError(); goto cleanup; }
/** * Iterate over the pool's directory and enumerate all disk images * within it. This is non-recursive. */ static int virStorageBackendFileSystemRefresh(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool) { DIR *dir; struct dirent *ent; struct statvfs sb; virStorageVolDefPtr vol = NULL; if (!(dir = opendir(pool->def->target.path))) { virReportSystemError(errno, _("cannot open path '%s'"), pool->def->target.path); goto cleanup; } while ((ent = readdir(dir)) != NULL) { int ret; char *backingStore; if (VIR_ALLOC(vol) < 0) goto no_memory; if ((vol->name = strdup(ent->d_name)) == NULL) goto no_memory; vol->type = VIR_STORAGE_VOL_FILE; vol->target.format = VIR_STORAGE_FILE_RAW; /* Real value is filled in during probe */ if (virAsprintf(&vol->target.path, "%s/%s", pool->def->target.path, vol->name) == -1) goto no_memory; if ((vol->key = strdup(vol->target.path)) == NULL) goto no_memory; if ((ret = virStorageBackendProbeTarget(&vol->target, &backingStore, &vol->allocation, &vol->capacity, &vol->target.encryption)) < 0) { if (ret == -1) goto cleanup; else { /* Silently ignore non-regular files, * eg '.' '..', 'lost+found' */ virStorageVolDefFree(vol); vol = NULL; continue; } } if (backingStore != NULL) { if (vol->target.format == VIR_STORAGE_FILE_QCOW2 && STRPREFIX("fmt:", backingStore)) { char *fmtstr = backingStore + 4; char *path = strchr(fmtstr, ':'); if (!path) { VIR_FREE(backingStore); } else { *path = '\0'; if ((vol->backingStore.format = virStorageFileFormatTypeFromString(fmtstr)) < 0) { VIR_FREE(backingStore); } else { memmove(backingStore, path, strlen(path) + 1); vol->backingStore.path = backingStore; if (virStorageBackendUpdateVolTargetInfo(&vol->backingStore, NULL, NULL) < 0) VIR_FREE(vol->backingStore); } } } else { vol->backingStore.path = backingStore; if ((ret = virStorageBackendProbeTarget(&vol->backingStore, NULL, NULL, NULL, NULL)) < 0) { if (ret == -1) goto cleanup; else { /* Silently ignore non-regular files, * eg '.' '..', 'lost+found' */ VIR_FREE(vol->backingStore); } } } } 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); if (statvfs(pool->def->target.path, &sb) < 0) { virReportSystemError(errno, _("cannot statvfs path '%s'"), pool->def->target.path); return -1; } pool->def->capacity = ((unsigned long long)sb.f_frsize * (unsigned long long)sb.f_blocks); pool->def->available = ((unsigned long long)sb.f_bfree * (unsigned long long)sb.f_bsize); pool->def->allocation = pool->def->capacity - pool->def->available; return 0; no_memory: virReportOOMError(); /* fallthrough */ cleanup: if (dir) closedir(dir); virStorageVolDefFree(vol); virStoragePoolObjClearVols(pool); return -1; }
static int virStorageBackendRBDRefreshPool(virConnectPtr conn, virStoragePoolObjPtr pool) { size_t max_size = 1024; int ret = -1; int len = -1; int r = 0; char *name, *names = NULL; virStorageBackendRBDState ptr; ptr.cluster = NULL; ptr.ioctx = NULL; if (virStorageBackendRBDOpenRADOSConn(&ptr, conn, pool) < 0) { goto cleanup; } if (virStorageBackendRBDOpenIoCTX(&ptr, pool) < 0) { goto cleanup; } struct rados_cluster_stat_t clusterstat; r = rados_cluster_stat(ptr.cluster, &clusterstat); if (r < 0) { virReportSystemError(-r, "%s", _("failed to stat the RADOS cluster")); goto cleanup; } struct rados_pool_stat_t poolstat; r = rados_ioctx_pool_stat(ptr.ioctx, &poolstat); if (r < 0) { virReportSystemError(-r, _("failed to stat the RADOS pool '%s'"), pool->def->source.name); goto cleanup; } pool->def->capacity = clusterstat.kb * 1024; pool->def->available = clusterstat.kb_avail * 1024; pool->def->allocation = poolstat.num_bytes; VIR_DEBUG("Utilization of RBD pool %s: (kb: %llu kb_avail: %llu num_bytes: %llu)", pool->def->source.name, (unsigned long long)clusterstat.kb, (unsigned long long)clusterstat.kb_avail, (unsigned long long)poolstat.num_bytes); while (true) { if (VIR_ALLOC_N(names, max_size) < 0) goto cleanup; len = rbd_list(ptr.ioctx, names, &max_size); if (len >= 0) break; if (len != -ERANGE) { VIR_WARN("%s", _("A problem occurred while listing RBD images")); goto cleanup; } VIR_FREE(names); } for (name = names; name < names + max_size;) { virStorageVolDefPtr vol; if (VIR_REALLOC_N(pool->volumes.objs, pool->volumes.count + 1) < 0) { virStoragePoolObjClearVols(pool); goto cleanup; } if (STREQ(name, "")) break; if (VIR_ALLOC(vol) < 0) goto cleanup; if (VIR_STRDUP(vol->name, name) < 0) { VIR_FREE(vol); goto cleanup; } name += strlen(name) + 1; if (volStorageBackendRBDRefreshVolInfo(vol, pool, &ptr) < 0) { virStorageVolDefFree(vol); goto cleanup; } pool->volumes.objs[pool->volumes.count++] = vol; } VIR_DEBUG("Found %zu images in RBD pool %s", pool->volumes.count, pool->def->source.name); ret = 0; cleanup: VIR_FREE(names); virStorageBackendRBDCloseRADOSConn(&ptr); return ret; }