diff --git a/backends/rng-egd.c b/backends/rng-egd.c index 0f6d0af278..e2f8189d62 100644 --- a/backends/rng-egd.c +++ b/backends/rng-egd.c @@ -23,7 +23,7 @@ typedef struct RngEgd { RngBackend parent; - CharDriverState *chr; + CharBackend chr; char *chr_name; } RngEgd; @@ -42,7 +42,7 @@ static void rng_egd_request_entropy(RngBackend *b, RngRequest *req) /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(s->chr, header, sizeof(header)); + qemu_chr_fe_write_all(s->chr.chr, header, sizeof(header)); size -= len; } @@ -86,6 +86,7 @@ static void rng_egd_chr_read(void *opaque, const uint8_t *buf, int size) static void rng_egd_opened(RngBackend *b, Error **errp) { RngEgd *s = RNG_EGD(b); + CharDriverState *chr; if (s->chr_name == NULL) { error_setg(errp, QERR_INVALID_PARAMETER_VALUE, @@ -93,21 +94,23 @@ static void rng_egd_opened(RngBackend *b, Error **errp) return; } - s->chr = qemu_chr_find(s->chr_name); - if (s->chr == NULL) { + chr = qemu_chr_find(s->chr_name); + if (chr == NULL) { error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, "Device '%s' not found", s->chr_name); return; } - - if (qemu_chr_fe_claim(s->chr) != 0) { + if (qemu_chr_fe_claim(chr) != 0) { error_setg(errp, QERR_DEVICE_IN_USE, s->chr_name); return; } + if (!qemu_chr_fe_init(&s->chr, chr, errp)) { + return; + } /* FIXME we should resubmit pending requests when the CDS reconnects. */ - qemu_chr_add_handlers(s->chr, rng_egd_chr_can_read, rng_egd_chr_read, - NULL, s); + qemu_chr_add_handlers(s->chr.chr, rng_egd_chr_can_read, + rng_egd_chr_read, NULL, s); } static void rng_egd_set_chardev(Object *obj, const char *value, Error **errp) @@ -127,8 +130,8 @@ static char *rng_egd_get_chardev(Object *obj, Error **errp) { RngEgd *s = RNG_EGD(obj); - if (s->chr && s->chr->label) { - return g_strdup(s->chr->label); + if (s->chr.chr && s->chr.chr->label) { + return g_strdup(s->chr.chr->label); } return NULL; @@ -145,9 +148,9 @@ static void rng_egd_finalize(Object *obj) { RngEgd *s = RNG_EGD(obj); - if (s->chr) { - qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL); - qemu_chr_fe_release(s->chr); + if (s->chr.chr) { + qemu_chr_add_handlers(s->chr.chr, NULL, NULL, NULL, NULL); + qemu_chr_fe_release(s->chr.chr); } g_free(s->chr_name); diff --git a/gdbstub.c b/gdbstub.c index 2fe71caba4..347bd4de51 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -303,7 +303,7 @@ typedef struct GDBState { int fd; int running_state; #else - CharDriverState *chr; + CharBackend chr; CharDriverState *mon_chr; #endif char syscall_buf[256]; @@ -404,7 +404,7 @@ static void put_buffer(GDBState *s, const uint8_t *buf, int len) #else /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(s->chr, buf, len); + qemu_chr_fe_write_all(s->chr.chr, buf, len); #endif } @@ -1481,7 +1481,7 @@ void gdb_exit(CPUArchState *env, int code) return; } #else - if (!s->chr) { + if (!s->chr.chr) { return; } #endif @@ -1490,7 +1490,7 @@ void gdb_exit(CPUArchState *env, int code) put_packet(s, buf); #ifndef CONFIG_USER_ONLY - qemu_chr_delete(s->chr); + qemu_chr_delete(s->chr.chr); #endif } @@ -1750,8 +1750,6 @@ int gdbserver_start(const char *device) return -1; qemu_chr_fe_claim_no_fail(chr); - qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive, - gdb_chr_event, NULL); } s = gdbserver_state; @@ -1766,14 +1764,20 @@ int gdbserver_start(const char *device) mon_chr->chr_write = gdb_monitor_write; monitor_init(mon_chr, 0); } else { - if (s->chr) - qemu_chr_delete(s->chr); + if (s->chr.chr) { + qemu_chr_delete(s->chr.chr); + } mon_chr = s->mon_chr; memset(s, 0, sizeof(GDBState)); + s->mon_chr = mon_chr; } s->c_cpu = first_cpu; s->g_cpu = first_cpu; - s->chr = chr; + if (chr) { + qemu_chr_fe_init(&s->chr, chr, &error_abort); + qemu_chr_add_handlers(s->chr.chr, gdb_chr_can_receive, gdb_chr_receive, + gdb_chr_event, NULL); + } s->state = chr ? RS_IDLE : RS_INACTIVE; s->mon_chr = mon_chr; s->current_syscall_cb = NULL; diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c index 0b2a355f04..43d9c4b1f0 100644 --- a/hw/arm/omap2.c +++ b/hw/arm/omap2.c @@ -621,7 +621,7 @@ struct omap_sti_s { qemu_irq irq; MemoryRegion iomem; MemoryRegion iomem_fifo; - CharDriverState *chr; + CharBackend chr; uint32_t sysconfig; uint32_t systest; @@ -771,14 +771,14 @@ static void omap_sti_fifo_write(void *opaque, hwaddr addr, /* Flush channel value. */ /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(s->chr, (const uint8_t *) "\r", 1); + qemu_chr_fe_write_all(s->chr.chr, (const uint8_t *) "\r", 1); } else if (ch == STI_TRACE_CONSOLE_CHANNEL || 1) { if (value == 0xc0 || value == 0xc3) { /* Open channel ch. */ } else if (value == 0x00) - qemu_chr_fe_write_all(s->chr, (const uint8_t *) "\n", 1); + qemu_chr_fe_write_all(s->chr.chr, (const uint8_t *) "\n", 1); else - qemu_chr_fe_write_all(s->chr, &byte, 1); + qemu_chr_fe_write_all(s->chr.chr, &byte, 1); } } @@ -798,7 +798,8 @@ static struct omap_sti_s *omap_sti_init(struct omap_target_agent_s *ta, s->irq = irq; omap_sti_reset(s); - s->chr = chr ?: qemu_chr_new("null", "null"); + qemu_chr_fe_init(&s->chr, chr ?: qemu_chr_new("null", "null"), + &error_abort); memory_region_init_io(&s->iomem, NULL, &omap_sti_ops, s, "omap.sti", omap_l4_region_size(ta, 0)); diff --git a/hw/char/mcf_uart.c b/hw/char/mcf_uart.c index c184859c83..436e1b0228 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; @@ -26,7 +27,7 @@ typedef struct { int tx_enabled; int rx_enabled; qemu_irq irq; - CharDriverState *chr; + CharBackend chr; } mcf_uart_state; /* UART Status Register bits. */ @@ -92,7 +93,7 @@ uint64_t mcf_uart_read(void *opaque, hwaddr addr, if (s->fifo_len == 0) s->sr &= ~MCF_UART_RxRDY; mcf_uart_update(s); - qemu_chr_accept_input(s->chr); + qemu_chr_accept_input(s->chr.chr); return val; } case 0x10: @@ -113,10 +114,11 @@ uint64_t mcf_uart_read(void *opaque, hwaddr addr, static void mcf_uart_do_tx(mcf_uart_state *s) { if (s->tx_enabled && (s->sr & MCF_UART_TxEMP) == 0) { - if (s->chr) + if (s->chr.chr) { /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(s->chr, (unsigned char *)&s->tb, 1); + qemu_chr_fe_write_all(s->chr.chr, (unsigned char *)&s->tb, 1); + } s->sr |= MCF_UART_TxEMP; } if (s->tx_enabled) { @@ -280,9 +282,9 @@ void *mcf_uart_init(qemu_irq irq, CharDriverState *chr) mcf_uart_state *s; s = g_malloc0(sizeof(mcf_uart_state)); - s->chr = chr; s->irq = irq; if (chr) { + qemu_chr_fe_init(&s->chr, chr, &error_abort); qemu_chr_fe_claim_no_fail(chr); qemu_chr_add_handlers(chr, mcf_uart_can_receive, mcf_uart_receive, mcf_uart_event, s); diff --git a/hw/char/sh_serial.c b/hw/char/sh_serial.c index 97ce5629a4..c8b91bbaa2 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 @@ -62,7 +63,7 @@ typedef struct { int flags; int rtrg; - CharDriverState *chr; + CharBackend chr; qemu_irq eri; qemu_irq rxi; @@ -109,11 +110,11 @@ static void sh_serial_write(void *opaque, hwaddr offs, } return; case 0x0c: /* FTDR / TDR */ - if (s->chr) { + if (s->chr.chr) { ch = val; /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(s->chr, &ch, 1); + qemu_chr_fe_write_all(s->chr.chr, &ch, 1); } s->dr = val; s->flags &= ~SH_SERIAL_FLAG_TDE; @@ -395,10 +396,9 @@ void sh_serial_init(MemoryRegion *sysmem, 0, 0x28); memory_region_add_subregion(sysmem, A7ADDR(base), &s->iomem_a7); - s->chr = chr; - if (chr) { qemu_chr_fe_claim_no_fail(chr); + qemu_chr_fe_init(&s->chr, chr, &error_abort); qemu_chr_add_handlers(chr, sh_serial_can_receive1, sh_serial_receive1, sh_serial_event, s); } diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c index 11bf6a44cf..c1d36dc2d0 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 @@ -43,7 +44,7 @@ struct XenConsole { char console[XEN_BUFSIZE]; int ring_ref; void *sring; - CharDriverState *chr; + CharBackend chr; int backlog; }; @@ -148,11 +149,13 @@ static void xencons_send(struct XenConsole *con) ssize_t len, size; size = con->buffer.size - con->buffer.consumed; - if (con->chr) - len = qemu_chr_fe_write(con->chr, con->buffer.data + con->buffer.consumed, - size); - else + if (con->chr.chr) { + len = qemu_chr_fe_write(con->chr.chr, + con->buffer.data + con->buffer.consumed, + size); + } else { len = size; + } if (len < 1) { if (!con->backlog) { con->backlog = 1; @@ -196,13 +199,17 @@ static int con_init(struct XenDevice *xendev) /* no Xen override, use qemu output device */ if (output == NULL) { - con->chr = serial_hds[con->xendev.dev]; + if (con->xendev.dev) { + qemu_chr_fe_init(&con->chr, serial_hds[con->xendev.dev], + &error_abort); + } } else { snprintf(label, sizeof(label), "xencons%d", con->xendev.dev); - con->chr = qemu_chr_new(label, output); + qemu_chr_fe_init(&con->chr, + qemu_chr_new(label, output), &error_abort); } - xenstore_store_pv_console_info(con->xendev.dev, con->chr); + xenstore_store_pv_console_info(con->xendev.dev, con->chr.chr); out: g_free(type); @@ -235,15 +242,15 @@ static int con_initialise(struct XenDevice *xendev) return -1; xen_be_bind_evtchn(&con->xendev); - if (con->chr) { - if (qemu_chr_fe_claim(con->chr) == 0) { - qemu_chr_add_handlers(con->chr, xencons_can_receive, + if (con->chr.chr) { + if (qemu_chr_fe_claim(con->chr.chr) == 0) { + qemu_chr_add_handlers(con->chr.chr, xencons_can_receive, xencons_receive, NULL, con); } else { xen_be_printf(xendev, 0, "xen_console_init error chardev %s already used\n", - con->chr->label); - con->chr = NULL; + con->chr.chr->label); + con->chr.chr = NULL; } } @@ -259,9 +266,9 @@ static void con_disconnect(struct XenDevice *xendev) { struct XenConsole *con = container_of(xendev, struct XenConsole, xendev); - if (con->chr) { - qemu_chr_add_handlers(con->chr, NULL, NULL, NULL, NULL); - qemu_chr_fe_release(con->chr); + if (con->chr.chr) { + qemu_chr_add_handlers(con->chr.chr, NULL, NULL, NULL, NULL); + qemu_chr_fe_release(con->chr.chr); } xen_be_unbind_evtchn(&con->xendev); diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index ed0850c70c..d5601b18cb 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -85,7 +85,7 @@ typedef struct { uint32_t i2coe; uint32_t i2cout; uint32_t i2csel; - CharDriverState *display; + CharBackend display; char display_text[9]; SerialState *uart; bool display_inited; @@ -125,8 +125,10 @@ static void malta_fpga_update_display(void *opaque) } leds_text[8] = '\0'; - qemu_chr_fe_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text); - qemu_chr_fe_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text); + qemu_chr_fe_printf(s->display.chr, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", + leds_text); + qemu_chr_fe_printf(s->display.chr, "\n\n\n\n|\e[31m%-8.8s\e[00m|", + s->display_text); } /* @@ -536,15 +538,15 @@ static void malta_fgpa_display_event(void *opaque, int event) MaltaFPGAState *s = opaque; if (event == CHR_EVENT_OPENED && !s->display_inited) { - qemu_chr_fe_printf(s->display, "\e[HMalta LEDBAR\r\n"); - qemu_chr_fe_printf(s->display, "+--------+\r\n"); - qemu_chr_fe_printf(s->display, "+ +\r\n"); - qemu_chr_fe_printf(s->display, "+--------+\r\n"); - qemu_chr_fe_printf(s->display, "\n"); - qemu_chr_fe_printf(s->display, "Malta ASCII\r\n"); - qemu_chr_fe_printf(s->display, "+--------+\r\n"); - qemu_chr_fe_printf(s->display, "+ +\r\n"); - qemu_chr_fe_printf(s->display, "+--------+\r\n"); + qemu_chr_fe_printf(s->display.chr, "\e[HMalta LEDBAR\r\n"); + qemu_chr_fe_printf(s->display.chr, "+--------+\r\n"); + qemu_chr_fe_printf(s->display.chr, "+ +\r\n"); + qemu_chr_fe_printf(s->display.chr, "+--------+\r\n"); + qemu_chr_fe_printf(s->display.chr, "\n"); + qemu_chr_fe_printf(s->display.chr, "Malta ASCII\r\n"); + qemu_chr_fe_printf(s->display.chr, "+--------+\r\n"); + qemu_chr_fe_printf(s->display.chr, "+ +\r\n"); + qemu_chr_fe_printf(s->display.chr, "+--------+\r\n"); s->display_inited = true; } } @@ -553,6 +555,7 @@ static MaltaFPGAState *malta_fpga_init(MemoryRegion *address_space, hwaddr base, qemu_irq uart_irq, CharDriverState *uart_chr) { MaltaFPGAState *s; + CharDriverState *chr; s = (MaltaFPGAState *)g_malloc0(sizeof(MaltaFPGAState)); @@ -566,8 +569,9 @@ static MaltaFPGAState *malta_fpga_init(MemoryRegion *address_space, memory_region_add_subregion(address_space, base, &s->iomem_lo); memory_region_add_subregion(address_space, base + 0xa00, &s->iomem_hi); - s->display = qemu_chr_new("fpga", "vc:320x200"); - qemu_chr_add_handlers(s->display, NULL, NULL, + chr = qemu_chr_new("fpga", "vc:320x200"); + qemu_chr_fe_init(&s->display, chr, &error_abort); + qemu_chr_add_handlers(s->display.chr, NULL, NULL, malta_fgpa_display_event, s); s->uart = serial_mm_init(address_space, base + 0x900, 3, uart_irq, diff --git a/monitor.c b/monitor.c index 8728dd9fa5..40712f7046 100644 --- a/monitor.c +++ b/monitor.c @@ -186,7 +186,7 @@ typedef struct { } MonitorQAPIEventConf; struct Monitor { - CharDriverState *chr; + CharBackend chr; int reset_seen; int flags; int suspend_cnt; @@ -297,7 +297,7 @@ static void monitor_flush_locked(Monitor *mon) len = qstring_get_length(mon->outbuf); if (len && !mon->mux_out) { - rc = qemu_chr_fe_write(mon->chr, (const uint8_t *) buf, len); + rc = qemu_chr_fe_write(mon->chr.chr, (const uint8_t *) buf, len); if ((rc < 0 && errno != EAGAIN) || (rc == len)) { /* all flushed or error */ QDECREF(mon->outbuf); @@ -311,8 +311,9 @@ static void monitor_flush_locked(Monitor *mon) mon->outbuf = tmp; } if (mon->out_watch == 0) { - mon->out_watch = qemu_chr_fe_add_watch(mon->chr, G_IO_OUT|G_IO_HUP, - monitor_unblocked, mon); + mon->out_watch = + qemu_chr_fe_add_watch(mon->chr.chr, G_IO_OUT | G_IO_HUP, + monitor_unblocked, mon); } } } @@ -581,8 +582,8 @@ static void monitor_data_init(Monitor *mon) static void monitor_data_destroy(Monitor *mon) { - if (mon->chr) { - qemu_chr_add_handlers(mon->chr, NULL, NULL, NULL, NULL); + if (mon->chr.chr) { + qemu_chr_add_handlers(mon->chr.chr, NULL, NULL, NULL, NULL); } if (monitor_is_qmp(mon)) { json_message_parser_destroy(&mon->qmp.parser); @@ -1745,7 +1746,7 @@ void qmp_getfd(const char *fdname, Error **errp) mon_fd_t *monfd; int fd; - fd = qemu_chr_fe_get_msgfd(cur_mon->chr); + fd = qemu_chr_fe_get_msgfd(cur_mon->chr.chr); if (fd == -1) { error_setg(errp, QERR_FD_NOT_SUPPLIED); return; @@ -1870,7 +1871,7 @@ AddfdInfo *qmp_add_fd(bool has_fdset_id, int64_t fdset_id, bool has_opaque, Monitor *mon = cur_mon; AddfdInfo *fdinfo; - fd = qemu_chr_fe_get_msgfd(mon->chr); + fd = qemu_chr_fe_get_msgfd(mon->chr.chr); if (fd == -1) { error_setg(errp, QERR_FD_NOT_SUPPLIED); goto error; @@ -3977,7 +3978,7 @@ void monitor_init(CharDriverState *chr, int flags) mon = g_malloc(sizeof(*mon)); monitor_data_init(mon); - mon->chr = chr; + qemu_chr_fe_init(&mon->chr, chr, &error_abort); mon->flags = flags; if (flags & MONITOR_USE_READLINE) { mon->rs = readline_init(monitor_readline_printf, diff --git a/net/colo-compare.c b/net/colo-compare.c index 47703c59bc..efcd15e9ae 100644 --- a/net/colo-compare.c +++ b/net/colo-compare.c @@ -68,9 +68,9 @@ typedef struct CompareState { char *pri_indev; char *sec_indev; char *outdev; - CharDriverState *chr_pri_in; - CharDriverState *chr_sec_in; - CharDriverState *chr_out; + CharBackend chr_pri_in; + CharBackend chr_sec_in; + CharBackend chr_out; SocketReadState pri_rs; SocketReadState sec_rs; @@ -385,7 +385,7 @@ static void colo_compare_connection(void *opaque, void *user_data) } if (result) { - ret = compare_chr_send(s->chr_out, pkt->data, pkt->size); + ret = compare_chr_send(s->chr_out.chr, pkt->data, pkt->size); if (ret < 0) { error_report("colo_send_primary_packet failed"); } @@ -451,7 +451,7 @@ static void compare_pri_chr_in(void *opaque, const uint8_t *buf, int size) ret = net_fill_rstate(&s->pri_rs, buf, size); if (ret == -1) { - qemu_chr_add_handlers(s->chr_pri_in, NULL, NULL, NULL, NULL); + qemu_chr_add_handlers(s->chr_pri_in.chr, NULL, NULL, NULL, NULL); error_report("colo-compare primary_in error"); } } @@ -467,7 +467,7 @@ static void compare_sec_chr_in(void *opaque, const uint8_t *buf, int size) ret = net_fill_rstate(&s->sec_rs, buf, size); if (ret == -1) { - qemu_chr_add_handlers(s->chr_sec_in, NULL, NULL, NULL, NULL); + qemu_chr_add_handlers(s->chr_sec_in.chr, NULL, NULL, NULL, NULL); error_report("colo-compare secondary_in error"); } } @@ -480,9 +480,9 @@ static void *colo_compare_thread(void *opaque) worker_context = g_main_context_new(); - qemu_chr_add_handlers_full(s->chr_pri_in, compare_chr_can_read, + qemu_chr_add_handlers_full(s->chr_pri_in.chr, compare_chr_can_read, compare_pri_chr_in, NULL, s, worker_context); - qemu_chr_add_handlers_full(s->chr_sec_in, compare_chr_can_read, + qemu_chr_add_handlers_full(s->chr_sec_in.chr, compare_chr_can_read, compare_sec_chr_in, NULL, s, worker_context); compare_loop = g_main_loop_new(worker_context, FALSE); @@ -545,7 +545,7 @@ static void compare_pri_rs_finalize(SocketReadState *pri_rs) if (packet_enqueue(s, PRIMARY_IN)) { trace_colo_compare_main("primary: unsupported packet in"); - compare_chr_send(s->chr_out, pri_rs->buf, pri_rs->packet_len); + compare_chr_send(s->chr_out.chr, pri_rs->buf, pri_rs->packet_len); } else { /* compare connection */ g_queue_foreach(&s->conn_list, colo_compare_connection, s); @@ -634,23 +634,23 @@ static void colo_compare_complete(UserCreatable *uc, Error **errp) return; } - if (find_and_check_chardev(&s->chr_pri_in, s->pri_indev, errp)) { + if (find_and_check_chardev(&s->chr_pri_in.chr, s->pri_indev, errp)) { return; } - if (find_and_check_chardev(&s->chr_sec_in, s->sec_indev, errp)) { + if (find_and_check_chardev(&s->chr_sec_in.chr, s->sec_indev, errp)) { return; } - if (find_and_check_chardev(&s->chr_out, s->outdev, errp)) { + if (find_and_check_chardev(&s->chr_out.chr, s->outdev, errp)) { return; } - qemu_chr_fe_claim_no_fail(s->chr_pri_in); + qemu_chr_fe_claim_no_fail(s->chr_pri_in.chr); - qemu_chr_fe_claim_no_fail(s->chr_sec_in); + qemu_chr_fe_claim_no_fail(s->chr_sec_in.chr); - qemu_chr_fe_claim_no_fail(s->chr_out); + qemu_chr_fe_claim_no_fail(s->chr_out.chr); net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize); net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize); @@ -702,16 +702,16 @@ static void colo_compare_finalize(Object *obj) { CompareState *s = COLO_COMPARE(obj); - if (s->chr_pri_in) { - qemu_chr_add_handlers(s->chr_pri_in, NULL, NULL, NULL, NULL); - qemu_chr_fe_release(s->chr_pri_in); + if (s->chr_pri_in.chr) { + qemu_chr_add_handlers(s->chr_pri_in.chr, NULL, NULL, NULL, NULL); + qemu_chr_fe_release(s->chr_pri_in.chr); } - if (s->chr_sec_in) { - qemu_chr_add_handlers(s->chr_sec_in, NULL, NULL, NULL, NULL); - qemu_chr_fe_release(s->chr_sec_in); + if (s->chr_sec_in.chr) { + qemu_chr_add_handlers(s->chr_sec_in.chr, NULL, NULL, NULL, NULL); + qemu_chr_fe_release(s->chr_sec_in.chr); } - if (s->chr_out) { - qemu_chr_fe_release(s->chr_out); + if (s->chr_out.chr) { + qemu_chr_fe_release(s->chr_out.chr); } g_queue_free(&s->conn_list); diff --git a/net/filter-mirror.c b/net/filter-mirror.c index 0ee58d905e..425e146e9e 100644 --- a/net/filter-mirror.c +++ b/net/filter-mirror.c @@ -38,8 +38,8 @@ typedef struct MirrorState { NetFilterState parent_obj; char *indev; char *outdev; - CharDriverState *chr_in; - CharDriverState *chr_out; + CharBackend chr_in; + CharBackend chr_out; SocketReadState rs; } MirrorState; @@ -110,7 +110,7 @@ static void redirector_chr_read(void *opaque, const uint8_t *buf, int size) ret = net_fill_rstate(&s->rs, buf, size); if (ret == -1) { - qemu_chr_add_handlers(s->chr_in, NULL, NULL, NULL, NULL); + qemu_chr_add_handlers(s->chr_in.chr, NULL, NULL, NULL, NULL); } } @@ -121,7 +121,7 @@ static void redirector_chr_event(void *opaque, int event) switch (event) { case CHR_EVENT_CLOSED: - qemu_chr_add_handlers(s->chr_in, NULL, NULL, NULL, NULL); + qemu_chr_add_handlers(s->chr_in.chr, NULL, NULL, NULL, NULL); break; default: break; @@ -138,7 +138,7 @@ static ssize_t filter_mirror_receive_iov(NetFilterState *nf, MirrorState *s = FILTER_MIRROR(nf); int ret; - ret = filter_mirror_send(s->chr_out, iov, iovcnt); + ret = filter_mirror_send(s->chr_out.chr, iov, iovcnt); if (ret) { error_report("filter_mirror_send failed(%s)", strerror(-ret)); } @@ -160,8 +160,8 @@ static ssize_t filter_redirector_receive_iov(NetFilterState *nf, MirrorState *s = FILTER_REDIRECTOR(nf); int ret; - if (s->chr_out) { - ret = filter_mirror_send(s->chr_out, iov, iovcnt); + if (s->chr_out.chr) { + ret = filter_mirror_send(s->chr_out.chr, iov, iovcnt); if (ret) { error_report("filter_mirror_send failed(%s)", strerror(-ret)); } @@ -175,8 +175,8 @@ static void filter_mirror_cleanup(NetFilterState *nf) { MirrorState *s = FILTER_MIRROR(nf); - if (s->chr_out) { - qemu_chr_fe_release(s->chr_out); + if (s->chr_out.chr) { + qemu_chr_fe_release(s->chr_out.chr); } } @@ -184,18 +184,19 @@ static void filter_redirector_cleanup(NetFilterState *nf) { MirrorState *s = FILTER_REDIRECTOR(nf); - if (s->chr_in) { - qemu_chr_add_handlers(s->chr_in, NULL, NULL, NULL, NULL); - qemu_chr_fe_release(s->chr_in); + if (s->chr_in.chr) { + qemu_chr_add_handlers(s->chr_in.chr, NULL, NULL, NULL, NULL); + qemu_chr_fe_release(s->chr_in.chr); } - if (s->chr_out) { - qemu_chr_fe_release(s->chr_out); + if (s->chr_out.chr) { + qemu_chr_fe_release(s->chr_out.chr); } } static void filter_mirror_setup(NetFilterState *nf, Error **errp) { MirrorState *s = FILTER_MIRROR(nf); + CharDriverState *chr; if (!s->outdev) { error_setg(errp, "filter mirror needs 'outdev' " @@ -203,17 +204,19 @@ static void filter_mirror_setup(NetFilterState *nf, Error **errp) return; } - s->chr_out = qemu_chr_find(s->outdev); - if (s->chr_out == NULL) { + chr = qemu_chr_find(s->outdev); + if (chr == NULL) { error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, "Device '%s' not found", s->outdev); return; } - if (qemu_chr_fe_claim(s->chr_out) != 0) { + if (qemu_chr_fe_claim(chr) != 0) { error_setg(errp, QERR_DEVICE_IN_USE, s->outdev); return; } + + qemu_chr_fe_init(&s->chr_out, chr, errp); } static void redirector_rs_finalize(SocketReadState *rs) @@ -227,6 +230,7 @@ static void redirector_rs_finalize(SocketReadState *rs) static void filter_redirector_setup(NetFilterState *nf, Error **errp) { MirrorState *s = FILTER_REDIRECTOR(nf); + CharDriverState *chr; if (!s->indev && !s->outdev) { error_setg(errp, "filter redirector needs 'indev' or " @@ -243,26 +247,32 @@ static void filter_redirector_setup(NetFilterState *nf, Error **errp) net_socket_rs_init(&s->rs, redirector_rs_finalize); if (s->indev) { - s->chr_in = qemu_chr_find(s->indev); - if (s->chr_in == NULL) { + chr = qemu_chr_find(s->indev); + if (chr == NULL) { error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, "IN Device '%s' not found", s->indev); return; } - qemu_chr_fe_claim_no_fail(s->chr_in); - qemu_chr_add_handlers(s->chr_in, redirector_chr_can_read, + qemu_chr_fe_claim_no_fail(chr); + if (!qemu_chr_fe_init(&s->chr_in, chr, errp)) { + return; + } + qemu_chr_add_handlers(s->chr_in.chr, redirector_chr_can_read, redirector_chr_read, redirector_chr_event, nf); } if (s->outdev) { - s->chr_out = qemu_chr_find(s->outdev); - if (s->chr_out == NULL) { + chr = qemu_chr_find(s->outdev); + if (chr == NULL) { error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, "OUT Device '%s' not found", s->outdev); return; } - qemu_chr_fe_claim_no_fail(s->chr_out); + qemu_chr_fe_claim_no_fail(chr); + if (!qemu_chr_fe_init(&s->chr_out, chr, errp)) { + return; + } } } diff --git a/net/slirp.c b/net/slirp.c index f9fdff5fb9..407e8aa704 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) { @@ -682,7 +683,7 @@ int net_slirp_smb(const char *exported_dir) #endif /* !defined(_WIN32) */ struct GuestFwd { - CharDriverState *hd; + CharBackend hd; struct in_addr server; int port; Slirp *slirp; @@ -746,15 +747,23 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str, return -1; } } else { - fwd = g_new(struct GuestFwd, 1); - fwd->hd = qemu_chr_new(buf, p); - if (!fwd->hd) { + Error *err = NULL; + CharDriverState *chr = qemu_chr_new(buf, p); + + if (!chr) { error_report("could not open guest forwarding device '%s'", buf); + return -1; + } + + fwd = g_new(struct GuestFwd, 1); + qemu_chr_fe_init(&fwd->hd, chr, &err); + if (err) { + error_report_err(err); g_free(fwd); return -1; } - if (slirp_add_exec(s->slirp, 3, fwd->hd, &server, port) < 0) { + if (slirp_add_exec(s->slirp, 3, fwd->hd.chr, &server, port) < 0) { error_report("conflicting/invalid host:port in guest forwarding " "rule '%s'", config_str); g_free(fwd); @@ -764,8 +773,8 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str, fwd->port = port; fwd->slirp = s->slirp; - qemu_chr_fe_claim_no_fail(fwd->hd); - qemu_chr_add_handlers(fwd->hd, guestfwd_can_read, guestfwd_read, + qemu_chr_fe_claim_no_fail(fwd->hd.chr); + qemu_chr_add_handlers(fwd->hd.chr, guestfwd_can_read, guestfwd_read, NULL, fwd); } return 0; diff --git a/net/vhost-user.c b/net/vhost-user.c index 5b94c84541..957459f493 100644 --- a/net/vhost-user.c +++ b/net/vhost-user.c @@ -20,7 +20,7 @@ typedef struct VhostUserState { NetClientState nc; - CharDriverState *chr; + CharBackend chr; VHostNetState *vhost_net; guint watch; uint64_t acked_features; @@ -78,7 +78,7 @@ static int vhost_user_start(int queues, NetClientState *ncs[]) s = DO_UPCAST(VhostUserState, nc, ncs[i]); options.net_backend = ncs[i]; - options.opaque = s->chr; + options.opaque = s->chr.chr; options.busyloop_timeout = 0; net = vhost_net_init(&options); if (!net) { @@ -150,10 +150,10 @@ static void vhost_user_cleanup(NetClientState *nc) g_free(s->vhost_net); s->vhost_net = NULL; } - if (s->chr) { - qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL); - qemu_chr_fe_release(s->chr); - s->chr = NULL; + if (s->chr.chr) { + qemu_chr_add_handlers(s->chr.chr, NULL, NULL, NULL, NULL); + qemu_chr_fe_release(s->chr.chr); + s->chr.chr = NULL; } qemu_purge_queued_packets(nc); @@ -187,7 +187,7 @@ static gboolean net_vhost_user_watch(GIOChannel *chan, GIOCondition cond, { VhostUserState *s = opaque; - qemu_chr_disconnect(s->chr); + qemu_chr_disconnect(s->chr.chr); return FALSE; } @@ -206,13 +206,13 @@ static void net_vhost_user_event(void *opaque, int event) assert(queues < MAX_QUEUE_NUM); s = DO_UPCAST(VhostUserState, nc, ncs[0]); - trace_vhost_user_event(s->chr->label, event); + trace_vhost_user_event(s->chr.chr->label, event); switch (event) { case CHR_EVENT_OPENED: - s->watch = qemu_chr_fe_add_watch(s->chr, G_IO_HUP, + s->watch = qemu_chr_fe_add_watch(s->chr.chr, G_IO_HUP, net_vhost_user_watch, s); if (vhost_user_start(queues, ncs) < 0) { - qemu_chr_disconnect(s->chr); + qemu_chr_disconnect(s->chr.chr); return; } qmp_set_link(name, true, &err); @@ -235,6 +235,7 @@ static int net_vhost_user_init(NetClientState *peer, const char *device, const char *name, CharDriverState *chr, int queues) { + Error *err = NULL; NetClientState *nc, *nc0 = NULL; VhostUserState *s; int i; @@ -254,12 +255,14 @@ static int net_vhost_user_init(NetClientState *peer, const char *device, nc->queue_index = i; s = DO_UPCAST(VhostUserState, nc, nc); - s->chr = chr; + if (!qemu_chr_fe_init(&s->chr, chr, &err)) { + error_report_err(err); + return -1; + } } s = DO_UPCAST(VhostUserState, nc, nc0); do { - Error *err = NULL; if (qemu_chr_wait_connected(chr, &err) < 0) { error_report_err(err); return -1; diff --git a/qtest.c b/qtest.c index 2d9a021de3..3fb3c11c8e 100644 --- a/qtest.c +++ b/qtest.c @@ -38,7 +38,7 @@ bool qtest_allowed; static DeviceState *irq_intercept_dev; static FILE *qtest_log_fp; -static CharDriverState *qtest_chr; +static CharBackend qtest_chr; static GString *inbuf; static int irq_levels[MAX_IRQ]; static qemu_timeval start_time; @@ -249,7 +249,7 @@ static void qtest_irq_handler(void *opaque, int n, int level) qemu_set_irq(old_irq, level); if (irq_levels[n] != level) { - CharDriverState *chr = qtest_chr; + CharDriverState *chr = qtest_chr.chr; irq_levels[n] = level; qtest_send_prefix(chr); qtest_sendf(chr, "IRQ %s %d\n", @@ -690,12 +690,12 @@ void qtest_init(const char *qtest_chrdev, const char *qtest_log, Error **errp) qemu_chr_fe_set_echo(chr, true); inbuf = g_string_new(""); - qtest_chr = chr; + qemu_chr_fe_init(&qtest_chr, chr, errp); } bool qtest_driver(void) { - return qtest_chr; + return qtest_chr.chr != NULL; } static void qtest_accel_class_init(ObjectClass *oc, void *data) diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c index edf30ac73e..52fbc0386f 100644 --- a/tests/vhost-user-test.c +++ b/tests/vhost-user-test.c @@ -19,6 +19,7 @@ #include "libqos/libqos.h" #include "libqos/pci-pc.h" #include "libqos/virtio-pci.h" +#include "qapi/error.h" #include "libqos/pci-pc.h" #include "libqos/virtio-pci.h" @@ -141,7 +142,7 @@ typedef struct TestServer { gchar *socket_path; gchar *mig_path; gchar *chr_name; - CharDriverState *chr; + CharBackend chr; int fds_num; int fds[VHOST_MEMORY_MAX_NREGIONS]; VhostUserMemory memory; @@ -261,13 +262,13 @@ static int chr_can_read(void *opaque) static void chr_read(void *opaque, const uint8_t *buf, int size) { TestServer *s = opaque; - CharDriverState *chr = s->chr; + CharBackend *chr = &s->chr; VhostUserMsg msg; uint8_t *p = (uint8_t *) &msg; int fd; if (s->test_fail) { - qemu_chr_disconnect(chr); + qemu_chr_disconnect(chr->chr); /* now switch to non-failure */ s->test_fail = false; } @@ -282,7 +283,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size) if (msg.size) { p += VHOST_USER_HDR_SIZE; - size = qemu_chr_fe_read_all(chr, p, msg.size); + size = qemu_chr_fe_read_all(chr->chr, p, msg.size); if (size != msg.size) { g_test_message("Wrong message size received %d != %d\n", size, msg.size); @@ -305,14 +306,14 @@ static void chr_read(void *opaque, const uint8_t *buf, int size) s->test_flags = TEST_FLAGS_END; } p = (uint8_t *) &msg; - qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size); + qemu_chr_fe_write_all(chr->chr, p, VHOST_USER_HDR_SIZE + msg.size); break; case VHOST_USER_SET_FEATURES: g_assert_cmpint(msg.payload.u64 & (0x1ULL << VHOST_USER_F_PROTOCOL_FEATURES), !=, 0ULL); if (s->test_flags == TEST_FLAGS_DISCONNECT) { - qemu_chr_disconnect(chr); + qemu_chr_disconnect(chr->chr); s->test_flags = TEST_FLAGS_BAD; } break; @@ -326,7 +327,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size) msg.payload.u64 |= 1 << VHOST_USER_PROTOCOL_F_MQ; } p = (uint8_t *) &msg; - qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size); + qemu_chr_fe_write_all(chr->chr, p, VHOST_USER_HDR_SIZE + msg.size); break; case VHOST_USER_GET_VRING_BASE: @@ -335,7 +336,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size) msg.size = sizeof(m.payload.state); msg.payload.state.num = 0; p = (uint8_t *) &msg; - qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size); + qemu_chr_fe_write_all(chr->chr, p, VHOST_USER_HDR_SIZE + msg.size); assert(msg.payload.state.index < s->queues * 2); s->rings &= ~(0x1ULL << msg.payload.state.index); @@ -344,7 +345,8 @@ static void chr_read(void *opaque, const uint8_t *buf, int size) case VHOST_USER_SET_MEM_TABLE: /* received the mem table */ memcpy(&s->memory, &msg.payload.memory, sizeof(msg.payload.memory)); - s->fds_num = qemu_chr_fe_get_msgfds(chr, s->fds, G_N_ELEMENTS(s->fds)); + s->fds_num = qemu_chr_fe_get_msgfds(chr->chr, s->fds, + G_N_ELEMENTS(s->fds)); /* signal the test that it can continue */ g_cond_signal(&s->data_cond); @@ -353,7 +355,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size) case VHOST_USER_SET_VRING_KICK: case VHOST_USER_SET_VRING_CALL: /* consume the fd */ - qemu_chr_fe_get_msgfds(chr, &fd, 1); + qemu_chr_fe_get_msgfds(chr->chr, &fd, 1); /* * This is a non-blocking eventfd. * The receive function forces it to be blocking, @@ -367,11 +369,11 @@ static void chr_read(void *opaque, const uint8_t *buf, int size) close(s->log_fd); s->log_fd = -1; } - qemu_chr_fe_get_msgfds(chr, &s->log_fd, 1); + qemu_chr_fe_get_msgfds(chr->chr, &s->log_fd, 1); msg.flags |= VHOST_USER_REPLY_MASK; msg.size = 0; p = (uint8_t *) &msg; - qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE); + qemu_chr_fe_write_all(chr->chr, p, VHOST_USER_HDR_SIZE); g_cond_signal(&s->data_cond); break; @@ -386,7 +388,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size) msg.size = sizeof(m.payload.u64); msg.payload.u64 = s->queues; p = (uint8_t *) &msg; - qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size); + qemu_chr_fe_write_all(chr->chr, p, VHOST_USER_HDR_SIZE + msg.size); break; default: @@ -453,12 +455,13 @@ static void chr_event(void *opaque, int event) static void test_server_create_chr(TestServer *server, const gchar *opt) { gchar *chr_path; - + CharDriverState *chr; chr_path = g_strdup_printf("unix:%s%s", server->socket_path, opt); - server->chr = qemu_chr_new(server->chr_name, chr_path); + chr = qemu_chr_new(server->chr_name, chr_path); + qemu_chr_fe_init(&server->chr, chr, &error_abort); g_free(chr_path); - qemu_chr_add_handlers(server->chr, chr_can_read, chr_read, + qemu_chr_add_handlers(server->chr.chr, chr_can_read, chr_read, chr_event, server); } @@ -484,7 +487,7 @@ static gboolean _test_server_free(TestServer *server) { int i; - qemu_chr_delete(server->chr); + qemu_chr_delete(server->chr.chr); for (i = 0; i < server->fds_num; i++) { close(server->fds[i]); @@ -721,7 +724,7 @@ reconnect_cb(gpointer user_data) { TestServer *s = user_data; - qemu_chr_disconnect(s->chr); + qemu_chr_disconnect(s->chr.chr); return FALSE; }