aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@redhat.com>2016-10-22 12:52:58 +0300
committerPaolo Bonzini <pbonzini@redhat.com>2016-10-24 15:27:21 +0200
commitc39860e6dc90f6ee2e82ee078f978c5d7f3df86a (patch)
tree7af723a578b9f33ee172254b20fd9bbdd519cd0c
parent5d300164d00cf9d37a4481831d2c993255dfa0e8 (diff)
char: replace qemu_chr_claim/release with qemu_chr_fe_init/deinit
Now that all front end use qemu_chr_fe_init(), we can move chardev claiming in init(), and add a function deinit() to release the chardev and cleanup handlers. The qemu_chr_fe_claim_no_fail() for property are gone, since the property will raise an error instead. In other cases, where there is already an error path, an error is raised instead. Finally, other cases are handled by &error_abort in qemu_chr_fe_init(). Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20161022095318.17775-19-marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--backends/rng-egd.c10
-rw-r--r--gdbstub.c3
-rw-r--r--hw/arm/pxa2xx.c1
-rw-r--r--hw/char/mcf_uart.c1
-rw-r--r--hw/char/serial.c2
-rw-r--r--hw/char/sh_serial.c1
-rw-r--r--hw/char/xen_console.c16
-rw-r--r--hw/core/qdev-properties-system.c14
-rw-r--r--hw/usb/ccid-card-passthru.c1
-rw-r--r--hw/usb/redirect.c2
-rw-r--r--include/sysemu/char.h39
-rw-r--r--monitor.c4
-rw-r--r--net/colo-compare.c20
-rw-r--r--net/filter-mirror.c20
-rw-r--r--net/slirp.c1
-rw-r--r--net/vhost-user.c8
-rw-r--r--qemu-char.c36
-rw-r--r--tests/vhost-user-test.c1
-rw-r--r--vl.c1
19 files changed, 44 insertions, 137 deletions
diff --git a/backends/rng-egd.c b/backends/rng-egd.c
index d9e50bb085..433f583f78 100644
--- a/backends/rng-egd.c
+++ b/backends/rng-egd.c
@@ -100,10 +100,6 @@ static void rng_egd_opened(RngBackend *b, Error **errp)
"Device '%s' not found", s->chr_name);
return;
}
- 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;
}
@@ -149,11 +145,7 @@ static void rng_egd_finalize(Object *obj)
{
RngEgd *s = RNG_EGD(obj);
- if (s->chr.chr) {
- qemu_chr_fe_set_handlers(&s->chr, NULL, NULL, NULL, NULL, NULL);
- qemu_chr_fe_release(s->chr.chr);
- }
-
+ qemu_chr_fe_deinit(&s->chr);
g_free(s->chr_name);
}
diff --git a/gdbstub.c b/gdbstub.c
index 33b056e323..5944494924 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1494,6 +1494,7 @@ void gdb_exit(CPUArchState *env, int code)
put_packet(s, buf);
#ifndef CONFIG_USER_ONLY
+ qemu_chr_fe_deinit(&s->chr);
qemu_chr_delete(chr);
#endif
}
@@ -1752,8 +1753,6 @@ int gdbserver_start(const char *device)
chr = qemu_chr_new_noreplay("gdb", device);
if (!chr)
return -1;
-
- qemu_chr_fe_claim_no_fail(chr);
}
s = gdbserver_state;
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 798c05bf29..cd9837914f 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -1976,7 +1976,6 @@ static void pxa2xx_fir_realize(DeviceState *dev, Error **errp)
PXA2xxFIrState *s = PXA2XX_FIR(dev);
if (s->chr.chr) {
- qemu_chr_fe_claim_no_fail(s->chr.chr);
qemu_chr_fe_set_handlers(&s->chr, pxa2xx_fir_is_empty,
pxa2xx_fir_rx, pxa2xx_fir_event, s, NULL);
}
diff --git a/hw/char/mcf_uart.c b/hw/char/mcf_uart.c
index cc3db1373c..b5053431e5 100644
--- a/hw/char/mcf_uart.c
+++ b/hw/char/mcf_uart.c
@@ -285,7 +285,6 @@ void *mcf_uart_init(qemu_irq irq, CharDriverState *chr)
s->irq = irq;
if (chr) {
qemu_chr_fe_init(&s->chr, chr, &error_abort);
- qemu_chr_fe_claim_no_fail(chr);
qemu_chr_fe_set_handlers(&s->chr, mcf_uart_can_receive,
mcf_uart_receive, mcf_uart_event, s, NULL);
}
diff --git a/hw/char/serial.c b/hw/char/serial.c
index 509bc252df..54f80c6e91 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -905,7 +905,7 @@ void serial_realize_core(SerialState *s, Error **errp)
void serial_exit_core(SerialState *s)
{
- qemu_chr_fe_set_handlers(&s->chr, NULL, NULL, NULL, NULL, NULL);
+ qemu_chr_fe_deinit(&s->chr);
qemu_unregister_reset(serial_reset, s);
}
diff --git a/hw/char/sh_serial.c b/hw/char/sh_serial.c
index 8d82986d35..8bb45db634 100644
--- a/hw/char/sh_serial.c
+++ b/hw/char/sh_serial.c
@@ -397,7 +397,6 @@ void sh_serial_init(MemoryRegion *sysmem,
memory_region_add_subregion(sysmem, A7ADDR(base), &s->iomem_a7);
if (chr) {
- qemu_chr_fe_claim_no_fail(chr);
qemu_chr_fe_init(&s->chr, chr, &error_abort);
qemu_chr_fe_set_handlers(&s->chr, sh_serial_can_receive1,
sh_serial_receive1,
diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c
index 5e5aca1ed6..f664366f7c 100644
--- a/hw/char/xen_console.c
+++ b/hw/char/xen_console.c
@@ -245,15 +245,8 @@ static int con_initialise(struct XenDevice *xendev)
xen_be_bind_evtchn(&con->xendev);
if (con->chr.chr) {
- if (qemu_chr_fe_claim(con->chr.chr) == 0) {
- qemu_chr_fe_set_handlers(&con->chr, xencons_can_receive,
- xencons_receive, NULL, con, NULL);
- } else {
- xen_be_printf(xendev, 0,
- "xen_console_init error chardev %s already used\n",
- con->chr.chr->label);
- con->chr.chr = NULL;
- }
+ qemu_chr_fe_set_handlers(&con->chr, xencons_can_receive,
+ xencons_receive, NULL, con, NULL);
}
xen_be_printf(xendev, 1, "ring mfn %d, remote port %d, local port %d, limit %zd\n",
@@ -268,10 +261,7 @@ static void con_disconnect(struct XenDevice *xendev)
{
struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
- if (con->chr.chr) {
- qemu_chr_fe_set_handlers(&con->chr, NULL, NULL, NULL, NULL, NULL);
- qemu_chr_fe_release(con->chr.chr);
- }
+ qemu_chr_fe_deinit(&con->chr);
xen_be_unbind_evtchn(&con->xendev);
if (con->sring) {
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 6d45d327a5..c35f0f59d6 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -206,13 +206,12 @@ static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
object_get_typename(obj), prop->name, str);
return;
}
- if (qemu_chr_fe_claim(s) != 0) {
- error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
- object_get_typename(obj), prop->name, str);
+
+ if (!qemu_chr_fe_init(be, s, errp)) {
+ error_prepend(errp, "Property '%s.%s' can't take value '%s': ",
+ object_get_typename(obj), prop->name, str);
return;
}
-
- qemu_chr_fe_init(be, s, errp);
}
static void release_chr(Object *obj, const char *name, void *opaque)
@@ -221,10 +220,7 @@ static void release_chr(Object *obj, const char *name, void *opaque)
Property *prop = opaque;
CharBackend *be = qdev_get_prop_ptr(dev, prop);
- if (be->chr) {
- qemu_chr_fe_set_handlers(be, NULL, NULL, NULL, NULL, NULL);
- qemu_chr_fe_release(be->chr);
- }
+ qemu_chr_fe_deinit(be);
}
PropertyInfo qdev_prop_chr = {
diff --git a/hw/usb/ccid-card-passthru.c b/hw/usb/ccid-card-passthru.c
index a8c868446a..369a8f108b 100644
--- a/hw/usb/ccid-card-passthru.c
+++ b/hw/usb/ccid-card-passthru.c
@@ -266,6 +266,7 @@ static void ccid_card_vscard_drop_connection(PassthruState *card)
{
CharDriverState *chr = qemu_chr_fe_get_driver(&card->cs);
+ qemu_chr_fe_deinit(&card->cs);
qemu_chr_delete(chr);
card->vscard_in_pos = card->vscard_in_hdr = 0;
}
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 0fb2e9a203..6f5ad2049c 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -1430,9 +1430,9 @@ static void usbredir_handle_destroy(USBDevice *udev)
USBRedirDevice *dev = USB_REDIRECT(udev);
CharDriverState *chr = qemu_chr_fe_get_driver(&dev->cs);
+ qemu_chr_fe_deinit(&dev->cs);
qemu_chr_delete(chr);
- dev->cs.chr = NULL;
/* Note must be done after qemu_chr_close, as that causes a close event */
qemu_bh_delete(dev->chardev_close_bh);
qemu_bh_delete(dev->device_reject_bh);
diff --git a/include/sysemu/char.h b/include/sysemu/char.h
index f2b3999735..b81dbcc33b 100644
--- a/include/sysemu/char.h
+++ b/include/sysemu/char.h
@@ -362,35 +362,6 @@ int qemu_chr_fe_get_msgfds(CharBackend *be, int *fds, int num);
int qemu_chr_fe_set_msgfds(CharBackend *be, int *fds, int num);
/**
- * @qemu_chr_fe_claim:
- *
- * Claim a backend before using it, should be called before calling
- * qemu_chr_fe_set_handlers().
- *
- * Returns: -1 if the backend is already in use by another frontend, 0 on
- * success.
- */
-int qemu_chr_fe_claim(CharDriverState *s);
-
-/**
- * @qemu_chr_fe_claim_no_fail:
- *
- * Like qemu_chr_fe_claim, but will exit qemu with an error when the
- * backend is already in use.
- */
-void qemu_chr_fe_claim_no_fail(CharDriverState *s);
-
-/**
- * @qemu_chr_fe_release:
- *
- * Release a backend for use by another frontend.
- *
- * Returns: -1 if the backend is already in use by another frontend, 0 on
- * success.
- */
-void qemu_chr_fe_release(CharDriverState *s);
-
-/**
* @qemu_chr_be_can_write:
*
* Determine how much data the front end can currently accept. This function
@@ -437,7 +408,8 @@ void qemu_chr_be_event(CharDriverState *s, int event);
* @qemu_chr_fe_init:
*
* Initializes a front end for the given CharBackend and
- * CharDriver.
+ * CharDriver. Call qemu_chr_fe_deinit() to remove the association and
+ * release the driver.
*
* Returns: false on error.
*/
@@ -451,6 +423,13 @@ bool qemu_chr_fe_init(CharBackend *b, CharDriverState *s, Error **errp);
CharDriverState *qemu_chr_fe_get_driver(CharBackend *be);
/**
+ * @qemu_chr_fe_deinit:
+ *
+ * Dissociate the CharBackend from the CharDriver.
+ */
+void qemu_chr_fe_deinit(CharBackend *b);
+
+/**
* @qemu_chr_fe_set_handlers:
* @b: a CharBackend
* @fd_can_read: callback to get the amount of data the frontend may
diff --git a/monitor.c b/monitor.c
index 1c6f28fca6..5c349c5bf5 100644
--- a/monitor.c
+++ b/monitor.c
@@ -582,9 +582,7 @@ static void monitor_data_init(Monitor *mon)
static void monitor_data_destroy(Monitor *mon)
{
- if (mon->chr.chr) {
- qemu_chr_fe_set_handlers(&mon->chr, NULL, NULL, NULL, NULL, NULL);
- }
+ qemu_chr_fe_deinit(&mon->chr);
if (monitor_is_qmp(mon)) {
json_message_parser_destroy(&mon->qmp.parser);
}
diff --git a/net/colo-compare.c b/net/colo-compare.c
index 63d92cb9da..308368164c 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -590,12 +590,6 @@ static int find_and_check_chardev(CharDriverState **chr,
return 1;
}
- if (qemu_chr_fe_claim(*chr) < 0) {
- error_setg(errp, "chardev \"%s\" cannot be claimed",
- chr_name);
- return 1;
- }
-
return 0;
}
@@ -707,17 +701,9 @@ static void colo_compare_finalize(Object *obj)
{
CompareState *s = COLO_COMPARE(obj);
- if (s->chr_pri_in.chr) {
- qemu_chr_fe_set_handlers(&s->chr_pri_in, NULL, NULL, NULL, NULL, NULL);
- qemu_chr_fe_release(s->chr_pri_in.chr);
- }
- if (s->chr_sec_in.chr) {
- qemu_chr_fe_set_handlers(&s->chr_sec_in, NULL, NULL, NULL, NULL, NULL);
- qemu_chr_fe_release(s->chr_sec_in.chr);
- }
- if (s->chr_out.chr) {
- qemu_chr_fe_release(s->chr_out.chr);
- }
+ qemu_chr_fe_deinit(&s->chr_pri_in);
+ qemu_chr_fe_deinit(&s->chr_sec_in);
+ qemu_chr_fe_deinit(&s->chr_out);
g_queue_free(&s->conn_list);
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
index 12d79cd987..1864c818d5 100644
--- a/net/filter-mirror.c
+++ b/net/filter-mirror.c
@@ -175,22 +175,15 @@ static void filter_mirror_cleanup(NetFilterState *nf)
{
MirrorState *s = FILTER_MIRROR(nf);
- if (s->chr_out.chr) {
- qemu_chr_fe_release(s->chr_out.chr);
- }
+ qemu_chr_fe_deinit(&s->chr_out);
}
static void filter_redirector_cleanup(NetFilterState *nf)
{
MirrorState *s = FILTER_REDIRECTOR(nf);
- if (s->chr_in.chr) {
- qemu_chr_fe_set_handlers(&s->chr_in, NULL, NULL, NULL, NULL, NULL);
- qemu_chr_fe_release(s->chr_in.chr);
- }
- if (s->chr_out.chr) {
- qemu_chr_fe_release(s->chr_out.chr);
- }
+ qemu_chr_fe_deinit(&s->chr_in);
+ qemu_chr_fe_deinit(&s->chr_out);
}
static void filter_mirror_setup(NetFilterState *nf, Error **errp)
@@ -211,11 +204,6 @@ static void filter_mirror_setup(NetFilterState *nf, Error **errp)
return;
}
- 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);
}
@@ -254,7 +242,6 @@ static void filter_redirector_setup(NetFilterState *nf, Error **errp)
return;
}
- qemu_chr_fe_claim_no_fail(chr);
if (!qemu_chr_fe_init(&s->chr_in, chr, errp)) {
return;
}
@@ -271,7 +258,6 @@ static void filter_redirector_setup(NetFilterState *nf, Error **errp)
"OUT Device '%s' not found", s->outdev);
return;
}
- 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 f9f6fc6b0b..0e675354a4 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -774,7 +774,6 @@ 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.chr);
qemu_chr_fe_set_handlers(&fwd->hd, guestfwd_can_read, guestfwd_read,
NULL, fwd, NULL);
}
diff --git a/net/vhost-user.c b/net/vhost-user.c
index 357b500d82..140a4e0bde 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -150,10 +150,8 @@ static void vhost_user_cleanup(NetClientState *nc)
g_free(s->vhost_net);
s->vhost_net = NULL;
}
- if (nc->queue_index == 0 && s->chr.chr) {
- qemu_chr_fe_set_handlers(&s->chr, NULL, NULL, NULL, NULL, NULL);
- qemu_chr_fe_release(s->chr.chr);
- s->chr.chr = NULL;
+ if (nc->queue_index == 0) {
+ qemu_chr_fe_deinit(&s->chr);
}
qemu_purge_queued_packets(nc);
@@ -297,8 +295,6 @@ static CharDriverState *net_vhost_claim_chardev(
return NULL;
}
- qemu_chr_fe_claim_no_fail(chr);
-
return chr;
}
diff --git a/qemu-char.c b/qemu-char.c
index 115909fd48..e5e80381d7 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -776,6 +776,7 @@ static void mux_chr_close(struct CharDriverState *chr)
{
MuxDriver *d = chr->opaque;
+ qemu_chr_fe_deinit(&d->chr);
g_free(d);
}
@@ -884,6 +885,17 @@ bool qemu_chr_fe_init(CharBackend *b, CharDriverState *s, Error **errp)
return true;
}
+void qemu_chr_fe_deinit(CharBackend *b)
+{
+ assert(b);
+
+ if (b->chr) {
+ qemu_chr_fe_set_handlers(b, NULL, NULL, NULL, NULL, NULL);
+ b->chr->avail_connections++;
+ b->chr = NULL;
+ }
+}
+
void qemu_chr_fe_set_handlers(CharBackend *b,
IOCanReadHandler *fd_can_read,
IOReadHandler *fd_read,
@@ -4114,7 +4126,6 @@ CharDriverState *qemu_chr_new_noreplay(const char *label, const char *filename)
error_report_err(err);
}
if (chr && qemu_opt_get_bool(opts, "mux", 0)) {
- qemu_chr_fe_claim_no_fail(chr);
monitor_init(chr, MONITOR_USE_READLINE);
}
qemu_opts_del(opts);
@@ -4190,29 +4201,6 @@ guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond,
return tag;
}
-int qemu_chr_fe_claim(CharDriverState *s)
-{
- if (s->avail_connections < 1) {
- return -1;
- }
- s->avail_connections--;
- return 0;
-}
-
-void qemu_chr_fe_claim_no_fail(CharDriverState *s)
-{
- if (qemu_chr_fe_claim(s) != 0) {
- fprintf(stderr, "%s: error chardev \"%s\" already used\n",
- __func__, s->label);
- exit(1);
- }
-}
-
-void qemu_chr_fe_release(CharDriverState *s)
-{
- s->avail_connections++;
-}
-
void qemu_chr_fe_disconnect(CharBackend *be)
{
CharDriverState *chr = be->chr;
diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
index 2d86de1749..24c2323152 100644
--- a/tests/vhost-user-test.c
+++ b/tests/vhost-user-test.c
@@ -490,6 +490,7 @@ static gboolean _test_server_free(TestServer *server)
int i;
CharDriverState *chr = qemu_chr_fe_get_driver(&server->chr);
+ qemu_chr_fe_deinit(&server->chr);
qemu_chr_delete(chr);
for (i = 0; i < server->fds_num; i++) {
diff --git a/vl.c b/vl.c
index e4c534c6b2..44e08b4fc0 100644
--- a/vl.c
+++ b/vl.c
@@ -2417,7 +2417,6 @@ static int mon_init_func(void *opaque, QemuOpts *opts, Error **errp)
exit(1);
}
- qemu_chr_fe_claim_no_fail(chr);
monitor_init(chr, flags);
return 0;
}