958e1b
From 9e46b4be497106cff27fd67c5c3cc79023e21762 Mon Sep 17 00:00:00 2001
240766
From: Fam Zheng <famz@redhat.com>
240766
Date: Fri, 4 Apr 2014 05:55:57 +0200
240766
Subject: [PATCH 02/12] iscsi: correctly propagate errors in iscsi_open
240766
240766
RH-Author: Fam Zheng <famz@redhat.com>
240766
Message-id: <1396590962-25815-3-git-send-email-famz@redhat.com>
240766
Patchwork-id: 58339
240766
O-Subject: [RHEL-7 0day qemu-kvm PATCH 2/7] iscsi: correctly propagate errors in iscsi_open
958e1b
Bugzilla: 1083413
240766
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
240766
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
240766
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
240766
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
240766
240766
From: Paolo Bonzini <pbonzini@redhat.com>
240766
240766
Before:
240766
    $ ./qemu-io-old
240766
    qemu-io-old> open -r -o file.driver=iscsi,file.filename=foo
240766
    Failed to parse URL : foo
240766
    qemu-io-old: can't open device (null): Could not open 'foo': Invalid argument
240766
240766
After:
240766
    $ ./qemu-io
240766
    qemu-io> open -r -o file.driver=iscsi,file.filename=foo
240766
    qemu-io: can't open device (null): Failed to parse URL : foo
240766
240766
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
240766
Reviewed-by: Fam Zheng <famz@redhat.com>
240766
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
240766
(cherry picked from commit f2917853f715b0ef55df29eb2ffea29dc69ce814)
240766
Signed-off-by: Fam Zheng <famz@redhat.com>
240766
240766
Conflicts:
240766
	block/iscsi.c
240766
        Because 84d18f065fb041a1c0d78d20320d740ae0673c8a (Use
240766
        error_is_set() only when necessary) is not backpored, which
240766
        converted "if (error_is_set(&local_err))" to "if (local_err)".
240766
240766
Signed-off-by: Fam Zheng <famz@redhat.com>
240766
---
240766
 block/iscsi.c | 105 ++++++++++++++++++++++++++++++----------------------------
240766
 1 file changed, 54 insertions(+), 51 deletions(-)
240766
240766
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
240766
---
240766
 block/iscsi.c |  105 +++++++++++++++++++++++++++++---------------------------
240766
 1 files changed, 54 insertions(+), 51 deletions(-)
240766
240766
diff --git a/block/iscsi.c b/block/iscsi.c
240766
index 082956c..537d2cb 100644
240766
--- a/block/iscsi.c
240766
+++ b/block/iscsi.c
240766
@@ -1036,7 +1036,8 @@ retry:
240766
 
240766
 #endif /* SCSI_SENSE_ASCQ_CAPACITY_DATA_HAS_CHANGED */
240766
 
240766
-static int parse_chap(struct iscsi_context *iscsi, const char *target)
240766
+static void parse_chap(struct iscsi_context *iscsi, const char *target,
240766
+                       Error **errp)
240766
 {
240766
     QemuOptsList *list;
240766
     QemuOpts *opts;
240766
@@ -1045,37 +1046,35 @@ static int parse_chap(struct iscsi_context *iscsi, const char *target)
240766
 
240766
     list = qemu_find_opts("iscsi");
240766
     if (!list) {
240766
-        return 0;
240766
+        return;
240766
     }
240766
 
240766
     opts = qemu_opts_find(list, target);
240766
     if (opts == NULL) {
240766
         opts = QTAILQ_FIRST(&list->head);
240766
         if (!opts) {
240766
-            return 0;
240766
+            return;
240766
         }
240766
     }
240766
 
240766
     user = qemu_opt_get(opts, "user");
240766
     if (!user) {
240766
-        return 0;
240766
+        return;
240766
     }
240766
 
240766
     password = qemu_opt_get(opts, "password");
240766
     if (!password) {
240766
-        error_report("CHAP username specified but no password was given");
240766
-        return -1;
240766
+        error_setg(errp, "CHAP username specified but no password was given");
240766
+        return;
240766
     }
240766
 
240766
     if (iscsi_set_initiator_username_pwd(iscsi, user, password)) {
240766
-        error_report("Failed to set initiator username and password");
240766
-        return -1;
240766
+        error_setg(errp, "Failed to set initiator username and password");
240766
     }
240766
-
240766
-    return 0;
240766
 }
