From patchwork Mon Feb 17 13:43:53 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 320990 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 7AE212C00C4 for ; Tue, 18 Feb 2014 00:55:57 +1100 (EST) Received: from localhost ([::1]:40657 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WFObT-0001Fm-Hk for incoming@patchwork.ozlabs.org; Mon, 17 Feb 2014 08:51:23 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55609) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WFOUz-0000cX-Kx for qemu-devel@nongnu.org; Mon, 17 Feb 2014 08:44:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WFOUq-0000rF-2b for qemu-devel@nongnu.org; Mon, 17 Feb 2014 08:44:41 -0500 Received: from mail-qa0-x22b.google.com ([2607:f8b0:400d:c00::22b]:52108) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WFOUp-0000qU-TB for qemu-devel@nongnu.org; Mon, 17 Feb 2014 08:44:32 -0500 Received: by mail-qa0-f43.google.com with SMTP id o15so21635133qap.2 for ; Mon, 17 Feb 2014 05:44:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=ZtqAGIZtEau39sDqjA2b1Ps/8fCmWlQDWd0zmIqmXPY=; b=axMqgIbR9JITbacQCJhjFqAN8rbkmU6SArqCwLG+lMK0vVrdhXafEAG+Cf72SR2MLp o4PXIGNOxSw3sMvnPDYX7uilUNNMThTpEIT92RbUMfCIOdeiMWCxUKb8P3olpiTAZpht Zo1OO2gZ1vXVxcfHDSeqmnFjKSOOluB/GmjOOBiwrnAKyZRryycXkoR1S4tpJY1CHtor m/M51acLXKAmcQ+F9CNWcXsh4vYAqGjoYQA4/J6nd1lTZs+XEwGcorh8e6sK3Cjbcffz UtOYCagn0kO+Cf7BE9zKQgbcKN6chYu/up10485UTm1h3TcPH95xMrcDPU1/uPl/tqgI 2EVw== X-Received: by 10.229.172.4 with SMTP id j4mr34442530qcz.6.1392644671376; Mon, 17 Feb 2014 05:44:31 -0800 (PST) Received: from yakj.usersys.redhat.com (net-37-117-154-249.cust.vodafonedsl.it. [37.117.154.249]) by mx.google.com with ESMTPSA id p10sm45265803qag.8.2014.02.17.05.44.28 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 17 Feb 2014 05:44:30 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Mon, 17 Feb 2014 14:43:53 +0100 Message-Id: <1392644647-9897-7-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.5.3 In-Reply-To: <1392644647-9897-1-git-send-email-pbonzini@redhat.com> References: <1392644647-9897-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:400d:c00::22b Cc: kwolf@redhat.com, jcody@redhat.com, famz@redhat.com, stefanha@redhat.com Subject: [Qemu-devel] [PATCH v3 06/20] iscsi: correctly propagate errors in iscsi_open X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Before: $ ./qemu-io-old qemu-io-old> open -r -o file.driver=iscsi,file.filename=foo Failed to parse URL : foo qemu-io-old: can't open device (null): Could not open 'foo': Invalid argument After: $ ./qemu-io qemu-io> open -r -o file.driver=iscsi,file.filename=foo qemu-io: can't open device (null): Failed to parse URL : foo Signed-off-by: Paolo Bonzini Acked-by: Stefan Hajnoczi --- block/iscsi.c | 103 ++++++++++++++++++++++++++++++---------------------------- 1 file changed, 53 insertions(+), 50 deletions(-) diff --git a/block/iscsi.c b/block/iscsi.c index 95a1030..05dd50d 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -856,7 +856,8 @@ retry: #endif /* SCSI_SENSE_ASCQ_CAPACITY_DATA_HAS_CHANGED */ -static int parse_chap(struct iscsi_context *iscsi, const char *target) +static void parse_chap(struct iscsi_context *iscsi, const char *target, + Error **errp) { QemuOptsList *list; QemuOpts *opts; @@ -865,37 +866,35 @@ static int parse_chap(struct iscsi_context *iscsi, const char *target) list = qemu_find_opts("iscsi"); if (!list) { - return 0; + return; } opts = qemu_opts_find(list, target); if (opts == NULL) { opts = QTAILQ_FIRST(&list->head); if (!opts) { - return 0; + return; } } user = qemu_opt_get(opts, "user"); if (!user) { - return 0; + return; } password = qemu_opt_get(opts, "password"); if (!password) { - error_report("CHAP username specified but no password was given"); - return -1; + error_setg(errp, "CHAP username specified but no password was given"); + return; } if (iscsi_set_initiator_username_pwd(iscsi, user, password)) { - error_report("Failed to set initiator username and password"); - return -1; + error_setg(errp, "Failed to set initiator username and password"); } - - return 0; } -static void parse_header_digest(struct iscsi_context *iscsi, const char *target) +static void parse_header_digest(struct iscsi_context *iscsi, const char *target, + Error **errp) { QemuOptsList *list; QemuOpts *opts; @@ -928,7 +927,7 @@ static void parse_header_digest(struct iscsi_context *iscsi, const char *target) } else if (!strcmp(digest, "NONE-CRC32C")) { iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C); } else { - error_report("Invalid header-digest setting : %s", digest); + error_setg(errp, "Invalid header-digest setting : %s", digest); } } @@ -986,12 +985,11 @@ static void iscsi_nop_timed_event(void *opaque) } #endif -static int iscsi_readcapacity_sync(IscsiLun *iscsilun) +static void iscsi_readcapacity_sync(IscsiLun *iscsilun, Error **errp) { struct scsi_task *task = NULL; struct scsi_readcapacity10 *rc10 = NULL; struct scsi_readcapacity16 *rc16 = NULL; - int ret = 0; int retries = ISCSI_CMD_RETRIES; do { @@ -1006,8 +1004,7 @@ static int iscsi_readcapacity_sync(IscsiLun *iscsilun) if (task != NULL && task->status == SCSI_STATUS_GOOD) { rc16 = scsi_datain_unmarshall(task); if (rc16 == NULL) { - error_report("iSCSI: Failed to unmarshall readcapacity16 data."); - ret = -EINVAL; + error_setg(errp, "iSCSI: Failed to unmarshall readcapacity16 data."); } else { iscsilun->block_size = rc16->block_length; iscsilun->num_blocks = rc16->returned_lba + 1; @@ -1021,8 +1018,7 @@ static int iscsi_readcapacity_sync(IscsiLun *iscsilun) if (task != NULL && task->status == SCSI_STATUS_GOOD) { rc10 = scsi_datain_unmarshall(task); if (rc10 == NULL) { - error_report("iSCSI: Failed to unmarshall readcapacity10 data."); - ret = -EINVAL; + error_setg(errp, "iSCSI: Failed to unmarshall readcapacity10 data."); } else { iscsilun->block_size = rc10->block_size; if (rc10->lba == 0) { @@ -1035,20 +1031,18 @@ static int iscsi_readcapacity_sync(IscsiLun *iscsilun) } break; default: - return 0; + return; } } while (task != NULL && task->status == SCSI_STATUS_CHECK_CONDITION && task->sense.key == SCSI_SENSE_UNIT_ATTENTION && retries-- > 0); if (task == NULL || task->status != SCSI_STATUS_GOOD) { - error_report("iSCSI: failed to send readcapacity10 command."); - ret = -EINVAL; + error_setg(errp, "iSCSI: failed to send readcapacity10 command."); } if (task) { scsi_free_scsi_task(task); } - return ret; } /* TODO Convert to fine grained options */ @@ -1066,7 +1060,7 @@ static QemuOptsList runtime_opts = { }; static struct scsi_task *iscsi_do_inquiry(struct iscsi_context *iscsi, int lun, - int evpd, int pc) + int evpd, int pc, Error **errp) { int full_size; struct scsi_task *task = NULL; @@ -1088,8 +1082,8 @@ static struct scsi_task *iscsi_do_inquiry(struct iscsi_context *iscsi, int lun, return task; fail: - error_report("iSCSI: Inquiry command failed : %s", - iscsi_get_error(iscsi)); + error_setg(errp, "iSCSI: Inquiry command failed : %s", + iscsi_get_error(iscsi)); if (task) { scsi_free_scsi_task(task); return NULL; @@ -1120,27 +1114,25 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags, int ret; if ((BDRV_SECTOR_SIZE % 512) != 0) { - error_report("iSCSI: Invalid BDRV_SECTOR_SIZE. " - "BDRV_SECTOR_SIZE(%lld) is not a multiple " - "of 512", BDRV_SECTOR_SIZE); + error_setg(errp, "iSCSI: Invalid BDRV_SECTOR_SIZE. " + "BDRV_SECTOR_SIZE(%lld) is not a multiple " + "of 512", BDRV_SECTOR_SIZE); return -EINVAL; } opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort); qemu_opts_absorb_qdict(opts, options, &local_err); if (error_is_set(&local_err)) { - qerror_report_err(local_err); - error_free(local_err); + error_propagate(errp, local_err); ret = -EINVAL; goto out; } filename = qemu_opt_get(opts, "filename"); - iscsi_url = iscsi_parse_full_url(iscsi, filename); if (iscsi_url == NULL) { - error_report("Failed to parse URL : %s", filename); + error_setg(errp, "Failed to parse URL : %s", filename); ret = -EINVAL; goto out; } @@ -1151,13 +1143,13 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags, iscsi = iscsi_create_context(initiator_name); if (iscsi == NULL) { - error_report("iSCSI: Failed to create iSCSI context."); + error_setg(errp, "iSCSI: Failed to create iSCSI context."); ret = -ENOMEM; goto out; } if (iscsi_set_targetname(iscsi, iscsi_url->target)) { - error_report("iSCSI: Failed to set target name."); + error_setg(errp, "iSCSI: Failed to set target name."); ret = -EINVAL; goto out; } @@ -1166,21 +1158,22 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags, ret = iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user, iscsi_url->passwd); if (ret != 0) { - error_report("Failed to set initiator username and password"); + error_setg(errp, "Failed to set initiator username and password"); ret = -EINVAL; goto out; } } /* check if we got CHAP username/password via the options */ - if (parse_chap(iscsi, iscsi_url->target) != 0) { - error_report("iSCSI: Failed to set CHAP user/password"); + parse_chap(iscsi, iscsi_url->target, &local_err); + if (local_err != NULL) { + error_propagate(errp, local_err); ret = -EINVAL; goto out; } if (iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL) != 0) { - error_report("iSCSI: Failed to set session type to normal."); + error_setg(errp, "iSCSI: Failed to set session type to normal."); ret = -EINVAL; goto out; } @@ -1188,10 +1181,15 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags, iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C); /* check if we got HEADER_DIGEST via the options */ - parse_header_digest(iscsi, iscsi_url->target); + parse_header_digest(iscsi, iscsi_url->target, &local_err); + if (local_err != NULL) { + error_propagate(errp, local_err); + ret = -EINVAL; + goto out; + } if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) { - error_report("iSCSI: Failed to connect to LUN : %s", + error_setg(errp, "iSCSI: Failed to connect to LUN : %s", iscsi_get_error(iscsi)); ret = -EINVAL; goto out; @@ -1203,14 +1201,14 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags, task = iscsi_inquiry_sync(iscsi, iscsilun->lun, 0, 0, 36); if (task == NULL || task->status != SCSI_STATUS_GOOD) { - error_report("iSCSI: failed to send inquiry command."); + error_setg(errp, "iSCSI: failed to send inquiry command."); ret = -EINVAL; goto out; } inq = scsi_datain_unmarshall(task); if (inq == NULL) { - error_report("iSCSI: Failed to unmarshall inquiry data."); + error_setg(errp, "iSCSI: Failed to unmarshall inquiry data."); ret = -EINVAL; goto out; } @@ -1218,7 +1216,9 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags, iscsilun->type = inq->periperal_device_type; iscsilun->has_write_same = true; - if ((ret = iscsi_readcapacity_sync(iscsilun)) != 0) { + iscsi_readcapacity_sync(iscsilun, &local_err); + if (local_err != NULL) { + error_propagate(errp, local_err); goto out; } bs->total_sectors = sector_lun2qemu(iscsilun->num_blocks, iscsilun); @@ -1236,14 +1236,15 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags, if (iscsilun->lbpme) { struct scsi_inquiry_logical_block_provisioning *inq_lbp; task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1, - SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING); + SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING, + errp); if (task == NULL) { ret = -EINVAL; goto out; } inq_lbp = scsi_datain_unmarshall(task); if (inq_lbp == NULL) { - error_report("iSCSI: failed to unmarshall inquiry datain blob"); + error_setg(errp, "iSCSI: failed to unmarshall inquiry datain blob"); ret = -EINVAL; goto out; } @@ -1256,14 +1257,14 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags, if (iscsilun->lbp.lbpu || iscsilun->lbp.lbpws) { struct scsi_inquiry_block_limits *inq_bl; task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1, - SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS); + SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS, errp); if (task == NULL) { ret = -EINVAL; goto out; } inq_bl = scsi_datain_unmarshall(task); if (inq_bl == NULL) { - error_report("iSCSI: failed to unmarshall inquiry datain blob"); + error_setg(errp, "iSCSI: failed to unmarshall inquiry datain blob"); ret = -EINVAL; goto out; } @@ -1354,14 +1355,16 @@ static int iscsi_reopen_prepare(BDRVReopenState *state, static int iscsi_truncate(BlockDriverState *bs, int64_t offset) { IscsiLun *iscsilun = bs->opaque; - int ret = 0; + Error *local_err = NULL; if (iscsilun->type != TYPE_DISK) { return -ENOTSUP; } - if ((ret = iscsi_readcapacity_sync(iscsilun)) != 0) { - return ret; + iscsi_readcapacity_sync(iscsilun, &local_err); + if (local_err != NULL) { + error_free(local_err); + return -EIO; } if (offset > iscsi_getlength(bs)) {