From 79e56fc25a2dc3f09a2b709ca18a32a01f68d90c Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Tue, 4 Nov 2014 03:22:12 +0100 Subject: [PATCH 01/10] iscsi: Refuse to open as writable if the LUN is write protected Message-id: <1415071332-3470-1-git-send-email-famz@redhat.com> Patchwork-id: 62063 O-Subject: [RHEL-7.1 qemu-kvm-rhev PATCH] iscsi: Refuse to open as writable if the LUN is write protected Bugzilla: 1160102 RH-Acked-by: Markus Armbruster RH-Acked-by: Stefan Hajnoczi RH-Acked-by: Paolo Bonzini Before, when a write protected iSCSI target is attached as scsi-disk with BDRV_O_RDWR, we report it as writable, while in fact all writes will fail. One way to improve this is to report write protect flag as true to guest, but a even better way is to refuse using a write protected LUN to guest. Target write protect flag is checked with a mode sense query. Signed-off-by: Fam Zheng Signed-off-by: Paolo Bonzini (cherry picked from commit c1d4096b0f033d0a52c542f0948403783c3682e9) Signed-off-by: Fam Zheng Signed-off-by: Miroslav Rezanina --- block/iscsi.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/block/iscsi.c b/block/iscsi.c index 250c605..cc33c9d 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -1222,6 +1222,40 @@ static void iscsi_attach_aio_context(BlockDriverState *bs, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + NOP_INTERVAL); } +static bool iscsi_is_write_protected(IscsiLun *iscsilun) +{ + struct scsi_task *task; + struct scsi_mode_sense *ms = NULL; + bool wrprotected = false; + + task = iscsi_modesense6_sync(iscsilun->iscsi, iscsilun->lun, + 1, SCSI_MODESENSE_PC_CURRENT, + 0x3F, 0, 255); + if (task == NULL) { + error_report("iSCSI: Failed to send MODE_SENSE(6) command: %s", + iscsi_get_error(iscsilun->iscsi)); + goto out; + } + + if (task->status != SCSI_STATUS_GOOD) { + error_report("iSCSI: Failed MODE_SENSE(6), LUN assumed writable"); + goto out; + } + ms = scsi_datain_unmarshall(task); + if (!ms) { + error_report("iSCSI: Failed to unmarshall MODE_SENSE(6) data: %s", + iscsi_get_error(iscsilun->iscsi)); + goto out; + } + wrprotected = ms->device_specific_parameter & 0x80; + +out: + if (task) { + scsi_free_scsi_task(task); + } + return wrprotected; +} + /* * We support iscsi url's on the form * iscsi://[%@][:]// @@ -1342,6 +1376,14 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags, scsi_free_scsi_task(task); task = NULL; + /* Check the write protect flag of the LUN if we want to write */ + if (iscsilun->type == TYPE_DISK && (flags & BDRV_O_RDWR) && + iscsi_is_write_protected(iscsilun)) { + error_setg(errp, "Cannot open a write protected LUN as read-write"); + ret = -EACCES; + goto out; + } + iscsi_readcapacity_sync(iscsilun, &local_err); if (local_err != NULL) { error_propagate(errp, local_err); -- 1.8.3.1