[libvirt] [PATCH 1/4] rbd: Add wiping RBD volumes by using rbd_discard() or rbd_write()
John Ferlan
jferlan at redhat.com
Fri Jan 22 00:57:04 UTC 2016
On 01/13/2016 08:52 AM, Wido den Hollander wrote:
> This allows user to use the volume wiping functionality of the libvirt
> storage driver.
>
> This patch also adds a new wiping algorithm VIR_STORAGE_VOL_WIPE_ALG_DISCARD
>
> By default the VIR_STORAGE_VOL_WIPE_ALG_ZERO algorithm is used and with
> RBD this will called rbd_write() in chunks of the underlying object size
> to completely zero out the volume.
>
> With VIR_STORAGE_VOL_WIPE_ALG_DISCARD it will call rbd_discard() in the
> same object size chunks which will trim/discard all underlying RADOS objects
> in the Ceph cluster.
>
> Signed-off-by: Wido den Hollander <wido at widodh.nl>
> ---
> include/libvirt/libvirt-storage.h | 4 +
> src/storage/storage_backend_rbd.c | 157 +++++++++++++++++++++++++++++++++++++-
> tools/virsh-volume.c | 2 +-
> 3 files changed, 161 insertions(+), 2 deletions(-)
>
Looks like I missed these (I'm behind). Also, not sure why only 1 & 2 of
4 are here and there's cover letter. I assume they are the same as the
two I reviewed today.
John
> diff --git a/include/libvirt/libvirt-storage.h b/include/libvirt/libvirt-storage.h
> index 2c55c93..139add3 100644
> --- a/include/libvirt/libvirt-storage.h
> +++ b/include/libvirt/libvirt-storage.h
> @@ -153,6 +153,10 @@ typedef enum {
>
> VIR_STORAGE_VOL_WIPE_ALG_RANDOM = 8, /* 1-pass random */
>
> + VIR_STORAGE_VOL_WIPE_ALG_DISCARD = 9, /* 1-pass, discard all data on the
> + volume by using TRIM or
> + DISCARD */
> +
> # ifdef VIR_ENUM_SENTINELS
> VIR_STORAGE_VOL_WIPE_ALG_LAST
> /*
> diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backend_rbd.c
> index e20a54d..c0001d0 100644
> --- a/src/storage/storage_backend_rbd.c
> +++ b/src/storage/storage_backend_rbd.c
> @@ -32,6 +32,7 @@
> #include "base64.h"
> #include "viruuid.h"
> #include "virstring.h"
> +#include "virutil.h"
> #include "rados/librados.h"
> #include "rbd/librbd.h"
>
> @@ -730,6 +731,159 @@ static int virStorageBackendRBDResizeVol(virConnectPtr conn ATTRIBUTE_UNUSED,
> return ret;
> }
>
> +static int virStorageBackendRBDVolWipeZero(rbd_image_t image,
> + char *imgname,
> + rbd_image_info_t info,
> + uint64_t stripe_count)
> +{
> + int r = -1;
> + size_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));
> +
> + r = rbd_write(image, offset, length, writebuf);
> + if (r < 0) {
> + virReportSystemError(-r, _("writing %llu bytes failed on "
> + " RBD image %s at offset %llu"),
> + (unsigned long long)length,
> + imgname,
> + (unsigned long long)offset);
> + goto cleanup;
> + }
> +
> + VIR_DEBUG("Wrote %llu bytes to RBD image %s at offset %llu",
> + (unsigned long long)length,
> + imgname, (unsigned long long)offset);
> +
> + offset += length;
> + }
> +
> + cleanup:
> + VIR_FREE(writebuf);
> +
> + return r;
> +}
> +
> +static int virStorageBackendRBDVolWipeDiscard(rbd_image_t image,
> + char *imgname,
> + rbd_image_info_t info,
> + uint64_t stripe_count)
> +{
> + int r = -1;
> + size_t offset = 0;
> + uint64_t length;
> +
> + VIR_DEBUG("Wiping RBD %s volume using discard)", imgname);
> +
> + while (offset < info.size) {
> + length = MIN((info.size - offset), (info.obj_size * stripe_count));
> +
> + r = rbd_discard(image, offset, length);
> + if (r < 0) {
> + virReportSystemError(-r, _("discarding %llu bytes failed on "
> + " RBD image %s at offset %llu"),
> + (unsigned long long)length,
> + imgname,
> + (unsigned long long)offset);
> + goto cleanup;
> + }
> +
> + VIR_DEBUG("Discarded %llu bytes of RBD image %s at offset %llu",
> + (unsigned long long)length,
> + imgname, (unsigned long long)offset);
> +
> + offset += length;
> + }
> +
> + cleanup:
> + return r;
> +}
> +
> +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;
> +
> + virCheckFlags(VIR_STORAGE_VOL_WIPE_ALG_ZERO |
> + VIR_STORAGE_VOL_WIPE_ALG_DISCARD, -1);
> +
> + 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;
> +
> + 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_stat(image, &info, sizeof(info));
> + if (r < 0) {
> + virReportSystemError(-r, _("failed to stat the RBD image %s"),
> + vol->name);
> + goto cleanup;
> + }
> +
> + r = rbd_get_stripe_count(image, &stripe_count);
> + if (r < 0) {
> + virReportSystemError(-r, _("failed to get stripe count of RBD image %s"),
> + vol->name);
> + goto cleanup;
> + }
> +
> + VIR_DEBUG("Need to wipe %llu bytes from RBD image %s/%s",
> + (unsigned long long)info.size, pool->def->source.name, vol->name);
> +
> + switch (algorithm) {
> + case VIR_STORAGE_VOL_WIPE_ALG_ZERO:
> + r = virStorageBackendRBDVolWipeZero(image, vol->name,
> + info, stripe_count);
> + break;
> + case VIR_STORAGE_VOL_WIPE_ALG_DISCARD:
> + r = virStorageBackendRBDVolWipeDiscard(image, vol->name,
> + info, stripe_count);
> + break;
> + default:
> + virReportError(VIR_ERR_INVALID_ARG, _("unsupported algorithm %d"),
> + algorithm);
> + r = -VIR_ERR_INVALID_ARG;
> + goto cleanup;
> + }
> +
> + if (r < 0) {
> + virReportSystemError(-r, _("failed to wipe RBD image %s"),
> + vol->name);
> + goto cleanup;
> + }
> +
> + cleanup:
> + if (image)
> + rbd_close(image);
> +
> + virStorageBackendRBDCloseRADOSConn(&ptr);
> + return r;
> +}
> +
> virStorageBackend virStorageBackendRBD = {
> .type = VIR_STORAGE_POOL_RBD,
>
> @@ -738,5 +892,6 @@ virStorageBackend virStorageBackendRBD = {
> .buildVol = virStorageBackendRBDBuildVol,
> .refreshVol = virStorageBackendRBDRefreshVol,
> .deleteVol = virStorageBackendRBDDeleteVol,
> - .resizeVol = virStorageBackendRBDResizeVol,
> + .wipeVol = virStorageBackendRBDVolWipe,
> + .resizeVol = virStorageBackendRBDResizeVol
> };
> diff --git a/tools/virsh-volume.c b/tools/virsh-volume.c
> index 661c876..f86980f 100644
> --- a/tools/virsh-volume.c
> +++ b/tools/virsh-volume.c
> @@ -906,7 +906,7 @@ static const vshCmdOptDef opts_vol_wipe[] = {
> VIR_ENUM_DECL(virStorageVolWipeAlgorithm)
> VIR_ENUM_IMPL(virStorageVolWipeAlgorithm, VIR_STORAGE_VOL_WIPE_ALG_LAST,
> "zero", "nnsa", "dod", "bsi", "gutmann", "schneier",
> - "pfitzner7", "pfitzner33", "random");
> + "pfitzner7", "pfitzner33", "random", "discard");
>
> static bool
> cmdVolWipe(vshControl *ctl, const vshCmd *cmd)
>
More information about the libvir-list
mailing list