block: Error parameter for create functions
Add an Error ** parameter to bdrv_create and its associated functions to allow more specific error messages. Signed-off-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
parent
34b5d2c68e
commit
cc84d90ff5
80
block.c
80
block.c
@ -394,18 +394,26 @@ typedef struct CreateCo {
|
|||||||
char *filename;
|
char *filename;
|
||||||
QEMUOptionParameter *options;
|
QEMUOptionParameter *options;
|
||||||
int ret;
|
int ret;
|
||||||
|
Error *err;
|
||||||
} CreateCo;
|
} CreateCo;
|
||||||
|
|
||||||
static void coroutine_fn bdrv_create_co_entry(void *opaque)
|
static void coroutine_fn bdrv_create_co_entry(void *opaque)
|
||||||
{
|
{
|
||||||
|
Error *local_err = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
CreateCo *cco = opaque;
|
CreateCo *cco = opaque;
|
||||||
assert(cco->drv);
|
assert(cco->drv);
|
||||||
|
|
||||||
cco->ret = cco->drv->bdrv_create(cco->filename, cco->options, NULL);
|
ret = cco->drv->bdrv_create(cco->filename, cco->options, &local_err);
|
||||||
|
if (error_is_set(&local_err)) {
|
||||||
|
error_propagate(&cco->err, local_err);
|
||||||
|
}
|
||||||
|
cco->ret = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bdrv_create(BlockDriver *drv, const char* filename,
|
int bdrv_create(BlockDriver *drv, const char* filename,
|
||||||
QEMUOptionParameter *options)
|
QEMUOptionParameter *options, Error **errp)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -415,9 +423,11 @@ int bdrv_create(BlockDriver *drv, const char* filename,
|
|||||||
.filename = g_strdup(filename),
|
.filename = g_strdup(filename),
|
||||||
.options = options,
|
.options = options,
|
||||||
.ret = NOT_DONE,
|
.ret = NOT_DONE,
|
||||||
|
.err = NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!drv->bdrv_create) {
|
if (!drv->bdrv_create) {
|
||||||
|
error_setg(errp, "Driver '%s' does not support image creation", drv->format_name);
|
||||||
ret = -ENOTSUP;
|
ret = -ENOTSUP;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -434,22 +444,37 @@ int bdrv_create(BlockDriver *drv, const char* filename,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = cco.ret;
|
ret = cco.ret;
|
||||||
|
if (ret < 0) {
|
||||||
|
if (error_is_set(&cco.err)) {
|
||||||
|
error_propagate(errp, cco.err);
|
||||||
|
} else {
|
||||||
|
error_setg_errno(errp, -ret, "Could not create image");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
g_free(cco.filename);
|
g_free(cco.filename);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bdrv_create_file(const char* filename, QEMUOptionParameter *options)
|
int bdrv_create_file(const char* filename, QEMUOptionParameter *options,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
BlockDriver *drv;
|
BlockDriver *drv;
|
||||||
|
Error *local_err = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
drv = bdrv_find_protocol(filename, true);
|
drv = bdrv_find_protocol(filename, true);
|
||||||
if (drv == NULL) {
|
if (drv == NULL) {
|
||||||
|
error_setg(errp, "Could not find protocol for file '%s'", filename);
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bdrv_create(drv, filename, options);
|
ret = bdrv_create(drv, filename, options, &local_err);
|
||||||
|
if (error_is_set(&local_err)) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1082,11 +1107,14 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
|
|||||||
drv->format_name);
|
drv->format_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options);
|
ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options, &local_err);
|
||||||
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 "
|
error_setg_errno(errp, -ret, "Could not create temporary overlay "
|
||||||
"'%s'", tmp_filename);
|
"'%s': %s", tmp_filename,
|
||||||
|
error_get_pretty(local_err));
|
||||||
|
error_free(local_err);
|
||||||
|
local_err = NULL;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4461,6 +4489,7 @@ void bdrv_img_create(const char *filename, const char *fmt,
|
|||||||
BlockDriverState *bs = NULL;
|
BlockDriverState *bs = NULL;
|
||||||
BlockDriver *drv, *proto_drv;
|
BlockDriver *drv, *proto_drv;
|
||||||
BlockDriver *backing_drv = NULL;
|
BlockDriver *backing_drv = NULL;
|
||||||
|
Error *local_err = NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
/* Find driver and parse its options */
|
/* Find driver and parse its options */
|
||||||
@ -4547,10 +4576,13 @@ 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, NULL);
|
backing_drv, &local_err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_setg_errno(errp, -ret, "Could not open '%s'",
|
error_setg_errno(errp, -ret, "Could not open '%s': %s",
|
||||||
backing_file->value.s);
|
backing_file->value.s,
|
||||||
|
error_get_pretty(local_err));
|
||||||
|
error_free(local_err);
|
||||||
|
local_err = NULL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
bdrv_get_geometry(bs, &size);
|
bdrv_get_geometry(bs, &size);
|
||||||
@ -4569,22 +4601,19 @@ void bdrv_img_create(const char *filename, const char *fmt,
|
|||||||
print_option_parameters(param);
|
print_option_parameters(param);
|
||||||
puts("");
|
puts("");
|
||||||
}
|
}
|
||||||
ret = bdrv_create(drv, filename, param);
|
ret = bdrv_create(drv, filename, param, &local_err);
|
||||||
if (ret < 0) {
|
if (ret == -EFBIG) {
|
||||||
if (ret == -ENOTSUP) {
|
/* This is generally a better message than whatever the driver would
|
||||||
error_setg(errp,"Formatting or formatting option not supported for "
|
* deliver (especially because of the cluster_size_hint), since that
|
||||||
"file format '%s'", fmt);
|
* is most probably not much different from "image too large". */
|
||||||
} else if (ret == -EFBIG) {
|
const char *cluster_size_hint = "";
|
||||||
const char *cluster_size_hint = "";
|
if (get_option_parameter(create_options, BLOCK_OPT_CLUSTER_SIZE)) {
|
||||||
if (get_option_parameter(create_options, BLOCK_OPT_CLUSTER_SIZE)) {
|
cluster_size_hint = " (try using a larger cluster size)";
|
||||||
cluster_size_hint = " (try using a larger cluster size)";
|
|
||||||
}
|
|
||||||
error_setg(errp, "The image size is too large for file format '%s'%s",
|
|
||||||
fmt, cluster_size_hint);
|
|
||||||
} else {
|
|
||||||
error_setg(errp, "%s: error while creating %s: %s", filename, fmt,
|
|
||||||
strerror(-ret));
|
|
||||||
}
|
}
|
||||||
|
error_setg(errp, "The image size is too large for file format '%s'"
|
||||||
|
"%s", fmt, cluster_size_hint);
|
||||||
|
error_free(local_err);
|
||||||
|
local_err = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@ -4594,6 +4623,9 @@ out:
|
|||||||
if (bs) {
|
if (bs) {
|
||||||
bdrv_unref(bs);
|
bdrv_unref(bs);
|
||||||
}
|
}
|
||||||
|
if (error_is_set(&local_err)) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AioContext *bdrv_get_aio_context(BlockDriverState *bs)
|
AioContext *bdrv_get_aio_context(BlockDriverState *bs)
|
||||||
|
@ -316,8 +316,10 @@ static int cow_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
options++;
|
options++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = bdrv_create_file(filename, options);
|
ret = bdrv_create_file(filename, options, &local_err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
qerror_report_err(local_err);
|
||||||
|
error_free(local_err);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -684,8 +684,10 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
options++;
|
options++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = bdrv_create_file(filename, options);
|
ret = bdrv_create_file(filename, options, &local_err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
qerror_report_err(local_err);
|
||||||
|
error_free(local_err);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1365,7 +1365,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
|
|||||||
uint8_t* refcount_table;
|
uint8_t* refcount_table;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = bdrv_create_file(filename, options);
|
ret = bdrv_create_file(filename, options, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -555,8 +555,10 @@ static int qed_create(const char *filename, uint32_t cluster_size,
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
BlockDriverState *bs = NULL;
|
BlockDriverState *bs = NULL;
|
||||||
|
|
||||||
ret = bdrv_create_file(filename, NULL);
|
ret = bdrv_create_file(filename, NULL, &local_err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
qerror_report_err(local_err);
|
||||||
|
error_free(local_err);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +133,15 @@ static int raw_has_zero_init(BlockDriverState *bs)
|
|||||||
static int raw_create(const char *filename, QEMUOptionParameter *options,
|
static int raw_create(const char *filename, QEMUOptionParameter *options,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
return bdrv_create_file(filename, options);
|
Error *local_err = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = bdrv_create_file(filename, options, &local_err);
|
||||||
|
if (error_is_set(&local_err)) {
|
||||||
|
qerror_report_err(local_err);
|
||||||
|
error_free(local_err);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int raw_open(BlockDriverState *bs, QDict *options, int flags,
|
static int raw_open(BlockDriverState *bs, QDict *options, int flags,
|
||||||
|
@ -2928,8 +2928,10 @@ static int enable_write_target(BDRVVVFATState *s)
|
|||||||
set_option_parameter_int(options, BLOCK_OPT_SIZE, s->sector_count * 512);
|
set_option_parameter_int(options, BLOCK_OPT_SIZE, s->sector_count * 512);
|
||||||
set_option_parameter(options, BLOCK_OPT_BACKING_FILE, "fat:");
|
set_option_parameter(options, BLOCK_OPT_BACKING_FILE, "fat:");
|
||||||
|
|
||||||
ret = bdrv_create(bdrv_qcow, s->qcow_filename, options);
|
ret = bdrv_create(bdrv_qcow, s->qcow_filename, options, &local_err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
qerror_report_err(local_err);
|
||||||
|
error_free(local_err);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,8 +142,9 @@ BlockDriver *bdrv_find_format(const char *format_name);
|
|||||||
BlockDriver *bdrv_find_whitelisted_format(const char *format_name,
|
BlockDriver *bdrv_find_whitelisted_format(const char *format_name,
|
||||||
bool readonly);
|
bool readonly);
|
||||||
int bdrv_create(BlockDriver *drv, const char* filename,
|
int bdrv_create(BlockDriver *drv, const char* filename,
|
||||||
QEMUOptionParameter *options);
|
QEMUOptionParameter *options, Error **errp);
|
||||||
int bdrv_create_file(const char* filename, QEMUOptionParameter *options);
|
int bdrv_create_file(const char* filename, QEMUOptionParameter *options,
|
||||||
|
Error **errp);
|
||||||
BlockDriverState *bdrv_new(const char *device_name);
|
BlockDriverState *bdrv_new(const char *device_name);
|
||||||
void bdrv_make_anon(BlockDriverState *bs);
|
void bdrv_make_anon(BlockDriverState *bs);
|
||||||
void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old);
|
void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old);
|
||||||
|
16
qemu-img.c
16
qemu-img.c
@ -1139,6 +1139,7 @@ static int img_convert(int argc, char **argv)
|
|||||||
float local_progress = 0;
|
float local_progress = 0;
|
||||||
int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */
|
int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */
|
||||||
bool quiet = false;
|
bool quiet = false;
|
||||||
|
Error *local_err = NULL;
|
||||||
|
|
||||||
fmt = NULL;
|
fmt = NULL;
|
||||||
out_fmt = "raw";
|
out_fmt = "raw";
|
||||||
@ -1341,18 +1342,11 @@ static int img_convert(int argc, char **argv)
|
|||||||
|
|
||||||
if (!skip_create) {
|
if (!skip_create) {
|
||||||
/* Create the new image */
|
/* Create the new image */
|
||||||
ret = bdrv_create(drv, out_filename, param);
|
ret = bdrv_create(drv, out_filename, param, &local_err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (ret == -ENOTSUP) {
|
error_report("%s: error while converting %s: %s",
|
||||||
error_report("Formatting not supported for file format '%s'",
|
out_filename, out_fmt, error_get_pretty(local_err));
|
||||||
out_fmt);
|
error_free(local_err);
|
||||||
} else if (ret == -EFBIG) {
|
|
||||||
error_report("The image size is too large for file format '%s'",
|
|
||||||
out_fmt);
|
|
||||||
} else {
|
|
||||||
error_report("%s: error while converting %s: %s",
|
|
||||||
out_filename, out_fmt, strerror(-ret));
|
|
||||||
}
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user