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

Wido den Hollander wido at widodh.nl
Wed Jan 27 10:20:06 UTC 2016


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,
+                                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);
+
+    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:
+            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
 };
-- 
1.9.1




More information about the libvir-list mailing list