static int virStorageBackendRBDRefreshVol(virConnectPtr conn, virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, virStorageVolDefPtr vol) { virStorageBackendRBDStatePtr ptr; ptr.cluster = NULL; ptr.ioctx = NULL; int ret = -1; 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; } if (volStorageBackendRBDRefreshVolInfo(vol, pool, ptr) < 0) { goto cleanup; } ret = 0; cleanup: virStorageBackendRBDCloseRADOSConn(ptr); return ret; }
static int virStorageBackendRBDRefreshVol(virConnectPtr conn, virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, virStorageVolDefPtr vol) { virStorageBackendRBDState ptr; ptr.cluster = NULL; ptr.ioctx = NULL; int ret = -1; if (virStorageBackendRBDOpenRADOSConn(&ptr, conn, pool) < 0) { goto cleanup; } if (virStorageBackendRBDOpenIoCTX(&ptr, pool) < 0) { goto cleanup; } if (volStorageBackendRBDRefreshVolInfo(vol, pool, &ptr) < 0) { goto cleanup; } ret = 0; cleanup: virStorageBackendRBDCloseRADOSConn(&ptr); return ret; }
static int virStorageBackendRBDCreateVol(virConnectPtr conn, virStoragePoolObjPtr pool, virStorageVolDefPtr vol) { virStorageBackendRBDStatePtr ptr; ptr.cluster = NULL; ptr.ioctx = NULL; int order = 0; int ret = -1; VIR_DEBUG("Creating RBD image %s/%s with size %llu", pool->def->source.name, vol->name, vol->capacity); 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; } if (vol->target.encryption != NULL) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("storage pool does not support encrypted volumes")); goto cleanup; } if (rbd_create(ptr.ioctx, vol->name, vol->capacity, &order) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to create volume '%s/%s'"), pool->def->source.name, vol->name); goto cleanup; } if (volStorageBackendRBDRefreshVolInfo(vol, pool, ptr) < 0) { goto cleanup; } ret = 0; cleanup: virStorageBackendRBDCloseRADOSConn(ptr); return ret; }
static int virStorageBackendRBDResizeVol(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, virStorageVolDefPtr vol, unsigned long long capacity, unsigned int flags) { virStorageBackendRBDStatePtr ptr; ptr.cluster = NULL; ptr.ioctx = NULL; rbd_image_t image = NULL; int ret = -1; virCheckFlags(0, -1); 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; } if (rbd_open(ptr.ioctx, vol->name, &image, NULL) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to open the RBD image '%s'"), vol->name); goto cleanup; } if (rbd_resize(image, capacity) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to resize the RBD image '%s'"), vol->name); goto cleanup; } ret = 0; cleanup: if (image != NULL) rbd_close(image); virStorageBackendRBDCloseRADOSConn(ptr); return ret; }
static int virStorageBackendRBDResizeVol(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, virStorageVolDefPtr vol, unsigned long long capacity, unsigned int flags) { virStorageBackendRBDState ptr; ptr.cluster = NULL; ptr.ioctx = NULL; rbd_image_t image = NULL; int ret = -1; int r = 0; virCheckFlags(0, -1); if (virStorageBackendRBDOpenRADOSConn(&ptr, conn, pool) < 0) { goto cleanup; } if (virStorageBackendRBDOpenIoCTX(&ptr, pool) < 0) { goto cleanup; } r = rbd_open(ptr.ioctx, vol->name, &image, NULL); if (r < 0) { virReportSystemError(-r, _("failed to open the RBD image '%s'"), vol->name); goto cleanup; } r = rbd_resize(image, capacity); if (r < 0) { virReportSystemError(-r, _("failed to resize the RBD image '%s'"), vol->name); goto cleanup; } ret = 0; cleanup: if (image != NULL) rbd_close(image); virStorageBackendRBDCloseRADOSConn(&ptr); return ret; }
static int virStorageBackendRBDDeleteVol(virConnectPtr conn, virStoragePoolObjPtr pool, virStorageVolDefPtr vol, unsigned int flags) { int ret = -1; virStorageBackendRBDStatePtr ptr; ptr.cluster = NULL; ptr.ioctx = NULL; VIR_DEBUG("Removing RBD image %s/%s", pool->def->source.name, vol->name); if (flags & VIR_STORAGE_VOL_DELETE_ZEROED) { VIR_WARN("%s", _("This storage backend does not supported zeroed removal of volumes")); } 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; } if (rbd_remove(ptr.ioctx, vol->name) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to remove volume '%s/%s'"), pool->def->source.name, vol->name); goto cleanup; } ret = 0; cleanup: virStorageBackendRBDCloseRADOSConn(ptr); return ret; }
static int virStorageBackendRBDDeleteVol(virConnectPtr conn, virStoragePoolObjPtr pool, virStorageVolDefPtr vol, unsigned int flags) { int ret = -1; int r = 0; virStorageBackendRBDState ptr; ptr.cluster = NULL; ptr.ioctx = NULL; VIR_DEBUG("Removing RBD image %s/%s", pool->def->source.name, vol->name); if (flags & VIR_STORAGE_VOL_DELETE_ZEROED) { VIR_WARN("%s", _("This storage backend does not supported zeroed removal of volumes")); } if (virStorageBackendRBDOpenRADOSConn(&ptr, conn, &pool->def->source) < 0) { goto cleanup; } if (virStorageBackendRBDOpenIoCTX(&ptr, pool) < 0) { goto cleanup; } r = rbd_remove(ptr.ioctx, vol->name); if (r < 0) { virReportSystemError(-r, _("failed to remove volume '%s/%s'"), pool->def->source.name, vol->name); goto cleanup; } ret = 0; cleanup: virStorageBackendRBDCloseRADOSConn(&ptr); return ret; }
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; }
static int virStorageBackendRBDCreateImage(rados_ioctx_t io, char *name, long capacity) { int order = 0; #if LIBRBD_VERSION_CODE > 260 uint64_t features = 3; uint64_t stripe_count = 1; uint64_t stripe_unit = 4194304; if (rbd_create3(io, name, capacity, features, &order, stripe_count, stripe_unit) < 0) { #else if (rbd_create(io, name, capacity, &order) < 0) { #endif return -1; } return 0; } static int virStorageBackendRBDBuildVol(virConnectPtr conn, virStoragePoolObjPtr pool, virStorageVolDefPtr vol, unsigned int flags) { virStorageBackendRBDState ptr; ptr.cluster = NULL; ptr.ioctx = NULL; int ret = -1; int r = 0; VIR_DEBUG("Creating RBD image %s/%s with size %llu", pool->def->source.name, vol->name, vol->capacity); virCheckFlags(0, -1); if (virStorageBackendRBDOpenRADOSConn(&ptr, conn, pool) < 0) goto cleanup; if (virStorageBackendRBDOpenIoCTX(&ptr, pool) < 0) goto cleanup; if (vol->target.encryption != NULL) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("storage pool does not support encrypted volumes")); goto cleanup; } r = virStorageBackendRBDCreateImage(ptr.ioctx, vol->name, vol->capacity); if (r < 0) { virReportSystemError(-r, _("failed to create volume '%s/%s'"), pool->def->source.name, vol->name); goto cleanup; } if (volStorageBackendRBDRefreshVolInfo(vol, pool, &ptr) < 0) goto cleanup; ret = 0; cleanup: virStorageBackendRBDCloseRADOSConn(&ptr); return ret; }
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; }