Raise or assert on qemu_chr_add_handlers() error. Signed-off-by: Marc-André Lureau <marcandre.lur...@redhat.com> --- 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