block: Error parameter for open functions

Add an Error ** parameter to bdrv_open, bdrv_file_open and associated
functions to allow more specific error messages.

Signed-off-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
Max Reitz 2013-09-05 14:45:29 +02:00 committed by Kevin Wolf
parent d5124c00d8
commit 34b5d2c68e
17 changed files with 163 additions and 85 deletions

100
block.c
View File

@ -552,7 +552,7 @@ BlockDriver *bdrv_find_protocol(const char *filename,
} }
static int find_image_format(BlockDriverState *bs, const char *filename, static int find_image_format(BlockDriverState *bs, const char *filename,
BlockDriver **pdrv) BlockDriver **pdrv, Error **errp)
{ {
int score, score_max; int score, score_max;
BlockDriver *drv1, *drv; 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) { if (bs->sg || !bdrv_is_inserted(bs) || bdrv_getlength(bs) == 0) {
drv = bdrv_find_format("raw"); drv = bdrv_find_format("raw");
if (!drv) { if (!drv) {
error_setg(errp, "Could not find raw image format");
ret = -ENOENT; ret = -ENOENT;
} }
*pdrv = drv; *pdrv = drv;
@ -571,6 +572,8 @@ static int find_image_format(BlockDriverState *bs, const char *filename,
ret = bdrv_pread(bs, 0, buf, sizeof(buf)); ret = bdrv_pread(bs, 0, buf, sizeof(buf));
if (ret < 0) { if (ret < 0) {
error_setg_errno(errp, -ret, "Could not read image for determining its "
"format");
*pdrv = NULL; *pdrv = NULL;
return ret; return ret;
} }
@ -587,6 +590,8 @@ static int find_image_format(BlockDriverState *bs, const char *filename,
} }
} }
if (!drv) { if (!drv) {
error_setg(errp, "Could not determine image format: No compatible "
"driver found");
ret = -ENOENT; ret = -ENOENT;
} }
*pdrv = drv; *pdrv = drv;
@ -706,10 +711,11 @@ static int bdrv_open_flags(BlockDriverState *bs, int flags)
* Removes all processed options from *options. * Removes all processed options from *options.
*/ */
static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file, 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; int ret, open_flags;
const char *filename; const char *filename;
Error *local_err = NULL;
assert(drv != NULL); assert(drv != NULL);
assert(bs->file == 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); bs->read_only = !(open_flags & BDRV_O_RDWR);
if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv, bs->read_only)) { if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv, bs->read_only)) {
error_setg(errp, "Driver '%s' is not whitelisted", drv->format_name);
return -ENOTSUP; return -ENOTSUP;
} }
@ -761,25 +768,32 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
if (drv->bdrv_file_open) { if (drv->bdrv_file_open) {
assert(file == NULL); assert(file == NULL);
assert(drv->bdrv_parse_filename || filename != 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 { } else {
if (file == NULL) { if (file == NULL) {
qerror_report(ERROR_CLASS_GENERIC_ERROR, "Can't use '%s' as a " error_setg(errp, "Can't use '%s' as a block driver for the "
"block driver for the protocol level", "protocol level", drv->format_name);
drv->format_name);
ret = -EINVAL; ret = -EINVAL;
goto free_and_fail; goto free_and_fail;
} }
bs->file = file; 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 (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; goto free_and_fail;
} }
ret = refresh_total_sectors(bs, bs->total_sectors); ret = refresh_total_sectors(bs, bs->total_sectors);
if (ret < 0) { if (ret < 0) {
error_setg_errno(errp, -ret, "Could not refresh total sector count");
goto free_and_fail; goto free_and_fail;
} }
@ -808,12 +822,13 @@ free_and_fail:
* dictionary, it needs to use QINCREF() before calling bdrv_file_open. * dictionary, it needs to use QINCREF() before calling bdrv_file_open.
*/ */
int bdrv_file_open(BlockDriverState **pbs, const char *filename, int bdrv_file_open(BlockDriverState **pbs, const char *filename,
QDict *options, int flags) QDict *options, int flags, Error **errp)
{ {
BlockDriverState *bs; BlockDriverState *bs;
BlockDriver *drv; BlockDriver *drv;
const char *drvname; const char *drvname;
bool allow_protocol_prefix = false; bool allow_protocol_prefix = false;
Error *local_err = NULL;
int ret; int ret;
/* NULL means an empty set of options */ /* 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)); qdict_put(options, "filename", qstring_from_str(filename));
allow_protocol_prefix = true; allow_protocol_prefix = true;
} else { } else {
qerror_report(ERROR_CLASS_GENERIC_ERROR, "Can't specify 'file' and " error_setg(errp, "Can't specify 'file' and 'filename' options at the "
"'filename' options at the same time"); "same time");
ret = -EINVAL; ret = -EINVAL;
goto fail; goto fail;
} }
@ -842,53 +857,53 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename,
drvname = qdict_get_try_str(options, "driver"); drvname = qdict_get_try_str(options, "driver");
if (drvname) { if (drvname) {
drv = bdrv_find_whitelisted_format(drvname, !(flags & BDRV_O_RDWR)); drv = bdrv_find_whitelisted_format(drvname, !(flags & BDRV_O_RDWR));
if (!drv) {
error_setg(errp, "Unknown driver '%s'", drvname);
}
qdict_del(options, "driver"); qdict_del(options, "driver");
} else if (filename) { } else if (filename) {
drv = bdrv_find_protocol(filename, allow_protocol_prefix); drv = bdrv_find_protocol(filename, allow_protocol_prefix);
if (!drv) { if (!drv) {
qerror_report(ERROR_CLASS_GENERIC_ERROR, "Unknown protocol"); error_setg(errp, "Unknown protocol");
} }
} else { } else {
qerror_report(ERROR_CLASS_GENERIC_ERROR, error_setg(errp, "Must specify either driver or file");
"Must specify either driver or file");
drv = NULL; drv = NULL;
} }
if (!drv) { if (!drv) {
/* errp has been set already */
ret = -ENOENT; ret = -ENOENT;
goto fail; goto fail;
} }
/* Parse the filename and open it */ /* Parse the filename and open it */
if (drv->bdrv_parse_filename && filename) { if (drv->bdrv_parse_filename && filename) {
Error *local_err = NULL;
drv->bdrv_parse_filename(filename, options, &local_err); drv->bdrv_parse_filename(filename, options, &local_err);
if (error_is_set(&local_err)) { if (error_is_set(&local_err)) {
qerror_report_err(local_err); error_propagate(errp, local_err);
error_free(local_err);
ret = -EINVAL; ret = -EINVAL;
goto fail; goto fail;
} }
qdict_del(options, "filename"); qdict_del(options, "filename");
} else if (!drv->bdrv_parse_filename && !filename) { } else if (!drv->bdrv_parse_filename && !filename) {
qerror_report(ERROR_CLASS_GENERIC_ERROR, error_setg(errp, "The '%s' block driver requires a file name",
"The '%s' block driver requires a file name", drv->format_name);
drv->format_name);
ret = -EINVAL; ret = -EINVAL;
goto fail; 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) { if (ret < 0) {
error_propagate(errp, local_err);
goto fail; goto fail;
} }
/* Check if any unknown options were used */ /* Check if any unknown options were used */
if (qdict_size(options) != 0) { if (qdict_size(options) != 0) {
const QDictEntry *entry = qdict_first(options); const QDictEntry *entry = qdict_first(options);
qerror_report(ERROR_CLASS_GENERIC_ERROR, "Block protocol '%s' doesn't " error_setg(errp, "Block protocol '%s' doesn't support the option '%s'",
"support the option '%s'", drv->format_name, entry->key);
drv->format_name, entry->key);
ret = -EINVAL; ret = -EINVAL;
goto fail; goto fail;
} }
@ -915,11 +930,12 @@ fail:
* function (even on failure), so if the caller intends to reuse the dictionary, * function (even on failure), so if the caller intends to reuse the dictionary,
* it needs to use QINCREF() before calling bdrv_file_open. * 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]; char backing_filename[PATH_MAX];
int back_flags, ret; int back_flags, ret;
BlockDriver *back_drv = NULL; BlockDriver *back_drv = NULL;
Error *local_err = NULL;
if (bs->backing_hd != NULL) { if (bs->backing_hd != NULL) {
QDECREF(options); QDECREF(options);
@ -952,11 +968,12 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options)
ret = bdrv_open(bs->backing_hd, ret = bdrv_open(bs->backing_hd,
*backing_filename ? backing_filename : NULL, options, *backing_filename ? backing_filename : NULL, options,
back_flags, back_drv); back_flags, back_drv, &local_err);
if (ret < 0) { if (ret < 0) {
bdrv_unref(bs->backing_hd); bdrv_unref(bs->backing_hd);
bs->backing_hd = NULL; bs->backing_hd = NULL;
bs->open_flags |= BDRV_O_NO_BACKING; bs->open_flags |= BDRV_O_NO_BACKING;
error_propagate(errp, local_err);
return ret; return ret;
} }
return 0; 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. * dictionary, it needs to use QINCREF() before calling bdrv_open.
*/ */
int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
int flags, BlockDriver *drv) int flags, BlockDriver *drv, Error **errp)
{ {
int ret; int ret;
/* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */ /* 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; BlockDriverState *file = NULL;
QDict *file_options = NULL; QDict *file_options = NULL;
const char *drvname; const char *drvname;
Error *local_err = NULL;
/* NULL means an empty set of options */ /* NULL means an empty set of options */
if (options == NULL) { if (options == NULL) {
@ -1016,7 +1034,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
char backing_filename[PATH_MAX]; char backing_filename[PATH_MAX];
if (qdict_size(options) != 0) { 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; ret = -EINVAL;
goto fail; goto fail;
} }
@ -1027,7 +1045,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
/* if there is a backing file, use it */ /* if there is a backing file, use it */
bs1 = bdrv_new(""); bs1 = bdrv_new("");
ret = bdrv_open(bs1, filename, NULL, 0, drv); ret = bdrv_open(bs1, filename, NULL, 0, drv, &local_err);
if (ret < 0) { if (ret < 0) {
bdrv_unref(bs1); bdrv_unref(bs1);
goto fail; 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)); ret = get_tmp_filename(tmp_filename, sizeof(tmp_filename));
if (ret < 0) { if (ret < 0) {
error_setg_errno(errp, -ret, "Could not get temporary filename");
goto fail; goto fail;
} }
@ -1046,6 +1065,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
snprintf(backing_filename, sizeof(backing_filename), snprintf(backing_filename, sizeof(backing_filename),
"%s", filename); "%s", filename);
} else if (!realpath(filename, backing_filename)) { } else if (!realpath(filename, backing_filename)) {
error_setg_errno(errp, errno, "Could not resolve path '%s'", filename);
ret = -errno; ret = -errno;
goto fail; 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); ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options);
free_option_parameters(create_options); free_option_parameters(create_options);
if (ret < 0) { if (ret < 0) {
error_setg_errno(errp, -ret, "Could not create temporary overlay "
"'%s'", tmp_filename);
goto fail; goto fail;
} }
@ -1081,7 +1103,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
extract_subqdict(options, &file_options, "file."); extract_subqdict(options, &file_options, "file.");
ret = bdrv_file_open(&file, filename, file_options, 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) { if (ret < 0) {
goto fail; goto fail;
} }
@ -1094,7 +1116,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
} }
if (!drv) { if (!drv) {
ret = find_image_format(file, filename, &drv); ret = find_image_format(file, filename, &drv, &local_err);
} }
if (!drv) { if (!drv) {
@ -1102,7 +1124,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
} }
/* Open the image */ /* 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) { if (ret < 0) {
goto unlink_and_fail; goto unlink_and_fail;
} }
@ -1117,7 +1139,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
QDict *backing_options; QDict *backing_options;
extract_subqdict(options, &backing_options, "backing."); 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) { if (ret < 0) {
goto close_and_fail; 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 */ /* Check if any unknown options were used */
if (qdict_size(options) != 0) { if (qdict_size(options) != 0) {
const QDictEntry *entry = qdict_first(options); const QDictEntry *entry = qdict_first(options);
qerror_report(ERROR_CLASS_GENERIC_ERROR, "Block format '%s' used by " error_setg(errp, "Block format '%s' used by device '%s' doesn't "
"device '%s' doesn't support the option '%s'", "support the option '%s'", drv->format_name, bs->device_name,
drv->format_name, bs->device_name, entry->key); entry->key);
ret = -EINVAL; ret = -EINVAL;
goto close_and_fail; goto close_and_fail;
@ -1152,11 +1174,17 @@ fail:
QDECREF(bs->options); QDECREF(bs->options);
QDECREF(options); QDECREF(options);
bs->options = NULL; bs->options = NULL;
if (error_is_set(&local_err)) {
error_propagate(errp, local_err);
}
return ret; return ret;
close_and_fail: close_and_fail:
bdrv_close(bs); bdrv_close(bs);
QDECREF(options); QDECREF(options);
if (error_is_set(&local_err)) {
error_propagate(errp, local_err);
}
return ret; return ret;
} }
@ -4519,7 +4547,7 @@ void bdrv_img_create(const char *filename, const char *fmt,
bs = bdrv_new(""); bs = bdrv_new("");
ret = bdrv_open(bs, backing_file->value.s, NULL, back_flags, ret = bdrv_open(bs, backing_file->value.s, NULL, back_flags,
backing_drv); backing_drv, NULL);
if (ret < 0) { if (ret < 0) {
error_setg_errno(errp, -ret, "Could not open '%s'", error_setg_errno(errp, -ret, "Could not open '%s'",
backing_file->value.s); backing_file->value.s);

View File

@ -387,8 +387,10 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
goto fail; 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) { if (ret < 0) {
qerror_report_err(local_err);
error_free(local_err);
goto fail; goto fail;
} }

View File

@ -141,8 +141,10 @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags,
goto fail; 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) { if (ret < 0) {
qerror_report_err(local_err);
error_free(local_err);
goto fail; goto fail;
} }
@ -154,8 +156,10 @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags,
} }
s->test_file = bdrv_new(""); 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) { if (ret < 0) {
qerror_report_err(local_err);
error_free(local_err);
bdrv_unref(s->test_file); bdrv_unref(s->test_file);
s->test_file = NULL; s->test_file = NULL;
goto fail; goto fail;

View File

@ -302,6 +302,7 @@ static int cow_create(const char *filename, QEMUOptionParameter *options,
struct stat st; struct stat st;
int64_t image_sectors = 0; int64_t image_sectors = 0;
const char *image_filename = NULL; const char *image_filename = NULL;
Error *local_err = NULL;
int ret; int ret;
BlockDriverState *cow_bs; BlockDriverState *cow_bs;
@ -320,8 +321,10 @@ static int cow_create(const char *filename, QEMUOptionParameter *options,
return ret; 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) { if (ret < 0) {
qerror_report_err(local_err);
error_free(local_err);
return ret; return ret;
} }

View File

@ -505,14 +505,15 @@ static void mirror_iostatus_reset(BlockJob *job)
static void mirror_complete(BlockJob *job, Error **errp) static void mirror_complete(BlockJob *job, Error **errp)
{ {
MirrorBlockJob *s = container_of(job, MirrorBlockJob, common); MirrorBlockJob *s = container_of(job, MirrorBlockJob, common);
Error *local_err = NULL;
int ret; int ret;
ret = bdrv_open_backing_file(s->target, NULL); ret = bdrv_open_backing_file(s->target, NULL, &local_err);
if (ret < 0) { if (ret < 0) {
char backing_filename[PATH_MAX]; char backing_filename[PATH_MAX];
bdrv_get_full_backing_filename(s->target, backing_filename, bdrv_get_full_backing_filename(s->target, backing_filename,
sizeof(backing_filename)); sizeof(backing_filename));
error_setg_file_open(errp, -ret, backing_filename); error_propagate(errp, local_err);
return; return;
} }
if (!s->synced) { if (!s->synced) {

View File

@ -668,6 +668,7 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options,
int64_t total_size = 0; int64_t total_size = 0;
const char *backing_file = NULL; const char *backing_file = NULL;
int flags = 0; int flags = 0;
Error *local_err = NULL;
int ret; int ret;
BlockDriverState *qcow_bs; BlockDriverState *qcow_bs;
@ -688,8 +689,10 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options,
return ret; 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) { if (ret < 0) {
qerror_report_err(local_err);
error_free(local_err);
return ret; return ret;
} }

View File

@ -1370,7 +1370,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
return ret; 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) { if (ret < 0) {
return ret; return ret;
} }
@ -1423,7 +1423,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
BlockDriver* drv = bdrv_find_format("qcow2"); BlockDriver* drv = bdrv_find_format("qcow2");
assert(drv != NULL); assert(drv != NULL);
ret = bdrv_open(bs, filename, 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) { if (ret < 0) {
goto out; goto out;
} }

View File

@ -551,6 +551,7 @@ static int qed_create(const char *filename, uint32_t cluster_size,
QEDHeader le_header; QEDHeader le_header;
uint8_t *l1_table = NULL; uint8_t *l1_table = NULL;
size_t l1_size = header.cluster_size * header.table_size; size_t l1_size = header.cluster_size * header.table_size;
Error *local_err = NULL;
int ret = 0; int ret = 0;
BlockDriverState *bs = NULL; BlockDriverState *bs = NULL;
@ -559,8 +560,11 @@ static int qed_create(const char *filename, uint32_t cluster_size,
return ret; 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) { if (ret < 0) {
qerror_report_err(local_err);
error_free(local_err);
return ret; return ret;
} }

View File

@ -1401,10 +1401,13 @@ static int sd_prealloc(const char *filename)
uint32_t idx, max_idx; uint32_t idx, max_idx;
int64_t vdi_size; int64_t vdi_size;
void *buf = g_malloc0(SD_DATA_OBJ_SIZE); void *buf = g_malloc0(SD_DATA_OBJ_SIZE);
Error *local_err = NULL;
int ret; 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) { if (ret < 0) {
qerror_report_err(local_err);
error_free(local_err);
goto out; 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]; char vdi[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN];
uint32_t snapid; uint32_t snapid;
bool prealloc = false; bool prealloc = false;
Error *local_err = NULL;
s = g_malloc0(sizeof(BDRVSheepdogState)); s = g_malloc0(sizeof(BDRVSheepdogState));
@ -1502,8 +1506,10 @@ static int sd_create(const char *filename, QEMUOptionParameter *options,
goto out; 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) { if (ret < 0) {
qerror_report_err(local_err);
error_free(local_err);
goto out; goto out;
} }

View File

@ -697,6 +697,7 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
int64_t flat_offset; int64_t flat_offset;
char extent_path[PATH_MAX]; char extent_path[PATH_MAX];
BlockDriverState *extent_file; BlockDriverState *extent_file;
Error *local_err = NULL;
while (*p) { while (*p) {
/* parse extent line: /* parse extent line:
@ -726,8 +727,11 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
path_combine(extent_path, sizeof(extent_path), path_combine(extent_path, sizeof(extent_path),
desc_file_path, fname); 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) { if (ret) {
qerror_report_err(local_err);
error_free(local_err);
return ret; return ret;
} }
@ -1591,6 +1595,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
"ddb.geometry.heads = \"%d\"\n" "ddb.geometry.heads = \"%d\"\n"
"ddb.geometry.sectors = \"63\"\n" "ddb.geometry.sectors = \"63\"\n"
"ddb.adapterType = \"%s\"\n"; "ddb.adapterType = \"%s\"\n";
Error *local_err = NULL;
if (filename_decompose(filename, path, prefix, postfix, PATH_MAX)) { if (filename_decompose(filename, path, prefix, postfix, PATH_MAX)) {
return -EINVAL; return -EINVAL;
@ -1653,8 +1658,10 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
} }
if (backing_file) { if (backing_file) {
BlockDriverState *bs = bdrv_new(""); 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) { if (ret != 0) {
qerror_report_err(local_err);
error_free(local_err);
bdrv_unref(bs); bdrv_unref(bs);
return ret; return ret;
} }

View File

@ -2910,6 +2910,7 @@ static int enable_write_target(BDRVVVFATState *s)
{ {
BlockDriver *bdrv_qcow; BlockDriver *bdrv_qcow;
QEMUOptionParameter *options; QEMUOptionParameter *options;
Error *local_err = NULL;
int ret; int ret;
int size = sector2cluster(s, s->sector_count); int size = sector2cluster(s, s->sector_count);
s->used_clusters = calloc(size, 1); s->used_clusters = calloc(size, 1);
@ -2935,8 +2936,11 @@ static int enable_write_target(BDRVVVFATState *s)
s->qcow = bdrv_new(""); s->qcow = bdrv_new("");
ret = bdrv_open(s->qcow, s->qcow_filename, NULL, 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) { if (ret < 0) {
qerror_report_err(local_err);
error_free(local_err);
bdrv_unref(s->qcow); bdrv_unref(s->qcow);
goto err; goto err;
} }

View File

@ -710,17 +710,11 @@ static DriveInfo *blockdev_init(QemuOpts *all_opts,
} }
QINCREF(bs_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 < 0) {
if (ret == -EMEDIUMTYPE) { error_report("could not open disk image %s: %s",
error_report("could not open disk image %s: not in %s format", file ?: dinfo->id, error_get_pretty(error));
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));
}
goto err; goto err;
} }
@ -1156,9 +1150,9 @@ static void external_snapshot_prepare(BlkTransactionState *common,
/* TODO Inherit bs->options or only take explicit options with an /* TODO Inherit bs->options or only take explicit options with an
* extended QMP command? */ * extended QMP command? */
ret = bdrv_open(state->new_bs, new_image_file, NULL, 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) { if (ret != 0) {
error_setg_file_open(errp, -ret, new_image_file); error_propagate(errp, local_err);
} }
} }
@ -1393,11 +1387,12 @@ static void qmp_bdrv_open_encrypted(BlockDriverState *bs, const char *filename,
int bdrv_flags, BlockDriver *drv, int bdrv_flags, BlockDriver *drv,
const char *password, Error **errp) const char *password, Error **errp)
{ {
Error *local_err = NULL;
int ret; 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) { if (ret < 0) {
error_setg_file_open(errp, -ret, filename); error_propagate(errp, local_err);
return; return;
} }
@ -1817,10 +1812,10 @@ void qmp_drive_backup(const char *device, const char *target,
} }
target_bs = bdrv_new(""); 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) { if (ret < 0) {
bdrv_unref(target_bs); bdrv_unref(target_bs);
error_setg_file_open(errp, -ret, target); error_propagate(errp, local_err);
return; return;
} }
@ -1952,10 +1947,11 @@ void qmp_drive_mirror(const char *device, const char *target,
* file. * file.
*/ */
target_bs = bdrv_new(""); 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) { if (ret < 0) {
bdrv_unref(target_bs); bdrv_unref(target_bs);
error_setg_file_open(errp, -ret, target); error_propagate(errp, local_err);
return; return;
} }

View File

@ -809,10 +809,15 @@ static int blk_connect(struct XenDevice *xendev)
xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n"); xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n");
blkdev->bs = bdrv_new(blkdev->dev); blkdev->bs = bdrv_new(blkdev->dev);
if (blkdev->bs) { if (blkdev->bs) {
Error *local_err = NULL;
BlockDriver *drv = bdrv_find_whitelisted_format(blkdev->fileproto, BlockDriver *drv = bdrv_find_whitelisted_format(blkdev->fileproto,
readonly); readonly);
if (bdrv_open(blkdev->bs, 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); bdrv_unref(blkdev->bs);
blkdev->bs = NULL; blkdev->bs = NULL;
} }

View File

@ -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_cache_flags(const char *mode, int *flags);
int bdrv_parse_discard_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, int bdrv_file_open(BlockDriverState **pbs, const char *filename,
QDict *options, int flags); QDict *options, int flags, Error **errp);
int bdrv_open_backing_file(BlockDriverState *bs, QDict *options); int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp);
int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, 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, BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
BlockDriverState *bs, int flags); BlockDriverState *bs, int flags);
int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp); int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp);

