mirror of
https://github.com/qemu/qemu.git
synced 2026-07-08 17:46:10 +00:00
chardev: rework filename handling
Instead of checking, did backend set the filename state or not, let's be stateless: filename is needed rarely, so, let's just have a generic function (with optional implementation by backends) to get it. Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> [ Marc-André - fix leak in ivshmem-pci.c ] Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20260115144606.233252-10-vsementsov@yandex-team.ru>
This commit is contained in:
committed by
Marc-André Lureau
parent
e43eb54dc8
commit
bc339129b6
@@ -351,7 +351,6 @@ static bool pty_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
chr->filename = g_strdup_printf("pty:%s", s->pty_name);
|
|
||||||
qemu_printf("char device redirected to %s (label %s)\n",
|
qemu_printf("char device redirected to %s (label %s)\n",
|
||||||
s->pty_name, chr->label);
|
s->pty_name, chr->label);
|
||||||
|
|
||||||
@@ -393,6 +392,12 @@ static char *pty_chr_get_pty_name(Chardev *chr)
|
|||||||
return g_strdup(s->pty_name);
|
return g_strdup(s->pty_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *pty_chr_get_filename(Chardev *chr)
|
||||||
|
{
|
||||||
|
PtyChardev *s = PTY_CHARDEV(chr);
|
||||||
|
return g_strdup_printf("pty:%s", s->pty_name);
|
||||||
|
}
|
||||||
|
|
||||||
static void char_pty_class_init(ObjectClass *oc, const void *data)
|
static void char_pty_class_init(ObjectClass *oc, const void *data)
|
||||||
{
|
{
|
||||||
ChardevClass *cc = CHARDEV_CLASS(oc);
|
ChardevClass *cc = CHARDEV_CLASS(oc);
|
||||||
@@ -403,6 +408,7 @@ static void char_pty_class_init(ObjectClass *oc, const void *data)
|
|||||||
cc->chr_update_read_handler = pty_chr_update_read_handler;
|
cc->chr_update_read_handler = pty_chr_update_read_handler;
|
||||||
cc->chr_add_watch = pty_chr_add_watch;
|
cc->chr_add_watch = pty_chr_add_watch;
|
||||||
cc->chr_get_pty_name = pty_chr_get_pty_name;
|
cc->chr_get_pty_name = pty_chr_get_pty_name;
|
||||||
|
cc->chr_get_filename = pty_chr_get_filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo char_pty_type_info = {
|
static const TypeInfo char_pty_type_info = {
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
|
|
||||||
static gboolean socket_reconnect_timeout(gpointer opaque);
|
static gboolean socket_reconnect_timeout(gpointer opaque);
|
||||||
static void tcp_chr_telnet_init(Chardev *chr);
|
static void tcp_chr_telnet_init(Chardev *chr);
|
||||||
|
static char *qemu_chr_compute_filename(SocketChardev *s);
|
||||||
|
|
||||||
static void tcp_chr_change_state(SocketChardev *s, TCPChardevState state)
|
static void tcp_chr_change_state(SocketChardev *s, TCPChardevState state)
|
||||||
{
|
{
|
||||||
@@ -384,8 +385,6 @@ static void tcp_chr_free_connection(Chardev *chr)
|
|||||||
s->sioc = NULL;
|
s->sioc = NULL;
|
||||||
object_unref(OBJECT(s->ioc));
|
object_unref(OBJECT(s->ioc));
|
||||||
s->ioc = NULL;
|
s->ioc = NULL;
|
||||||
g_free(chr->filename);
|
|
||||||
chr->filename = NULL;
|
|
||||||
tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED);
|
tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -439,16 +438,17 @@ static char *qemu_chr_socket_address(SocketChardev *s, const char *prefix)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_disconnected_filename(SocketChardev *s)
|
static char *tcp_chr_get_filename(Chardev *chr)
|
||||||
{
|
{
|
||||||
Chardev *chr = CHARDEV(s);
|
SocketChardev *s = SOCKET_CHARDEV(chr);
|
||||||
|
|
||||||
g_free(chr->filename);
|
if (s->state == TCP_CHARDEV_STATE_CONNECTED) {
|
||||||
if (s->addr) {
|
return qemu_chr_compute_filename(s);
|
||||||
chr->filename = qemu_chr_socket_address(s, "disconnected:");
|
} else if (s->addr) {
|
||||||
} else {
|
return qemu_chr_socket_address(s, "disconnected:");
|
||||||
chr->filename = g_strdup("disconnected:socket");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return g_strdup("disconnected:socket");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NB may be called even if tcp_chr_connect has not been
|
/* NB may be called even if tcp_chr_connect has not been
|
||||||
@@ -468,7 +468,6 @@ static void tcp_chr_disconnect_locked(Chardev *chr)
|
|||||||
qio_net_listener_set_client_func_full(s->listener, tcp_chr_accept,
|
qio_net_listener_set_client_func_full(s->listener, tcp_chr_accept,
|
||||||
chr, NULL, chr->gcontext);
|
chr, NULL, chr->gcontext);
|
||||||
}
|
}
|
||||||
update_disconnected_filename(s);
|
|
||||||
if (emit_close) {
|
if (emit_close) {
|
||||||
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
|
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
|
||||||
}
|
}
|
||||||
@@ -639,9 +638,6 @@ static void tcp_chr_connect(void *opaque)
|
|||||||
Chardev *chr = CHARDEV(opaque);
|
Chardev *chr = CHARDEV(opaque);
|
||||||
SocketChardev *s = SOCKET_CHARDEV(opaque);
|
SocketChardev *s = SOCKET_CHARDEV(opaque);
|
||||||
|
|
||||||
g_free(chr->filename);
|
|
||||||
chr->filename = qemu_chr_compute_filename(s);
|
|
||||||
|
|
||||||
tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTED);
|
tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTED);
|
||||||
update_ioc_handlers(s);
|
update_ioc_handlers(s);
|
||||||
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
|
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
|
||||||
@@ -1000,8 +996,8 @@ static void tcp_chr_accept_server_sync(Chardev *chr)
|
|||||||
{
|
{
|
||||||
SocketChardev *s = SOCKET_CHARDEV(chr);
|
SocketChardev *s = SOCKET_CHARDEV(chr);
|
||||||
QIOChannelSocket *sioc;
|
QIOChannelSocket *sioc;
|
||||||
info_report("QEMU waiting for connection on: %s",
|
g_autofree char *filename = qemu_chr_get_filename(chr);
|
||||||
chr->filename);
|
info_report("QEMU waiting for connection on: %s", filename);
|
||||||
tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
|
tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
|
||||||
sioc = qio_net_listener_wait_client(s->listener);
|
sioc = qio_net_listener_wait_client(s->listener);
|
||||||
tcp_chr_set_client_ioc_name(chr, sioc);
|
tcp_chr_set_client_ioc_name(chr, sioc);
|
||||||
@@ -1258,8 +1254,6 @@ static int qmp_chardev_open_socket_server(Chardev *chr,
|
|||||||
s->addr = qio_net_listener_get_local_address(s->listener, 0, errp);
|
s->addr = qio_net_listener_get_local_address(s->listener, 0, errp);
|
||||||
|
|
||||||
skip_listen:
|
skip_listen:
|
||||||
update_disconnected_filename(s);
|
|
||||||
|
|
||||||
if (is_waitconnect) {
|
if (is_waitconnect) {
|
||||||
tcp_chr_accept_server_sync(chr);
|
tcp_chr_accept_server_sync(chr);
|
||||||
} else {
|
} else {
|
||||||
@@ -1436,8 +1430,6 @@ static bool tcp_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
|
|||||||
}
|
}
|
||||||
s->registered_yank = true;
|
s->registered_yank = true;
|
||||||
|
|
||||||
update_disconnected_filename(s);
|
|
||||||
|
|
||||||
if (s->is_listen) {
|
if (s->is_listen) {
|
||||||
if (qmp_chardev_open_socket_server(chr, is_telnet || is_tn3270,
|
if (qmp_chardev_open_socket_server(chr, is_telnet || is_tn3270,
|
||||||
is_waitconnect, errp) < 0) {
|
is_waitconnect, errp) < 0) {
|
||||||
@@ -1593,6 +1585,7 @@ static void char_socket_class_init(ObjectClass *oc, const void *data)
|
|||||||
cc->chr_add_watch = tcp_chr_add_watch;
|
cc->chr_add_watch = tcp_chr_add_watch;
|
||||||
cc->chr_update_read_handler = tcp_chr_update_read_handler;
|
cc->chr_update_read_handler = tcp_chr_update_read_handler;
|
||||||
cc->chr_listener_cleanup = tcp_chr_listener_cleanup;
|
cc->chr_listener_cleanup = tcp_chr_listener_cleanup;
|
||||||
|
cc->chr_get_filename = tcp_chr_get_filename;
|
||||||
|
|
||||||
object_class_property_add(oc, "addr", "SocketAddress",
|
object_class_property_add(oc, "addr", "SocketAddress",
|
||||||
char_socket_get_addr, NULL,
|
char_socket_get_addr, NULL,
|
||||||
|
|||||||
@@ -309,7 +309,6 @@ static void char_finalize(Object *obj)
|
|||||||
if (chr->fe) {
|
if (chr->fe) {
|
||||||
chr->fe->chr = NULL;
|
chr->fe->chr = NULL;
|
||||||
}
|
}
|
||||||
g_free(chr->filename);
|
|
||||||
g_free(chr->label);
|
g_free(chr->label);
|
||||||
if (chr->logfd != -1) {
|
if (chr->logfd != -1) {
|
||||||
close(chr->logfd);
|
close(chr->logfd);
|
||||||
@@ -796,7 +795,7 @@ static int qmp_query_chardev_foreach(Object *obj, void *data)
|
|||||||
ChardevInfo *value = g_malloc0(sizeof(*value));
|
ChardevInfo *value = g_malloc0(sizeof(*value));
|
||||||
|
|
||||||
value->label = g_strdup(chr->label);
|
value->label = g_strdup(chr->label);
|
||||||
value->filename = g_strdup(chr->filename);
|
value->filename = qemu_chr_get_filename(chr);
|
||||||
value->frontend_open = chr->fe && chr->fe->fe_is_open;
|
value->frontend_open = chr->fe && chr->fe->fe_is_open;
|
||||||
|
|
||||||
QAPI_LIST_PREPEND(*list, value);
|
QAPI_LIST_PREPEND(*list, value);
|
||||||
@@ -1025,10 +1024,6 @@ static Chardev *chardev_new(const char *id, const char *typename,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!chr->filename) {
|
|
||||||
chr->filename = g_strdup(typename + 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
return chr;
|
return chr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1110,6 +1105,20 @@ char *qemu_chr_get_pty_name(Chardev *chr)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *qemu_chr_get_filename(Chardev *chr)
|
||||||
|
{
|
||||||
|
ChardevClass *cc = CHARDEV_GET_CLASS(chr);
|
||||||
|
const char *typename;
|
||||||
|
|
||||||
|
if (cc->chr_get_filename) {
|
||||||
|
return cc->chr_get_filename(chr);
|
||||||
|
}
|
||||||
|
|
||||||
|
typename = object_get_typename(OBJECT(chr));
|
||||||
|
assert(g_str_has_prefix(typename, "chardev-"));
|
||||||
|
return g_strdup(typename + 8);
|
||||||
|
}
|
||||||
|
|
||||||
ChardevReturn *qmp_chardev_change(const char *id, ChardevBackend *backend,
|
ChardevReturn *qmp_chardev_change(const char *id, ChardevBackend *backend,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -873,10 +873,11 @@ static void ivshmem_common_realize(PCIDevice *dev, Error **errp)
|
|||||||
host_memory_backend_set_mapped(s->hostmem, true);
|
host_memory_backend_set_mapped(s->hostmem, true);
|
||||||
} else {
|
} else {
|
||||||
Chardev *chr = qemu_chr_fe_get_driver(&s->server_chr);
|
Chardev *chr = qemu_chr_fe_get_driver(&s->server_chr);
|
||||||
assert(chr);
|
g_autofree char *filename = NULL;
|
||||||
|
|
||||||
IVSHMEM_DPRINTF("using shared memory server (socket = %s)\n",
|
assert(chr);
|
||||||
chr->filename);
|
filename = qemu_chr_get_filename(chr);
|
||||||
|
IVSHMEM_DPRINTF("using shared memory server (socket = %s)\n", filename);
|
||||||
|
|
||||||
/* we allocate enough space for 16 peers and grow as needed */
|
/* we allocate enough space for 16 peers and grow as needed */
|
||||||
resize_peers(s, 16);
|
resize_peers(s, 16);
|
||||||
|
|||||||
@@ -62,7 +62,6 @@ struct Chardev {
|
|||||||
QemuMutex chr_write_lock;
|
QemuMutex chr_write_lock;
|
||||||
CharFrontend *fe;
|
CharFrontend *fe;
|
||||||
char *label;
|
char *label;
|
||||||
char *filename;
|
|
||||||
int logfd;
|
int logfd;
|
||||||
int be_open;
|
int be_open;
|
||||||
/* used to coordinate the chardev-change special-case: */
|
/* used to coordinate the chardev-change special-case: */
|
||||||
@@ -309,6 +308,9 @@ struct ChardevClass {
|
|||||||
|
|
||||||
/* return PTY name if available */
|
/* return PTY name if available */
|
||||||
char *(*chr_get_pty_name)(Chardev *s);
|
char *(*chr_get_pty_name)(Chardev *s);
|
||||||
|
|
||||||
|
/* get filename for reporting */
|
||||||
|
char *(*chr_get_filename)(Chardev *s);
|
||||||
};
|
};
|
||||||
|
|
||||||
Chardev *qemu_chardev_new(const char *id, const char *typename,
|
Chardev *qemu_chardev_new(const char *id, const char *typename,
|
||||||
@@ -324,5 +326,6 @@ void suspend_mux_open(void);
|
|||||||
void resume_mux_open(void);
|
void resume_mux_open(void);
|
||||||
|
|
||||||
char *qemu_chr_get_pty_name(Chardev *chr);
|
char *qemu_chr_get_pty_name(Chardev *chr);
|
||||||
|
char *qemu_chr_get_filename(Chardev *chr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user