1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2024-12-23 21:34:54 +03:00

rbd: Add support for wiping RBD volumes

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@widodh.nl>
This commit is contained in:
Wido den Hollander 2016-01-27 11:20:06 +01:00 committed by John Ferlan
parent 69535c6124
commit f226ecbfbb

View File

@ -1,7 +1,7 @@
/*
* storage_backend_rbd.c: storage backend for RBD (RADOS Block Device) handling
*
* Copyright (C) 2013-2015 Red Hat, Inc.
* Copyright (C) 2013-2016 Red Hat, Inc.
* Copyright (C) 2012 Wido den Hollander
*
* This library is free software; you can redistribute it and/or
@ -732,6 +732,128 @@ 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(0, -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;
case VIR_STORAGE_VOL_WIPE_ALG_NNSA:
case VIR_STORAGE_VOL_WIPE_ALG_DOD:
case VIR_STORAGE_VOL_WIPE_ALG_BSI:
case VIR_STORAGE_VOL_WIPE_ALG_GUTMANN:
case VIR_STORAGE_VOL_WIPE_ALG_SCHNEIER:
case VIR_STORAGE_VOL_WIPE_ALG_PFITZNER7:
case VIR_STORAGE_VOL_WIPE_ALG_PFITZNER33:
case VIR_STORAGE_VOL_WIPE_ALG_RANDOM:
case VIR_STORAGE_VOL_WIPE_ALG_LAST:
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 +863,5 @@ virStorageBackend virStorageBackendRBD = {
.refreshVol = virStorageBackendRBDRefreshVol,
.deleteVol = virStorageBackendRBDDeleteVol,
.resizeVol = virStorageBackendRBDResizeVol,
.wipeVol = virStorageBackendRBDVolWipe
};