aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block.c22
-rw-r--r--block/crypto.c13
-rw-r--r--block/qcow2.c8
-rw-r--r--blockjob.c8
-rw-r--r--hw/block/xen-block.c1
-rw-r--r--hw/ide/ahci.c12
-rw-r--r--include/block/block.h1
-rw-r--r--monitor/monitor.c25
-rw-r--r--monitor/qmp.c5
-rw-r--r--storage-daemon/qemu-storage-daemon.c2
-rwxr-xr-xtests/qemu-iotests/2592
-rw-r--r--tests/qemu-iotests/common.rc4
12 files changed, 69 insertions, 34 deletions
diff --git a/block.c b/block.c
index c682c3e3b9..a1f3cecd75 100644
--- a/block.c
+++ b/block.c
@@ -706,6 +706,28 @@ int coroutine_fn bdrv_co_delete_file(BlockDriverState *bs, Error **errp)
return ret;
}
+void coroutine_fn bdrv_co_delete_file_noerr(BlockDriverState *bs)
+{
+ Error *local_err = NULL;
+ int ret;
+
+ if (!bs) {
+ return;
+ }
+
+ ret = bdrv_co_delete_file(bs, &local_err);
+ /*
+ * ENOTSUP will happen if the block driver doesn't support
+ * the 'bdrv_co_delete_file' interface. This is a predictable
+ * scenario and shouldn't be reported back to the user.
+ */
+ if (ret == -ENOTSUP) {
+ error_free(local_err);
+ } else if (ret < 0) {
+ error_report_err(local_err);
+ }
+}
+
/**
* Try to get @bs's logical and physical block size.
* On success, store them in @bsz struct and return 0.
diff --git a/block/crypto.c b/block/crypto.c
index aef5a5721a..1d30fde38e 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -725,17 +725,8 @@ fail:
* If an error occurred, delete 'filename'. Even if the file existed
* beforehand, it has been truncated and corrupted in the process.
*/
- if (ret && bs) {
- Error *local_delete_err = NULL;
- int r_del = bdrv_co_delete_file(bs, &local_delete_err);
- /*
- * ENOTSUP will happen if the block driver doesn't support
- * the 'bdrv_co_delete_file' interface. This is a predictable
- * scenario and shouldn't be reported back to the user.
- */
- if ((r_del < 0) && (r_del != -ENOTSUP)) {
- error_report_err(local_delete_err);
- }
+ if (ret) {
+ bdrv_co_delete_file_noerr(bs);
}
bdrv_unref(bs);
diff --git a/block/qcow2.c b/block/qcow2.c
index 5d94f45be9..d9f49a52e7 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -3846,12 +3846,14 @@ static int coroutine_fn qcow2_co_create_opts(BlockDriver *drv,
/* Create the qcow2 image (format layer) */
ret = qcow2_co_create(create_options, errp);
+finish:
if (ret < 0) {
- goto finish;
+ bdrv_co_delete_file_noerr(bs);
+ bdrv_co_delete_file_noerr(data_bs);
+ } else {
+ ret = 0;
}
- ret = 0;
-finish:
qobject_unref(qdict);
bdrv_unref(bs);
bdrv_unref(data_bs);
diff --git a/blockjob.c b/blockjob.c
index db3a21699c..f2feff051d 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -212,15 +212,19 @@ int block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs,
uint64_t perm, uint64_t shared_perm, Error **errp)
{
BdrvChild *c;
+ bool need_context_ops;
bdrv_ref(bs);
- if (job->job.aio_context != qemu_get_aio_context()) {
+
+ need_context_ops = bdrv_get_aio_context(bs) != job->job.aio_context;
+
+ if (need_context_ops && job->job.aio_context != qemu_get_aio_context()) {
aio_context_release(job->job.aio_context);
}
c = bdrv_root_attach_child(bs, name, &child_job, 0,
job->job.aio_context, perm, shared_perm, job,
errp);
- if (job->job.aio_context != qemu_get_aio_context()) {
+ if (need_context_ops && job->job.aio_context != qemu_get_aio_context()) {
aio_context_acquire(job->job.aio_context);
}
if (c == NULL) {
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
index 0e7d66c2a7..a3b69e2709 100644
--- a/hw/block/xen-block.c
+++ b/hw/block/xen-block.c
@@ -253,6 +253,7 @@ static void xen_block_realize(XenDevice *xendev, Error **errp)
xen_device_backend_printf(xendev, "feature-discard", "%u", 1);
xen_device_backend_printf(xendev, "discard-granularity", "%u",
conf->discard_granularity);
+ xen_device_backend_printf(xendev, "discard-alignment", "%u", 0);
}
xen_device_backend_printf(xendev, "feature-flush-cache", "%u", 1);
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 6d50482b8d..f2c5157483 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -700,7 +700,7 @@ static void ahci_reset_port(AHCIState *s, int port)
}
/* Buffer pretty output based on a raw FIS structure. */
-static char *ahci_pretty_buffer_fis(uint8_t *fis, int cmd_len)
+static char *ahci_pretty_buffer_fis(const uint8_t *fis, int cmd_len)
{
int i;
GString *s = g_string_new("FIS:");
@@ -1100,11 +1100,11 @@ static void execute_ncq_command(NCQTransferState *ncq_tfs)
}
-static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
+static void process_ncq_command(AHCIState *s, int port, const uint8_t *cmd_fis,
uint8_t slot)
{
AHCIDevice *ad = &s->dev[port];
- NCQFrame *ncq_fis = (NCQFrame*)cmd_fis;
+ const NCQFrame *ncq_fis = (NCQFrame *)cmd_fis;
uint8_t tag = ncq_fis->tag >> 3;
NCQTransferState *ncq_tfs = &ad->ncq_tfs[tag];
size_t size;
@@ -1185,7 +1185,7 @@ static AHCICmdHdr *get_cmd_header(AHCIState *s, uint8_t port, uint8_t slot)
}
static void handle_reg_h2d_fis(AHCIState *s, int port,
- uint8_t slot, uint8_t *cmd_fis)
+ uint8_t slot, const uint8_t *cmd_fis)
{
IDEState *ide_state = &s->dev[port].port.ifs[0];
AHCICmdHdr *cmd = get_cmd_header(s, port, slot);
@@ -1301,7 +1301,7 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
tbl_addr = le64_to_cpu(cmd->tbl_addr);
cmd_len = 0x80;
cmd_fis = dma_memory_map(s->as, tbl_addr, &cmd_len,
- DMA_DIRECTION_FROM_DEVICE);
+ DMA_DIRECTION_TO_DEVICE);
if (!cmd_fis) {
trace_handle_cmd_badfis(s, port);
return -1;
@@ -1326,7 +1326,7 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
}
out:
- dma_memory_unmap(s->as, cmd_fis, cmd_len, DMA_DIRECTION_FROM_DEVICE,
+ dma_memory_unmap(s->as, cmd_fis, cmd_len, DMA_DIRECTION_TO_DEVICE,
cmd_len);
if (s->dev[port].port.ifs[0].status & (BUSY_STAT|DRQ_STAT)) {
diff --git a/include/block/block.h b/include/block/block.h
index a9b7f03f11..b3f6e509d4 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -441,6 +441,7 @@ int bdrv_freeze_backing_chain(BlockDriverState *bs, BlockDriverState *base,
Error **errp);
void bdrv_unfreeze_backing_chain(BlockDriverState *bs, BlockDriverState *base);
int coroutine_fn bdrv_co_delete_file(BlockDriverState *bs, Error **errp);
+void coroutine_fn bdrv_co_delete_file_noerr(BlockDriverState *bs);
typedef struct BdrvCheckResult {
diff --git a/monitor/monitor.c b/monitor/monitor.c
index 1e4a6b3f20..e94f532cf5 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -619,16 +619,6 @@ void monitor_data_destroy(Monitor *mon)
void monitor_cleanup(void)
{
/*
- * We need to explicitly stop the I/O thread (but not destroy it),
- * clean up the monitor resources, then destroy the I/O thread since
- * we need to unregister from chardev below in
- * monitor_data_destroy(), and chardev is not thread-safe yet
- */
- if (mon_iothread) {
- iothread_stop(mon_iothread);
- }
-
- /*
* The dispatcher needs to stop before destroying the monitor and
* the I/O thread.
*
@@ -637,6 +627,11 @@ void monitor_cleanup(void)
* eventually terminates. qemu_aio_context is automatically
* polled by calling AIO_WAIT_WHILE on it, but we must poll
* iohandler_ctx manually.
+ *
+ * Letting the iothread continue while shutting down the dispatcher
+ * means that new requests may still be coming in. This is okay,
+ * we'll just leave them in the queue without sending a response
+ * and monitor_data_destroy() will free them.
*/
qmp_dispatcher_co_shutdown = true;
if (!qatomic_xchg(&qmp_dispatcher_co_busy, true)) {
@@ -647,6 +642,16 @@ void monitor_cleanup(void)
(aio_poll(iohandler_get_aio_context(), false),
qatomic_mb_read(&qmp_dispatcher_co_busy)));
+ /*
+ * We need to explicitly stop the I/O thread (but not destroy it),
+ * clean up the monitor resources, then destroy the I/O thread since
+ * we need to unregister from chardev below in
+ * monitor_data_destroy(), and chardev is not thread-safe yet
+ */
+ if (mon_iothread) {
+ iothread_stop(mon_iothread);
+ }
+
/* Flush output buffers and destroy monitors */
qemu_mutex_lock(&monitor_lock);
monitor_destroyed = true;
diff --git a/monitor/qmp.c b/monitor/qmp.c
index 43880fa623..2326bd7f9b 100644
--- a/monitor/qmp.c
+++ b/monitor/qmp.c
@@ -227,6 +227,11 @@ void coroutine_fn monitor_qmp_dispatcher_co(void *data)
*/
qatomic_mb_set(&qmp_dispatcher_co_busy, false);
+ /* On shutdown, don't take any more requests from the queue */
+ if (qmp_dispatcher_co_shutdown) {
+ return;
+ }
+
while (!(req_obj = monitor_qmp_requests_pop_any_with_lock())) {
/*
* No more requests to process. Wait to be reentered from
diff --git a/storage-daemon/qemu-storage-daemon.c b/storage-daemon/qemu-storage-daemon.c
index d8d172cc60..9021a46b3a 100644
--- a/storage-daemon/qemu-storage-daemon.c
+++ b/storage-daemon/qemu-storage-daemon.c
@@ -144,6 +144,8 @@ static void init_qmp_commands(void)
qmp_init_marshal(&qmp_commands);
qmp_register_command(&qmp_commands, "query-qmp-schema",
qmp_query_qmp_schema, QCO_ALLOW_PRECONFIG);
+ qmp_register_command(&qmp_commands, "object-add", qmp_object_add,
+ QCO_NO_OPTIONS);
QTAILQ_INIT(&qmp_cap_negotiation_commands);
qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities",
diff --git a/tests/qemu-iotests/259 b/tests/qemu-iotests/259
index 76cde429c4..1b15e8fb48 100755
--- a/tests/qemu-iotests/259
+++ b/tests/qemu-iotests/259
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
-# group: rw auto quick
+# group: rw quick
#
# Test generic image creation fallback (by using NBD)
#
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index 77c37e8312..65cdba5723 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -885,7 +885,9 @@ _unsupported_imgopts()
{
for bad_opt
do
- if echo "$IMGOPTS" | grep -q 2>/dev/null "$bad_opt"
+ # Add a space so tests can match for whitespace that marks the
+ # end of an option (\b or \> are not portable)
+ if echo "$IMGOPTS " | grep -q 2>/dev/null "$bad_opt"
then
_notrun "not suitable for image option: $bad_opt"
fi