From patchwork Tue Sep 10 14:49:34 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 273891 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)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id E5FD82C0106 for ; Wed, 11 Sep 2013 00:51:48 +1000 (EST) Received: from localhost ([::1]:58442 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VJPI9-0005E1-Vv for incoming@patchwork.ozlabs.org; Tue, 10 Sep 2013 10:51:46 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53106) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VJPHR-000513-MH for qemu-devel@nongnu.org; Tue, 10 Sep 2013 10:51:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VJPHL-0006pu-3g for qemu-devel@nongnu.org; Tue, 10 Sep 2013 10:51:01 -0400 Received: from mx1.redhat.com ([209.132.183.28]:39024) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VJPHK-0006pp-Mh for qemu-devel@nongnu.org; Tue, 10 Sep 2013 10:50:55 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r8AEosn6015583 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 10 Sep 2013 10:50:54 -0400 Received: from localhost (dhcp-200-247.str.redhat.com [10.33.200.247]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r8AEoqD4014924 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NO); Tue, 10 Sep 2013 10:50:53 -0400 From: Max Reitz To: qemu-devel@nongnu.org Date: Tue, 10 Sep 2013 16:49:34 +0200 Message-Id: <1378824578-30394-4-git-send-email-mreitz@redhat.com> In-Reply-To: <1378824578-30394-1-git-send-email-mreitz@redhat.com> References: <1378824578-30394-1-git-send-email-mreitz@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Kevin Wolf , Stefan Hajnoczi , Max Reitz Subject: [Qemu-devel] [PATCH 3/7] block: Error parameter for open functions 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 Add an Error ** parameter to bdrv_open, bdrv_file_open and associated functions to allow more specific error messages. Signed-off-by: Max Reitz --- block.c | 100 ++++++++++++++++++++++++++++++++------------------ block/blkdebug.c | 4 +- block/blkverify.c | 8 +++- block/cow.c | 5 ++- block/mirror.c | 5 ++- block/qcow.c | 5 ++- block/qcow2.c | 4 +- block/qed.c | 6 ++- block/sheepdog.c | 10 ++++- block/vmdk.c | 11 +++++- block/vvfat.c | 6 ++- blockdev.c | 30 +++++++-------- hw/block/xen_disk.c | 7 +++- include/block/block.h | 6 +-- qemu-img.c | 21 +++++++---- qemu-io.c | 14 +++++-- qemu-nbd.c | 6 ++- 17 files changed, 163 insertions(+), 85 deletions(-) diff --git a/block.c b/block.c index f9b7033..ba0d876 100644 --- a/block.c +++ b/block.c @@ -552,7 +552,7 @@ BlockDriver *bdrv_find_protocol(const char *filename, } static int find_image_format(BlockDriverState *bs, const char *filename, - BlockDriver **pdrv) + BlockDriver **pdrv, Error **errp) { int score, score_max; BlockDriver *drv1, *drv; @@ -563,6 +563,7 @@ static int find_image_format(BlockDriverState *bs, const char *filename, if (bs->sg || !bdrv_is_inserted(bs) || bdrv_getlength(bs) == 0) { drv = bdrv_find_format("raw"); if (!drv) { + error_setg(errp, "Could not find raw image format"); ret = -ENOENT; } *pdrv = drv; @@ -571,6 +572,8 @@ static int find_image_format(BlockDriverState *bs, const char *filename, ret = bdrv_pread(bs, 0, buf, sizeof(buf)); if (ret < 0) { + error_setg_errno(errp, -ret, "Could not read image for determining its " + "format"); *pdrv = NULL; return ret; } @@ -587,6 +590,8 @@ static int find_image_format(BlockDriverState *bs, const char *filename, } } if (!drv) { + error_setg(errp, "Could not determine image format: No compatible " + "driver found"); ret = -ENOENT; } *pdrv = drv; @@ -706,10 +711,11 @@ static int bdrv_open_flags(BlockDriverState *bs, int flags) * Removes all processed options from *options. */ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file, - QDict *options, int flags, BlockDriver *drv) + QDict *options, int flags, BlockDriver *drv, Error **errp) { int ret, open_flags; const char *filename; + Error *local_err = NULL; assert(drv != NULL); assert(bs->file == NULL); @@ -738,6 +744,7 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file, bs->read_only = !(open_flags & BDRV_O_RDWR); if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv, bs->read_only)) { + error_setg(errp, "Driver '%s' is not whitelisted", drv->format_name); return -ENOTSUP; } @@ -761,25 +768,32 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file, if (drv->bdrv_file_open) { assert(file == NULL); assert(drv->bdrv_parse_filename || filename != NULL); - ret = drv->bdrv_file_open(bs, options, open_flags, NULL); + ret = drv->bdrv_file_open(bs, options, open_flags, &local_err); } else { if (file == NULL) { - qerror_report(ERROR_CLASS_GENERIC_ERROR, "Can't use '%s' as a " - "block driver for the protocol level", - drv->format_name); + error_setg(errp, "Can't use '%s' as a block driver for the " + "protocol level", drv->format_name); ret = -EINVAL; goto free_and_fail; } bs->file = file; - ret = drv->bdrv_open(bs, options, open_flags, NULL); + ret = drv->bdrv_open(bs, options, open_flags, &local_err); } if (ret < 0) { + if (error_is_set(&local_err)) { + error_propagate(errp, local_err); + } else if (filename) { + error_setg_errno(errp, -ret, "Could not open '%s'", filename); + } else { + error_setg_errno(errp, -ret, "Could not open image"); + } goto free_and_fail; } ret = refresh_total_sectors(bs, bs->total_sectors); if (ret < 0) { + error_setg_errno(errp, -ret, "Could not refresh total sector count"); goto free_and_fail; } @@ -808,12 +822,13 @@ free_and_fail: * dictionary, it needs to use QINCREF() before calling bdrv_file_open. */ int bdrv_file_open(BlockDriverState **pbs, const char *filename, - QDict *options, int flags) + QDict *options, int flags, Error **errp) { BlockDriverState *bs; BlockDriver *drv; const char *drvname; bool allow_protocol_prefix = false; + Error *local_err = NULL; int ret; /* NULL means an empty set of options */ @@ -832,8 +847,8 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, qdict_put(options, "filename", qstring_from_str(filename)); allow_protocol_prefix = true; } else { - qerror_report(ERROR_CLASS_GENERIC_ERROR, "Can't specify 'file' and " - "'filename' options at the same time"); + error_setg(errp, "Can't specify 'file' and 'filename' options at the " + "same time"); ret = -EINVAL; goto fail; } @@ -842,53 +857,53 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, drvname = qdict_get_try_str(options, "driver"); if (drvname) { drv = bdrv_find_whitelisted_format(drvname, !(flags & BDRV_O_RDWR)); + if (!drv) { + error_setg(errp, "Unknown driver '%s'", drvname); + } qdict_del(options, "driver"); } else if (filename) { drv = bdrv_find_protocol(filename, allow_protocol_prefix); if (!drv) { - qerror_report(ERROR_CLASS_GENERIC_ERROR, "Unknown protocol"); + error_setg(errp, "Unknown protocol"); } } else { - qerror_report(ERROR_CLASS_GENERIC_ERROR, - "Must specify either driver or file"); + error_setg(errp, "Must specify either driver or file"); drv = NULL; } if (!drv) { + /* errp has been set already */ ret = -ENOENT; goto fail; } /* Parse the filename and open it */ if (drv->bdrv_parse_filename && filename) { - Error *local_err = NULL; drv->bdrv_parse_filename(filename, 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 fail; } qdict_del(options, "filename"); } else if (!drv->bdrv_parse_filename && !filename) { - qerror_report(ERROR_CLASS_GENERIC_ERROR, - "The '%s' block driver requires a file name", - drv->format_name); + error_setg(errp, "The '%s' block driver requires a file name", + drv->format_name); ret = -EINVAL; goto fail; } - ret = bdrv_open_common(bs, NULL, options, flags, drv); + ret = bdrv_open_common(bs, NULL, options, flags, drv, &local_err); if (ret < 0) { + error_propagate(errp, local_err); goto fail; } /* Check if any unknown options were used */ if (qdict_size(options) != 0) { const QDictEntry *entry = qdict_first(options); - qerror_report(ERROR_CLASS_GENERIC_ERROR, "Block protocol '%s' doesn't " - "support the option '%s'", - drv->format_name, entry->key); + error_setg(errp, "Block protocol '%s' doesn't support the option '%s'", + drv->format_name, entry->key); ret = -EINVAL; goto fail; } @@ -915,11 +930,12 @@ fail: * function (even on failure), so if the caller intends to reuse the dictionary, * it needs to use QINCREF() before calling bdrv_file_open. */ -int bdrv_open_backing_file(BlockDriverState *bs, QDict *options) +int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp) { char backing_filename[PATH_MAX]; int back_flags, ret; BlockDriver *back_drv = NULL; + Error *local_err = NULL; if (bs->backing_hd != NULL) { QDECREF(options); @@ -952,11 +968,12 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options) ret = bdrv_open(bs->backing_hd, *backing_filename ? backing_filename : NULL, options, - back_flags, back_drv); + back_flags, back_drv, &local_err); if (ret < 0) { bdrv_unref(bs->backing_hd); bs->backing_hd = NULL; bs->open_flags |= BDRV_O_NO_BACKING; + error_propagate(errp, local_err); return ret; } return 0; @@ -990,7 +1007,7 @@ static void extract_subqdict(QDict *src, QDict **dst, const char *start) * dictionary, it needs to use QINCREF() before calling bdrv_open. */ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, - int flags, BlockDriver *drv) + int flags, BlockDriver *drv, Error **errp) { int ret; /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */ @@ -998,6 +1015,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, BlockDriverState *file = NULL; QDict *file_options = NULL; const char *drvname; + Error *local_err = NULL; /* NULL means an empty set of options */ if (options == NULL) { @@ -1016,7 +1034,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, char backing_filename[PATH_MAX]; if (qdict_size(options) != 0) { - error_report("Can't use snapshot=on with driver-specific options"); + error_setg(errp, "Can't use snapshot=on with driver-specific options"); ret = -EINVAL; goto fail; } @@ -1027,7 +1045,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, /* if there is a backing file, use it */ bs1 = bdrv_new(""); - ret = bdrv_open(bs1, filename, NULL, 0, drv); + ret = bdrv_open(bs1, filename, NULL, 0, drv, &local_err); if (ret < 0) { bdrv_unref(bs1); goto fail; @@ -1038,6 +1056,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, ret = get_tmp_filename(tmp_filename, sizeof(tmp_filename)); if (ret < 0) { + error_setg_errno(errp, -ret, "Could not get temporary filename"); goto fail; } @@ -1046,6 +1065,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, snprintf(backing_filename, sizeof(backing_filename), "%s", filename); } else if (!realpath(filename, backing_filename)) { + error_setg_errno(errp, errno, "Could not resolve path '%s'", filename); ret = -errno; goto fail; } @@ -1065,6 +1085,8 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options); free_option_parameters(create_options); if (ret < 0) { + error_setg_errno(errp, -ret, "Could not create temporary overlay " + "'%s'", tmp_filename); goto fail; } @@ -1081,7 +1103,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, extract_subqdict(options, &file_options, "file."); ret = bdrv_file_open(&file, filename, file_options, - bdrv_open_flags(bs, flags | BDRV_O_UNMAP)); + bdrv_open_flags(bs, flags | BDRV_O_UNMAP), &local_err); if (ret < 0) { goto fail; } @@ -1094,7 +1116,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, } if (!drv) { - ret = find_image_format(file, filename, &drv); + ret = find_image_format(file, filename, &drv, &local_err); } if (!drv) { @@ -1102,7 +1124,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, } /* Open the image */ - ret = bdrv_open_common(bs, file, options, flags, drv); + ret = bdrv_open_common(bs, file, options, flags, drv, &local_err); if (ret < 0) { goto unlink_and_fail; } @@ -1117,7 +1139,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, QDict *backing_options; extract_subqdict(options, &backing_options, "backing."); - ret = bdrv_open_backing_file(bs, backing_options); + ret = bdrv_open_backing_file(bs, backing_options, &local_err); if (ret < 0) { goto close_and_fail; } @@ -1126,9 +1148,9 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, /* Check if any unknown options were used */ if (qdict_size(options) != 0) { const QDictEntry *entry = qdict_first(options); - qerror_report(ERROR_CLASS_GENERIC_ERROR, "Block format '%s' used by " - "device '%s' doesn't support the option '%s'", - drv->format_name, bs->device_name, entry->key); + error_setg(errp, "Block format '%s' used by device '%s' doesn't " + "support the option '%s'", drv->format_name, bs->device_name, + entry->key); ret = -EINVAL; goto close_and_fail; @@ -1152,11 +1174,17 @@ fail: QDECREF(bs->options); QDECREF(options); bs->options = NULL; + if (error_is_set(&local_err)) { + error_propagate(errp, local_err); + } return ret; close_and_fail: bdrv_close(bs); QDECREF(options); + if (error_is_set(&local_err)) { + error_propagate(errp, local_err); + } return ret; } @@ -4519,7 +4547,7 @@ void bdrv_img_create(const char *filename, const char *fmt, bs = bdrv_new(""); ret = bdrv_open(bs, backing_file->value.s, NULL, back_flags, - backing_drv); + backing_drv, NULL); if (ret < 0) { error_setg_errno(errp, -ret, "Could not open '%s'", backing_file->value.s); diff --git a/block/blkdebug.c b/block/blkdebug.c index 52d65ff..be948b2 100644 --- a/block/blkdebug.c +++ b/block/blkdebug.c @@ -387,8 +387,10 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags, goto fail; } - ret = bdrv_file_open(&bs->file, filename, NULL, flags); + ret = bdrv_file_open(&bs->file, filename, NULL, flags, &local_err); if (ret < 0) { + qerror_report_err(local_err); + error_free(local_err); goto fail; } diff --git a/block/blkverify.c b/block/blkverify.c index 2093391..bff95d2 100644 --- a/block/blkverify.c +++ b/block/blkverify.c @@ -141,8 +141,10 @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags, goto fail; } - ret = bdrv_file_open(&bs->file, raw, NULL, flags); + ret = bdrv_file_open(&bs->file, raw, NULL, flags, &local_err); if (ret < 0) { + qerror_report_err(local_err); + error_free(local_err); goto fail; } @@ -154,8 +156,10 @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags, } s->test_file = bdrv_new(""); - ret = bdrv_open(s->test_file, filename, NULL, flags, NULL); + ret = bdrv_open(s->test_file, filename, NULL, flags, NULL, &local_err); if (ret < 0) { + qerror_report_err(local_err); + error_free(local_err); bdrv_unref(s->test_file); s->test_file = NULL; goto fail; diff --git a/block/cow.c b/block/cow.c index e252c95..3a93ed9 100644 --- a/block/cow.c +++ b/block/cow.c @@ -302,6 +302,7 @@ static int cow_create(const char *filename, QEMUOptionParameter *options, struct stat st; int64_t image_sectors = 0; const char *image_filename = NULL; + Error *local_err = NULL; int ret; BlockDriverState *cow_bs; @@ -320,8 +321,10 @@ static int cow_create(const char *filename, QEMUOptionParameter *options, return ret; } - ret = bdrv_file_open(&cow_bs, filename, NULL, BDRV_O_RDWR); + ret = bdrv_file_open(&cow_bs, filename, NULL, BDRV_O_RDWR, &local_err); if (ret < 0) { + qerror_report_err(local_err); + error_free(local_err); return ret; } diff --git a/block/mirror.c b/block/mirror.c index f61a779..6e7a274 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -505,14 +505,15 @@ static void mirror_iostatus_reset(BlockJob *job) static void mirror_complete(BlockJob *job, Error **errp) { MirrorBlockJob *s = container_of(job, MirrorBlockJob, common); + Error *local_err = NULL; int ret; - ret = bdrv_open_backing_file(s->target, NULL); + ret = bdrv_open_backing_file(s->target, NULL, &local_err); if (ret < 0) { char backing_filename[PATH_MAX]; bdrv_get_full_backing_filename(s->target, backing_filename, sizeof(backing_filename)); - error_setg_file_open(errp, -ret, backing_filename); + error_propagate(errp, local_err); return; } if (!s->synced) { diff --git a/block/qcow.c b/block/qcow.c index 0911edf..396636f 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -668,6 +668,7 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options, int64_t total_size = 0; const char *backing_file = NULL; int flags = 0; + Error *local_err = NULL; int ret; BlockDriverState *qcow_bs; @@ -688,8 +689,10 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options, return ret; } - ret = bdrv_file_open(&qcow_bs, filename, NULL, BDRV_O_RDWR); + ret = bdrv_file_open(&qcow_bs, filename, NULL, BDRV_O_RDWR, &local_err); if (ret < 0) { + qerror_report_err(local_err); + error_free(local_err); return ret; } diff --git a/block/qcow2.c b/block/qcow2.c index 43edc5b..dabfe8d 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1370,7 +1370,7 @@ static int qcow2_create2(const char *filename, int64_t total_size, return ret; } - ret = bdrv_file_open(&bs, filename, NULL, BDRV_O_RDWR); + ret = bdrv_file_open(&bs, filename, NULL, BDRV_O_RDWR, NULL); if (ret < 0) { return ret; } @@ -1423,7 +1423,7 @@ static int qcow2_create2(const char *filename, int64_t total_size, BlockDriver* drv = bdrv_find_format("qcow2"); assert(drv != NULL); ret = bdrv_open(bs, filename, NULL, - BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, drv); + BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, drv, NULL); if (ret < 0) { goto out; } diff --git a/block/qed.c b/block/qed.c index 250fa89..f17094c 100644 --- a/block/qed.c +++ b/block/qed.c @@ -551,6 +551,7 @@ static int qed_create(const char *filename, uint32_t cluster_size, QEDHeader le_header; uint8_t *l1_table = NULL; size_t l1_size = header.cluster_size * header.table_size; + Error *local_err = NULL; int ret = 0; BlockDriverState *bs = NULL; @@ -559,8 +560,11 @@ static int qed_create(const char *filename, uint32_t cluster_size, return ret; } - ret = bdrv_file_open(&bs, filename, NULL, BDRV_O_RDWR | BDRV_O_CACHE_WB); + ret = bdrv_file_open(&bs, filename, NULL, BDRV_O_RDWR | BDRV_O_CACHE_WB, + &local_err); if (ret < 0) { + qerror_report_err(local_err); + error_free(local_err); return ret; } diff --git a/block/sheepdog.c b/block/sheepdog.c index 8ff3895..c10e5e3 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -1401,10 +1401,13 @@ static int sd_prealloc(const char *filename) uint32_t idx, max_idx; int64_t vdi_size; void *buf = g_malloc0(SD_DATA_OBJ_SIZE); + Error *local_err = NULL; int ret; - ret = bdrv_file_open(&bs, filename, NULL, BDRV_O_RDWR); + ret = bdrv_file_open(&bs, filename, NULL, BDRV_O_RDWR, &local_err); if (ret < 0) { + qerror_report_err(local_err); + error_free(local_err); goto out; } @@ -1449,6 +1452,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options, char vdi[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN]; uint32_t snapid; bool prealloc = false; + Error *local_err = NULL; s = g_malloc0(sizeof(BDRVSheepdogState)); @@ -1502,8 +1506,10 @@ static int sd_create(const char *filename, QEMUOptionParameter *options, goto out; } - ret = bdrv_file_open(&bs, backing_file, NULL, 0); + ret = bdrv_file_open(&bs, backing_file, NULL, 0, &local_err); if (ret < 0) { + qerror_report_err(local_err); + error_free(local_err); goto out; } diff --git a/block/vmdk.c b/block/vmdk.c index a98da08..96ef1b5 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -697,6 +697,7 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs, int64_t flat_offset; char extent_path[PATH_MAX]; BlockDriverState *extent_file; + Error *local_err = NULL; while (*p) { /* parse extent line: @@ -726,8 +727,11 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs, path_combine(extent_path, sizeof(extent_path), desc_file_path, fname); - ret = bdrv_file_open(&extent_file, extent_path, NULL, bs->open_flags); + ret = bdrv_file_open(&extent_file, extent_path, NULL, bs->open_flags, + &local_err); if (ret) { + qerror_report_err(local_err); + error_free(local_err); return ret; } @@ -1591,6 +1595,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options, "ddb.geometry.heads = \"%d\"\n" "ddb.geometry.sectors = \"63\"\n" "ddb.adapterType = \"%s\"\n"; + Error *local_err = NULL; if (filename_decompose(filename, path, prefix, postfix, PATH_MAX)) { return -EINVAL; @@ -1653,8 +1658,10 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options, } if (backing_file) { BlockDriverState *bs = bdrv_new(""); - ret = bdrv_open(bs, backing_file, NULL, 0, NULL); + ret = bdrv_open(bs, backing_file, NULL, 0, NULL, &local_err); if (ret != 0) { + qerror_report_err(local_err); + error_free(local_err); bdrv_unref(bs); return ret; } diff --git a/block/vvfat.c b/block/vvfat.c index 2f8be7c..788d063 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -2910,6 +2910,7 @@ static int enable_write_target(BDRVVVFATState *s) { BlockDriver *bdrv_qcow; QEMUOptionParameter *options; + Error *local_err = NULL; int ret; int size = sector2cluster(s, s->sector_count); s->used_clusters = calloc(size, 1); @@ -2935,8 +2936,11 @@ static int enable_write_target(BDRVVVFATState *s) s->qcow = bdrv_new(""); ret = bdrv_open(s->qcow, s->qcow_filename, NULL, - BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, bdrv_qcow); + BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, bdrv_qcow, + &local_err); if (ret < 0) { + qerror_report_err(local_err); + error_free(local_err); bdrv_unref(s->qcow); goto err; } diff --git a/blockdev.c b/blockdev.c index 07dac05..bdbfbfb 100644 --- a/blockdev.c +++ b/blockdev.c @@ -710,17 +710,11 @@ static DriveInfo *blockdev_init(QemuOpts *all_opts, } QINCREF(bs_opts); - ret = bdrv_open(dinfo->bdrv, file, bs_opts, bdrv_flags, drv); + ret = bdrv_open(dinfo->bdrv, file, bs_opts, bdrv_flags, drv, &error); if (ret < 0) { - if (ret == -EMEDIUMTYPE) { - error_report("could not open disk image %s: not in %s format", - file ?: dinfo->id, drv ? drv->format_name : - qdict_get_str(bs_opts, "driver")); - } else { - error_report("could not open disk image %s: %s", - file ?: dinfo->id, strerror(-ret)); - } + error_report("could not open disk image %s: %s", + file ?: dinfo->id, error_get_pretty(error)); goto err; } @@ -971,9 +965,9 @@ static void external_snapshot_prepare(BlkTransactionState *common, /* TODO Inherit bs->options or only take explicit options with an * extended QMP command? */ ret = bdrv_open(state->new_bs, new_image_file, NULL, - flags | BDRV_O_NO_BACKING, drv); + flags | BDRV_O_NO_BACKING, drv, &local_err); if (ret != 0) { - error_setg_file_open(errp, -ret, new_image_file); + error_propagate(errp, local_err); } } @@ -1203,11 +1197,12 @@ static void qmp_bdrv_open_encrypted(BlockDriverState *bs, const char *filename, int bdrv_flags, BlockDriver *drv, const char *password, Error **errp) { + Error *local_err = NULL; int ret; - ret = bdrv_open(bs, filename, NULL, bdrv_flags, drv); + ret = bdrv_open(bs, filename, NULL, bdrv_flags, drv, &local_err); if (ret < 0) { - error_setg_file_open(errp, -ret, filename); + error_propagate(errp, local_err); return; } @@ -1627,10 +1622,10 @@ void qmp_drive_backup(const char *device, const char *target, } target_bs = bdrv_new(""); - ret = bdrv_open(target_bs, target, NULL, flags, drv); + ret = bdrv_open(target_bs, target, NULL, flags, drv, &local_err); if (ret < 0) { bdrv_unref(target_bs); - error_setg_file_open(errp, -ret, target); + error_propagate(errp, local_err); return; } @@ -1762,10 +1757,11 @@ void qmp_drive_mirror(const char *device, const char *target, * file. */ target_bs = bdrv_new(""); - ret = bdrv_open(target_bs, target, NULL, flags | BDRV_O_NO_BACKING, drv); + ret = bdrv_open(target_bs, target, NULL, flags | BDRV_O_NO_BACKING, drv, + &local_err); if (ret < 0) { bdrv_unref(target_bs); - error_setg_file_open(errp, -ret, target); + error_propagate(errp, local_err); return; } diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c index 668cc06..f35fc59 100644 --- a/hw/block/xen_disk.c +++ b/hw/block/xen_disk.c @@ -809,10 +809,15 @@ static int blk_connect(struct XenDevice *xendev) xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n"); blkdev->bs = bdrv_new(blkdev->dev); if (blkdev->bs) { + Error *local_err = NULL; BlockDriver *drv = bdrv_find_whitelisted_format(blkdev->fileproto, readonly); if (bdrv_open(blkdev->bs, - blkdev->filename, NULL, qflags, drv) != 0) { + blkdev->filename, NULL, qflags, drv, &local_err) != 0) + { + xen_be_printf(&blkdev->xendev, 0, "error: %s\n", + error_get_pretty(local_err)); + error_free(local_err); bdrv_unref(blkdev->bs); blkdev->bs = NULL; } diff --git a/include/block/block.h b/include/block/block.h index 1c5f939..9dbc5ef 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -151,10 +151,10 @@ void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top); int bdrv_parse_cache_flags(const char *mode, int *flags); int bdrv_parse_discard_flags(const char *mode, int *flags); int bdrv_file_open(BlockDriverState **pbs, const char *filename, - QDict *options, int flags); -int bdrv_open_backing_file(BlockDriverState *bs, QDict *options); + QDict *options, int flags, Error **errp); +int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp); int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, - int flags, BlockDriver *drv); + int flags, BlockDriver *drv, Error **errp); BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue, BlockDriverState *bs, int flags); int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp); diff --git a/qemu-img.c b/qemu-img.c index 0cf6be2..0c9d4ce 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -266,6 +266,7 @@ static BlockDriverState *bdrv_new_open(const char *filename, BlockDriverState *bs; BlockDriver *drv; char password[256]; + Error *local_err = NULL; int ret; bs = bdrv_new("image"); @@ -280,9 +281,11 @@ static BlockDriverState *bdrv_new_open(const char *filename, drv = NULL; } - ret = bdrv_open(bs, filename, NULL, flags, drv); + ret = bdrv_open(bs, filename, NULL, flags, drv, &local_err); if (ret < 0) { - error_report("Could not open '%s': %s", filename, strerror(-ret)); + error_report("Could not open '%s': %s", filename, + error_get_pretty(local_err)); + error_free(local_err); goto fail; } @@ -2124,6 +2127,7 @@ static int img_rebase(int argc, char **argv) int unsafe = 0; int progress = 0; bool quiet = false; + Error *local_err = NULL; /* Parse commandline parameters */ fmt = NULL; @@ -2227,18 +2231,21 @@ static int img_rebase(int argc, char **argv) bs_old_backing = bdrv_new("old_backing"); bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name)); ret = bdrv_open(bs_old_backing, backing_name, NULL, BDRV_O_FLAGS, - old_backing_drv); + old_backing_drv, &local_err); if (ret) { - error_report("Could not open old backing file '%s'", backing_name); + error_report("Could not open old backing file '%s': %s", + backing_name, error_get_pretty(local_err)); + error_free(local_err); goto out; } if (out_baseimg[0]) { bs_new_backing = bdrv_new("new_backing"); ret = bdrv_open(bs_new_backing, out_baseimg, NULL, BDRV_O_FLAGS, - new_backing_drv); + new_backing_drv, &local_err); if (ret) { - error_report("Could not open new backing file '%s'", - out_baseimg); + error_report("Could not open new backing file '%s': %s", + out_baseimg, error_get_pretty(local_err)); + error_free(local_err); goto out; } } diff --git a/qemu-io.c b/qemu-io.c index 71f4ff1..f4b8efc 100644 --- a/qemu-io.c +++ b/qemu-io.c @@ -46,21 +46,27 @@ static const cmdinfo_t close_cmd = { static int openfile(char *name, int flags, int growable) { + Error *local_err = NULL; + if (qemuio_bs) { fprintf(stderr, "file open already, try 'help close'\n"); return 1; } if (growable) { - if (bdrv_file_open(&qemuio_bs, name, NULL, flags)) { - fprintf(stderr, "%s: can't open device %s\n", progname, name); + if (bdrv_file_open(&qemuio_bs, name, NULL, flags, &local_err)) { + fprintf(stderr, "%s: can't open device %s: %s\n", progname, name, + error_get_pretty(local_err)); + error_free(local_err); return 1; } } else { qemuio_bs = bdrv_new("hda"); - if (bdrv_open(qemuio_bs, name, NULL, flags, NULL) < 0) { - fprintf(stderr, "%s: can't open device %s\n", progname, name); + if (bdrv_open(qemuio_bs, name, NULL, flags, NULL, &local_err) < 0) { + fprintf(stderr, "%s: can't open device %s: %s\n", progname, name, + error_get_pretty(local_err)); + error_free(local_err); bdrv_unref(qemuio_bs); qemuio_bs = NULL; return 1; diff --git a/qemu-nbd.c b/qemu-nbd.c index f044546..c26c98e 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -355,6 +355,7 @@ int main(int argc, char **argv) #endif pthread_t client_thread; const char *fmt = NULL; + Error *local_err = NULL; /* The client thread uses SIGTERM to interrupt the server. A signal * handler ensures that "qemu-nbd -v -c" exits with a nice status code. @@ -573,10 +574,11 @@ int main(int argc, char **argv) bs = bdrv_new("hda"); srcpath = argv[optind]; - ret = bdrv_open(bs, srcpath, NULL, flags, drv); + ret = bdrv_open(bs, srcpath, NULL, flags, drv, &local_err); if (ret < 0) { errno = -ret; - err(EXIT_FAILURE, "Failed to bdrv_open '%s'", argv[optind]); + err(EXIT_FAILURE, "Failed to bdrv_open '%s': %s", argv[optind], + error_get_pretty(local_err)); } fd_size = bdrv_getlength(bs);