View File

@ -266,6 +266,7 @@ static BlockDriverState *bdrv_new_open(const char *filename,
BlockDriverState *bs; BlockDriverState *bs;
BlockDriver *drv; BlockDriver *drv;
char password[256]; char password[256];
Error *local_err = NULL;
int ret; int ret;
bs = bdrv_new("image"); bs = bdrv_new("image");
@ -280,9 +281,11 @@ static BlockDriverState *bdrv_new_open(const char *filename,
drv = NULL; drv = NULL;
} }
ret = bdrv_open(bs, filename, NULL, flags, drv); ret = bdrv_open(bs, filename, NULL, flags, drv, &local_err);
if (ret < 0) { 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; goto fail;
} }
@ -2127,6 +2130,7 @@ static int img_rebase(int argc, char **argv)
int unsafe = 0; int unsafe = 0;
int progress = 0; int progress = 0;
bool quiet = false; bool quiet = false;
Error *local_err = NULL;
/* Parse commandline parameters */ /* Parse commandline parameters */
fmt = NULL; fmt = NULL;
@ -2230,18 +2234,21 @@ static int img_rebase(int argc, char **argv)
bs_old_backing = bdrv_new("old_backing"); bs_old_backing = bdrv_new("old_backing");
bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name)); bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
ret = bdrv_open(bs_old_backing, backing_name, NULL, BDRV_O_FLAGS, ret = bdrv_open(bs_old_backing, backing_name, NULL, BDRV_O_FLAGS,
old_backing_drv); old_backing_drv, &local_err);
if (ret) { 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; goto out;
} }
if (out_baseimg[0]) { if (out_baseimg[0]) {
bs_new_backing = bdrv_new("new_backing"); bs_new_backing = bdrv_new("new_backing");
ret = bdrv_open(bs_new_backing, out_baseimg, NULL, BDRV_O_FLAGS, ret = bdrv_open(bs_new_backing, out_baseimg, NULL, BDRV_O_FLAGS,
new_backing_drv); new_backing_drv, &local_err);
if (ret) { if (ret) {
error_report("Could not open new backing file '%s'", error_report("Could not open new backing file '%s': %s",
out_baseimg); out_baseimg, error_get_pretty(local_err));
error_free(local_err);
goto out; goto out;
} }
} }

