[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 7/9] char: handle qemu_chr_add_handlers() error
From: |
Marc-André Lureau |
Subject: |
[Qemu-devel] [PATCH 7/9] char: handle qemu_chr_add_handlers() error |
Date: |
Thu, 13 Oct 2016 15:14:47 +0400 |
Raise or assert on qemu_chr_add_handlers() error.
Signed-off-by: Marc-André Lureau <address@hidden>
---
backends/rng-egd.c | 2 +-
gdbstub.c | 4 ++--
hw/arm/pxa2xx.c | 3 ++-
hw/arm/strongarm.c | 3 ++-
hw/char/bcm2835_aux.c | 2 +-
hw/char/cadence_uart.c | 2 +-
hw/char/debugcon.c | 5 ++++-
hw/char/digic-uart.c | 3 ++-
hw/char/escc.c | 3 ++-
hw/char/etraxfs_ser.c | 4 ++--
hw/char/exynos4210_uart.c | 9 +++++++-
hw/char/grlib_apbuart.c | 3 ++-
hw/char/imx_serial.c | 2 +-
hw/char/ipoctal232.c | 5 ++++-
hw/char/lm32_juart.c | 3 ++-
hw/char/lm32_uart.c | 3 ++-
hw/char/mcf_uart.c | 3 ++-
hw/char/milkymist-uart.c | 3 ++-
hw/char/pl011.c | 2 +-
hw/char/sclpconsole-lm.c | 9 ++++++--
hw/char/sclpconsole.c | 3 ++-
hw/char/serial.c | 6 ++++-
hw/char/sh_serial.c | 3 ++-
hw/char/spapr_vty.c | 2 +-
hw/char/stm32f2xx_usart.c | 2 +-
hw/char/virtio-console.c | 7 ++++--
hw/char/xen_console.c | 11 +++++++++-
hw/char/xilinx_uartlite.c | 3 ++-
hw/ipmi/ipmi_bmc_extern.c | 3 ++-
hw/misc/ivshmem.c | 5 ++++-
hw/usb/ccid-card-passthru.c | 9 +++++++-
hw/usb/dev-serial.c | 6 ++++-
hw/usb/redirect.c | 6 ++++-
monitor.c | 12 +++++++---
net/colo-compare.c | 23 ++++++++++++++++----
net/filter-mirror.c | 6 ++++-
net/slirp.c | 8 ++++++-
net/vhost-user.c | 14 +++++++-----
qemu-char.c | 53 +++++++++++++++++++++++----------------------
qtest.c | 7 ++++--
stubs/monitor-init.c | 2 +-
tests/vhost-user-test.c | 3 ++-
vl.c | 2 +-
include/monitor/monitor.h | 2 +-
include/sysemu/char.h | 19 +++++-----------
45 files changed, 193 insertions(+), 97 deletions(-)
diff --git a/backends/rng-egd.c b/backends/rng-egd.c
index 5d8485f..a62eefa 100644
--- a/backends/rng-egd.c
+++ b/backends/rng-egd.c
@@ -111,7 +111,7 @@ static void rng_egd_opened(RngBackend *b, Error **errp)
if (s->chr_tag == -1) {
s->chr_tag =
qemu_chr_add_handlers(s->chr, rng_egd_chr_can_read,
- rng_egd_chr_read, NULL, s);
+ rng_egd_chr_read, NULL, s, NULL, errp);
}
}
diff --git a/gdbstub.c b/gdbstub.c
index 054a1d3..ee04be3 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1754,7 +1754,7 @@ int gdbserver_start(const char *device)
qemu_chr_fe_claim_no_fail(chr);
chr_tag =
qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
- gdb_chr_event, NULL);
+ gdb_chr_event, NULL, NULL, &error_abort);
}
s = gdbserver_state;
@@ -1767,7 +1767,7 @@ int gdbserver_start(const char *device)
/* Initialize a monitor terminal for gdb */
mon_chr = qemu_chr_alloc(&common, &error_abort);
mon_chr->chr_write = gdb_monitor_write;
- monitor_init(mon_chr, 0);
+ monitor_init(mon_chr, 0, &error_abort);
} else {
if (s->chr) {
qemu_chr_remove_handlers(s->chr, s->chr_tag);
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index e17b904..d70712d 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -1978,7 +1978,8 @@ static void pxa2xx_fir_realize(DeviceState *dev, Error
**errp)
qemu_chr_fe_claim_no_fail(s->chr);
s->chr_tag =
qemu_chr_add_handlers(s->chr, pxa2xx_fir_is_empty,
- pxa2xx_fir_rx, pxa2xx_fir_event, s);
+ pxa2xx_fir_rx, pxa2xx_fir_event,
+ s, NULL, errp);
}
}
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
index 48b4a7c..03150ab 100644
--- a/hw/arm/strongarm.c
+++ b/hw/arm/strongarm.c
@@ -39,6 +39,7 @@
#include "hw/ssi/ssi.h"
#include "qemu/cutils.h"
#include "qemu/log.h"
+#include "qapi/error.h"
//#define DEBUG
@@ -1246,7 +1247,7 @@ static void strongarm_uart_init(Object *obj)
strongarm_uart_can_receive,
strongarm_uart_receive,
strongarm_uart_event,
- s);
+ s, NULL, &error_abort);
}
}
diff --git a/hw/char/bcm2835_aux.c b/hw/char/bcm2835_aux.c
index 5694c32..7e00c68 100644
--- a/hw/char/bcm2835_aux.c
+++ b/hw/char/bcm2835_aux.c
@@ -285,7 +285,7 @@ static void bcm2835_aux_realize(DeviceState *dev, Error
**errp)
if (s->chr) {
s->chr_tag =
qemu_chr_add_handlers(s->chr, bcm2835_aux_can_receive,
- bcm2835_aux_receive, NULL, s);
+ bcm2835_aux_receive, NULL, s, NULL, errp);
}
}
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
index 7ca8f0a..3d66e1b 100644
--- a/hw/char/cadence_uart.c
+++ b/hw/char/cadence_uart.c
@@ -477,7 +477,7 @@ static void cadence_uart_realize(DeviceState *dev, Error
**errp)
if (s->chr) {
s->chr_tag =
qemu_chr_add_handlers(s->chr, uart_can_receive, uart_receive,
- uart_event, s);
+ uart_event, s, NULL, errp);
}
}
diff --git a/hw/char/debugcon.c b/hw/char/debugcon.c
index 45876a7..4f4e4e6 100644
--- a/hw/char/debugcon.c
+++ b/hw/char/debugcon.c
@@ -98,7 +98,10 @@ static void debugcon_isa_realizefn(DeviceState *dev, Error
**errp)
}
/* necessary to start the be */
- s->chr_tag = qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, s);
+ s->chr_tag = qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, s, NULL,
errp);
+ if (s->chr_tag == -1) {
+ return;
+ }
memory_region_init_io(&s->io, OBJECT(dev), &debugcon_ops, s,
TYPE_ISA_DEBUGCON_DEVICE, 1);
diff --git a/hw/char/digic-uart.c b/hw/char/digic-uart.c
index 83217a4..04013f7 100644
--- a/hw/char/digic-uart.c
+++ b/hw/char/digic-uart.c
@@ -149,7 +149,8 @@ static void digic_uart_realize(DeviceState *dev, Error
**errp)
if (s->chr) {
s->chr_tag =
- qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
+ qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event,
+ s, NULL, errp);
}
}
diff --git a/hw/char/escc.c b/hw/char/escc.c
index 0cbaf27..0e97291 100644
--- a/hw/char/escc.c
+++ b/hw/char/escc.c
@@ -1018,7 +1018,8 @@ static void escc_realize(DeviceState *dev, Error **errp)
s->chn[i].clock = s->frequency / 2;
s->chn[i].chr_tag =
qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
- serial_receive1, serial_event, &s->chn[i]);
+ serial_receive1, serial_event,
&s->chn[i],
+ NULL, errp);
}
}
diff --git a/hw/char/etraxfs_ser.c b/hw/char/etraxfs_ser.c
index e606a76..b7cf7b5 100644
--- a/hw/char/etraxfs_ser.c
+++ b/hw/char/etraxfs_ser.c
@@ -235,8 +235,8 @@ static void etraxfs_ser_realize(DeviceState *dev, Error
**errp)
if (s->chr) {
s->chr_tag =
qemu_chr_add_handlers(s->chr,
- serial_can_receive, serial_receive,
- serial_event, s);
+ serial_can_receive, serial_receive,
+ serial_event, s, NULL, errp);
}
}
diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
index ba84a4f..40139ae 100644
--- a/hw/char/exynos4210_uart.c
+++ b/hw/char/exynos4210_uart.c
@@ -24,6 +24,7 @@
#include "qemu/error-report.h"
#include "sysemu/sysemu.h"
#include "sysemu/char.h"
+#include "qapi/error.h"
#include "hw/arm/exynos4210.h"
@@ -633,6 +634,7 @@ DeviceState *exynos4210_uart_create(hwaddr addr,
static int exynos4210_uart_init(SysBusDevice *dev)
{
Exynos4210UartState *s = EXYNOS4210_UART(dev);
+ Error *err = NULL;
/* memory mapping */
memory_region_init_io(&s->iomem, OBJECT(s), &exynos4210_uart_ops, s,
@@ -643,7 +645,12 @@ static int exynos4210_uart_init(SysBusDevice *dev)
s->chr_tag =
qemu_chr_add_handlers(s->chr, exynos4210_uart_can_receive,
- exynos4210_uart_receive, exynos4210_uart_event, s);
+ exynos4210_uart_receive, exynos4210_uart_event,
+ s, NULL, &err);
+ if (err) {
+ error_report_err(err);
+ return -1;
+ }
return 0;
}
diff --git a/hw/char/grlib_apbuart.c b/hw/char/grlib_apbuart.c
index 963ca6d..dcacb3a 100644
--- a/hw/char/grlib_apbuart.c
+++ b/hw/char/grlib_apbuart.c
@@ -25,6 +25,7 @@
#include "qemu/osdep.h"
#include "hw/sysbus.h"
#include "sysemu/char.h"
+#include "qapi/error.h"
#include "trace.h"
@@ -248,7 +249,7 @@ static int grlib_apbuart_init(SysBusDevice *dev)
grlib_apbuart_can_receive,
grlib_apbuart_receive,
grlib_apbuart_event,
- uart);
+ uart, NULL, &error_abort);
sysbus_init_irq(dev, &uart->irq);
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
index 5ac3122..ceb9951 100644
--- a/hw/char/imx_serial.c
+++ b/hw/char/imx_serial.c
@@ -321,7 +321,7 @@ static void imx_serial_realize(DeviceState *dev, Error
**errp)
if (s->chr) {
s->chr_tag =
qemu_chr_add_handlers(s->chr, imx_can_receive, imx_receive,
- imx_event, s);
+ imx_event, s, NULL, errp);
} else {
DPRINTF("No char dev for uart\n");
}
diff --git a/hw/char/ipoctal232.c b/hw/char/ipoctal232.c
index 4adc500..8175273 100644
--- a/hw/char/ipoctal232.c
+++ b/hw/char/ipoctal232.c
@@ -549,7 +549,10 @@ static void ipoctal_realize(DeviceState *dev, Error **errp)
/* Redirect IP-Octal channels to host character devices */
if (ch->dev) {
ch->chr_tag = qemu_chr_add_handlers(ch->dev, hostdev_can_receive,
- hostdev_receive, hostdev_event, ch);
+ hostdev_receive, hostdev_event, ch, NULL, errp);
+ if (ch->chr_tag == -1) {
+ return;
+ }
DPRINTF("Redirecting channel %u to %s\n", i, ch->dev->label);
} else {
DPRINTF("Could not redirect channel %u, no chardev set\n", i);
diff --git a/hw/char/lm32_juart.c b/hw/char/lm32_juart.c
index 065195d..6c2677f 100644
--- a/hw/char/lm32_juart.c
+++ b/hw/char/lm32_juart.c
@@ -123,7 +123,8 @@ static void lm32_juart_realize(DeviceState *dev, Error
**errp)
if (s->chr) {
s->chr_tag = qemu_chr_add_handlers(s->chr, juart_can_rx,
- juart_rx, juart_event, s);
+ juart_rx, juart_event,
+ s, NULL, errp);
}
}
diff --git a/hw/char/lm32_uart.c b/hw/char/lm32_uart.c
index c94cf19..6c74c55 100644
--- a/hw/char/lm32_uart.c
+++ b/hw/char/lm32_uart.c
@@ -270,7 +270,8 @@ static void lm32_uart_realize(DeviceState *dev, Error
**errp)
if (s->chr) {
s->chr_tag =
- qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
+ qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event,
+ s, NULL, errp);
}
}
diff --git a/hw/char/mcf_uart.c b/hw/char/mcf_uart.c
index 7a677c7..3d9037d 100644
--- a/hw/char/mcf_uart.c
+++ b/hw/char/mcf_uart.c
@@ -10,6 +10,7 @@
#include "hw/m68k/mcf.h"
#include "sysemu/char.h"
#include "exec/address-spaces.h"
+#include "qapi/error.h"
typedef struct {
MemoryRegion iomem;
@@ -287,7 +288,7 @@ void *mcf_uart_init(qemu_irq irq, CharDriverState *chr)
qemu_chr_fe_claim_no_fail(chr);
s->chr_tag =
qemu_chr_add_handlers(chr, mcf_uart_can_receive, mcf_uart_receive,
- mcf_uart_event, s);
+ mcf_uart_event, s, NULL, &error_abort);
}
mcf_uart_reset(s);
return s;
diff --git a/hw/char/milkymist-uart.c b/hw/char/milkymist-uart.c
index 0203512..04fec4c 100644
--- a/hw/char/milkymist-uart.c
+++ b/hw/char/milkymist-uart.c
@@ -203,7 +203,8 @@ static void milkymist_uart_realize(DeviceState *dev, Error
**errp)
if (s->chr) {
s->chr_tag =
- qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
+ qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event,
+ s, NULL, errp);
}
}
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
index 903c044..0827c51 100644
--- a/hw/char/pl011.c
+++ b/hw/char/pl011.c
@@ -306,7 +306,7 @@ static void pl011_realize(DeviceState *dev, Error **errp)
if (s->chr) {
s->chr_tag =
qemu_chr_add_handlers(s->chr, pl011_can_receive, pl011_receive,
- pl011_event, s);
+ pl011_event, s, NULL, errp);
}
}
diff --git a/hw/char/sclpconsole-lm.c b/hw/char/sclpconsole-lm.c
index 7c76d9e..5677864 100644
--- a/hw/char/sclpconsole-lm.c
+++ b/hw/char/sclpconsole-lm.c
@@ -18,6 +18,7 @@
#include "qemu/thread.h"
#include "qemu/error-report.h"
#include "sysemu/char.h"
+#include "qapi/error.h"
#include "hw/s390x/sclp.h"
#include "hw/s390x/event-facility.h"
@@ -304,8 +305,8 @@ static const VMStateDescription vmstate_sclplmconsole = {
static int console_init(SCLPEvent *event)
{
static bool console_available;
-
SCLPConsoleLM *scon = SCLPLM_CONSOLE(event);
+ Error *err = NULL;
if (console_available) {
error_report("Multiple line-mode operator consoles are not supported");
@@ -316,7 +317,11 @@ static int console_init(SCLPEvent *event)
if (scon->chr) {
scon->chr_tag =
qemu_chr_add_handlers(scon->chr, chr_can_read,
- chr_read, NULL, scon);
+ chr_read, NULL, scon, NULL, &err);
+ if (err) {
+ error_report_err(err);
+ return -1;
+ }
}
return 0;
diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c
index cf0b309..d3f87ce 100644
--- a/hw/char/sclpconsole.c
+++ b/hw/char/sclpconsole.c
@@ -20,6 +20,7 @@
#include "hw/s390x/sclp.h"
#include "hw/s390x/event-facility.h"
#include "sysemu/char.h"
+#include "qapi/error.h"
typedef struct ASCIIConsoleData {
EventBufferHeader ebh;
@@ -231,7 +232,7 @@ static int console_init(SCLPEvent *event)
if (scon->chr) {
scon->chr_tag =
qemu_chr_add_handlers(scon->chr, chr_can_read,
- chr_read, NULL, scon);
+ chr_read, NULL, scon, NULL, &error_abort);
}
return 0;
diff --git a/hw/char/serial.c b/hw/char/serial.c
index 9d7d57b..f877cec 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -895,7 +895,11 @@ void serial_realize_core(SerialState *s, Error **errp)
s->chr_tag =
qemu_chr_add_handlers(s->chr, serial_can_receive1, serial_receive1,
- serial_event, s);
+ serial_event, s, NULL, errp);
+ if (s->chr_tag == -1) {
+ return;
+ }
+
fifo8_create(&s->recv_fifo, UART_FIFO_LENGTH);
fifo8_create(&s->xmit_fifo, UART_FIFO_LENGTH);
serial_reset(s);
diff --git a/hw/char/sh_serial.c b/hw/char/sh_serial.c
index e093689..034bc49 100644
--- a/hw/char/sh_serial.c
+++ b/hw/char/sh_serial.c
@@ -29,6 +29,7 @@
#include "hw/sh4/sh.h"
#include "sysemu/char.h"
#include "exec/address-spaces.h"
+#include "qapi/error.h"
//#define DEBUG_SERIAL
@@ -403,7 +404,7 @@ void sh_serial_init(MemoryRegion *sysmem,
qemu_chr_fe_claim_no_fail(chr);
tag = qemu_chr_add_handlers(chr, sh_serial_can_receive1,
sh_serial_receive1,
- sh_serial_event, s);
+ sh_serial_event, s, NULL, &error_abort);
assert(tag != -1);
}
diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c
index fdc32e3..dfb12ac 100644
--- a/hw/char/spapr_vty.c
+++ b/hw/char/spapr_vty.c
@@ -77,7 +77,7 @@ static void spapr_vty_realize(VIOsPAPRDevice *sdev, Error
**errp)
dev->chr_tag =
qemu_chr_add_handlers(dev->chardev, vty_can_receive,
- vty_receive, NULL, dev);
+ vty_receive, NULL, dev, NULL, errp);
}
static void spapr_vty_unrealize(DeviceState *s, Error **errp)
diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c
index 9f8aac5..b1897e9 100644
--- a/hw/char/stm32f2xx_usart.c
+++ b/hw/char/stm32f2xx_usart.c
@@ -215,7 +215,7 @@ static void stm32f2xx_usart_realize(DeviceState *dev, Error
**errp)
if (s->chr) {
s->chr_tag =
qemu_chr_add_handlers(s->chr, stm32f2xx_usart_can_receive,
- stm32f2xx_usart_receive, NULL, s);
+ stm32f2xx_usart_receive, NULL, s, NULL,
errp);
}
}
diff --git a/hw/char/virtio-console.c b/hw/char/virtio-console.c
index f3f3aa3..984dc25 100644
--- a/hw/char/virtio-console.c
+++ b/hw/char/virtio-console.c
@@ -192,13 +192,16 @@ static void virtconsole_realize(DeviceState *dev, Error
**errp)
vcon->chr->explicit_fe_open = 0;
vcon->chr_tag =
qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read,
- NULL, vcon);
+ NULL, vcon, NULL, errp);
+ if (vcon->chr_tag == -1) {
+ return;
+ }
virtio_serial_open(port);
} else {
vcon->chr->explicit_fe_open = 1;
vcon->chr_tag =
qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read,
- chr_event, vcon);
+ chr_event, vcon, NULL, errp);
}
}
}
diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c
index f263dfa..401ec8c 100644
--- a/hw/char/xen_console.c
+++ b/hw/char/xen_console.c
@@ -26,6 +26,7 @@
#include "hw/hw.h"
#include "sysemu/char.h"
#include "hw/xen/xen_backend.h"
+#include "qapi/error.h"
#include <xen/io/console.h>
@@ -200,6 +201,7 @@ static int con_init(struct XenDevice *xendev)
con->chr = serial_hds[con->xendev.dev];
} else {
snprintf(label, sizeof(label), "xencons%d", con->xendev.dev);
+ /* FIXME: leaks on destroy & initialize error */
con->chr = qemu_chr_new(label, output, NULL);
}
@@ -213,6 +215,7 @@ out:
static int con_initialise(struct XenDevice *xendev)
{
struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
+ Error *err = NULL;
int limit;
if (xenstore_read_int(con->console, "ring-ref", &con->ring_ref) == -1)
@@ -240,7 +243,13 @@ static int con_initialise(struct XenDevice *xendev)
if (qemu_chr_fe_claim(con->chr) == 0) {
con->chr_tag =
qemu_chr_add_handlers(con->chr, xencons_can_receive,
- xencons_receive, NULL, con);
+ xencons_receive, NULL, con, NULL, &err);
+ if (con->chr_tag == -1) {
+ xen_be_printf(xendev, 0, "error: %s\n",
+ error_get_pretty(err));
+ error_free(err);
+ con->chr = NULL;
+ }
} else {
xen_be_printf(xendev, 0,
"xen_console_init error chardev %s already used\n",
diff --git a/hw/char/xilinx_uartlite.c b/hw/char/xilinx_uartlite.c
index e6b103e..664ac97 100644
--- a/hw/char/xilinx_uartlite.c
+++ b/hw/char/xilinx_uartlite.c
@@ -216,7 +216,8 @@ static void xilinx_uartlite_realize(DeviceState *dev, Error
**errp)
if (s->chr) {
s->chr_tag =
- qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
+ qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event,
+ s, NULL, errp);
}
}
diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c
index 927bed2..e239834 100644
--- a/hw/ipmi/ipmi_bmc_extern.c
+++ b/hw/ipmi/ipmi_bmc_extern.c
@@ -449,7 +449,8 @@ static void ipmi_bmc_extern_realize(DeviceState *dev, Error
**errp)
}
ibe->chr_tag =
- qemu_chr_add_handlers(ibe->chr, can_receive, receive, chr_event, ibe);
+ qemu_chr_add_handlers(ibe->chr, can_receive, receive,
+ chr_event, ibe, NULL, errp);
}
static void ipmi_bmc_extern_unrealize(DeviceState *dev, Error **errp)
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 19079f4..9983f7c 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -898,7 +898,10 @@ static void ivshmem_common_realize(PCIDevice *dev, Error
**errp)
s->server_chr_tag =
qemu_chr_add_handlers(s->server_chr, ivshmem_can_receive,
- ivshmem_read, NULL, s);
+ ivshmem_read, NULL, s, NULL, errp);
+ if (s->server_chr_tag == -1) {
+ return;
+ }
if (ivshmem_setup_interrupts(s) < 0) {
error_setg(errp, "failed to initialize interrupts");
diff --git a/hw/usb/ccid-card-passthru.c b/hw/usb/ccid-card-passthru.c
index 8960972..5c0870c 100644
--- a/hw/usb/ccid-card-passthru.c
+++ b/hw/usb/ccid-card-passthru.c
@@ -14,6 +14,7 @@
#include "qemu/sockets.h"
#include "ccid.h"
#include "cacard/vscard_common.h"
+#include "qapi/error.h"
#define DPRINTF(card, lvl, fmt, ...) \
do { \
@@ -343,6 +344,7 @@ static const uint8_t *passthru_get_atr(CCIDCardState *base,
uint32_t *len)
static int passthru_initfn(CCIDCardState *base)
{
PassthruState *card = PASSTHRU_CCID_CARD(base);
+ Error *err = NULL;
card->vscard_in_pos = 0;
card->vscard_in_hdr = 0;
@@ -351,7 +353,12 @@ static int passthru_initfn(CCIDCardState *base)
card->chr_tag = qemu_chr_add_handlers(card->cs,
ccid_card_vscard_can_read,
ccid_card_vscard_read,
- ccid_card_vscard_event, card);
+ ccid_card_vscard_event, card,
+ NULL, &err);
+ if (err) {
+ error_report_err(err);
+ return -1;
+ }
ccid_card_vscard_send_init(card);
} else {
error_report("missing chardev");
diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c
index 4dcfc68..a1e183a 100644
--- a/hw/usb/dev-serial.c
+++ b/hw/usb/dev-serial.c
@@ -502,7 +502,11 @@ static void usb_serial_realize(USBDevice *dev, Error
**errp)
s->chr_tag =
qemu_chr_add_handlers(s->cs, usb_serial_can_read, usb_serial_read,
- usb_serial_event, s);
+ usb_serial_event, s, NULL, errp);
+ if (s->chr_tag == -1) {
+ return;
+ }
+
usb_serial_handle_reset(dev);
if (s->cs->be_open && !dev->attached) {
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 7d73c93..6dcc56b 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -1410,7 +1410,11 @@ static void usbredir_realize(USBDevice *udev, Error
**errp)
/* Let the backend know we are ready */
dev->chr_tag =
qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,
- usbredir_chardev_read, usbredir_chardev_event, dev);
+ usbredir_chardev_read, usbredir_chardev_event,
+ dev, NULL, errp);
+ if (dev->chr_tag == -1) {
+ return;
+ }
qemu_add_vm_change_state_handler(usbredir_vm_state_change, dev);
}
diff --git a/monitor.c b/monitor.c
index 0d6f0ad..33e063e 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3964,7 +3964,7 @@ static void __attribute__((constructor))
monitor_lock_init(void)
qemu_mutex_init(&monitor_lock);
}
-void monitor_init(CharDriverState *chr, int flags)
+void monitor_init(CharDriverState *chr, int flags, Error **errp)
{
static int is_first_init = 1;
Monitor *mon;
@@ -3991,13 +3991,19 @@ void monitor_init(CharDriverState *chr, int flags)
if (monitor_is_qmp(mon)) {
mon->chr_tag =
qemu_chr_add_handlers(chr, monitor_can_read, monitor_qmp_read,
- monitor_qmp_event, mon);
+ monitor_qmp_event, mon, NULL, errp);
qemu_chr_fe_set_echo(chr, true);
json_message_parser_init(&mon->qmp.parser, handle_qmp_command);
} else {
mon->chr_tag =
qemu_chr_add_handlers(chr, monitor_can_read, monitor_read,
- monitor_event, mon);
+ monitor_event, mon, NULL, errp);
+ }
+
+ if (mon->chr_tag == -1) {
+ monitor_data_destroy(mon);
+ g_free(mon);
+ return;
}
qemu_mutex_lock(&monitor_lock);
diff --git a/net/colo-compare.c b/net/colo-compare.c
index 88582c8..58e894b 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -481,21 +481,36 @@ static void *colo_compare_thread(void *opaque)
GMainContext *worker_context;
GMainLoop *compare_loop;
CompareState *s = opaque;
+ Error *err = NULL;
worker_context = g_main_context_new();
s->chr_pri_tag =
- qemu_chr_add_handlers_full(s->chr_pri_in, compare_chr_can_read,
- compare_pri_chr_in, NULL, s,
worker_context);
+ qemu_chr_add_handlers(s->chr_pri_in, compare_chr_can_read,
+ compare_pri_chr_in, NULL, s,
+ worker_context, &err);
+ if (err) {
+ goto end;
+ }
+
s->chr_sec_tag =
- qemu_chr_add_handlers_full(s->chr_sec_in, compare_chr_can_read,
- compare_sec_chr_in, NULL, s,
worker_context);
+ qemu_chr_add_handlers(s->chr_sec_in, compare_chr_can_read,
+ compare_sec_chr_in, NULL, s,
+ worker_context, &err);
+ if (err) {
+ goto end;
+ }
compare_loop = g_main_loop_new(worker_context, FALSE);
g_main_loop_run(compare_loop);
g_main_loop_unref(compare_loop);
+
+end:
+ if (err) {
+ error_report_err(err);
+ }
g_main_context_unref(worker_context);
return NULL;
}
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
index 8c1d613..13ea039 100644
--- a/net/filter-mirror.c
+++ b/net/filter-mirror.c
@@ -258,7 +258,11 @@ static void filter_redirector_setup(NetFilterState *nf,
Error **errp)
qemu_chr_fe_claim_no_fail(s->chr_in);
s->chr_in_tag =
qemu_chr_add_handlers(s->chr_in, redirector_chr_can_read,
- redirector_chr_read, redirector_chr_event, nf);
+ redirector_chr_read, redirector_chr_event,
+ nf, NULL, errp);
+ if (s->chr_in_tag == -1) {
+ return;
+ }
}
if (s->outdev) {
diff --git a/net/slirp.c b/net/slirp.c
index 80eefb0..355c90c 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -40,6 +40,7 @@
#include "sysemu/char.h"
#include "sysemu/sysemu.h"
#include "qemu/cutils.h"
+#include "qapi/error.h"
static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
{
@@ -704,6 +705,7 @@ static void guestfwd_read(void *opaque, const uint8_t *buf,
int size)
static int slirp_guestfwd(SlirpState *s, const char *config_str,
int legacy_format)
{
+ Error *err = NULL;
struct in_addr server = { .s_addr = 0 };
struct GuestFwd *fwd;
const char *p;
@@ -768,7 +770,11 @@ static int slirp_guestfwd(SlirpState *s, const char
*config_str,
qemu_chr_fe_claim_no_fail(fwd->hd);
fwd->chr_tag =
qemu_chr_add_handlers(fwd->hd, guestfwd_can_read, guestfwd_read,
- NULL, fwd);
+ NULL, fwd, NULL, &err);
+ if (fwd->chr_tag < 0) {
+ error_report_err(err);
+ return -1;
+ }
}
return 0;
diff --git a/net/vhost-user.c b/net/vhost-user.c
index f3cf623..804ccb7 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -234,7 +234,7 @@ static void net_vhost_user_event(void *opaque, int event)
static int net_vhost_user_init(NetClientState *peer, const char *device,
const char *name, CharDriverState *chr,
- int queues)
+ int queues, Error **errp)
{
NetClientState *nc, *nc0 = NULL;
VhostUserState *s;
@@ -261,11 +261,13 @@ static int net_vhost_user_init(NetClientState *peer,
const char *device,
s = DO_UPCAST(VhostUserState, nc, nc0);
s->chr_tag =
qemu_chr_add_handlers(chr, NULL, NULL,
- net_vhost_user_event, nc0->name);
+ net_vhost_user_event, nc0->name, NULL, errp);
+ if (s->chr_tag == -1) {
+ return -1;
+ }
+
do {
- Error *err = NULL;
- if (qemu_chr_wait_connected(chr, &err) < 0) {
- error_report_err(err);
+ if (qemu_chr_wait_connected(chr, errp) < 0) {
return -1;
}
} while (!s->started);
@@ -351,5 +353,5 @@ int net_init_vhost_user(const Netdev *netdev, const char
*name,
return -1;
}
- return net_vhost_user_init(peer, "vhost_user", name, chr, queues);
+ return net_vhost_user_init(peer, "vhost_user", name, chr, queues, errp);
}
diff --git a/qemu-char.c b/qemu-char.c
index 261a8f9..775015b 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -487,20 +487,22 @@ qemu_chr_set_handlers(CharDriverState *s,
}
}
-static int mux_chr_new_handler_tag(CharDriverState *chr, GMainContext
*context);
+static int mux_chr_new_handler_tag(CharDriverState *chr, GMainContext *context,
+ Error **errp);
static void mux_set_focus(MuxDriver *d, int focus);
-int qemu_chr_add_handlers_full(CharDriverState *s,
- IOCanReadHandler *fd_can_read,
- IOReadHandler *fd_read,
- IOEventHandler *fd_event,
- void *opaque,
- GMainContext *context)
+int qemu_chr_add_handlers(CharDriverState *s,
+ IOCanReadHandler *fd_can_read,
+ IOReadHandler *fd_read,
+ IOEventHandler *fd_event,
+ void *opaque,
+ GMainContext *context,
+ Error **errp)
{
int tag = 0;
if (s->is_mux) {
- tag = mux_chr_new_handler_tag(s, context);
+ tag = mux_chr_new_handler_tag(s, context, errp);
if (tag < 0) {
return tag;
}
@@ -516,16 +518,6 @@ int qemu_chr_add_handlers_full(CharDriverState *s,
return tag;
}
-int qemu_chr_add_handlers(CharDriverState *s,
- IOCanReadHandler *fd_can_read,
- IOReadHandler *fd_read,
- IOEventHandler *fd_event,
- void *opaque)
-{
- return qemu_chr_add_handlers_full(s, fd_can_read, fd_read,
- fd_event, opaque, NULL);
-}
-
void qemu_chr_remove_handlers(CharDriverState *s, int tag)
{
if (tag < 0) {
@@ -841,21 +833,25 @@ static void mux_chr_close(struct CharDriverState *chr)
g_free(d);
}
-static int mux_chr_new_handler_tag(CharDriverState *chr, GMainContext *context)
+static int mux_chr_new_handler_tag(CharDriverState *chr, GMainContext *context,
+ Error **errp)
{
MuxDriver *d = chr->opaque;
if (d->mux_cnt >= MAX_MUX) {
- fprintf(stderr, "Cannot add I/O handlers, MUX array is full\n");
+ error_setg(errp, "Cannot add I/O handlers, MUX array is full");
return -1;
}
/* Fix up the real driver with mux routines */
if (d->mux_tag == -1) {
- d->mux_tag = qemu_chr_add_handlers_full(d->drv, mux_chr_can_read,
- mux_chr_read,
- mux_chr_event,
- chr, context);
+ d->mux_tag = qemu_chr_add_handlers(d->drv, mux_chr_can_read,
+ mux_chr_read,
+ mux_chr_event,
+ chr, context, errp);
+ if (d->mux_tag == -1) {
+ return -1;
+ }
}
return d->mux_cnt++;
@@ -4090,11 +4086,16 @@ CharDriverState *qemu_chr_new_noreplay(const char
*label, const char *filename,
chr = qemu_chr_new_from_opts(opts, init, &err);
if (err) {
- error_report_err(err);
+ goto end;
}
if (chr && qemu_opt_get_bool(opts, "mux", 0)) {
qemu_chr_fe_claim_no_fail(chr);
- monitor_init(chr, MONITOR_USE_READLINE);
+ monitor_init(chr, MONITOR_USE_READLINE, &err);
+ }
+
+end:
+ if (err) {
+ error_report_err(err);
}
qemu_opts_del(opts);
return chr;
diff --git a/qtest.c b/qtest.c
index 73e07c2..e3a2a99 100644
--- a/qtest.c
+++ b/qtest.c
@@ -680,8 +680,11 @@ void qtest_init(const char *qtest_chrdev, const char
*qtest_log, Error **errp)
qtest_log_fp = stderr;
}
- qtest_chr_tag =
- qemu_chr_add_handlers(chr, qtest_can_read, qtest_read, qtest_event,
chr);
+ qtest_chr_tag = qemu_chr_add_handlers(chr, qtest_can_read, qtest_read,
+ qtest_event, chr, NULL, errp);
+ if (qtest_chr_tag == -1) {
+ return;
+ }
qemu_chr_fe_set_echo(chr, true);
inbuf = g_string_new("");
diff --git a/stubs/monitor-init.c b/stubs/monitor-init.c
index de1bc7c..c24a76f 100644
--- a/stubs/monitor-init.c
+++ b/stubs/monitor-init.c
@@ -2,6 +2,6 @@
#include "qemu-common.h"
#include "monitor/monitor.h"
-void monitor_init(CharDriverState *chr, int flags)
+void monitor_init(CharDriverState *chr, int flags, Error **errp)
{
}
diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
index 133cbdc..2e349a8 100644
--- a/tests/vhost-user-test.c
+++ b/tests/vhost-user-test.c
@@ -11,6 +11,7 @@
#include "qemu/osdep.h"
#include "libqtest.h"
+#include "qapi/error.h"
#include "qemu/option.h"
#include "qemu/range.h"
#include "qemu/sockets.h"
@@ -461,7 +462,7 @@ static void test_server_create_chr(TestServer *server,
const gchar *opt)
server->chr_tag =
qemu_chr_add_handlers(server->chr, chr_can_read, chr_read,
- chr_event, server);
+ chr_event, server, NULL, &error_abort);
}
static void test_server_listen(TestServer *server)
diff --git a/vl.c b/vl.c
index c657acd..bab77e0 100644
--- a/vl.c
+++ b/vl.c
@@ -2418,7 +2418,7 @@ static int mon_init_func(void *opaque, QemuOpts *opts,
Error **errp)
}
qemu_chr_fe_claim_no_fail(chr);
- monitor_init(chr, flags);
+ monitor_init(chr, flags, errp);
return 0;
}
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index a714d8e..7d31d1b 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -16,7 +16,7 @@ extern Monitor *cur_mon;
bool monitor_cur_is_qmp(void);
-void monitor_init(CharDriverState *chr, int flags);
+void monitor_init(CharDriverState *chr, int flags, Error **errp);
void monitor_cleanup(void);
int monitor_suspend(Monitor *mon);
diff --git a/include/sysemu/char.h b/include/sysemu/char.h
index 9632dbb..2c2083d 100644
--- a/include/sysemu/char.h
+++ b/include/sysemu/char.h
@@ -441,19 +441,12 @@ void qemu_chr_be_event(CharDriverState *s, int event);
*/
G_GNUC_WARN_UNUSED_RESULT
int qemu_chr_add_handlers(CharDriverState *s,
- IOCanReadHandler *fd_can_read,
- IOReadHandler *fd_read,
- IOEventHandler *fd_event,
- void *opaque);
-
-/* This API can make handler run in the context what you pass to. */
-G_GNUC_WARN_UNUSED_RESULT
-int qemu_chr_add_handlers_full(CharDriverState *s,
- IOCanReadHandler *fd_can_read,
- IOReadHandler *fd_read,
- IOEventHandler *fd_event,
- void *opaque,
- GMainContext *context);
+ IOCanReadHandler *fd_can_read,
+ IOReadHandler *fd_read,
+ IOEventHandler *fd_event,
+ void *opaque,
+ GMainContext *context,
+ Error **errp);
/**
* @qemu_chr_remove_handlers:
--
2.10.0
- [Qemu-devel] [PATCH 0/9] Fix mux regression (commit 949055a2), Marc-André Lureau, 2016/10/13
- [Qemu-devel] [PATCH 1/9] Revert "char: use a fixed idx for child muxed chr", Marc-André Lureau, 2016/10/13
- [Qemu-devel] [PATCH 2/9] char: return a tag when adding the fe handlers, Marc-André Lureau, 2016/10/13
- [Qemu-devel] [PATCH 3/9] char: add qemu_chr_remove_handlers(), Marc-André Lureau, 2016/10/13
- [Qemu-devel] [PATCH 5/9] char: warn on unused qemu_chr_add_handlers() result, Marc-André Lureau, 2016/10/13
- [Qemu-devel] [PATCH 4/9] char: keep track of qemu_chr_add_handlers(), Marc-André Lureau, 2016/10/13
- [Qemu-devel] [PATCH 6/9] qdev: remove call to qemu_chr_add_handlers(), Marc-André Lureau, 2016/10/13
- [Qemu-devel] [PATCH 8/9] ringbuf: fix chr_write return value, Marc-André Lureau, 2016/10/13
- [Qemu-devel] [PATCH 7/9] char: handle qemu_chr_add_handlers() error,
Marc-André Lureau <=
- [Qemu-devel] [PATCH 9/9] tests: start chardev unit tests, Marc-André Lureau, 2016/10/13
- Re: [Qemu-devel] [PATCH 0/9] Fix mux regression (commit 949055a2), Paolo Bonzini, 2016/10/13
- Re: [Qemu-devel] [PATCH 0/9] Fix mux regression (commit 949055a2), Peter Maydell, 2016/10/13