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@xxxxxxxxx> > --- > 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) > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list