From nobody Sun Feb 8 20:53:26 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1551884482850886.9423270168601; Wed, 6 Mar 2019 07:01:22 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C0301C05D3F4; Wed, 6 Mar 2019 15:01:20 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9343734D4F; Wed, 6 Mar 2019 15:01:20 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 19830181A12A; Wed, 6 Mar 2019 15:01:20 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x26ExRwp009289 for ; Wed, 6 Mar 2019 09:59:27 -0500 Received: by smtp.corp.redhat.com (Postfix) id 9C6E76B485; Wed, 6 Mar 2019 14:59:27 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.30]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1FEDC6B483 for ; Wed, 6 Mar 2019 14:59:26 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Wed, 6 Mar 2019 15:59:12 +0100 Message-Id: <14cc0d555430d2e864c49efbbbd5d175d7165d37.1551884250.git.mprivozn@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 2/8] storage_backend_iscsi_direct: Simplify vol zeroing X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Wed, 06 Mar 2019 15:01:21 +0000 (UTC) Content-Type: text/plain; charset="utf-8" So far we have two branches: either we zero BLOCK_PER_PACKET (currently 128) block at one, or if we're close to the last block then we zero out one block at the time. This is very suboptimal. We know how many block are there left. Might as well just write them all at once. Also, SCSI protocol has WRITESAME command which allows us to write a single buffer multiple times. This means, that we have to transfer the buffer far less frequently and have the destination write it over and over again. Ideally, we would allocate a buffer with size equivalent to block size of the LUN and then write it as many times as there are blocks on the LUN. Sadly, this works well in theory but in practise I've found out that it's possible to write only 4096 blocks at once. Any higher value leads to a failure. But still better than Twili^Wwhat we have now. Since 4096 seems like an arbitrary number, I'm also implementing a mechanism that exponentially decreases the number of blocks we're trying to write at once. It starts at 4096 blocks and if that's too much the number is halved, and so on. Signed-off-by: Michal Privoznik --- src/storage/storage_backend_iscsi_direct.c | 55 ++++++++++++++++------ 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/src/storage/storage_backend_iscsi_direct.c b/src/storage/stora= ge_backend_iscsi_direct.c index fc3b6550f7..0af7adf32c 100644 --- a/src/storage/storage_backend_iscsi_direct.c +++ b/src/storage/storage_backend_iscsi_direct.c @@ -39,9 +39,11 @@ =20 #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:" =20 +/* Empirically tested to be the highest value to work without any error. */ +#define WIPE_BLOCKS_AT_ONCE 4096 + VIR_LOG_INIT("storage.storage_backend_iscsi_direct"); =20 static struct iscsi_context * @@ -624,6 +626,7 @@ virStorageBackendISCSIDirectVolWipeZero(virStorageVolDe= fPtr vol, uint64_t lba =3D 0; uint32_t block_size; uint64_t nb_block; + uint64_t wipe_at_once =3D WIPE_BLOCKS_AT_ONCE; struct scsi_task *task =3D NULL; int lun =3D 0; int ret =3D -1; @@ -635,25 +638,49 @@ virStorageBackendISCSIDirectVolWipeZero(virStorageVol= DefPtr vol, return ret; if (virISCSIDirectGetVolumeCapacity(iscsi, lun, &block_size, &nb_block= )) return ret; - if (VIR_ALLOC_N(data, block_size * BLOCK_PER_PACKET)) + if (VIR_ALLOC_N(data, block_size)) return ret; =20 + VIR_DEBUG("Starting zeroing of lun=3D%d block_size=3D%ju nb_block=3D%j= u wipe_at_once=3D%ju", + lun, (uintmax_t) block_size, (uintmax_t) nb_block, (uintmax_= t) wipe_at_once); + while (lba < nb_block) { - if (nb_block - lba > block_size * BLOCK_PER_PACKET) { + const uint64_t to_write =3D MIN(nb_block - lba + 1, wipe_at_once); + bool fail =3D false; =20 - if (!(task =3D iscsi_write16_sync(iscsi, lun, lba, data, - block_size * BLOCK_PER_PACKET, - block_size, 0, 0, 0, 0, 0))) - return -1; - scsi_free_scsi_task(task); - lba +=3D BLOCK_PER_PACKET; - } else { - if (!(task =3D iscsi_write16_sync(iscsi, lun, lba, data, block= _size, - block_size, 0, 0, 0, 0, 0))) - return -1; + if (!(task =3D iscsi_writesame16_sync(iscsi, lun, lba, + data, block_size, + to_write, + 0, 0, 0, 0))) + fail =3D true; + + if (task && + task->status =3D=3D SCSI_STATUS_CHECK_CONDITION && + task->sense.key =3D=3D SCSI_SENSE_ILLEGAL_REQUEST && + task->sense.ascq =3D=3D SCSI_SENSE_ASCQ_INVALID_FIELD_IN_CDB) { + /* This means that we tried to write too much blocks at once. + * Halve it (if it's not small enough already) and retry. */ + if (wipe_at_once > 1) { + wipe_at_once /=3D 2; + VIR_DEBUG("Halving wipe_at_once to %ju", (uintmax_t) wipe_= at_once); + scsi_free_scsi_task(task); + continue; + } + + fail =3D true; + } + + if (fail) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("failed to run writesame: %s"), + iscsi_get_error(iscsi)); scsi_free_scsi_task(task); - lba++; + return -1; } + + scsi_free_scsi_task(task); + + lba +=3D to_write; } =20 return 0; --=20 2.19.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list