diff --git a/block.c b/block.c index d36eb75be96a..d4939b49bf05 100644 --- a/block.c +++ b/block.c @@ -1526,6 +1526,13 @@ static int bdrv_open_inherit(BlockDriverState **pbs, const char *filename, if (!bs) { return -ENODEV; } + + if (bs->throttle_state) { + error_setg(errp, "Cannot reference an existing block device for " + "which I/O throttling is enabled"); + return -EINVAL; + } + bdrv_ref(bs); *pbs = bs; return 0; diff --git a/block/crypto.c b/block/crypto.c index be3498581c55..1903e84fbd85 100644 --- a/block/crypto.c +++ b/block/crypto.c @@ -196,6 +196,7 @@ block_crypto_open_opts_init(QCryptoBlockFormat format, OptsVisitor *ov; QCryptoBlockOpenOptions *ret = NULL; Error *local_err = NULL; + Error *end_err = NULL; ret = g_new0(QCryptoBlockOpenOptions, 1); ret->format = format; @@ -218,10 +219,9 @@ block_crypto_open_opts_init(QCryptoBlockFormat format, error_setg(&local_err, "Unsupported block format %d", format); break; } - error_propagate(errp, local_err); - local_err = NULL; - visit_end_struct(opts_get_visitor(ov), &local_err); + visit_end_struct(opts_get_visitor(ov), &end_err); + error_propagate(&local_err, end_err); out: if (local_err) { @@ -242,6 +242,7 @@ block_crypto_create_opts_init(QCryptoBlockFormat format, OptsVisitor *ov; QCryptoBlockCreateOptions *ret = NULL; Error *local_err = NULL; + Error *end_err = NULL; ret = g_new0(QCryptoBlockCreateOptions, 1); ret->format = format; @@ -264,10 +265,9 @@ block_crypto_create_opts_init(QCryptoBlockFormat format, error_setg(&local_err, "Unsupported block format %d", format); break; } - error_propagate(errp, local_err); - local_err = NULL; - visit_end_struct(opts_get_visitor(ov), &local_err); + visit_end_struct(opts_get_visitor(ov), &end_err); + error_propagate(&local_err, end_err); out: if (local_err) { diff --git a/blockdev.c b/blockdev.c index e50e8eabd094..f1f520a2653b 100644 --- a/blockdev.c +++ b/blockdev.c @@ -2661,6 +2661,13 @@ void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd, goto out; } + /* The BlockBackend must be the only parent */ + assert(QLIST_FIRST(&bs->parents)); + if (QLIST_NEXT(QLIST_FIRST(&bs->parents), next_parent)) { + error_setg(errp, "Cannot throttle device with multiple parents"); + goto out; + } + throttle_config_init(&cfg); cfg.buckets[THROTTLE_BPS_TOTAL].avg = bps; cfg.buckets[THROTTLE_BPS_READ].avg = bps_rd; @@ -4027,6 +4034,11 @@ void qmp_x_blockdev_del(bool has_id, const char *id, error_setg(errp, "Cannot find block backend %s", id); return; } + if (blk_legacy_dinfo(blk)) { + error_setg(errp, "Deleting block backend added with drive-add" + " is not supported"); + return; + } if (blk_get_refcnt(blk) > 1) { error_setg(errp, "Block backend %s is in use", id); return; diff --git a/tests/qemu-iotests/149 b/tests/qemu-iotests/149 index bb5811d93b44..52e23d2946e2 100755 --- a/tests/qemu-iotests/149 +++ b/tests/qemu-iotests/149 @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Copyright (C) 2016 Red Hat, Inc. #