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:
parent
69535c6124
commit
f226ecbfbb
@ -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
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user