From: Clementine Hayat <clem@xxxxxxxxxxxx> Signed-off-by: Clementine Hayat <clem@xxxxxxxxxxxx> --- src/storage/storage_backend_iscsi_direct.c | 121 ++++++++++++++++++++- 1 file changed, 120 insertions(+), 1 deletion(-) diff --git a/src/storage/storage_backend_iscsi_direct.c b/src/storage/storage_backend_iscsi_direct.c index 7bdd39582b..5a7d70f24d 100644 --- a/src/storage/storage_backend_iscsi_direct.c +++ b/src/storage/storage_backend_iscsi_direct.c @@ -41,6 +41,8 @@ #define ISCSI_DEFAULT_TARGET_PORT 3260 #define VIR_ISCSI_TEST_UNIT_TIMEOUT 30 * 1000 +#define BLOCK_PER_PACKET 128 +#define VOL_NAME_PREFIX "unit:0:0:" VIR_LOG_INIT("storage.storage_backend_iscsi_direct"); @@ -225,7 +227,7 @@ virISCSIDirectSetVolumeAttributes(virStoragePoolObjPtr pool, { virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool); - if (virAsprintf(&vol->name, "unit:0:0:%u", lun) < 0) + if (virAsprintf(&vol->name, "%s%u", VOL_NAME_PREFIX, lun) < 0) return -1; if (virAsprintf(&vol->key, "ip-%s-iscsi-%s-lun-%u", portal, def->source.devices[0].path, lun) < 0) @@ -601,12 +603,129 @@ virStorageBackendISCSIDirectRefreshPool(virStoragePoolObjPtr pool) return ret; } +static int +virStorageBackendISCSIDirectGetLun(virStorageVolDefPtr vol, + int *lun) +{ + const char *name = vol->name; + int ret = -1; + + if (!STRPREFIX(name, VOL_NAME_PREFIX)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid volume name %s"), name); + goto cleanup; + } + + name += strlen(VOL_NAME_PREFIX); + if (virStrToLong_i(name, NULL, 10, lun) < 0) + goto cleanup; + + ret = 0; + cleanup: + return ret; +} + +static int +virStorageBackendISCSIDirectVolWipeZero(virStorageVolDefPtr vol, + struct iscsi_context *iscsi) +{ + uint32_t lba = 0; + uint32_t block_size; + uint32_t nb_block; + struct scsi_task *task = NULL; + int lun = 0; + int ret = -1; + unsigned char *data; + + if (virStorageBackendISCSIDirectGetLun(vol, &lun) < 0) + return ret; + if (virISCSIDirectTestUnitReady(iscsi, lun) < 0) + return ret; + if (virISCSIDirectGetVolumeCapacity(iscsi, lun, &block_size, &nb_block)) + return ret; + if (VIR_ALLOC_N(data, block_size * BLOCK_PER_PACKET)) + return ret; + + while (lba < nb_block) { + if (nb_block - lba > block_size * BLOCK_PER_PACKET) { + + if (!(task = iscsi_write10_sync(iscsi, lun, lba, data, + block_size * BLOCK_PER_PACKET, + block_size, 0, 0, 0, 0, 0))) + goto cleanup; + scsi_free_scsi_task(task); + lba += BLOCK_PER_PACKET; + } else { + if (!(task = iscsi_write10_sync(iscsi, lun, lba, data, block_size, + block_size, 0, 0, 0, 0, 0))) + goto cleanup; + scsi_free_scsi_task(task); + lba++; + } + } + + ret = 0; + cleanup: + VIR_FREE(data); + return ret; +} + +static int +virStorageBackenISCSIDirectWipeVol(virStoragePoolObjPtr pool, + virStorageVolDefPtr vol, + unsigned int algorithm, + unsigned int flags) +{ + struct iscsi_context *iscsi = NULL; + char *portal = NULL; + int ret = -1; + + virCheckFlags(0, -1); + + if (!(iscsi = virStorageBackendISCSIDirectSetConnection(pool, &portal))) + goto cleanup; + + switch ((virStorageVolWipeAlgorithm) algorithm) { + case VIR_STORAGE_VOL_WIPE_ALG_ZERO: + if (virStorageBackendISCSIDirectVolWipeZero(vol, iscsi) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("failed to wipe volume %s"), + vol->name); + goto disconnect; + } + break; + case VIR_STORAGE_VOL_WIPE_ALG_TRIM: + 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 disconnect; + } + + ret = 0; + disconnect: + virISCSIDirectDisconnect(iscsi); + iscsi_destroy_context(iscsi); + cleanup: + VIR_FREE(portal); + return ret; +} + + virStorageBackend virStorageBackendISCSIDirect = { .type = VIR_STORAGE_POOL_ISCSI_DIRECT, .checkPool = virStorageBackendISCSIDirectCheckPool, .findPoolSources = virStorageBackendISCSIDirectFindPoolSources, .refreshPool = virStorageBackendISCSIDirectRefreshPool, + .wipeVol = virStorageBackenISCSIDirectWipeVol, }; int -- 2.18.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list