240766
 
240766
-static void parse_header_digest(struct iscsi_context *iscsi, const char *target)
240766
+static void parse_header_digest(struct iscsi_context *iscsi, const char *target,
240766
+                                Error **errp)
240766
 {
240766
     QemuOptsList *list;
240766
     QemuOpts *opts;
240766
@@ -1108,7 +1107,7 @@ static void parse_header_digest(struct iscsi_context *iscsi, const char *target)
240766
     } else if (!strcmp(digest, "NONE-CRC32C")) {
240766
         iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
240766
     } else {
240766
-        error_report("Invalid header-digest setting : %s", digest);
240766
+        error_setg(errp, "Invalid header-digest setting : %s", digest);
240766
     }
240766
 }
240766
 
240766
@@ -1166,12 +1165,11 @@ static void iscsi_nop_timed_event(void *opaque)
240766
 }
240766
 #endif
240766
 
240766
-static int iscsi_readcapacity_sync(IscsiLun *iscsilun)
240766
+static void iscsi_readcapacity_sync(IscsiLun *iscsilun, Error **errp)
240766
 {
240766
     struct scsi_task *task = NULL;
240766
     struct scsi_readcapacity10 *rc10 = NULL;
240766
     struct scsi_readcapacity16 *rc16 = NULL;
240766
-    int ret = 0;
240766
     int retries = ISCSI_CMD_RETRIES; 
240766
 
240766
     do {
240766
@@ -1186,8 +1184,7 @@ static int iscsi_readcapacity_sync(IscsiLun *iscsilun)
240766
             if (task != NULL && task->status == SCSI_STATUS_GOOD) {
240766
                 rc16 = scsi_datain_unmarshall(task);
240766
                 if (rc16 == NULL) {
240766
-                    error_report("iSCSI: Failed to unmarshall readcapacity16 data.");
240766
-                    ret = -EINVAL;
240766
+                    error_setg(errp, "iSCSI: Failed to unmarshall readcapacity16 data.");
240766
                 } else {
240766
                     iscsilun->block_size = rc16->block_length;
240766
                     iscsilun->num_blocks = rc16->returned_lba + 1;
240766
@@ -1201,8 +1198,7 @@ static int iscsi_readcapacity_sync(IscsiLun *iscsilun)
240766
             if (task != NULL && task->status == SCSI_STATUS_GOOD) {
240766
                 rc10 = scsi_datain_unmarshall(task);
240766
                 if (rc10 == NULL) {
240766
-                    error_report("iSCSI: Failed to unmarshall readcapacity10 data.");
240766
-                    ret = -EINVAL;
240766
+                    error_setg(errp, "iSCSI: Failed to unmarshall readcapacity10 data.");
240766
                 } else {
240766
                     iscsilun->block_size = rc10->block_size;
240766
                     if (rc10->lba == 0) {
240766
@@ -1215,20 +1211,18 @@ static int iscsi_readcapacity_sync(IscsiLun *iscsilun)
240766
             }
240766
             break;
240766
         default:
240766
-            return 0;
240766
+            return;
240766
         }
240766
     } while (task != NULL && task->status == SCSI_STATUS_CHECK_CONDITION
240766
              && task->sense.key == SCSI_SENSE_UNIT_ATTENTION
240766
              && retries-- > 0);
240766
 
240766
     if (task == NULL || task->status != SCSI_STATUS_GOOD) {
240766
-        error_report("iSCSI: failed to send readcapacity10 command.");
240766
-        ret = -EINVAL;
240766
+        error_setg(errp, "iSCSI: failed to send readcapacity10 command.");
240766
     }
240766
     if (task) {
240766
         scsi_free_scsi_task(task);
240766
     }
240766
-    return ret;
240766
 }
240766
 
240766
 /* TODO Convert to fine grained options */
240766
@@ -1246,7 +1240,7 @@ static QemuOptsList runtime_opts = {
240766
 };
240766
 
240766
 static struct scsi_task *iscsi_do_inquiry(struct iscsi_context *iscsi, int lun,
240766
-                                          int evpd, int pc)
240766
+                                          int evpd, int pc, Error **errp)
240766
 {
240766
     int full_size;
240766
     struct scsi_task *task = NULL;
240766
@@ -1268,8 +1262,8 @@ static struct scsi_task *iscsi_do_inquiry(struct iscsi_context *iscsi, int lun,
240766
     return task;
240766
 
240766
 fail:
240766
-    error_report("iSCSI: Inquiry command failed : %s",
240766
-                 iscsi_get_error(iscsi));
240766
+    error_setg(errp, "iSCSI: Inquiry command failed : %s",
240766
+               iscsi_get_error(iscsi));
240766
     if (task) {
240766
         scsi_free_scsi_task(task);
240766
         return NULL;
240766
@@ -1296,27 +1290,25 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
240766
     int ret;
240766
 
240766
     if ((BDRV_SECTOR_SIZE % 512) != 0) {
240766
-        error_report("iSCSI: Invalid BDRV_SECTOR_SIZE. "
240766
-                     "BDRV_SECTOR_SIZE(%lld) is not a multiple "
240766
-                     "of 512", BDRV_SECTOR_SIZE);
240766
+        error_setg(errp, "iSCSI: Invalid BDRV_SECTOR_SIZE. "
240766
+                   "BDRV_SECTOR_SIZE(%lld) is not a multiple "
240766
+                   "of 512", BDRV_SECTOR_SIZE);
240766
         return -EINVAL;
240766
     }
240766
 
240766
     opts = qemu_opts_create_nofail(&runtime_opts);
240766
     qemu_opts_absorb_qdict(opts, options, &local_err);
240766
-    if (error_is_set(&local_err)) {
240766
-        qerror_report_err(local_err);
240766
-        error_free(local_err);
240766
+    if (local_err) {
240766
+        error_propagate(errp, local_err);
240766
         ret = -EINVAL;
240766
         goto out;
240766
     }
240766
 
240766
     filename = qemu_opt_get(opts, "filename");
240766
 
240766
-
240766
     iscsi_url = iscsi_parse_full_url(iscsi, filename);
240766
     if (iscsi_url == NULL) {
240766
-        error_report("Failed to parse URL : %s", filename);
240766
+        error_setg(errp, "Failed to parse URL : %s", filename);
240766
         ret = -EINVAL;
240766
         goto out;
240766
     }
240766
@@ -1327,13 +1319,13 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
240766
 
240766
     iscsi = iscsi_create_context(initiator_name);
240766
     if (iscsi == NULL) {
240766
-        error_report("iSCSI: Failed to create iSCSI context.");
240766
+        error_setg(errp, "iSCSI: Failed to create iSCSI context.");
240766
         ret = -ENOMEM;
240766
         goto out;
240766
     }
240766
 
240766
     if (iscsi_set_targetname(iscsi, iscsi_url->target)) {
240766
-        error_report("iSCSI: Failed to set target name.");
240766
+        error_setg(errp, "iSCSI: Failed to set target name.");
240766
         ret = -EINVAL;
240766
         goto out;
240766
     }
240766
@@ -1342,21 +1334,22 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
240766
         ret = iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user,
240766
                                               iscsi_url->passwd);
240766
         if (ret != 0) {
240766
-            error_report("Failed to set initiator username and password");
240766
+            error_setg(errp, "Failed to set initiator username and password");
240766
             ret = -EINVAL;
240766
             goto out;
240766
         }
240766
     }
240766
 
240766
     /* check if we got CHAP username/password via the options */
240766
-    if (parse_chap(iscsi, iscsi_url->target) != 0) {
240766
-        error_report("iSCSI: Failed to set CHAP user/password");
240766
+    parse_chap(iscsi, iscsi_url->target, &local_err);
240766
+    if (local_err != NULL) {
240766
+        error_propagate(errp, local_err);
240766
         ret = -EINVAL;
240766
         goto out;
240766
     }
240766
 
240766
     if (iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL) != 0) {
240766
-        error_report("iSCSI: Failed to set session type to normal.");
240766
+        error_setg(errp, "iSCSI: Failed to set session type to normal.");
240766
         ret = -EINVAL;
240766
         goto out;
240766
     }
240766
@@ -1364,10 +1357,15 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
240766
     iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
240766
 
240766
     /* check if we got HEADER_DIGEST via the options */
240766
-    parse_header_digest(iscsi, iscsi_url->target);
240766
+    parse_header_digest(iscsi, iscsi_url->target, &local_err);
240766
+    if (local_err != NULL) {
240766
+        error_propagate(errp, local_err);
240766
+        ret = -EINVAL;
240766
+        goto out;
240766
+    }
240766
 
240766
     if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) {
240766
-        error_report("iSCSI: Failed to connect to LUN : %s",
240766
+        error_setg(errp, "iSCSI: Failed to connect to LUN : %s",
240766
             iscsi_get_error(iscsi));
240766
         ret = -EINVAL;
240766
         goto out;
240766
@@ -1379,14 +1377,14 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
240766
     task = iscsi_inquiry_sync(iscsi, iscsilun->lun, 0, 0, 36);
240766
 
240766
     if (task == NULL || task->status != SCSI_STATUS_GOOD) {
240766
-        error_report("iSCSI: failed to send inquiry command.");
240766
+        error_setg(errp, "iSCSI: failed to send inquiry command.");
240766
         ret = -EINVAL;
240766
         goto out;
240766
     }
240766
 
240766
     inq = scsi_datain_unmarshall(task);
240766
     if (inq == NULL) {
240766
-        error_report("iSCSI: Failed to unmarshall inquiry data.");
240766
+        error_setg(errp, "iSCSI: Failed to unmarshall inquiry data.");
240766
         ret = -EINVAL;
240766
         goto out;
240766
     }
240766
@@ -1394,7 +1392,9 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
240766
     iscsilun->type = inq->periperal_device_type;
240766
     iscsilun->has_write_same = true;
240766
 
240766
-    if ((ret = iscsi_readcapacity_sync(iscsilun)) != 0) {
240766
+    iscsi_readcapacity_sync(iscsilun, &local_err);
240766
+    if (local_err != NULL) {
240766
+        error_propagate(errp, local_err);
240766
         goto out;
240766
     }
240766
     bs->total_sectors = sector_lun2qemu(iscsilun->num_blocks, iscsilun);
240766
@@ -1411,14 +1411,15 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
240766
     if (iscsilun->lbpme) {
240766
         struct scsi_inquiry_logical_block_provisioning *inq_lbp;
240766
         task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
240766
-                                SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING);
240766
+                                SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING,
240766
+                                errp);
240766
         if (task == NULL) {
240766
             ret = -EINVAL;
240766
             goto out;
240766
         }
240766
         inq_lbp = scsi_datain_unmarshall(task);
240766
         if (inq_lbp == NULL) {
240766
-            error_report("iSCSI: failed to unmarshall inquiry datain blob");
240766
+            error_setg(errp, "iSCSI: failed to unmarshall inquiry datain blob");
240766
             ret = -EINVAL;
240766
             goto out;
240766
         }
240766
@@ -1431,14 +1432,14 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
240766
     if (iscsilun->lbp.lbpu || iscsilun->lbp.lbpws) {
240766
         struct scsi_inquiry_block_limits *inq_bl;
240766
         task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
240766
-                                SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS);
240766
+                                SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS, errp);
240766
         if (task == NULL) {
240766
             ret = -EINVAL;
240766
             goto out;
240766
         }
240766
         inq_bl = scsi_datain_unmarshall(task);
240766
         if (inq_bl == NULL) {
240766
-            error_report("iSCSI: failed to unmarshall inquiry datain blob");
240766
+            error_setg(errp, "iSCSI: failed to unmarshall inquiry datain blob");
240766
             ret = -EINVAL;
240766
             goto out;
240766
         }
240766
@@ -1529,14 +1530,16 @@ static int iscsi_reopen_prepare(BDRVReopenState *state,
240766
 static int iscsi_truncate(BlockDriverState *bs, int64_t offset)
240766
 {
240766
     IscsiLun *iscsilun = bs->opaque;
240766
-    int ret = 0;
240766
+    Error *local_err = NULL;
240766
 
240766
     if (iscsilun->type != TYPE_DISK) {
240766
         return -ENOTSUP;
240766
     }
240766
 
240766
-    if ((ret = iscsi_readcapacity_sync(iscsilun)) != 0) {
240766
-        return ret;
240766
+    iscsi_readcapacity_sync(iscsilun, &local_err);
240766
+    if (local_err != NULL) {
240766
+        error_free(local_err);
240766
+        return -EIO;
240766
     }
240766
 
240766
     if (offset > iscsi_getlength(bs)) {
240766
-- 
240766
1.7.1
240766