|
|
05bba0 |
From 8f412efbb8bb57fde0f924a7ad084f1c536c4a0b Mon Sep 17 00:00:00 2001
|
|
|
05bba0 |
From: Fam Zheng <famz@redhat.com>
|
|
|
05bba0 |
Date: Tue, 20 Jan 2015 03:42:13 +0100
|
|
|
05bba0 |
Subject: [PATCH 06/16] iscsi: Refuse to open as writable if the LUN is write
|
|
|
05bba0 |
protected
|
|
|
05bba0 |
|
|
|
05bba0 |
Message-id: <1421725333-27072-1-git-send-email-famz@redhat.com>
|
|
|
05bba0 |
Patchwork-id: 63370
|
|
|
05bba0 |
O-Subject: [RHEL-7.2 qemu-kvm PATCH v2] iscsi: Refuse to open as writable if the LUN is write protected
|
|
|
05bba0 |
Bugzilla: 1032412
|
|
|
05bba0 |
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
05bba0 |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
05bba0 |
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
05bba0 |
|
|
|
05bba0 |
Before, when a write protected iSCSI target is attached as scsi-disk
|
|
|
05bba0 |
with BDRV_O_RDWR, we report it as writable, while in fact all writes
|
|
|
05bba0 |
will fail.
|
|
|
05bba0 |
|
|
|
05bba0 |
One way to improve this is to report write protect flag as true to
|
|
|
05bba0 |
guest, but a even better way is to refuse using a write protected LUN to
|
|
|
05bba0 |
guest.
|
|
|
05bba0 |
|
|
|
05bba0 |
Target write protect flag is checked with a mode sense query.
|
|
|
05bba0 |
|
|
|
05bba0 |
Signed-off-by: Fam Zheng <famz@redhat.com>
|
|
|
05bba0 |
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
05bba0 |
(cherry picked from commit c1d4096b0f033d0a52c542f0948403783c3682e9)
|
|
|
05bba0 |
Signed-off-by: Fam Zheng <famz@redhat.com>
|
|
|
05bba0 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
05bba0 |
|
|
|
05bba0 |
Conflicts:
|
|
|
05bba0 |
block/iscsi.c
|
|
|
05bba0 |
|
|
|
05bba0 |
Trivial context conflict: AioContext attach/detach functions are not
|
|
|
05bba0 |
present in downstream.
|
|
|
05bba0 |
---
|
|
|
05bba0 |
block/iscsi.c | 43 +++++++++++++++++++++++++++++++++++++++++++
|
|
|
05bba0 |
1 file changed, 43 insertions(+)
|
|
|
05bba0 |
|
|
|
05bba0 |
diff --git a/block/iscsi.c b/block/iscsi.c
|
|
|
05bba0 |
index 4f42f29..3d61dd7 100644
|
|
|
05bba0 |
--- a/block/iscsi.c
|
|
|
05bba0 |
+++ b/block/iscsi.c
|
|
|
05bba0 |
@@ -1290,6 +1290,41 @@ fail:
|
|
|
05bba0 |
return NULL;
|
|
|
05bba0 |
}
|
|
|
05bba0 |
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+static bool iscsi_is_write_protected(IscsiLun *iscsilun)
|
|
|
05bba0 |
+{
|
|
|
05bba0 |
+ struct scsi_task *task;
|
|
|
05bba0 |
+ struct scsi_mode_sense *ms = NULL;
|
|
|
05bba0 |
+ bool wrprotected = false;
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+ task = iscsi_modesense6_sync(iscsilun->iscsi, iscsilun->lun,
|
|
|
05bba0 |
+ 1, SCSI_MODESENSE_PC_CURRENT,
|
|
|
05bba0 |
+ 0x3F, 0, 255);
|
|
|
05bba0 |
+ if (task == NULL) {
|
|
|
05bba0 |
+ error_report("iSCSI: Failed to send MODE_SENSE(6) command: %s",
|
|
|
05bba0 |
+ iscsi_get_error(iscsilun->iscsi));
|
|
|
05bba0 |
+ goto out;
|
|
|
05bba0 |
+ }
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+ if (task->status != SCSI_STATUS_GOOD) {
|
|
|
05bba0 |
+ error_report("iSCSI: Failed MODE_SENSE(6), LUN assumed writable");
|
|
|
05bba0 |
+ goto out;
|
|
|
05bba0 |
+ }
|
|
|
05bba0 |
+ ms = scsi_datain_unmarshall(task);
|
|
|
05bba0 |
+ if (!ms) {
|
|
|
05bba0 |
+ error_report("iSCSI: Failed to unmarshall MODE_SENSE(6) data: %s",
|
|
|
05bba0 |
+ iscsi_get_error(iscsilun->iscsi));
|
|
|
05bba0 |
+ goto out;
|
|
|
05bba0 |
+ }
|
|
|
05bba0 |
+ wrprotected = ms->device_specific_parameter & 0x80;
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+out:
|
|
|
05bba0 |
+ if (task) {
|
|
|
05bba0 |
+ scsi_free_scsi_task(task);
|
|
|
05bba0 |
+ }
|
|
|
05bba0 |
+ return wrprotected;
|
|
|
05bba0 |
+}
|
|
|
05bba0 |
+
|
|
|
05bba0 |
/*
|
|
|
05bba0 |
* We support iscsi url's on the form
|
|
|
05bba0 |
* iscsi://[<username>%<password>@]<host>[:<port>]/<targetname>/<lun>
|
|
|
05bba0 |
@@ -1405,6 +1440,14 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
|
|
|
05bba0 |
scsi_free_scsi_task(task);
|
|
|
05bba0 |
task = NULL;
|
|
|
05bba0 |
|
|
|
05bba0 |
+ /* Check the write protect flag of the LUN if we want to write */
|
|
|
05bba0 |
+ if (iscsilun->type == TYPE_DISK && (flags & BDRV_O_RDWR) &&
|
|
|
05bba0 |
+ iscsi_is_write_protected(iscsilun)) {
|
|
|
05bba0 |
+ error_setg(errp, "Cannot open a write protected LUN as read-write");
|
|
|
05bba0 |
+ ret = -EACCES;
|
|
|
05bba0 |
+ goto out;
|
|
|
05bba0 |
+ }
|
|
|
05bba0 |
+
|
|
|
05bba0 |
iscsi_readcapacity_sync(iscsilun, &local_err);
|
|
|
05bba0 |
if (local_err != NULL) {
|
|
|
05bba0 |
error_propagate(errp, local_err);
|
|
|
05bba0 |
--
|
|
|
05bba0 |
1.8.3.1
|
|
|
05bba0 |
|