[libvirt] [PATCH 1/2] rbd: Implement wiping RBD volumes using rbd_discard()

Wido den Hollander wido at widodh.nl
Wed Dec 23 09:29:04 UTC 2015


This allows user to use the volume wiping functionality of the libvirt
storage driver.

All data from the volume will be wiped by calling rbd_discard() in chunks of the
underlying object and stripe size inside Ceph.

This will ensure all data is zeroed and leaves the user with a completely empty volume
ready for use again.

Signed-off-by: Wido den Hollander <wido at widodh.nl>
---
 src/storage/storage_backend_rbd.c | 90 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 89 insertions(+), 1 deletion(-)

diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backend_rbd.c
index cdbfdee..5e16e7a 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"
 
@@ -700,6 +701,92 @@ static int virStorageBackendRBDResizeVol(virConnectPtr conn ATTRIBUTE_UNUSED,
     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;
+    int r = -1;
+    size_t offset = 0;
+    uint64_t stripe_count;
+    uint64_t length;
+
+    virCheckFlags(0, -1);
+
+    VIR_DEBUG("Wiping RBD image %s/%s", pool->def->source.name, vol->name);
+
+    if (algorithm != VIR_STORAGE_VOL_WIPE_ALG_ZERO) {
+        virReportError(VIR_ERR_NO_SUPPORT, "%s",
+                       _("RBD storage pool does not support other wiping"
+                         " algorithms than zero"));
+        goto cleanup;
+    }
+
+    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);
+
+    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,
+                                     vol->name,
+                                     (unsigned long long)offset);
+            goto cleanup;
+        }
+
+        VIR_DEBUG("Discarded %llu bytes of RBD image %s/%s at offset %llu",
+                  (unsigned long long)length,
+                  pool->def->source.name,
+                  vol->name, (unsigned long long)offset);
+
+        offset += length;
+    }
+
+ cleanup:
+    if (image)
+        rbd_close(image);
+
+    virStorageBackendRBDCloseRADOSConn(&ptr);
+    return r;
+}
+
 virStorageBackend virStorageBackendRBD = {
     .type = VIR_STORAGE_POOL_RBD,
 
@@ -708,5 +795,6 @@ virStorageBackend virStorageBackendRBD = {
     .buildVol = virStorageBackendRBDBuildVol,
     .refreshVol = virStorageBackendRBDRefreshVol,
     .deleteVol = virStorageBackendRBDDeleteVol,
-    .resizeVol = virStorageBackendRBDResizeVol,
+    .wipeVol = virStorageBackendRBDVolWipe,
+    .resizeVol = virStorageBackendRBDResizeVol
 };
-- 
1.9.1




More information about the libvir-list mailing list