diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2014-04-28 11:50:30 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2014-04-28 11:50:31 +0100 |
commit | a41b2c995b52b2ce26c171c52ac7dc11c7dccd99 (patch) | |
tree | 63d44a2ccd30e219c4b10edc2b7fbb5f226a8756 | |
parent | d09a18d44d5bc0db10caa97cdd22c70e65adfe01 (diff) | |
parent | 172fc4dd33e604dcf868c28e73398c19e161708b (diff) | |
download | qemu-a41b2c995b52b2ce26c171c52ac7dc11c7dccd99.zip qemu-a41b2c995b52b2ce26c171c52ac7dc11c7dccd99.tar.gz qemu-a41b2c995b52b2ce26c171c52ac7dc11c7dccd99.tar.bz2 |
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
Block pull request
# gpg: Signature made Fri 25 Apr 2014 17:05:13 BST using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>"
* remotes/stefanha/tags/block-pull-request:
iscsi: Don't use error_is_set() to suppress additional errors
blockdev: Clean up fragile use of error_is_set()
nbd: Use return values instead of error_is_set(errp)
qemu-img: Consistently name Error * objects err, and not errp
Use error_is_set() only when necessary (again)
block: Expose host_* drivers in blockdev-add
MAINTAINERS: Add qemu-img/io to block subsystem
qemu-iotests: Improve and make use of QMPTestCase.wait_until_completed()
doc: add -drive rerror=,werror= to qemu --help output
block: Prevent coroutine stack overflow when recursing in bdrv_open_backing_file.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | MAINTAINERS | 2 | ||||
-rw-r--r-- | block.c | 35 | ||||
-rw-r--r-- | block/iscsi.c | 9 | ||||
-rw-r--r-- | block/mirror.c | 2 | ||||
-rw-r--r-- | block/nbd.c | 2 | ||||
-rw-r--r-- | block/nfs.c | 2 | ||||
-rw-r--r-- | block/quorum.c | 4 | ||||
-rw-r--r-- | blockdev.c | 7 | ||||
-rw-r--r-- | docs/writing-qmp-commands.txt | 6 | ||||
-rw-r--r-- | qapi-schema.json | 8 | ||||
-rw-r--r-- | qemu-img.c | 12 | ||||
-rw-r--r-- | qemu-options.hx | 3 | ||||
-rwxr-xr-x | tests/qemu-iotests/030 | 50 | ||||
-rwxr-xr-x | tests/qemu-iotests/056 | 9 | ||||
-rw-r--r-- | tests/qemu-iotests/iotests.py | 5 | ||||
-rw-r--r-- | tests/test-qmp-input-strict.c | 8 |
16 files changed, 66 insertions, 98 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index c66946f..b287ef8 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 @@ -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 a636ea4..a30202b 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 2618c37..36f4f8e 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 5512423..613f258 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 98aa363..9fa831f 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 7f580a8..ecec3a5 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); @@ -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 8349dec..3930a9b 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 391356f..0b00427 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', @@ -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 6457034..98b4002 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 59a34f7..8cb61fd 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 6389342..54e4bd0 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 e4fa9af..f6c437c 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -257,7 +257,7 @@ class QMPTestCase(unittest.TestCase): 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 @@ class QMPTestCase(unittest.TestCase): 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 38b5e95..f03353b 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); } |