diff --git a/MAINTAINERS b/MAINTAINERS index c66946ff07dca063d61f707e8a10e486b35c9159..b287ef893918730cedc0081eceef201d3aa909da 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -674,6 +674,8 @@ S: Supported F: block* F: block/ F: hw/block/ +F: qemu-img* +F: qemu-io* T: git git://repo.or.cz/qemu/kevin.git block T: git git://github.com/stefanha/qemu.git block diff --git a/block.c b/block.c index fc2edd33ae945ec61b4d5a96c65e23bd21067c48..4745712d22e571f0a59f4e7acf94938d2a418f21 100644 --- a/block.c +++ b/block.c @@ -864,7 +864,7 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file, node_name = qdict_get_try_str(options, "node-name"); bdrv_assign_node_name(bs, node_name, &local_err); - if (error_is_set(&local_err)) { + if (local_err) { error_propagate(errp, local_err); return -EINVAL; } @@ -1068,14 +1068,14 @@ fail: */ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp) { - char backing_filename[PATH_MAX]; - int back_flags, ret; + char *backing_filename = g_malloc0(PATH_MAX); + int back_flags, ret = 0; BlockDriver *back_drv = NULL; Error *local_err = NULL; if (bs->backing_hd != NULL) { QDECREF(options); - return 0; + goto free_exit; } /* NULL means an empty set of options */ @@ -1088,10 +1088,9 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp) backing_filename[0] = '\0'; } else if (bs->backing_file[0] == '\0' && qdict_size(options) == 0) { QDECREF(options); - return 0; + goto free_exit; } else { - bdrv_get_full_backing_filename(bs, backing_filename, - sizeof(backing_filename)); + bdrv_get_full_backing_filename(bs, backing_filename, PATH_MAX); } if (bs->backing_format[0] != '\0') { @@ -1112,7 +1111,7 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp) error_setg(errp, "Could not open backing file: %s", error_get_pretty(local_err)); error_free(local_err); - return ret; + goto free_exit; } if (bs->backing_hd->file) { @@ -1123,7 +1122,9 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp) /* Recalculate the BlockLimits with the backing file */ bdrv_refresh_limits(bs); - return 0; +free_exit: + g_free(backing_filename); + return ret; } /* @@ -1180,8 +1181,7 @@ done: void bdrv_append_temp_snapshot(BlockDriverState *bs, Error **errp) { /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */ - char tmp_filename[PATH_MAX + 1]; - + char *tmp_filename = g_malloc0(PATH_MAX + 1); int64_t total_size; BlockDriver *bdrv_qcow2; QEMUOptionParameter *create_options; @@ -1197,15 +1197,15 @@ void bdrv_append_temp_snapshot(BlockDriverState *bs, Error **errp) total_size = bdrv_getlength(bs); if (total_size < 0) { error_setg_errno(errp, -total_size, "Could not get image size"); - return; + goto out; } total_size &= BDRV_SECTOR_MASK; /* Create the temporary image */ - ret = get_tmp_filename(tmp_filename, sizeof(tmp_filename)); + ret = get_tmp_filename(tmp_filename, PATH_MAX + 1); if (ret < 0) { error_setg_errno(errp, -ret, "Could not get temporary filename"); - return; + goto out; } bdrv_qcow2 = bdrv_find_format("qcow2"); @@ -1221,7 +1221,7 @@ void bdrv_append_temp_snapshot(BlockDriverState *bs, Error **errp) "'%s': %s", tmp_filename, error_get_pretty(local_err)); error_free(local_err); - return; + goto out; } /* Prepare a new options QDict for the temporary file */ @@ -1238,10 +1238,13 @@ void bdrv_append_temp_snapshot(BlockDriverState *bs, Error **errp) bs->open_flags & ~BDRV_O_SNAPSHOT, bdrv_qcow2, &local_err); if (ret < 0) { error_propagate(errp, local_err); - return; + goto out; } bdrv_append(bs_snapshot, bs); + +out: + g_free(tmp_filename); } /* diff --git a/block/iscsi.c b/block/iscsi.c index a636ea4f53f4ddc6d60d1c85160dfb69cca1f6e8..a30202b4fef54829164fdb29ab6fc93e6b3c4489 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -1095,16 +1095,15 @@ static struct scsi_task *iscsi_do_inquiry(struct iscsi_context *iscsi, int lun, *inq = scsi_datain_unmarshall(task); if (*inq == NULL) { error_setg(errp, "iSCSI: failed to unmarshall inquiry datain blob"); - goto fail; + goto fail_with_err; } return task; fail: - if (!error_is_set(errp)) { - error_setg(errp, "iSCSI: Inquiry command failed : %s", - iscsi_get_error(iscsi)); - } + error_setg(errp, "iSCSI: Inquiry command failed : %s", + iscsi_get_error(iscsi)); +fail_with_err: if (task != NULL) { scsi_free_scsi_task(task); } diff --git a/block/mirror.c b/block/mirror.c index 2618c3763ce31f28b74a1c0a35b6d85221225f72..36f4f8e8bd86479f4db0ee93a5511d43f346daec 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -680,7 +680,7 @@ void commit_active_start(BlockDriverState *bs, BlockDriverState *base, mirror_start_job(bs, base, speed, 0, 0, on_error, on_error, cb, opaque, &local_err, &commit_active_job_driver, false, base); - if (error_is_set(&local_err)) { + if (local_err) { error_propagate(errp, local_err); goto error_restore_flags; } diff --git a/block/nbd.c b/block/nbd.c index 55124239df5286b8398b0555f70fe26158e287bb..613f2581aec6c3acf4bf53c8e25d16e4144a6225 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -175,7 +175,7 @@ static void nbd_parse_filename(const char *filename, QDict *options, InetSocketAddress *addr = NULL; addr = inet_parse(host_spec, errp); - if (error_is_set(errp)) { + if (!addr) { goto out; } diff --git a/block/nfs.c b/block/nfs.c index 98aa363e48d15fe49a3a8b8648ba4fd22fd75589..9fa831f1600f39bf34e4247bca78cbac257e4c57 100644 --- a/block/nfs.c +++ b/block/nfs.c @@ -343,7 +343,7 @@ static int nfs_file_open(BlockDriverState *bs, QDict *options, int flags, opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort); qemu_opts_absorb_qdict(opts, options, &local_err); - if (error_is_set(&local_err)) { + if (local_err) { error_propagate(errp, local_err); return -EINVAL; } diff --git a/block/quorum.c b/block/quorum.c index 7f580a83b5f1f06fedf14646c6a5718532275d62..ecec3a54071c08eac8bb1d8e20240cc97cdb3759 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -753,7 +753,7 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags, opts = qemu_opts_create(&quorum_runtime_opts, NULL, 0, &error_abort); qemu_opts_absorb_qdict(opts, options, &local_err); - if (error_is_set(&local_err)) { + if (local_err) { ret = -EINVAL; goto exit; } @@ -828,7 +828,7 @@ close_exit: g_free(opened); exit: /* propagate error */ - if (error_is_set(&local_err)) { + if (local_err) { error_propagate(errp, local_err); } QDECREF(list); diff --git a/blockdev.c b/blockdev.c index 09826f10cf357f5a8193cc488a5711eabed7416d..952eb60e3d3ce124d10111a7a16fd75540b6fbf7 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1115,6 +1115,7 @@ typedef struct InternalSnapshotState { static void internal_snapshot_prepare(BlkTransactionState *common, Error **errp) { + Error *local_err = NULL; const char *device; const char *name; BlockDriverState *bs; @@ -1163,8 +1164,10 @@ static void internal_snapshot_prepare(BlkTransactionState *common, } /* check whether a snapshot with name exist */ - ret = bdrv_snapshot_find_by_id_and_name(bs, NULL, name, &old_sn, errp); - if (error_is_set(errp)) { + ret = bdrv_snapshot_find_by_id_and_name(bs, NULL, name, &old_sn, + &local_err); + if (local_err) { + error_propagate(errp, local_err); return; } else if (ret) { error_setg(errp, diff --git a/docs/writing-qmp-commands.txt b/docs/writing-qmp-commands.txt index 8349dec8af20f5d14119da8d8710a9ae7cc0468b..3930a9ba70d9a5010e6f73a019a9e9b4caa16f5f 100644 --- a/docs/writing-qmp-commands.txt +++ b/docs/writing-qmp-commands.txt @@ -311,7 +311,7 @@ void hmp_hello_world(Monitor *mon, const QDict *qdict) Error *errp = NULL; qmp_hello_world(!!message, message, &errp); - if (error_is_set(&errp)) { + if (errp) { monitor_printf(mon, "%s\n", error_get_pretty(errp)); error_free(errp); return; @@ -483,7 +483,7 @@ void hmp_info_alarm_clock(Monitor *mon) Error *errp = NULL; clock = qmp_query_alarm_clock(&errp); - if (error_is_set(&errp)) { + if (errp) { monitor_printf(mon, "Could not query alarm clock information\n"); error_free(errp); return; @@ -634,7 +634,7 @@ void hmp_info_alarm_methods(Monitor *mon) Error *errp = NULL; method_list = qmp_query_alarm_methods(&errp); - if (error_is_set(&errp)) { + if (errp) { monitor_printf(mon, "Could not query alarm methods\n"); error_free(errp); return; diff --git a/qapi-schema.json b/qapi-schema.json index 391356fe2934014d3ff5ee888db9663a44b5f724..0b00427c8cdece936977932c92677c568d70c89f 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -4285,10 +4285,13 @@ # # Drivers that are supported in block device operations. # +# @host_device, @host_cdrom, @host_floppy: Since 2.1 +# # Since: 2.0 ## { 'enum': 'BlockdevDriver', - 'data': [ 'file', 'http', 'https', 'ftp', 'ftps', 'tftp', 'vvfat', 'blkdebug', + 'data': [ 'file', 'host_device', 'host_cdrom', 'host_floppy', + 'http', 'https', 'ftp', 'ftps', 'tftp', 'vvfat', 'blkdebug', 'blkverify', 'bochs', 'cloop', 'cow', 'dmg', 'parallels', 'qcow', 'qcow2', 'qed', 'raw', 'vdi', 'vhdx', 'vmdk', 'vpc', 'quorum' ] } @@ -4555,6 +4558,9 @@ 'discriminator': 'driver', 'data': { 'file': 'BlockdevOptionsFile', + 'host_device':'BlockdevOptionsFile', + 'host_cdrom': 'BlockdevOptionsFile', + 'host_floppy':'BlockdevOptionsFile', 'http': 'BlockdevOptionsFile', 'https': 'BlockdevOptionsFile', 'ftp': 'BlockdevOptionsFile', diff --git a/qemu-img.c b/qemu-img.c index 4dae84a1824e7bb0ffa3af8d779e021285c2645c..968b4c8e83c5bed9894b8893da12c26a2dbb689d 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -457,12 +457,12 @@ fail: static void dump_json_image_check(ImageCheck *check, bool quiet) { - Error *errp = NULL; + Error *local_err = NULL; QString *str; QmpOutputVisitor *ov = qmp_output_visitor_new(); QObject *obj; visit_type_ImageCheck(qmp_output_get_visitor(ov), - &check, NULL, &errp); + &check, NULL, &local_err); obj = qmp_output_get_qobject(ov); str = qobject_to_json_pretty(obj); assert(str != NULL); @@ -1731,12 +1731,12 @@ static void dump_snapshots(BlockDriverState *bs) static void dump_json_image_info_list(ImageInfoList *list) { - Error *errp = NULL; + Error *local_err = NULL; QString *str; QmpOutputVisitor *ov = qmp_output_visitor_new(); QObject *obj; visit_type_ImageInfoList(qmp_output_get_visitor(ov), - &list, NULL, &errp); + &list, NULL, &local_err); obj = qmp_output_get_qobject(ov); str = qobject_to_json_pretty(obj); assert(str != NULL); @@ -1748,12 +1748,12 @@ static void dump_json_image_info_list(ImageInfoList *list) static void dump_json_image_info(ImageInfo *info) { - Error *errp = NULL; + Error *local_err = NULL; QString *str; QmpOutputVisitor *ov = qmp_output_visitor_new(); QObject *obj; visit_type_ImageInfo(qmp_output_get_visitor(ov), - &info, NULL, &errp); + &info, NULL, &local_err); obj = qmp_output_get_qobject(ov); str = qobject_to_json_pretty(obj); assert(str != NULL); diff --git a/qemu-options.hx b/qemu-options.hx index 6457034b8c25aee253f2446c64735f3088b2241e..98b4002fc714a648c579ee6607c7345eb1c697a4 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -408,7 +408,8 @@ DEF("drive", HAS_ARG, QEMU_OPTION_drive, "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n" " [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off]\n" " [,cache=writethrough|writeback|none|directsync|unsafe][,format=f]\n" - " [,serial=s][,addr=A][,id=name][,aio=threads|native]\n" + " [,serial=s][,addr=A][,rerror=ignore|stop|report]\n" + " [,werror=ignore|stop|report|enospc][,id=name][,aio=threads|native]\n" " [,readonly=on|off][,copy-on-read=on|off]\n" " [[,bps=b]|[[,bps_rd=r][,bps_wr=w]]]\n" " [[,iops=i]|[[,iops_rd=r][,iops_wr=w]]]\n" diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030 index 59a34f76f59ff1e5fbc9815c350f3f238a2addcc..8cb61fd7ec9ea304a07b6d563ce59296c9959514 100755 --- a/tests/qemu-iotests/030 +++ b/tests/qemu-iotests/030 @@ -50,15 +50,7 @@ class TestSingleDrive(iotests.QMPTestCase): result = self.vm.qmp('block-stream', device='drive0') self.assert_qmp(result, 'return', {}) - completed = False - while not completed: - for event in self.vm.get_qmp_events(wait=True): - if event['event'] == 'BLOCK_JOB_COMPLETED': - self.assert_qmp(event, 'data/type', 'stream') - self.assert_qmp(event, 'data/device', 'drive0') - self.assert_qmp(event, 'data/offset', self.image_len) - self.assert_qmp(event, 'data/len', self.image_len) - completed = True + self.wait_until_completed() self.assert_no_active_block_jobs() self.vm.shutdown() @@ -89,15 +81,7 @@ class TestSingleDrive(iotests.QMPTestCase): self.assert_qmp(result, 'return', {}) self.vm.resume_drive('drive0') - completed = False - while not completed: - for event in self.vm.get_qmp_events(wait=True): - if event['event'] == 'BLOCK_JOB_COMPLETED': - self.assert_qmp(event, 'data/type', 'stream') - self.assert_qmp(event, 'data/device', 'drive0') - self.assert_qmp(event, 'data/offset', self.image_len) - self.assert_qmp(event, 'data/len', self.image_len) - completed = True + self.wait_until_completed() self.assert_no_active_block_jobs() self.vm.shutdown() @@ -112,15 +96,7 @@ class TestSingleDrive(iotests.QMPTestCase): result = self.vm.qmp('block-stream', device='drive0', base=mid_img) self.assert_qmp(result, 'return', {}) - completed = False - while not completed: - for event in self.vm.get_qmp_events(wait=True): - if event['event'] == 'BLOCK_JOB_COMPLETED': - self.assert_qmp(event, 'data/type', 'stream') - self.assert_qmp(event, 'data/device', 'drive0') - self.assert_qmp(event, 'data/offset', self.image_len) - self.assert_qmp(event, 'data/len', self.image_len) - completed = True + self.wait_until_completed() self.assert_no_active_block_jobs() self.vm.shutdown() @@ -152,15 +128,7 @@ class TestSmallerBackingFile(iotests.QMPTestCase): result = self.vm.qmp('block-stream', device='drive0') self.assert_qmp(result, 'return', {}) - completed = False - while not completed: - for event in self.vm.get_qmp_events(wait=True): - if event['event'] == 'BLOCK_JOB_COMPLETED': - self.assert_qmp(event, 'data/type', 'stream') - self.assert_qmp(event, 'data/device', 'drive0') - self.assert_qmp(event, 'data/offset', self.image_len) - self.assert_qmp(event, 'data/len', self.image_len) - completed = True + self.wait_until_completed() self.assert_no_active_block_jobs() self.vm.shutdown() @@ -442,15 +410,7 @@ class TestSetSpeed(iotests.QMPTestCase): result = self.vm.qmp('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024) self.assert_qmp(result, 'return', {}) - completed = False - while not completed: - for event in self.vm.get_qmp_events(wait=True): - if event['event'] == 'BLOCK_JOB_COMPLETED': - self.assert_qmp(event, 'data/type', 'stream') - self.assert_qmp(event, 'data/device', 'drive0') - self.assert_qmp(event, 'data/offset', self.image_len) - self.assert_qmp(event, 'data/len', self.image_len) - completed = True + self.wait_until_completed() self.assert_no_active_block_jobs() diff --git a/tests/qemu-iotests/056 b/tests/qemu-iotests/056 index 63893423cfbe0a2b508d1a0332913265888ad396..54e4bd06925a0ada910f761d0e45bf8aa2b556b2 100755 --- a/tests/qemu-iotests/056 +++ b/tests/qemu-iotests/056 @@ -57,14 +57,7 @@ class TestSyncModesNoneAndTop(iotests.QMPTestCase): format=iotests.imgfmt, target=target_img) self.assert_qmp(result, 'return', {}) - # Custom completed check as we are not copying all data. - completed = False - while not completed: - for event in self.vm.get_qmp_events(wait=True): - if event['event'] == 'BLOCK_JOB_COMPLETED': - self.assert_qmp(event, 'data/device', 'drive0') - self.assert_qmp_absent(event, 'data/error') - completed = True + self.wait_until_completed(check_offset=False) self.assert_no_active_block_jobs() self.vm.shutdown() diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index e4fa9af714609837d0c4b0b559064d76104bf65b..f6c437c0c35d1af7d90680e592cad5b14c639352 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -257,7 +257,7 @@ def cancel_and_wait(self, drive='drive0', force=False, resume=False): self.assert_no_active_block_jobs() return result - def wait_until_completed(self, drive='drive0'): + def wait_until_completed(self, drive='drive0', check_offset=True): '''Wait for a block job to finish, returning the event''' completed = False while not completed: @@ -265,7 +265,8 @@ def wait_until_completed(self, drive='drive0'): if event['event'] == 'BLOCK_JOB_COMPLETED': self.assert_qmp(event, 'data/device', drive) self.assert_qmp_absent(event, 'data/error') - self.assert_qmp(event, 'data/offset', self.image_len) + if check_offset: + self.assert_qmp(event, 'data/offset', self.image_len) self.assert_qmp(event, 'data/len', self.image_len) completed = True diff --git a/tests/test-qmp-input-strict.c b/tests/test-qmp-input-strict.c index 38b5e95f687814a4372eccbe20fbe7faed4f2919..f03353b75572fff204d702881a2bade4df9baa10 100644 --- a/tests/test-qmp-input-strict.c +++ b/tests/test-qmp-input-strict.c @@ -153,7 +153,7 @@ static void test_validate_union_flat(TestInputVisitorData *data, /* TODO when generator bug is fixed, add 'integer': 41 */ visit_type_UserDefFlatUnion(v, &tmp, NULL, &errp); - g_assert(!error_is_set(&errp)); + g_assert(!errp); qapi_free_UserDefFlatUnion(tmp); } @@ -167,7 +167,7 @@ static void test_validate_union_anon(TestInputVisitorData *data, v = validate_test_init(data, "42"); visit_type_UserDefAnonUnion(v, &tmp, NULL, &errp); - g_assert(!error_is_set(&errp)); + g_assert(!errp); qapi_free_UserDefAnonUnion(tmp); } @@ -240,7 +240,7 @@ static void test_validate_fail_union_flat(TestInputVisitorData *data, v = validate_test_init(data, "{ 'string': 'c', 'integer': 41, 'boolean': true }"); visit_type_UserDefFlatUnion(v, &tmp, NULL, &errp); - g_assert(error_is_set(&errp)); + g_assert(errp); qapi_free_UserDefFlatUnion(tmp); } @@ -254,7 +254,7 @@ static void test_validate_fail_union_anon(TestInputVisitorData *data, v = validate_test_init(data, "3.14"); visit_type_UserDefAnonUnion(v, &tmp, NULL, &errp); - g_assert(error_is_set(&errp)); + g_assert(errp); qapi_free_UserDefAnonUnion(tmp); }