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(a)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
};