Revision 34b5d2c6 block.c
b/block.c | ||
---|---|---|
552 | 552 |
} |
553 | 553 |
|
554 | 554 |
static int find_image_format(BlockDriverState *bs, const char *filename, |
555 |
BlockDriver **pdrv) |
|
555 |
BlockDriver **pdrv, Error **errp)
|
|
556 | 556 |
{ |
557 | 557 |
int score, score_max; |
558 | 558 |
BlockDriver *drv1, *drv; |
... | ... | |
563 | 563 |
if (bs->sg || !bdrv_is_inserted(bs) || bdrv_getlength(bs) == 0) { |
564 | 564 |
drv = bdrv_find_format("raw"); |
565 | 565 |
if (!drv) { |
566 |
error_setg(errp, "Could not find raw image format"); |
|
566 | 567 |
ret = -ENOENT; |
567 | 568 |
} |
568 | 569 |
*pdrv = drv; |
... | ... | |
571 | 572 |
|
572 | 573 |
ret = bdrv_pread(bs, 0, buf, sizeof(buf)); |
573 | 574 |
if (ret < 0) { |
575 |
error_setg_errno(errp, -ret, "Could not read image for determining its " |
|
576 |
"format"); |
|
574 | 577 |
*pdrv = NULL; |
575 | 578 |
return ret; |
576 | 579 |
} |
... | ... | |
587 | 590 |
} |
588 | 591 |
} |
589 | 592 |
if (!drv) { |
593 |
error_setg(errp, "Could not determine image format: No compatible " |
|
594 |
"driver found"); |
|
590 | 595 |
ret = -ENOENT; |
591 | 596 |
} |
592 | 597 |
*pdrv = drv; |
... | ... | |
706 | 711 |
* Removes all processed options from *options. |
707 | 712 |
*/ |
708 | 713 |
static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file, |
709 |
QDict *options, int flags, BlockDriver *drv) |
|
714 |
QDict *options, int flags, BlockDriver *drv, Error **errp)
|
|
710 | 715 |
{ |
711 | 716 |
int ret, open_flags; |
712 | 717 |
const char *filename; |
718 |
Error *local_err = NULL; |
|
713 | 719 |
|
714 | 720 |
assert(drv != NULL); |
715 | 721 |
assert(bs->file == NULL); |
... | ... | |
738 | 744 |
bs->read_only = !(open_flags & BDRV_O_RDWR); |
739 | 745 |
|
740 | 746 |
if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv, bs->read_only)) { |
747 |
error_setg(errp, "Driver '%s' is not whitelisted", drv->format_name); |
|
741 | 748 |
return -ENOTSUP; |
742 | 749 |
} |
743 | 750 |
|
... | ... | |
761 | 768 |
if (drv->bdrv_file_open) { |
762 | 769 |
assert(file == NULL); |
763 | 770 |
assert(drv->bdrv_parse_filename || filename != NULL); |
764 |
ret = drv->bdrv_file_open(bs, options, open_flags, NULL);
|
|
771 |
ret = drv->bdrv_file_open(bs, options, open_flags, &local_err);
|
|
765 | 772 |
} else { |
766 | 773 |
if (file == NULL) { |
767 |
qerror_report(ERROR_CLASS_GENERIC_ERROR, "Can't use '%s' as a " |
|
768 |
"block driver for the protocol level", |
|
769 |
drv->format_name); |
|
774 |
error_setg(errp, "Can't use '%s' as a block driver for the " |
|
775 |
"protocol level", drv->format_name); |
|
770 | 776 |
ret = -EINVAL; |
771 | 777 |
goto free_and_fail; |
772 | 778 |
} |
773 | 779 |
bs->file = file; |
774 |
ret = drv->bdrv_open(bs, options, open_flags, NULL);
|
|
780 |
ret = drv->bdrv_open(bs, options, open_flags, &local_err);
|
|
775 | 781 |
} |
776 | 782 |
|
777 | 783 |
if (ret < 0) { |
784 |
if (error_is_set(&local_err)) { |
|
785 |
error_propagate(errp, local_err); |
|
786 |
} else if (filename) { |
|
787 |
error_setg_errno(errp, -ret, "Could not open '%s'", filename); |
|
788 |
} else { |
|
789 |
error_setg_errno(errp, -ret, "Could not open image"); |
|
790 |
} |
|
778 | 791 |
goto free_and_fail; |
779 | 792 |
} |
780 | 793 |
|
781 | 794 |
ret = refresh_total_sectors(bs, bs->total_sectors); |
782 | 795 |
if (ret < 0) { |
796 |
error_setg_errno(errp, -ret, "Could not refresh total sector count"); |
|
783 | 797 |
goto free_and_fail; |
784 | 798 |
} |
785 | 799 |
|
... | ... | |
808 | 822 |
* dictionary, it needs to use QINCREF() before calling bdrv_file_open. |
809 | 823 |
*/ |
810 | 824 |
int bdrv_file_open(BlockDriverState **pbs, const char *filename, |
811 |
QDict *options, int flags) |
|
825 |
QDict *options, int flags, Error **errp)
|
|
812 | 826 |
{ |
813 | 827 |
BlockDriverState *bs; |
814 | 828 |
BlockDriver *drv; |
815 | 829 |
const char *drvname; |
816 | 830 |
bool allow_protocol_prefix = false; |
831 |
Error *local_err = NULL; |
|
817 | 832 |
int ret; |
818 | 833 |
|
819 | 834 |
/* NULL means an empty set of options */ |
... | ... | |
832 | 847 |
qdict_put(options, "filename", qstring_from_str(filename)); |
833 | 848 |
allow_protocol_prefix = true; |
834 | 849 |
} else { |
835 |
qerror_report(ERROR_CLASS_GENERIC_ERROR, "Can't specify 'file' and "
|
|
836 |
"'filename' options at the same time");
|
|
850 |
error_setg(errp, "Can't specify 'file' and 'filename' options at the "
|
|
851 |
"same time");
|
|
837 | 852 |
ret = -EINVAL; |
838 | 853 |
goto fail; |
839 | 854 |
} |
... | ... | |
842 | 857 |
drvname = qdict_get_try_str(options, "driver"); |
843 | 858 |
if (drvname) { |
844 | 859 |
drv = bdrv_find_whitelisted_format(drvname, !(flags & BDRV_O_RDWR)); |
860 |
if (!drv) { |
|
861 |
error_setg(errp, "Unknown driver '%s'", drvname); |
|
862 |
} |
|
845 | 863 |
qdict_del(options, "driver"); |
846 | 864 |
} else if (filename) { |
847 | 865 |
drv = bdrv_find_protocol(filename, allow_protocol_prefix); |
848 | 866 |
if (!drv) { |
849 |
qerror_report(ERROR_CLASS_GENERIC_ERROR, "Unknown protocol");
|
|
867 |
error_setg(errp, "Unknown protocol");
|
|
850 | 868 |
} |
851 | 869 |
} else { |
852 |
qerror_report(ERROR_CLASS_GENERIC_ERROR, |
|
853 |
"Must specify either driver or file"); |
|
870 |
error_setg(errp, "Must specify either driver or file"); |
|
854 | 871 |
drv = NULL; |
855 | 872 |
} |
856 | 873 |
|
857 | 874 |
if (!drv) { |
875 |
/* errp has been set already */ |
|
858 | 876 |
ret = -ENOENT; |
859 | 877 |
goto fail; |
860 | 878 |
} |
861 | 879 |
|
862 | 880 |
/* Parse the filename and open it */ |
863 | 881 |
if (drv->bdrv_parse_filename && filename) { |
864 |
Error *local_err = NULL; |
|
865 | 882 |
drv->bdrv_parse_filename(filename, options, &local_err); |
866 | 883 |
if (error_is_set(&local_err)) { |
867 |
qerror_report_err(local_err); |
|
868 |
error_free(local_err); |
|
884 |
error_propagate(errp, local_err); |
|
869 | 885 |
ret = -EINVAL; |
870 | 886 |
goto fail; |
871 | 887 |
} |
872 | 888 |
qdict_del(options, "filename"); |
873 | 889 |
} else if (!drv->bdrv_parse_filename && !filename) { |
874 |
qerror_report(ERROR_CLASS_GENERIC_ERROR, |
|
875 |
"The '%s' block driver requires a file name", |
|
876 |
drv->format_name); |
|
890 |
error_setg(errp, "The '%s' block driver requires a file name", |
|
891 |
drv->format_name); |
|
877 | 892 |
ret = -EINVAL; |
878 | 893 |
goto fail; |
879 | 894 |
} |
880 | 895 |
|
881 |
ret = bdrv_open_common(bs, NULL, options, flags, drv); |
|
896 |
ret = bdrv_open_common(bs, NULL, options, flags, drv, &local_err);
|
|
882 | 897 |
if (ret < 0) { |
898 |
error_propagate(errp, local_err); |
|
883 | 899 |
goto fail; |
884 | 900 |
} |
885 | 901 |
|
886 | 902 |
/* Check if any unknown options were used */ |
887 | 903 |
if (qdict_size(options) != 0) { |
888 | 904 |
const QDictEntry *entry = qdict_first(options); |
889 |
qerror_report(ERROR_CLASS_GENERIC_ERROR, "Block protocol '%s' doesn't " |
|
890 |
"support the option '%s'", |
|
891 |
drv->format_name, entry->key); |
|
905 |
error_setg(errp, "Block protocol '%s' doesn't support the option '%s'", |
|
906 |
drv->format_name, entry->key); |
|
892 | 907 |
ret = -EINVAL; |
893 | 908 |
goto fail; |
894 | 909 |
} |
... | ... | |
915 | 930 |
* function (even on failure), so if the caller intends to reuse the dictionary, |
916 | 931 |
* it needs to use QINCREF() before calling bdrv_file_open. |
917 | 932 |
*/ |
918 |
int bdrv_open_backing_file(BlockDriverState *bs, QDict *options) |
|
933 |
int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
|
|
919 | 934 |
{ |
920 | 935 |
char backing_filename[PATH_MAX]; |
921 | 936 |
int back_flags, ret; |
922 | 937 |
BlockDriver *back_drv = NULL; |
938 |
Error *local_err = NULL; |
|
923 | 939 |
|
924 | 940 |
if (bs->backing_hd != NULL) { |
925 | 941 |
QDECREF(options); |
... | ... | |
952 | 968 |
|
953 | 969 |
ret = bdrv_open(bs->backing_hd, |
954 | 970 |
*backing_filename ? backing_filename : NULL, options, |
955 |
back_flags, back_drv); |
|
971 |
back_flags, back_drv, &local_err);
|
|
956 | 972 |
if (ret < 0) { |
957 | 973 |
bdrv_unref(bs->backing_hd); |
958 | 974 |
bs->backing_hd = NULL; |
959 | 975 |
bs->open_flags |= BDRV_O_NO_BACKING; |
976 |
error_propagate(errp, local_err); |
|
960 | 977 |
return ret; |
961 | 978 |
} |
962 | 979 |
return 0; |
... | ... | |
990 | 1007 |
* dictionary, it needs to use QINCREF() before calling bdrv_open. |
991 | 1008 |
*/ |
992 | 1009 |
int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, |
993 |
int flags, BlockDriver *drv) |
|
1010 |
int flags, BlockDriver *drv, Error **errp)
|
|
994 | 1011 |
{ |
995 | 1012 |
int ret; |
996 | 1013 |
/* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */ |
... | ... | |
998 | 1015 |
BlockDriverState *file = NULL; |
999 | 1016 |
QDict *file_options = NULL; |
1000 | 1017 |
const char *drvname; |
1018 |
Error *local_err = NULL; |
|
1001 | 1019 |
|
1002 | 1020 |
/* NULL means an empty set of options */ |
1003 | 1021 |
if (options == NULL) { |
... | ... | |
1016 | 1034 |
char backing_filename[PATH_MAX]; |
1017 | 1035 |
|
1018 | 1036 |
if (qdict_size(options) != 0) { |
1019 |
error_report("Can't use snapshot=on with driver-specific options");
|
|
1037 |
error_setg(errp, "Can't use snapshot=on with driver-specific options");
|
|
1020 | 1038 |
ret = -EINVAL; |
1021 | 1039 |
goto fail; |
1022 | 1040 |
} |
... | ... | |
1027 | 1045 |
|
1028 | 1046 |
/* if there is a backing file, use it */ |
1029 | 1047 |
bs1 = bdrv_new(""); |
1030 |
ret = bdrv_open(bs1, filename, NULL, 0, drv); |
|
1048 |
ret = bdrv_open(bs1, filename, NULL, 0, drv, &local_err);
|
|
1031 | 1049 |
if (ret < 0) { |
1032 | 1050 |
bdrv_unref(bs1); |
1033 | 1051 |
goto fail; |
... | ... | |
1038 | 1056 |
|
1039 | 1057 |
ret = get_tmp_filename(tmp_filename, sizeof(tmp_filename)); |
1040 | 1058 |
if (ret < 0) { |
1059 |
error_setg_errno(errp, -ret, "Could not get temporary filename"); |
|
1041 | 1060 |
goto fail; |
1042 | 1061 |
} |
1043 | 1062 |
|
... | ... | |
1046 | 1065 |
snprintf(backing_filename, sizeof(backing_filename), |
1047 | 1066 |
"%s", filename); |
1048 | 1067 |
} else if (!realpath(filename, backing_filename)) { |
1068 |
error_setg_errno(errp, errno, "Could not resolve path '%s'", filename); |
|
1049 | 1069 |
ret = -errno; |
1050 | 1070 |
goto fail; |
1051 | 1071 |
} |
... | ... | |
1065 | 1085 |
ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options); |
1066 | 1086 |
free_option_parameters(create_options); |
1067 | 1087 |
if (ret < 0) { |
1088 |
error_setg_errno(errp, -ret, "Could not create temporary overlay " |
|
1089 |
"'%s'", tmp_filename); |
|
1068 | 1090 |
goto fail; |
1069 | 1091 |
} |
1070 | 1092 |
|
... | ... | |
1081 | 1103 |
extract_subqdict(options, &file_options, "file."); |
1082 | 1104 |
|
1083 | 1105 |
ret = bdrv_file_open(&file, filename, file_options, |
1084 |
bdrv_open_flags(bs, flags | BDRV_O_UNMAP)); |
|
1106 |
bdrv_open_flags(bs, flags | BDRV_O_UNMAP), &local_err);
|
|
1085 | 1107 |
if (ret < 0) { |
1086 | 1108 |
goto fail; |
1087 | 1109 |
} |
... | ... | |
1094 | 1116 |
} |
1095 | 1117 |
|
1096 | 1118 |
if (!drv) { |
1097 |
ret = find_image_format(file, filename, &drv); |
|
1119 |
ret = find_image_format(file, filename, &drv, &local_err);
|
|
1098 | 1120 |
} |
1099 | 1121 |
|
1100 | 1122 |
if (!drv) { |
... | ... | |
1102 | 1124 |
} |
1103 | 1125 |
|
1104 | 1126 |
/* Open the image */ |
1105 |
ret = bdrv_open_common(bs, file, options, flags, drv); |
|
1127 |
ret = bdrv_open_common(bs, file, options, flags, drv, &local_err);
|
|
1106 | 1128 |
if (ret < 0) { |
1107 | 1129 |
goto unlink_and_fail; |
1108 | 1130 |
} |
... | ... | |
1117 | 1139 |
QDict *backing_options; |
1118 | 1140 |
|
1119 | 1141 |
extract_subqdict(options, &backing_options, "backing."); |
1120 |
ret = bdrv_open_backing_file(bs, backing_options); |
|
1142 |
ret = bdrv_open_backing_file(bs, backing_options, &local_err);
|
|
1121 | 1143 |
if (ret < 0) { |
1122 | 1144 |
goto close_and_fail; |
1123 | 1145 |
} |
... | ... | |
1126 | 1148 |
/* Check if any unknown options were used */ |
1127 | 1149 |
if (qdict_size(options) != 0) { |
1128 | 1150 |
const QDictEntry *entry = qdict_first(options); |
1129 |
qerror_report(ERROR_CLASS_GENERIC_ERROR, "Block format '%s' used by "
|
|
1130 |
"device '%s' doesn't support the option '%s'",
|
|
1131 |
drv->format_name, bs->device_name, entry->key);
|
|
1151 |
error_setg(errp, "Block format '%s' used by device '%s' doesn't "
|
|
1152 |
"support the option '%s'", drv->format_name, bs->device_name,
|
|
1153 |
entry->key);
|
|
1132 | 1154 |
|
1133 | 1155 |
ret = -EINVAL; |
1134 | 1156 |
goto close_and_fail; |
... | ... | |
1152 | 1174 |
QDECREF(bs->options); |
1153 | 1175 |
QDECREF(options); |
1154 | 1176 |
bs->options = NULL; |
1177 |
if (error_is_set(&local_err)) { |
|
1178 |
error_propagate(errp, local_err); |
|
1179 |
} |
|
1155 | 1180 |
return ret; |
1156 | 1181 |
|
1157 | 1182 |
close_and_fail: |
1158 | 1183 |
bdrv_close(bs); |
1159 | 1184 |
QDECREF(options); |
1185 |
if (error_is_set(&local_err)) { |
|
1186 |
error_propagate(errp, local_err); |
|
1187 |
} |
|
1160 | 1188 |
return ret; |
1161 | 1189 |
} |
1162 | 1190 |
|
... | ... | |
4519 | 4547 |
bs = bdrv_new(""); |
4520 | 4548 |
|
4521 | 4549 |
ret = bdrv_open(bs, backing_file->value.s, NULL, back_flags, |
4522 |
backing_drv); |
|
4550 |
backing_drv, NULL);
|
|
4523 | 4551 |
if (ret < 0) { |
4524 | 4552 |
error_setg_errno(errp, -ret, "Could not open '%s'", |
4525 | 4553 |
backing_file->value.s); |
Also available in: Unified diff