View File

@ -46,21 +46,27 @@ static const cmdinfo_t close_cmd = {
static int openfile(char *name, int flags, int growable) static int openfile(char *name, int flags, int growable)
{ {
Error *local_err = NULL;
if (qemuio_bs) { if (qemuio_bs) {
fprintf(stderr, "file open already, try 'help close'\n"); fprintf(stderr, "file open already, try 'help close'\n");
return 1; return 1;
} }
if (growable) { if (growable) {
if (bdrv_file_open(&qemuio_bs, name, NULL, flags)) { if (bdrv_file_open(&qemuio_bs, name, NULL, flags, &local_err)) {
fprintf(stderr, "%s: can't open device %s\n", progname, name); fprintf(stderr, "%s: can't open device %s: %s\n", progname, name,
error_get_pretty(local_err));
error_free(local_err);
return 1; return 1;
} }
} else { } else {
qemuio_bs = bdrv_new("hda"); qemuio_bs = bdrv_new("hda");
if (bdrv_open(qemuio_bs, name, NULL, flags, NULL) < 0) { if (bdrv_open(qemuio_bs, name, NULL, flags, NULL, &local_err) < 0) {
fprintf(stderr, "%s: can't open device %s\n", progname, name); 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); bdrv_unref(qemuio_bs);
qemuio_bs = NULL; qemuio_bs = NULL;
return 1; return 1;

View File

@ -355,6 +355,7 @@ int main(int argc, char **argv)
#endif #endif
pthread_t client_thread; pthread_t client_thread;
const char *fmt = NULL; const char *fmt = NULL;
Error *local_err = NULL;
/* The client thread uses SIGTERM to interrupt the server. A signal /* The client thread uses SIGTERM to interrupt the server. A signal
* handler ensures that "qemu-nbd -v -c" exits with a nice status code. * 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"); bs = bdrv_new("hda");
srcpath = argv[optind]; srcpath = argv[optind];
ret = bdrv_open(bs, srcpath, NULL, flags, drv); ret = bdrv_open(bs, srcpath, NULL, flags, drv, &local_err);
if (ret < 0) { if (ret < 0) {
errno = -ret; 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); fd_size = bdrv_getlength(bs);