aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block/mirror.c4
-rw-r--r--hw/core/qdev-properties-system.c11
-rw-r--r--hw/i386/pc.c2
-rw-r--r--hw/ide/ahci.c4
-rw-r--r--hw/ide/core.c1
-rw-r--r--hw/input/virtio-input.c11
-rw-r--r--hw/mips/cps.c2
-rw-r--r--hw/nvram/fw_cfg.c2
-rw-r--r--hw/ppc/spapr_cpu_core.c2
-rw-r--r--hw/s390x/s390-pci-bus.c2
-rw-r--r--hw/sparc/leon3.c6
-rw-r--r--hw/usb/bus.c7
-rw-r--r--hw/usb/desc.c1
-rw-r--r--hw/vfio/platform.c2
-rw-r--r--kvm-all.c2
-rw-r--r--migration/qjson.c1
-rw-r--r--numa.c15
-rw-r--r--qemu-char.c58
-rw-r--r--qemu-img.c4
-rwxr-xr-xscripts/checkpatch.pl5
-rw-r--r--scripts/coccinelle/err-bad-newline.cocci29
-rw-r--r--slirp/slirp.c8
-rw-r--r--target-i386/kvm.c2
-rw-r--r--tests/Makefile.include2
-rwxr-xr-xtests/qemu-iotests/1092
-rw-r--r--tests/qemu-iotests/109.out8
-rw-r--r--tests/qemu-iotests/common.filter6
-rw-r--r--tests/test-blockjob.c147
-rw-r--r--ui/vnc.c2
29 files changed, 297 insertions, 51 deletions
diff --git a/block/mirror.c b/block/mirror.c
index d6034f5b70..e0b3f4180f 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -419,6 +419,10 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
mirror_wait_for_io(s);
}
+ if (s->ret < 0) {
+ return 0;
+ }
+
mirror_clip_sectors(s, sector_num, &io_sectors);
switch (mirror_method) {
case MIRROR_METHOD_COPY:
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 2ba2504ea0..e55afe6bf2 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -126,7 +126,16 @@ static void release_drive(Object *obj, const char *name, void *opaque)
static char *print_drive(void *ptr)
{
- return g_strdup(blk_name(ptr));
+ const char *name;
+
+ name = blk_name(ptr);
+ if (!*name) {
+ BlockDriverState *bs = blk_bs(ptr);
+ if (bs) {
+ name = bdrv_get_node_name(bs);
+ }
+ }
+ return g_strdup(name);
}
static void get_drive(Object *obj, Visitor *v, const char *name, void *opaque,
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 47593b741a..022dd1b205 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -381,7 +381,7 @@ ISADevice *pc_find_fdc0(void)
error_report("warning: multiple floppy disk controllers with "
"iobase=0x3f0 have been found");
error_printf("the one being picked for CMOS setup might not reflect "
- "your intent");
+ "your intent\n");
}
return state.floppy;
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index bcb9ff9e1b..f3438ad78a 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -919,6 +919,7 @@ static void ncq_err(NCQTransferState *ncq_tfs)
ide_state->error = ABRT_ERR;
ide_state->status = READY_STAT | ERR_STAT;
ncq_tfs->drive->port_regs.scr_err |= (1 << ncq_tfs->tag);
+ qemu_sglist_destroy(&ncq_tfs->sglist);
ncq_tfs->used = 0;
}
@@ -1025,7 +1026,6 @@ static void execute_ncq_command(NCQTransferState *ncq_tfs)
default:
DPRINTF(port, "error: unsupported NCQ command (0x%02x) received\n",
ncq_tfs->cmd);
- qemu_sglist_destroy(&ncq_tfs->sglist);
ncq_err(ncq_tfs);
}
}
@@ -1092,7 +1092,6 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
error_report("ahci: PRDT length for NCQ command (0x%zx) "
"is smaller than the requested size (0x%zx)",
ncq_tfs->sglist.size, size);
- qemu_sglist_destroy(&ncq_tfs->sglist);
ncq_err(ncq_tfs);
ahci_trigger_irq(ad->hba, ad, PORT_IRQ_OVERFLOW);
return;
@@ -1478,6 +1477,7 @@ void ahci_realize(AHCIState *s, DeviceState *qdev, AddressSpace *as, int ports)
ad->port.dma->ops = &ahci_dma_ops;
ide_register_restart_cb(&ad->port);
}
+ g_free(irqs);
}
void ahci_uninit(AHCIState *s)
diff --git a/hw/ide/core.c b/hw/ide/core.c
index d117b7c202..45b6df132c 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -824,6 +824,7 @@ static void ide_dma_cb(void *opaque, int ret)
if (ret < 0) {
if (ide_handle_rw_error(s, -ret, ide_dma_cmd_to_retry(s->dma_cmd))) {
s->bus->dma->aiocb = NULL;
+ dma_buf_commit(s, 0);
return;
}
}
diff --git a/hw/input/virtio-input.c b/hw/input/virtio-input.c
index a87fd6862e..ccdf7308a5 100644
--- a/hw/input/virtio-input.c
+++ b/hw/input/virtio-input.c
@@ -270,6 +270,16 @@ static void virtio_input_device_realize(DeviceState *dev, Error **errp)
vinput->sts = virtio_add_queue(vdev, 64, virtio_input_handle_sts);
}
+static void virtio_input_finalize(Object *obj)
+{
+ VirtIOInput *vinput = VIRTIO_INPUT(obj);
+ VirtIOInputConfig *cfg, *next;
+
+ QTAILQ_FOREACH_SAFE(cfg, &vinput->cfg_list, node, next) {
+ QTAILQ_REMOVE(&vinput->cfg_list, cfg, node);
+ g_free(cfg);
+ }
+}
static void virtio_input_device_unrealize(DeviceState *dev, Error **errp)
{
VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(dev);
@@ -318,6 +328,7 @@ static const TypeInfo virtio_input_info = {
.class_size = sizeof(VirtIOInputClass),
.class_init = virtio_input_class_init,
.abstract = true,
+ .instance_finalize = virtio_input_finalize,
};
/* ----------------------------------------------------------------- */
diff --git a/hw/mips/cps.c b/hw/mips/cps.c
index 77c621797a..4ef337d5c4 100644
--- a/hw/mips/cps.c
+++ b/hw/mips/cps.c
@@ -73,7 +73,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
for (i = 0; i < s->num_vp; i++) {
cpu = cpu_mips_init(s->cpu_model);
if (cpu == NULL) {
- error_setg(errp, "%s: CPU initialization failed\n", __func__);
+ error_setg(errp, "%s: CPU initialization failed", __func__);
return;
}
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index f10d5ec9c8..6a68e594d5 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -744,7 +744,7 @@ static int get_fw_cfg_order(FWCfgState *s, const char *name)
}
/* Stick unknown stuff at the end. */
- error_report("warning: Unknown firmware file in legacy mode: %s\n", name);
+ error_report("warning: Unknown firmware file in legacy mode: %s", name);
return FW_CFG_ORDER_OVERRIDE_LAST;
}
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index 704803ac23..716f7c44cd 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -231,7 +231,7 @@ void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
}
if (cc->core_id % smp_threads) {
- error_setg(&local_err, "invalid core id %d\n", cc->core_id);
+ error_setg(&local_err, "invalid core id %d", cc->core_id);
goto out;
}
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 47ca853bd2..9c1c04e590 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -712,7 +712,7 @@ static void s390_pcihost_hot_unplug(HotplugHandler *hotplug_dev,
pci_dev = PCI_DEVICE(dev);
for (i = 0 ; i < PCI_SLOT_MAX; i++) {
- if (s->pbdev[i]->pdev == pci_dev) {
+ if (s->pbdev[i] && s->pbdev[i]->pdev == pci_dev) {
pbdev = s->pbdev[i];
break;
}
diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c
index dbae41f3a4..6e16478413 100644
--- a/hw/sparc/leon3.c
+++ b/hw/sparc/leon3.c
@@ -171,7 +171,11 @@ static void leon3_generic_hw_init(MachineState *machine)
}
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
- bios_size = get_image_size(filename);
+ if (filename) {
+ bios_size = get_image_size(filename);
+ } else {
+ bios_size = -1;
+ }
if (bios_size > prom_size) {
fprintf(stderr, "qemu: could not load prom '%s': file too big\n",
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index c28ccb8a96..25913ad488 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -279,6 +279,13 @@ static void usb_qdev_realize(DeviceState *qdev, Error **errp)
static void usb_qdev_unrealize(DeviceState *qdev, Error **errp)
{
USBDevice *dev = USB_DEVICE(qdev);
+ USBDescString *s, *next;
+
+ QLIST_FOREACH_SAFE(s, &dev->strings, next, next) {
+ QLIST_REMOVE(s, next);
+ g_free(s->str);
+ g_free(s);
+ }
if (dev->attached) {
usb_device_detach(dev);
diff --git a/hw/usb/desc.c b/hw/usb/desc.c
index adb026e43b..5e0e1d157e 100644
--- a/hw/usb/desc.c
+++ b/hw/usb/desc.c
@@ -574,6 +574,7 @@ void usb_desc_create_serial(USBDevice *dev)
}
dst += snprintf(serial+dst, sizeof(serial)-dst, "-%s", dev->port->path);
usb_desc_set_string(dev, index, serial);
+ g_free(path);
}
const char *usb_desc_get_string(USBDevice *dev, uint8_t index)
diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c
index 1798a00a3f..a559e7b659 100644
--- a/hw/vfio/platform.c
+++ b/hw/vfio/platform.c
@@ -496,7 +496,7 @@ static int vfio_populate_device(VFIODevice *vbasedev)
irq.index = i;
ret = ioctl(vbasedev->fd, VFIO_DEVICE_GET_IRQ_INFO, &irq);
if (ret) {
- error_printf("vfio: error getting device %s irq info",
+ error_report("vfio: error getting device %s irq info",
vbasedev->name);
goto irq_err;
} else {
diff --git a/kvm-all.c b/kvm-all.c
index 65608def36..ebf35b0c5b 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -2143,7 +2143,7 @@ void kvm_device_access(int fd, int group, uint64_t attr,
if (err < 0) {
error_report("KVM_%s_DEVICE_ATTR failed: %s",
write ? "SET" : "GET", strerror(-err));
- error_printf("Group %d attr 0x%016" PRIx64, group, attr);
+ error_printf("Group %d attr 0x%016" PRIx64 "\n", group, attr);
abort();
}
}
diff --git a/migration/qjson.c b/migration/qjson.c
index 5cae55af07..f345904919 100644
--- a/migration/qjson.c
+++ b/migration/qjson.c
@@ -109,5 +109,6 @@ void qjson_finish(QJSON *json)
void qjson_destroy(QJSON *json)
{
+ QDECREF(json->str);
g_free(json);
}
diff --git a/numa.c b/numa.c
index 72861713e5..6289f469bd 100644
--- a/numa.c
+++ b/numa.c
@@ -223,14 +223,14 @@ static int parse_numa(void *opaque, QemuOpts *opts, Error **errp)
}
if (err) {
- goto error;
+ goto end;
}
switch (object->type) {
case NUMA_OPTIONS_KIND_NODE:
numa_node_parse(object->u.node.data, opts, &err);
if (err) {
- goto error;
+ goto end;
}
nb_numa_nodes++;
break;
@@ -238,13 +238,14 @@ static int parse_numa(void *opaque, QemuOpts *opts, Error **errp)
abort();
}
- return 0;
-
-error:
- error_report_err(err);
+end:
qapi_free_NumaOptions(object);
+ if (err) {
+ error_report_err(err);
+ return -1;
+ }
- return -1;
+ return 0;
}
static char *enumerate_cpus(unsigned long *cpus, int max_cpus)
diff --git a/qemu-char.c b/qemu-char.c
index 27f2dbbbb5..8a0ab05a7b 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -786,6 +786,13 @@ static GSource *mux_chr_add_watch(CharDriverState *s, GIOCondition cond)
return d->drv->chr_add_watch(d->drv, cond);
}
+static void mux_chr_close(struct CharDriverState *chr)
+{
+ MuxDriver *d = chr->opaque;
+
+ g_free(d);
+}
+
static CharDriverState *qemu_chr_open_mux(const char *id,
ChardevBackend *backend,
ChardevReturn *ret, Error **errp)
@@ -810,6 +817,7 @@ static CharDriverState *qemu_chr_open_mux(const char *id,
chr->opaque = d;
d->drv = drv;
d->focus = -1;
+ chr->chr_close = mux_chr_close;
chr->chr_write = mux_chr_write;
chr->chr_update_read_handler = mux_chr_update_read_handler;
chr->chr_accept_input = mux_chr_accept_input;
@@ -2763,6 +2771,7 @@ static int tcp_set_msgfds(CharDriverState *chr, int *fds, int num)
/* clear old pending fd array */
g_free(s->write_msgfds);
s->write_msgfds = NULL;
+ s->write_msgfds_num = 0;
if (!s->connected ||
!qio_channel_has_feature(s->ioc,
@@ -2843,19 +2852,24 @@ static GSource *tcp_chr_add_watch(CharDriverState *chr, GIOCondition cond)
return qio_channel_create_watch(s->ioc, cond);
}
-static void tcp_chr_disconnect(CharDriverState *chr)
+static void tcp_chr_free_connection(CharDriverState *chr)
{
TCPCharDriver *s = chr->opaque;
+ int i;
if (!s->connected) {
return;
}
- s->connected = 0;
- if (s->listen_ioc) {
- s->listen_tag = qio_channel_add_watch(
- QIO_CHANNEL(s->listen_ioc), G_IO_IN, tcp_chr_accept, chr, NULL);
+ if (s->read_msgfds_num) {
+ for (i = 0; i < s->read_msgfds_num; i++) {
+ close(s->read_msgfds[i]);
+ }
+ g_free(s->read_msgfds);
+ s->read_msgfds = NULL;
+ s->read_msgfds_num = 0;
}
+
tcp_set_msgfds(chr, NULL, 0);
remove_fd_in_watch(chr);
object_unref(OBJECT(s->sioc));
@@ -2863,6 +2877,24 @@ static void tcp_chr_disconnect(CharDriverState *chr)
object_unref(OBJECT(s->ioc));
s->ioc = NULL;
g_free(chr->filename);
+ chr->filename = NULL;
+ s->connected = 0;
+}
+
+static void tcp_chr_disconnect(CharDriverState *chr)
+{
+ TCPCharDriver *s = chr->opaque;
+
+ if (!s->connected) {
+ return;
+ }
+
+ tcp_chr_free_connection(chr);
+
+ if (s->listen_ioc) {
+ s->listen_tag = qio_channel_add_watch(
+ QIO_CHANNEL(s->listen_ioc), G_IO_IN, tcp_chr_accept, chr, NULL);
+ }
chr->filename = SocketAddress_to_str("disconnected:", s->addr,
s->is_listen, s->is_telnet);
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
@@ -3177,17 +3209,14 @@ int qemu_chr_wait_connected(CharDriverState *chr, Error **errp)
static void tcp_chr_close(CharDriverState *chr)
{
TCPCharDriver *s = chr->opaque;
- int i;
+
+ tcp_chr_free_connection(chr);
if (s->reconnect_timer) {
g_source_remove(s->reconnect_timer);
s->reconnect_timer = 0;
}
qapi_free_SocketAddress(s->addr);
- remove_fd_in_watch(chr);
- if (s->ioc) {
- object_unref(OBJECT(s->ioc));
- }
if (s->listen_tag) {
g_source_remove(s->listen_tag);
s->listen_tag = 0;
@@ -3195,18 +3224,9 @@ static void tcp_chr_close(CharDriverState *chr)
if (s->listen_ioc) {
object_unref(OBJECT(s->listen_ioc));
}
- if (s->read_msgfds_num) {
- for (i = 0; i < s->read_msgfds_num; i++) {
- close(s->read_msgfds[i]);
- }
- g_free(s->read_msgfds);
- }
if (s->tls_creds) {
object_unref(OBJECT(s->tls_creds));
}
- if (s->write_msgfds_num) {
- g_free(s->write_msgfds);
- }
g_free(s);
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}
diff --git a/qemu-img.c b/qemu-img.c
index 2e40e1fc84..d2865a589e 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -3490,7 +3490,7 @@ typedef struct BenchData {
static void bench_undrained_flush_cb(void *opaque, int ret)
{
if (ret < 0) {
- error_report("Failed flush request: %s\n", strerror(-ret));
+ error_report("Failed flush request: %s", strerror(-ret));
exit(EXIT_FAILURE);
}
}
@@ -3501,7 +3501,7 @@ static void bench_cb(void *opaque, int ret)
BlockAIOCB *acb;
if (ret < 0) {
- error_report("Failed request: %s\n", strerror(-ret));
+ error_report("Failed request: %s", strerror(-ret));
exit(EXIT_FAILURE);
}
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index b7cb4ab478..9297087212 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -2514,11 +2514,14 @@ sub process {
my $qemu_error_funcs = qr{error_setg|
error_setg_errno|
error_setg_win32|
+ error_setg_file_open|
error_set|
+ error_prepend|
+ error_reportf_err|
error_vreport|
error_report}x;
- if ($rawline =~ /\b(?:$qemu_error_funcs)\s*\(\s*\".*\\n/) {
+ if ($rawline =~ /\b(?:$qemu_error_funcs)\s*\(.*\".*\\n/) {
WARN("Error messages should not contain newlines\n" . $herecurr);
}
diff --git a/scripts/coccinelle/err-bad-newline.cocci b/scripts/coccinelle/err-bad-newline.cocci
new file mode 100644
index 0000000000..1316cc86a6
--- /dev/null
+++ b/scripts/coccinelle/err-bad-newline.cocci
@@ -0,0 +1,29 @@
+// Error messages should not contain newlines. This script finds
+// messages that do. Fixing them is manual.
+@r@
+expression errp, eno, cls, fmt;
+position p;
+@@
+(
+error_report(fmt, ...)@p
+|
+error_setg(errp, fmt, ...)@p
+|
+error_setg_errno(errp, eno, fmt, ...)@p
+|
+error_setg_win32(errp, eno, cls, fmt, ...)@p
+|
+error_prepend(errp, fmt, ...)@p
+|
+error_setg_file_open(errp, eno, cls, fmt, ...)@p
+|
+error_reportf_err(errp, fmt, ...)@p
+|
+error_set(errp, cls, fmt, ...)@p
+)
+@script:python@
+fmt << r.fmt;
+p << r.p;
+@@
+if "\\n" in str(fmt):
+ print "%s:%s:%s:%s" % (p[0].file, p[0].line, p[0].column, fmt)
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 7eb183d0e9..47a1652952 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -1197,8 +1197,8 @@ static void slirp_socket_save(QEMUFile *f, struct socket *so)
qemu_put_be16(f, so->so_fport);
break;
default:
- error_report(
- "so_ffamily unknown, unable to save so_faddr and so_fport\n");
+ error_report("so_ffamily unknown, unable to save so_faddr and"
+ " so_fport");
}
qemu_put_be16(f, so->so_lfamily);
switch (so->so_lfamily) {
@@ -1207,8 +1207,8 @@ static void slirp_socket_save(QEMUFile *f, struct socket *so)
qemu_put_be16(f, so->so_lport);
break;
default:
- error_report(
- "so_ffamily unknown, unable to save so_laddr and so_lport\n");
+ error_report("so_ffamily unknown, unable to save so_laddr and"
+ " so_lport");
}
qemu_put_byte(f, so->so_iptos);
qemu_put_byte(f, so->so_emu);
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 9697e16fdd..0b2016a77a 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -3250,7 +3250,7 @@ int kvm_arch_irqchip_create(MachineState *ms, KVMState *s)
if (machine_kernel_irqchip_split(ms)) {
ret = kvm_vm_enable_cap(s, KVM_CAP_SPLIT_IRQCHIP, 0, 24);
if (ret) {
- error_report("Could not enable split irqchip mode: %s\n",
+ error_report("Could not enable split irqchip mode: %s",
strerror(-ret));
exit(1);
} else {
diff --git a/tests/Makefile.include b/tests/Makefile.include
index ebecfa445c..14be4915b9 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -52,6 +52,7 @@ gcov-files-test-thread-pool-y = thread-pool.c
gcov-files-test-hbitmap-y = util/hbitmap.c
check-unit-y += tests/test-hbitmap$(EXESUF)
gcov-files-test-hbitmap-y = blockjob.c
+check-unit-y += tests/test-blockjob$(EXESUF)
check-unit-y += tests/test-blockjob-txn$(EXESUF)
check-unit-y += tests/test-x86-cpuid$(EXESUF)
# all code tested by test-x86-cpuid is inside topology.h
@@ -449,6 +450,7 @@ tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(test-block-obj-y)
tests/test-aio$(EXESUF): tests/test-aio.o $(test-block-obj-y)
tests/test-rfifolock$(EXESUF): tests/test-rfifolock.o $(test-util-obj-y)
tests/test-throttle$(EXESUF): tests/test-throttle.o $(test-block-obj-y)
+tests/test-blockjob$(EXESUF): tests/test-blockjob.o $(test-block-obj-y) $(test-util-obj-y)
tests/test-blockjob-txn$(EXESUF): tests/test-blockjob-txn.o $(test-block-obj-y) $(test-util-obj-y)
tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(test-block-obj-y)
tests/test-iov$(EXESUF): tests/test-iov.o $(test-util-obj-y)
diff --git a/tests/qemu-iotests/109 b/tests/qemu-iotests/109
index adf98892f0..280ed27aa9 100755
--- a/tests/qemu-iotests/109
+++ b/tests/qemu-iotests/109
@@ -100,7 +100,7 @@ for sample_img in empty.bochs iotest-dirtylog-10G-4M.vhdx parallels-v1 \
_make_test_img 64M
bzcat "$SAMPLE_IMG_DIR/$sample_img.bz2" > "$TEST_IMG.src"
- run_qemu "$TEST_IMG" "$TEST_IMG.src" "" "BLOCK_JOB_ERROR"
+ run_qemu "$TEST_IMG" "$TEST_IMG.src" "" "BLOCK_JOB_ERROR" | _filter_block_job_offset
$QEMU_IO -c 'read -P 0 0 64k' "$TEST_IMG" | _filter_qemu_io
run_qemu "$TEST_IMG" "$TEST_IMG.src" "'format': 'raw'," "BLOCK_JOB_READY"
diff --git a/tests/qemu-iotests/109.out b/tests/qemu-iotests/109.out
index 7c797ed31c..e5d70d75f1 100644
--- a/tests/qemu-iotests/109.out
+++ b/tests/qemu-iotests/109.out
@@ -135,7 +135,7 @@ Automatically detecting the format is dangerous for raw images, write operations
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2560, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2560, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -155,7 +155,7 @@ Automatically detecting the format is dangerous for raw images, write operations
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 31457280, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 31457280, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -175,7 +175,7 @@ Automatically detecting the format is dangerous for raw images, write operations
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 327680, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 327680, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -195,7 +195,7 @@ Automatically detecting the format is dangerous for raw images, write operations
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2048, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2048, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
index 7853dbbfdc..3ab6e4d764 100644
--- a/tests/qemu-iotests/common.filter
+++ b/tests/qemu-iotests/common.filter
@@ -77,6 +77,12 @@ _filter_qmp()
-e ' QMP_VERSION'
}
+# replace block job offset
+_filter_block_job_offset()
+{
+ sed -e 's/, "offset": [0-9]\+,/, "offset": OFFSET,/'
+}
+
# replace driver-specific options in the "Formatting..." line
_filter_img_create()
{
diff --git a/tests/test-blockjob.c b/tests/test-blockjob.c
new file mode 100644
index 0000000000..5b0e934a0c
--- /dev/null
+++ b/tests/test-blockjob.c
@@ -0,0 +1,147 @@
+/*
+ * Blockjob tests
+ *
+ * Copyright Igalia, S.L. 2016
+ *
+ * Authors:
+ * Alberto Garcia <berto@igalia.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu/main-loop.h"
+#include "block/blockjob.h"
+#include "sysemu/block-backend.h"
+
+static const BlockJobDriver test_block_job_driver = {
+ .instance_size = sizeof(BlockJob),
+};
+
+static void block_job_cb(void *opaque, int ret)
+{
+}
+
+static BlockJob *do_test_id(BlockBackend *blk, const char *id,
+ bool should_succeed)
+{
+ BlockJob *job;
+ Error *errp = NULL;
+
+ job = block_job_create(id, &test_block_job_driver, blk_bs(blk), 0,
+ block_job_cb, NULL, &errp);
+ if (should_succeed) {
+ g_assert_null(errp);
+ g_assert_nonnull(job);
+ if (id) {
+ g_assert_cmpstr(job->id, ==, id);
+ } else {
+ g_assert_cmpstr(job->id, ==, blk_name(blk));
+ }
+ } else {
+ g_assert_nonnull(errp);
+ g_assert_null(job);
+ error_free(errp);
+ }
+
+ return job;
+}
+
+/* This creates a BlockBackend (optionally with a name) with a
+ * BlockDriverState inserted. */
+static BlockBackend *create_blk(const char *name)
+{
+ BlockBackend *blk = blk_new();
+ BlockDriverState *bs = bdrv_new();
+
+ blk_insert_bs(blk, bs);
+ bdrv_unref(bs);
+
+ if (name) {
+ Error *errp = NULL;
+ monitor_add_blk(blk, name, &errp);
+ g_assert_null(errp);
+ }
+
+ return blk;
+}
+
+/* This destroys the backend */
+static void destroy_blk(BlockBackend *blk)
+{
+ if (blk_name(blk)[0] != '\0') {
+ monitor_remove_blk(blk);
+ }
+
+ blk_remove_bs(blk);
+ blk_unref(blk);
+}
+
+static void test_job_ids(void)
+{
+ BlockBackend *blk[3];
+ BlockJob *job[3];
+
+ blk[0] = create_blk(NULL);
+ blk[1] = create_blk("drive1");
+ blk[2] = create_blk("drive2");
+
+ /* No job ID provided and the block backend has no name */
+ job[0] = do_test_id(blk[0], NULL, false);
+
+ /* These are all invalid job IDs */
+ job[0] = do_test_id(blk[0], "0id", false);
+ job[0] = do_test_id(blk[0], "", false);
+ job[0] = do_test_id(blk[0], " ", false);
+ job[0] = do_test_id(blk[0], "123", false);
+ job[0] = do_test_id(blk[0], "_id", false);
+ job[0] = do_test_id(blk[0], "-id", false);
+ job[0] = do_test_id(blk[0], ".id", false);
+ job[0] = do_test_id(blk[0], "#id", false);
+
+ /* This one is valid */
+ job[0] = do_test_id(blk[0], "id0", true);
+
+ /* We cannot have two jobs in the same BDS */
+ do_test_id(blk[0], "id1", false);
+
+ /* Duplicate job IDs are not allowed */
+ job[1] = do_test_id(blk[1], "id0", false);
+
+ /* But once job[0] finishes we can reuse its ID */
+ block_job_unref(job[0]);
+ job[1] = do_test_id(blk[1], "id0", true);
+
+ /* No job ID specified, defaults to the backend name ('drive1') */
+ block_job_unref(job[1]);
+ job[1] = do_test_id(blk[1], NULL, true);
+
+ /* Duplicate job ID */
+ job[2] = do_test_id(blk[2], "drive1", false);
+
+ /* The ID of job[2] would default to 'drive2' but it is already in use */
+ job[0] = do_test_id(blk[0], "drive2", true);
+ job[2] = do_test_id(blk[2], NULL, false);
+
+ /* This one is valid */
+ job[2] = do_test_id(blk[2], "id_2", true);
+
+ block_job_unref(job[0]);
+ block_job_unref(job[1]);
+ block_job_unref(job[2]);
+
+ destroy_blk(blk[0]);
+ destroy_blk(blk[1]);
+ destroy_blk(blk[2]);
+}
+
+int main(int argc, char **argv)
+{
+ qemu_init_main_loop(&error_abort);
+
+ g_test_init(&argc, &argv, NULL);
+ g_test_add_func("/blockjob/ids", test_job_ids);
+ return g_test_run();
+}
diff --git a/ui/vnc.c b/ui/vnc.c
index 4ce903429f..853b57e982 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -3201,7 +3201,7 @@ int vnc_display_password(const char *id, const char *password)
}
if (vs->auth == VNC_AUTH_NONE) {
error_printf_unless_qmp("If you want use passwords please enable "
- "password auth using '-vnc ${dpy},password'.");
+ "password auth using '-vnc ${dpy},password'.\n");
return -EINVAL;
}