[libvirt] [PATCH 2/5] rbd: Add support for wiping RBD volumes

John Ferlan jferlan at redhat.com
Fri Jan 29 19:03:01 UTC 2016



On 01/27/2016 05:20 AM, Wido den Hollander wrote:
> When wiping the RBD image will be filled with zeros started
> at offset 0 and until the end of the volume.
> 
> This will result in the RBD volume growing to it's full allocation
> on the Ceph cluster. All data on the volume will be overwritten
> however, making it unavailable.
> 
> It does NOT take any RBD snapshots into account. The original data
> might still be in a snapshot of that RBD volume.
> 
> Signed-off-by: Wido den Hollander <wido at widodh.nl>
> ---
>  src/storage/storage_backend_rbd.c | 115 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 115 insertions(+)
> 
> diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backend_rbd.c
> index 8c7a80d..7e669ff 100644
> --- a/src/storage/storage_backend_rbd.c
> +++ b/src/storage/storage_backend_rbd.c
> @@ -732,6 +732,120 @@ static int virStorageBackendRBDResizeVol(virConnectPtr conn ATTRIBUTE_UNUSED,
>      return ret;
>  }
>  
> +static int
> +virStorageBackendRBDVolWipeZero(rbd_image_t image,
> +                                char *imgname,
> +                                rbd_image_info_t info,

^^
I changed this to a pointer (*info) in order to avoid Coverity whines
about pass_by_value... Had to obviously change the info. to be info->
and the call to pass by reference (&info).

> +                                uint64_t stripe_count)
> +{
> +    int r = -1;
> +    int ret = -1;
> +    uint64_t offset = 0;
> +    uint64_t length;
> +    char *writebuf;
> +
> +    if (VIR_ALLOC_N(writebuf, info.obj_size * stripe_count) < 0)
> +        goto cleanup;
> +
> +    while (offset < info.size) {
> +        length = MIN((info.size - offset), (info.obj_size * stripe_count));
> +
> +        if ((r = rbd_write(image, offset, length, writebuf)) < 0) {
> +            virReportSystemError(-r, _("writing %zu bytes failed on "
> +                                       "RBD image %s at offset %zu"),
> +                                       length, imgname, offset);
> +            goto cleanup;
> +        }
> +
> +        VIR_DEBUG("Wrote %zu bytes to RBD image %s at offset %zu",
> +                  length, imgname, offset);
> +
> +        offset += length;
> +    }
> +
> +    ret = 0;
> +
> + cleanup:
> +    VIR_FREE(writebuf);
> +
> +    return ret;
> +}
> +
> +static int
> +virStorageBackendRBDVolWipe(virConnectPtr conn,
> +                            virStoragePoolObjPtr pool,
> +                            virStorageVolDefPtr vol,
> +                            unsigned int algorithm,
> +                            unsigned int flags)
> +{
> +    virStorageBackendRBDState ptr;
> +    ptr.cluster = NULL;
> +    ptr.ioctx = NULL;
> +    rbd_image_t image = NULL;
> +    rbd_image_info_t info;
> +    uint64_t stripe_count;
> +    int r = -1;
> +    int ret = -1;
> +
> +    virCheckFlags(VIR_STORAGE_VOL_WIPE_ALG_ZERO, -1);

Like 1/5... My bad...  I'll clean up...  It'll be (0, -1) since the
flags argument isn't defined. <sigh>

> +
> +    VIR_DEBUG("Wiping RBD image %s/%s", pool->def->source.name, vol->name);
> +
> +    if (virStorageBackendRBDOpenRADOSConn(&ptr, conn, &pool->def->source) < 0)
> +        goto cleanup;
> +
> +    if (virStorageBackendRBDOpenIoCTX(&ptr, pool) < 0)
> +        goto cleanup;
> +
> +    if ((r = rbd_open(ptr.ioctx, vol->name, &image, NULL)) < 0) {
> +        virReportSystemError(-r, _("failed to open the RBD image %s"),
> +                             vol->name);
> +        goto cleanup;
> +    }
> +
> +    if ((r = rbd_stat(image, &info, sizeof(info))) < 0) {
> +        virReportSystemError(-r, _("failed to stat the RBD image %s"),
> +                             vol->name);
> +        goto cleanup;
> +    }
> +
> +    if ((r = rbd_get_stripe_count(image, &stripe_count)) < 0) {
> +        virReportSystemError(-r, _("failed to get stripe count of RBD image %s"),
> +                             vol->name);
> +        goto cleanup;
> +    }
> +
> +    VIR_DEBUG("Need to wipe %zu bytes from RBD image %s/%s",
> +              info.size, pool->def->source.name, vol->name);
> +
> +    switch ((virStorageVolWipeAlgorithm) algorithm) {
> +        case VIR_STORAGE_VOL_WIPE_ALG_ZERO:
> +            r = virStorageBackendRBDVolWipeZero(image, vol->name,
> +                                                info, stripe_count);
> +            break;
> +        default:

Similar to 1/5 this needs to be fully populated...  I'll clean up and push.

Tks -

John
> +            virReportError(VIR_ERR_INVALID_ARG, _("unsupported algorithm %d"),
> +                           algorithm);
> +            goto cleanup;
> +    }
> +
> +    if (r < 0) {
> +        virReportSystemError(-r, _("failed to wipe RBD image %s"),
> +                             vol->name);
> +        goto cleanup;
> +    }
> +
> +    ret = 0;
> +
> + cleanup:
> +    if (image)
> +        rbd_close(image);
> +
> +    virStorageBackendRBDCloseRADOSConn(&ptr);
> +
> +    return ret;
> +}
> +
>  virStorageBackend virStorageBackendRBD = {
>      .type = VIR_STORAGE_POOL_RBD,
>  
> @@ -741,4 +855,5 @@ virStorageBackend virStorageBackendRBD = {
>      .refreshVol = virStorageBackendRBDRefreshVol,
>      .deleteVol = virStorageBackendRBDDeleteVol,
>      .resizeVol = virStorageBackendRBDResizeVol,
> +    .wipeVol = virStorageBackendRBDVolWipe
>  };
> 




More information about the libvir-list mailing list