Revision cc84d90f block.c
b/block.c | ||
---|---|---|
394 | 394 |
char *filename; |
395 | 395 |
QEMUOptionParameter *options; |
396 | 396 |
int ret; |
397 |
Error *err; |
|
397 | 398 |
} CreateCo; |
398 | 399 |
|
399 | 400 |
static void coroutine_fn bdrv_create_co_entry(void *opaque) |
400 | 401 |
{ |
402 |
Error *local_err = NULL; |
|
403 |
int ret; |
|
404 |
|
|
401 | 405 |
CreateCo *cco = opaque; |
402 | 406 |
assert(cco->drv); |
403 | 407 |
|
404 |
cco->ret = cco->drv->bdrv_create(cco->filename, cco->options, NULL); |
|
408 |
ret = cco->drv->bdrv_create(cco->filename, cco->options, &local_err); |
|
409 |
if (error_is_set(&local_err)) { |
|
410 |
error_propagate(&cco->err, local_err); |
|
411 |
} |
|
412 |
cco->ret = ret; |
|
405 | 413 |
} |
406 | 414 |
|
407 | 415 |
int bdrv_create(BlockDriver *drv, const char* filename, |
408 |
QEMUOptionParameter *options) |
|
416 |
QEMUOptionParameter *options, Error **errp)
|
|
409 | 417 |
{ |
410 | 418 |
int ret; |
411 | 419 |
|
... | ... | |
415 | 423 |
.filename = g_strdup(filename), |
416 | 424 |
.options = options, |
417 | 425 |
.ret = NOT_DONE, |
426 |
.err = NULL, |
|
418 | 427 |
}; |
419 | 428 |
|
420 | 429 |
if (!drv->bdrv_create) { |
430 |
error_setg(errp, "Driver '%s' does not support image creation", drv->format_name); |
|
421 | 431 |
ret = -ENOTSUP; |
422 | 432 |
goto out; |
423 | 433 |
} |
... | ... | |
434 | 444 |
} |
435 | 445 |
|
436 | 446 |
ret = cco.ret; |
447 |
if (ret < 0) { |
|
448 |
if (error_is_set(&cco.err)) { |
|
449 |
error_propagate(errp, cco.err); |
|
450 |
} else { |
|
451 |
error_setg_errno(errp, -ret, "Could not create image"); |
|
452 |
} |
|
453 |
} |
|
437 | 454 |
|
438 | 455 |
out: |
439 | 456 |
g_free(cco.filename); |
440 | 457 |
return ret; |
441 | 458 |
} |
442 | 459 |
|
443 |
int bdrv_create_file(const char* filename, QEMUOptionParameter *options) |
|
460 |
int bdrv_create_file(const char* filename, QEMUOptionParameter *options, |
|
461 |
Error **errp) |
|
444 | 462 |
{ |
445 | 463 |
BlockDriver *drv; |
464 |
Error *local_err = NULL; |
|
465 |
int ret; |
|
446 | 466 |
|
447 | 467 |
drv = bdrv_find_protocol(filename, true); |
448 | 468 |
if (drv == NULL) { |
469 |
error_setg(errp, "Could not find protocol for file '%s'", filename); |
|
449 | 470 |
return -ENOENT; |
450 | 471 |
} |
451 | 472 |
|
452 |
return bdrv_create(drv, filename, options); |
|
473 |
ret = bdrv_create(drv, filename, options, &local_err); |
|
474 |
if (error_is_set(&local_err)) { |
|
475 |
error_propagate(errp, local_err); |
|
476 |
} |
|
477 |
return ret; |
|
453 | 478 |
} |
454 | 479 |
|
455 | 480 |
/* |
... | ... | |
1082 | 1107 |
drv->format_name); |
1083 | 1108 |
} |
1084 | 1109 |
|
1085 |
ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options); |
|
1110 |
ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options, &local_err);
|
|
1086 | 1111 |
free_option_parameters(create_options); |
1087 | 1112 |
if (ret < 0) { |
1088 | 1113 |
error_setg_errno(errp, -ret, "Could not create temporary overlay " |
1089 |
"'%s'", tmp_filename); |
|
1114 |
"'%s': %s", tmp_filename, |
|
1115 |
error_get_pretty(local_err)); |
|
1116 |
error_free(local_err); |
|
1117 |
local_err = NULL; |
|
1090 | 1118 |
goto fail; |
1091 | 1119 |
} |
1092 | 1120 |
|
... | ... | |
4461 | 4489 |
BlockDriverState *bs = NULL; |
4462 | 4490 |
BlockDriver *drv, *proto_drv; |
4463 | 4491 |
BlockDriver *backing_drv = NULL; |
4492 |
Error *local_err = NULL; |
|
4464 | 4493 |
int ret = 0; |
4465 | 4494 |
|
4466 | 4495 |
/* Find driver and parse its options */ |
... | ... | |
4547 | 4576 |
bs = bdrv_new(""); |
4548 | 4577 |
|
4549 | 4578 |
ret = bdrv_open(bs, backing_file->value.s, NULL, back_flags, |
4550 |
backing_drv, NULL);
|
|
4579 |
backing_drv, &local_err);
|
|
4551 | 4580 |
if (ret < 0) { |
4552 |
error_setg_errno(errp, -ret, "Could not open '%s'", |
|
4553 |
backing_file->value.s); |
|
4581 |
error_setg_errno(errp, -ret, "Could not open '%s': %s", |
|
4582 |
backing_file->value.s, |
|
4583 |
error_get_pretty(local_err)); |
|
4584 |
error_free(local_err); |
|
4585 |
local_err = NULL; |
|
4554 | 4586 |
goto out; |
4555 | 4587 |
} |
4556 | 4588 |
bdrv_get_geometry(bs, &size); |
... | ... | |
4569 | 4601 |
print_option_parameters(param); |
4570 | 4602 |
puts(""); |
4571 | 4603 |
} |
4572 |
ret = bdrv_create(drv, filename, param); |
|
4573 |
if (ret < 0) { |
|
4574 |
if (ret == -ENOTSUP) { |
|
4575 |
error_setg(errp,"Formatting or formatting option not supported for " |
|
4576 |
"file format '%s'", fmt); |
|
4577 |
} else if (ret == -EFBIG) { |
|
4578 |
const char *cluster_size_hint = ""; |
|
4579 |
if (get_option_parameter(create_options, BLOCK_OPT_CLUSTER_SIZE)) { |
|
4580 |
cluster_size_hint = " (try using a larger cluster size)"; |
|
4581 |
} |
|
4582 |
error_setg(errp, "The image size is too large for file format '%s'%s", |
|
4583 |
fmt, cluster_size_hint); |
|
4584 |
} else { |
|
4585 |
error_setg(errp, "%s: error while creating %s: %s", filename, fmt, |
|
4586 |
strerror(-ret)); |
|
4604 |
ret = bdrv_create(drv, filename, param, &local_err); |
|
4605 |
if (ret == -EFBIG) { |
|
4606 |
/* This is generally a better message than whatever the driver would |
|
4607 |
* deliver (especially because of the cluster_size_hint), since that |
|
4608 |
* is most probably not much different from "image too large". */ |
|
4609 |
const char *cluster_size_hint = ""; |
|
4610 |
if (get_option_parameter(create_options, BLOCK_OPT_CLUSTER_SIZE)) { |
|
4611 |
cluster_size_hint = " (try using a larger cluster size)"; |
|
4587 | 4612 |
} |
4613 |
error_setg(errp, "The image size is too large for file format '%s'" |
|
4614 |
"%s", fmt, cluster_size_hint); |
|
4615 |
error_free(local_err); |
|
4616 |
local_err = NULL; |
|
4588 | 4617 |
} |
4589 | 4618 |
|
4590 | 4619 |
out: |
... | ... | |
4594 | 4623 |
if (bs) { |
4595 | 4624 |
bdrv_unref(bs); |
4596 | 4625 |
} |
4626 |
if (error_is_set(&local_err)) { |
|
4627 |
error_propagate(errp, local_err); |
|
4628 |
} |
|
4597 | 4629 |
} |
4598 | 4630 |
|
4599 | 4631 |
AioContext *bdrv_get_aio_context(BlockDriverState *bs) |
Also available in: Unified diff