aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-04-28 11:50:30 +0100
committerPeter Maydell <peter.maydell@linaro.org>2014-04-28 11:50:31 +0100
commita41b2c995b52b2ce26c171c52ac7dc11c7dccd99 (patch)
tree63d44a2ccd30e219c4b10edc2b7fbb5f226a8756
parentd09a18d44d5bc0db10caa97cdd22c70e65adfe01 (diff)
parent172fc4dd33e604dcf868c28e73398c19e161708b (diff)
downloadqemu-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--MAINTAINERS2
-rw-r--r--block.c35
-rw-r--r--block/iscsi.c9
-rw-r--r--block/mirror.c2
-rw-r--r--block/nbd.c2
-rw-r--r--block/nfs.c2
-rw-r--r--block/quorum.c4
-rw-r--r--blockdev.c7
-rw-r--r--docs/writing-qmp-commands.txt6
-rw-r--r--qapi-schema.json8
-rw-r--r--qemu-img.c12
-rw-r--r--qemu-options.hx3
-rwxr-xr-xtests/qemu-iotests/03050
-rwxr-xr-xtests/qemu-iotests/0569
-rw-r--r--tests/qemu-iotests/iotests.py5
-rw-r--r--tests/test-qmp-input-strict.c8
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
diff --git a/block.c b/block.c
index fc2edd3..4745712 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 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);
diff --git a/blockdev.c b/blockdev.c
index 09826f1..952eb60 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 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',
diff --git a/qemu-img.c b/qemu-img.c
index 4dae84a..968b4c8 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 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);
}