* [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1)
@ 2009-07-01 16:21 Daniel P. Berrange
2009-07-01 16:26 ` [Qemu-devel] [PATCH 1/2] APIs to capture character device data Daniel P. Berrange
` (4 more replies)
0 siblings, 5 replies; 24+ messages in thread
From: Daniel P. Berrange @ 2009-07-01 16:21 UTC (permalink / raw)
To: qemu-devel
The following two patches make it possible to tunnel character devices
over VNC, using a new VNC extension. This is motivated by the existing
QEMU support for tunnelling audio streams over VNC, and the code follows
a very similar design. The key requirement here is that it should not
be neccessary to specifically configure each character device to make
it available via VNC. The admin should be able to configure the char
devices with all current available backends (file, pty, null, tcp, udp,
unix, etc), and regardless of this config be able to snoop on data from
any active VNC client on demand.
The first patch adds a bunch of support APIs to qemu-char{.h,.c}
- An API to iterate over all current character devices. This allows
the VNC server to inform the client of the current list of available
data streams upon connection
- An API to monitor creation & deletion of character devices. This
allows the VNC server to inform the client when character devices
are hot-plugged/unplugged.
- An API to request capture data on a specific character device.
This is how the VNC server gets the data coming out of the guest
The design for this stuff follows that used in the audio stream capture
APIs (audio/audio.h)
The second patch implements the VNC extension for tunnelling multiple
independant data streams over a connection. I have stolen one of
the psuedo encodings assigned to Anthony for this purpose, and also
added a new message sub-type to the 'aliguori' client/server message
type. Hopefully anthony will approve this allocation if the patches
look good :-)
The VNC extension is for generic data streams, so it can be implemented
by any VNC server that wants this. The QEMU implementation maps data
streams onto character devices. Every data stream has a name, and in
this case I'm using the QEMU character device label, since this can be
explicitly set by mgmt tools starting QEMU, and allows VNC client to
correlate the stream with devices, and with the monitor. When the client
requests capture on a specific device, the server assigns an integer
ID to the stream and that's used in place of the name for all future
messages. The idea is that if you're sending a few bytes at a time of
data, it is overkill to send a 20 byte string with the name whn you
could just send an int32 identifier. I might actually make it an int8.
The wire format for the messages is again closely following the model
used for the earlier audio stream extension.
Regards,
Daniel
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH 1/2] APIs to capture character device data
2009-07-01 16:21 [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1) Daniel P. Berrange
@ 2009-07-01 16:26 ` Daniel P. Berrange
2009-07-01 16:27 ` [Qemu-devel] [PATCH 2/2] VNC char device data stream tunnelling Daniel P. Berrange
` (3 subsequent siblings)
4 siblings, 0 replies; 24+ messages in thread
From: Daniel P. Berrange @ 2009-07-01 16:26 UTC (permalink / raw)
To: qemu-devel
commit b6d541a02ffa3dbff3f0e6a27d7441ff24481185
Author: Daniel P. Berrange <berrange@redhat.com>
Date: Wed Jul 1 14:21:17 2009 +0100
Add APIs for capturing data written to character devices, and
for receiving notification of creation & deletion of character
devices
diff --git a/qemu-char.c b/qemu-char.c
index 287e0cd..bee309c 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -106,6 +106,23 @@
/***********************************************************/
/* character device */
+struct CharCaptureState {
+ struct CharCaptureOps *ops;
+ void *opaque;
+
+ TAILQ_ENTRY(CharCaptureState) next;
+};
+
+struct CharMonitorState {
+ struct CharMonitorOps *ops;
+ void *opaque;
+
+ TAILQ_ENTRY(CharMonitorState) next;
+};
+
+static TAILQ_HEAD(CharMonitorStateHead, CharMonitorState) charmonitors =
+ TAILQ_HEAD_INITIALIZER(charmonitors);
+
static TAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs =
TAILQ_HEAD_INITIALIZER(chardevs);
static int initial_reset_issued;
@@ -146,6 +163,13 @@ void qemu_chr_initial_reset(void)
int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
{
+ CharCaptureState *cap;
+
+ TAILQ_FOREACH(cap, &s->capture, next) {
+ if (cap->ops->capture)
+ (*cap->ops->capture)(cap->opaque, buf, len);
+ }
+
return s->chr_write(s, buf, len);
}
@@ -2215,17 +2239,41 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i
}
if (chr) {
+ CharMonitorState *mon;
+
if (!chr->filename)
chr->filename = qemu_strdup(filename);
chr->init = init;
chr->label = qemu_strdup(label);
TAILQ_INSERT_TAIL(&chardevs, chr, next);
+
+ TAILQ_INIT(&chr->capture);
+
+ TAILQ_FOREACH(mon, &charmonitors, next) {
+ if (mon->ops->opened)
+ (*mon->ops->opened)(chr, mon->opaque);
+ }
}
return chr;
}
void qemu_chr_close(CharDriverState *chr)
{
+ CharMonitorState *mon;
+ CharCaptureState *cap, *captmp;
+
+ TAILQ_FOREACH_SAFE(cap, &chr->capture, next, captmp) {
+ if (cap->ops->destroy)
+ (*cap->ops->destroy)(cap->opaque);
+
+ qemu_free(cap);
+ }
+
+ TAILQ_FOREACH(mon, &charmonitors, next) {
+ if (mon->ops->closing)
+ (*mon->ops->closing)(chr, mon->opaque);
+ }
+
TAILQ_REMOVE(&chardevs, chr, next);
if (chr->chr_close)
chr->chr_close(chr);
@@ -2242,3 +2290,77 @@ void qemu_chr_info(Monitor *mon)
monitor_printf(mon, "%s: filename=%s\n", chr->label, chr->filename);
}
}
+
+
+
+CharCaptureState *qemu_chr_add_capture(CharDriverState *s,
+ struct CharCaptureOps *ops,
+ void *opaque)
+{
+ CharCaptureState *cap;
+
+ cap = qemu_mallocz(sizeof(*cap));
+
+ cap->ops = ops;
+ cap->opaque = opaque;
+
+ TAILQ_INSERT_TAIL(&s->capture, cap, next);
+
+ return cap;
+}
+
+
+void qemu_chr_del_capture(CharDriverState *s,
+ CharCaptureState *cap)
+{
+ TAILQ_REMOVE(&s->capture, cap, next);
+
+ qemu_free(cap);
+}
+
+CharMonitorState *qemu_chr_add_monitor(struct CharMonitorOps *ops,
+ void *opaque)
+{
+ CharMonitorState *mon;
+
+ mon = qemu_mallocz(sizeof(*mon));
+
+ mon->ops = ops;
+ mon->opaque = opaque;
+
+ TAILQ_INSERT_TAIL(&charmonitors, mon, next);
+
+ return mon;
+}
+
+
+void qemu_chr_remove_monitor(CharMonitorState *mon)
+{
+ TAILQ_REMOVE(&charmonitors, mon, next);
+
+ qemu_free(mon);
+}
+
+
+int qemu_chr_iterate(qemu_chr_iterator iter,
+ void *opaque)
+{
+ CharDriverState *chr;
+
+ TAILQ_FOREACH(chr, &chardevs, next) {
+ if ((*iter)(chr, opaque) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+CharDriverState *qemu_chr_fetch(const char *label)
+{
+ CharDriverState *chr;
+
+ TAILQ_FOREACH(chr, &chardevs, next) {
+ if (strcmp(chr->label, label) == 0)
+ return chr;
+ }
+ return NULL;
+}
diff --git a/qemu-char.h b/qemu-char.h
index e1aa8db..94613e7 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -46,6 +46,19 @@ typedef struct {
typedef void IOEventHandler(void *opaque, int event);
+struct CharCaptureOps {
+ void (*capture) (void *opaque, const void *buf, int size);
+ void (*destroy) (void *opaque);
+};
+
+struct CharMonitorOps {
+ void (*opened) (CharDriverState *s, void *opaque);
+ void (*closing) (CharDriverState *s, void *opaque);
+};
+
+typedef struct CharMonitorState CharMonitorState;
+typedef struct CharCaptureState CharCaptureState;
+
struct CharDriverState {
void (*init)(struct CharDriverState *s);
int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len);
@@ -64,6 +77,8 @@ struct CharDriverState {
char *label;
char *filename;
TAILQ_ENTRY(CharDriverState) next;
+
+ TAILQ_HEAD(CharCaptureStateHead, CharCaptureState) capture;
};
CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*init)(struct CharDriverState *s));
@@ -84,6 +99,48 @@ void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len);
void qemu_chr_accept_input(CharDriverState *s);
void qemu_chr_info(Monitor *mon);
+/*
+ * Register to capture all data written to the character
+ * device.
+ */
+CharCaptureState *qemu_chr_add_capture(CharDriverState *s,
+ struct CharCaptureOps *ops,
+ void *opaque);
+
+/*
+ * Unregister a capture register on the character device
+ */
+void qemu_chr_del_capture(CharDriverState *s,
+ CharCaptureState *c);
+
+
+/*
+ * Register to get notifications of the creation and deletion
+ * of character devices
+ */
+CharMonitorState *qemu_chr_add_monitor(struct CharMonitorOps *ops,
+ void *opaque);
+/*
+ * Unregister notification of creation and deletion of
+ * character devices
+ */
+void qemu_chr_del_monitor(CharMonitorState *m);
+
+
+/*
+ * Iterate over all existing character devices
+ */
+typedef int (*qemu_chr_iterator)(CharDriverState *s,
+ void *opaque);
+int qemu_chr_iterate(qemu_chr_iterator iter,
+ void *opaque);
+
+/*
+ * Fetch a character device based on its assigned label
+ */
+CharDriverState *qemu_chr_fetch(const char *label);
+
+
extern int term_escape_char;
/* async I/O support */
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH 2/2] VNC char device data stream tunnelling
2009-07-01 16:21 [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1) Daniel P. Berrange
2009-07-01 16:26 ` [Qemu-devel] [PATCH 1/2] APIs to capture character device data Daniel P. Berrange
@ 2009-07-01 16:27 ` Daniel P. Berrange
2009-07-01 18:44 ` Anthony Liguori
2009-07-01 16:32 ` [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1) Daniel P. Berrange
` (2 subsequent siblings)
4 siblings, 1 reply; 24+ messages in thread
From: Daniel P. Berrange @ 2009-07-01 16:27 UTC (permalink / raw)
To: qemu-devel
commit 71000d52fb4f9a4bef1f4841dd97561416fe5eed
Author: Daniel P. Berrange <berrange@redhat.com>
Date: Wed Jul 1 17:03:46 2009 +0100
Add a new VNC extension to allowing tunnelling of gemeric data streams.
Map QEMU character devices onto VNC data streams
diff --git a/Makefile b/Makefile
index 2a4b3f3..a7de1a5 100644
--- a/Makefile
+++ b/Makefile
@@ -156,7 +156,7 @@ obj-y += $(addprefix audio/, $(audio-obj-y))
obj-y += keymaps.o
obj-$(CONFIG_SDL) += sdl.o sdl_zoom.o x_keymap.o
obj-$(CONFIG_CURSES) += curses.o
-obj-y += vnc.o acl.o d3des.o
+obj-y += vnc.o vnc-char.o acl.o d3des.o
obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o
obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o
obj-$(CONFIG_COCOA) += cocoa.o
diff --git a/vnc-char.c b/vnc-char.c
new file mode 100644
index 0000000..b7b4606
--- /dev/null
+++ b/vnc-char.c
@@ -0,0 +1,401 @@
+/*
+ * QEMU VNC display driver: Char device capture
+ *
+ * Copyright (C) 2009 Red Hat, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "vnc.h"
+
+/*
+ * Encoding #: -260
+ *
+ * The server notifies the client of available streams using the
+ * framebuffer update for our psuedo encoding #.
+ *
+ * The 'x' field is '0' for a device addition, '1' for removal
+ *
+ * The payload of the update is the device name
+ * - u32 - length of device name
+ * - u8 * len - text of device name, not including \0
+ *
+ * When client indicates it accepts the stream encoding,
+ * the server will send back a stream addition update for
+ * each initial device. Hotplug/unplug for streams will
+ * trigger further updates.
+ *
+ * For QEMU, the streams extension maps 1-stream to 1 char device
+ *
+ * Stream capture uses an new 'aliguori' message sub-type. There
+ * are 3 client -> server messages, and 3 server -> client messages
+ *
+ * Client starts capture by supplying a stream name. Server replies
+ * givng the stream name -> stream ID mapping. All further messages
+ * use the unique stream ID.
+ *
+ * Client -> server messages:
+ *
+ * Message == u8: 255 (aliguouri)
+ * sub-type == u8: 2 (streams)
+ * operation == u8:
+ * 0 == start capture
+ * 1 == end capture
+ * 2 == send data
+ *
+ * For operation == start capture:
+ * content:
+ * u32 - length of device name
+ * u8 *len - device name to capture
+ *
+ * For operation == end capture
+ * content:
+ * u32 - capture session ID
+ *
+ * For operation == send data
+ * content:
+ * u32 - capture session ID
+ * u32 - length of data
+ * u8*len - raw data
+ *
+ *
+ *
+ * Server -> client messages:
+ *
+ * Message == u8: 255 (aliguouri)
+ * sub-type == u8: 2 (streams)
+ * operation == u8:
+ * 0 == start capture
+ * 1 == end capture
+ * 2 == send data
+ *
+ * For operation == start capture
+ * content:
+ * u32 - capture session ID
+ * u32 - length of device name
+ * u8 *len - device name to capture
+ *
+ * For operation == end capture
+ * content:
+ * u32 - capture session ID
+ *
+ * For operation == send data
+ * content:
+ * u32 - capture session ID
+ * u32 - length of data
+ * u8*len - raw data
+ */
+
+static void vnc_send_start_capture(VncState *client,
+ VncCharCaptureState *chr);
+static void vnc_send_end_capture(VncState *client,
+ VncCharCaptureState *chr);
+static void vnc_send_data_capture(VncState *client,
+ VncCharCaptureState *chr,
+ const void *buf,
+ int len);
+
+
+static VncCharCaptureState *vnc_char_get_capture(VncState *client,
+ int id)
+{
+ VncCharCaptureState *cap;
+
+ TAILQ_FOREACH(cap, &client->char_cap, next) {
+ if (cap->id == id)
+ return cap;
+ }
+
+ return NULL;
+}
+
+
+/*
+ * From guest device to VNC client
+ */
+static void vnc_char_capture(void *opaque, const void *buf, int len)
+{
+ VncCharCaptureState *cap = opaque;
+
+ if (!cap)
+ return;
+
+ vnc_send_data_capture(cap->client, cap, buf, len);
+}
+
+static void vnc_char_destroy(void *opaque)
+{
+ VncCharCaptureState *cap = opaque;
+
+ if (!cap)
+ return;
+
+ qemu_chr_del_capture(cap->chr, cap->cap);
+ cap->chr = NULL;
+ cap->cap = NULL;
+}
+
+static struct CharCaptureOps vnc_char_capture_ops = {
+ vnc_char_capture,
+ vnc_char_destroy,
+};
+
+
+
+int vnc_char_add_capture(VncState *client,
+ const char *chrname)
+{
+ VncCharCaptureState *cap;
+ CharDriverState *chr;
+
+ chr = qemu_chr_fetch("serial0");
+ if (!chr)
+ return -1;
+
+ cap = qemu_mallocz(sizeof(*cap));
+ cap->id = client->char_cap_next_id++;
+ cap->chr = chr;
+ cap->cap = qemu_chr_add_capture(chr, &vnc_char_capture_ops, cap);
+ cap->client = client;
+
+ TAILQ_INSERT_TAIL(&client->char_cap, cap, next);
+
+ vnc_send_start_capture(client, cap);
+
+ return cap->id;
+}
+
+void vnc_char_del_capture(VncState *client,
+ int id)
+{
+ VncCharCaptureState *cap = vnc_char_get_capture(client, id);
+ if (!cap)
+ return;
+
+ TAILQ_REMOVE(&client->char_cap, cap, next);
+
+ if (cap->chr)
+ qemu_chr_del_capture(cap->chr, cap->cap);
+
+ vnc_send_end_capture(client, cap);
+
+ qemu_free(cap);
+}
+
+void vnc_char_clear_capture(VncState *client)
+{
+ VncCharCaptureState *cap, *tmp;
+
+ TAILQ_FOREACH_SAFE(cap, &client->char_cap, next, tmp) {
+ if (cap->chr)
+ qemu_chr_del_capture(cap->chr, cap->cap);
+
+ qemu_free(cap);
+ }
+}
+
+
+/*
+ * From VNC client to guest device
+ */
+void vnc_char_write(VncState *client,
+ int id,
+ const void *buf,
+ int len)
+{
+ VncCharCaptureState *cap = vnc_char_get_capture(client, id);
+ if (!cap)
+ return; /* XXX kill client */
+
+ if (cap->chr)
+ qemu_chr_write(cap->chr, buf, len);
+}
+
+
+static void
+vnc_framebuffer_update_stream(VncState *client,
+ CharDriverState *chr,
+ int deleted)
+{
+ if (strcmp(chr->label, "monitor") == 0)
+ return;
+
+ vnc_write_u8(client, 0);
+ vnc_write_u8(client, 0);
+ vnc_write_u16(client, 1);
+ vnc_framebuffer_update(client,
+ deleted,
+ 0,
+ ds_get_width(client->ds),
+ ds_get_height(client->ds),
+ VNC_ENCODING_STREAMS);
+ vnc_write_u32(client, strlen(chr->label));
+ vnc_write(client, chr->label, strlen(chr->label));
+}
+
+static int vnc_chr_iterator(CharDriverState *chr, void *opaque) {
+ VncState *client = opaque;
+
+ vnc_framebuffer_update_stream(client, chr, 0);
+ return 0;
+}
+
+
+static void vnc_chr_opened(CharDriverState *chr, void *opaque) {
+ VncState *client = opaque;
+
+ vnc_framebuffer_update_stream(client, chr, 0);
+ vnc_flush(client);
+}
+
+static void vnc_chr_closing(CharDriverState *chr, void *opaque) {
+ VncState *client = opaque;
+
+ vnc_framebuffer_update_stream(client, chr, 1);
+ vnc_flush(client);
+}
+
+static struct CharMonitorOps vnc_monops = {
+ vnc_chr_opened, vnc_chr_closing
+};
+
+void vnc_streams_ack(VncState *client)
+{
+ if (client->char_mon)
+ return;
+
+ qemu_chr_iterate(vnc_chr_iterator, client);
+ vnc_flush(client);
+
+ client->char_mon = qemu_chr_add_monitor(&vnc_monops, client);
+}
+
+
+static void vnc_send_start_capture(VncState *client,
+ VncCharCaptureState *chr) {
+ vnc_write_u8(client, 255);
+ vnc_write_u8(client, 2);
+ vnc_write_u8(client, 0);
+
+ vnc_write_u32(client, chr->id);
+ vnc_write_u32(client, strlen(chr->chr->label));
+ vnc_write(client, chr->chr->label, strlen(chr->chr->label));
+ vnc_flush(client);
+}
+
+
+static void vnc_send_end_capture(VncState *client,
+ VncCharCaptureState *chr) {
+ vnc_write_u8(client, 255);
+ vnc_write_u8(client, 2);
+ vnc_write_u8(client, 1);
+
+ vnc_write_u32(client, chr->id);
+ vnc_flush(client);
+}
+
+
+static void vnc_send_data_capture(VncState *client,
+ VncCharCaptureState *chr,
+ const void *data,
+ int len) {
+ vnc_write_u8(client, 255);
+ vnc_write_u8(client, 2);
+ vnc_write_u8(client, 2);
+
+ vnc_write_u32(client, chr->id);
+ vnc_write_u32(client, len);
+ vnc_write(client, data, len);
+ vnc_flush(client);
+}
+
+
+int vnc_streams_msg(VncState *client, uint8_t *data, int len) {
+ if (len == 2)
+ return 3;
+
+ switch (read_u8(data, 2)) {
+ case 0: {
+ uint32_t n_name;
+ char *name;
+
+ if (len == 3)
+ return 7;
+
+ n_name = read_u32(data, 3);
+ if (n_name > 4096) {
+ vnc_client_error(client);
+ break;
+ }
+
+ if (len == 7)
+ return 7 + n_name;
+
+ name = qemu_malloc(n_name + 1);
+ memcpy(name, data + 7, n_name);
+ name[n_name] = '\0';
+
+ if (strcmp(name, "monitor") == 0) {
+ vnc_client_error(client);
+ qemu_free(name);
+ break;
+ }
+
+ vnc_char_add_capture(client, name);
+ qemu_free(name);
+ } break;
+
+ case 1: {
+ uint32_t id;
+ if (len == 3)
+ return 7;
+
+ id = read_u32(data, 3);
+
+ vnc_char_del_capture(client, id);
+ } break;
+
+ case 2: {
+ uint32_t id;
+ uint32_t n_data;
+ if (len == 3)
+ return 11;
+
+ id = read_u32(data, 3);
+ n_data = read_u32(data, 7);
+
+ if (n_data > 4096) {
+ vnc_client_error(client);
+ break;
+ }
+
+ if (len == 11)
+ return 11 + n_data;
+
+ vnc_char_write(client, id, data + 11, n_data);
+ } break;
+
+ default:
+ printf ("Invalid audio message %d\n", read_u8(data, 4));
+ vnc_client_error(client);
+ break;
+ }
+
+ return 0;
+}
diff --git a/vnc-char.h b/vnc-char.h
new file mode 100644
index 0000000..b421448
--- /dev/null
+++ b/vnc-char.h
@@ -0,0 +1,60 @@
+/*
+ * QEMU VNC display driver: Char device capture
+ *
+ * Copyright (C) 2009 Red Hat, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+
+#ifndef __QEMU_VNC_CHAR_H__
+#define __QEMU_VNC_CHAR_H__
+
+typedef struct VncCharCaptureState VncCharCaptureState;
+struct VncCharCaptureState
+{
+ int id;
+ CharDriverState *chr;
+ CharCaptureState *cap;
+
+ VncState *client;
+
+ TAILQ_ENTRY(VncCharCaptureState) next;
+};
+
+
+int vnc_char_add_capture(VncState *client,
+ const char *chrname);
+
+void vnc_char_del_capture(VncState *client,
+ int id);
+
+void vnc_char_clear_capture(VncState *client);
+
+void vnc_char_write(VncState *client,
+ int id,
+ const void *buf,
+ int len);
+
+void vnc_streams_ack(VncState *client);
+
+int vnc_streams_msg(VncState *client, uint8_t *data, int len);
+
+
+#endif /* __QEMU_VNC_CHAR_H__ */
diff --git a/vnc.c b/vnc.c
index de0ff87..d73ed80 100644
--- a/vnc.c
+++ b/vnc.c
@@ -296,8 +296,8 @@ static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
}
}
-static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
- int32_t encoding)
+void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
+ int32_t encoding)
{
vnc_write_u16(vs, x);
vnc_write_u16(vs, y);
@@ -901,6 +901,8 @@ static void vnc_disconnect_finish(VncState *vs)
#endif /* CONFIG_VNC_SASL */
audio_del(vs);
+ vnc_char_clear_capture(vs);
+
VncState *p, *parent = NULL;
for (p = vs->vd->clients; p != NULL; p = p->next) {
if (p == vs) {
@@ -1523,6 +1525,7 @@ static void send_ext_audio_ack(VncState *vs)
vnc_flush(vs);
}
+
static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
{
int i;
@@ -1564,6 +1567,9 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
case VNC_ENCODING_AUDIO:
send_ext_audio_ack(vs);
break;
+ case VNC_ENCODING_STREAMS:
+ vnc_streams_ack(vs);
+ break;
case VNC_ENCODING_WMVi:
vs->features |= VNC_FEATURE_WMVI_MASK;
break;
@@ -1706,6 +1712,7 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
{
int i;
uint16_t limit;
+ int ret;
switch (data[0]) {
case 0:
@@ -1822,6 +1829,12 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
}
break;
+ case 2:
+ ret = vnc_streams_msg(vs, data, len);
+ if (ret)
+ return ret;
+ break;
+
default:
printf("Msg: %d\n", read_u16(data, 0));
vnc_client_error(vs);
@@ -2082,6 +2095,8 @@ static void vnc_connect(VncDisplay *vd, int csock)
vnc_read_when(vs, protocol_version, 12);
reset_keys(vs);
+ TAILQ_INIT(&vs->char_cap);
+
vs->next = vd->clients;
vd->clients = vs;
diff --git a/vnc.h b/vnc.h
index 3ae95f3..73d9ee5 100644
--- a/vnc.h
+++ b/vnc.h
@@ -31,6 +31,7 @@
#include "console.h"
#include "monitor.h"
#include "audio/audio.h"
+#include "qemu-char.h"
#include <zlib.h>
#include "keymaps.h"
@@ -84,6 +85,7 @@ typedef struct VncDisplay VncDisplay;
#include "vnc-auth-sasl.h"
#endif
+#include "vnc-char.h"
struct VncDisplay
{
@@ -152,6 +154,10 @@ struct VncState
CaptureVoiceOut *audio_cap;
struct audsettings as;
+ TAILQ_HEAD(VncCharCaptureStateHead, VncCharCaptureState) char_cap;
+ int char_cap_next_id;
+ CharMonitorState *char_mon;
+
VncReadEvent *read_handler;
size_t read_handler_expect;
/* input */
@@ -224,6 +230,7 @@ enum {
#define VNC_ENCODING_POINTER_TYPE_CHANGE 0XFFFFFEFF /* -257 */
#define VNC_ENCODING_EXT_KEY_EVENT 0XFFFFFEFE /* -258 */
#define VNC_ENCODING_AUDIO 0XFFFFFEFD /* -259 */
+#define VNC_ENCODING_STREAMS 0XFFFFFEFC /* -260 */
#define VNC_ENCODING_WMVi 0x574D5669
/*****************************************************************************
@@ -303,6 +310,9 @@ int vnc_client_io_error(VncState *vs, int ret, int last_errno);
void start_client_init(VncState *vs);
void start_auth_vnc(VncState *vs);
+void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
+ int32_t encoding);
+
/* Buffer management */
void buffer_reserve(Buffer *buffer, size_t len);
int buffer_empty(Buffer *buffer);
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1)
2009-07-01 16:21 [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1) Daniel P. Berrange
2009-07-01 16:26 ` [Qemu-devel] [PATCH 1/2] APIs to capture character device data Daniel P. Berrange
2009-07-01 16:27 ` [Qemu-devel] [PATCH 2/2] VNC char device data stream tunnelling Daniel P. Berrange
@ 2009-07-01 16:32 ` Daniel P. Berrange
2009-07-01 16:42 ` Gerd Hoffmann
2009-07-01 18:36 ` Anthony Liguori
4 siblings, 0 replies; 24+ messages in thread
From: Daniel P. Berrange @ 2009-07-01 16:32 UTC (permalink / raw)
To: qemu-devel
If anyone wants to actually try this code out, the following patch is
a quick proof of concept hack against GTK-VNC[1] and enables a single data
stream for device 'serial0' just printing the received data to stdout.
eg, start QEMU with
./i386-softmmu/qemu -kernel ~/vmlinuz -serial file:foo.log -append 'console=ttyS0' -vnc :1
And then start GTK-VNC with
./examples/gvncviewer localhost:1
If all goes to plan, gvncviewer should output the kernel boot messages,
and QEMU will be saving them in 'foo.log' as per its config.
Regards,
Daniel
[1] http://git.gnome.org/cgit/gtk-vnc/
diff --git a/src/gvnc.c b/src/gvnc.c
index c3b3163..7cafa0e 100644
--- a/src/gvnc.c
+++ b/src/gvnc.c
@@ -2144,6 +2144,39 @@ static void gvnc_ext_key_event(struct gvnc *gvnc)
gvnc->keycode_map = x_keycode_to_pc_keycode_map();
}
+static void gvnc_stream_event(struct gvnc *gvnc, int deleted)
+{
+ int n_name = gvnc_read_u32(gvnc);
+ char *name;
+ if (gvnc->has_error)
+ return;
+ if (n_name > 4096) {
+ gvnc->has_error = TRUE;
+ return;
+ }
+ name = g_new(char, n_name + 1);
+ gvnc_read(gvnc, name, n_name);
+ name[n_name] = '\0';
+
+ fprintf(stderr, "Got stream %s '%s'\n", deleted ? "del" : "add", name);
+
+ if (strcmp(name, "serial0") == 0) {
+ gvnc_write_u8(gvnc, 255);
+ gvnc_write_u8(gvnc, 2);
+ if (deleted) {
+ gvnc_write_u8(gvnc, 1);
+ gvnc_write_u8(gvnc, 1); /* XXX id */
+ } else {
+ gvnc_write_u8(gvnc, 0);
+ gvnc_write_u32(gvnc, strlen(name));
+ gvnc_write(gvnc, name, strlen(name));
+ }
+ gvnc_flush(gvnc);
+ }
+
+ free(name);
+}
+
static void gvnc_framebuffer_update(struct gvnc *gvnc, int32_t etype,
uint16_t x, uint16_t y,
uint16_t width, uint16_t height)
@@ -2195,6 +2228,10 @@ static void gvnc_framebuffer_update(struct gvnc *gvnc, int32_t etype,
case GVNC_ENCODING_EXT_KEY_EVENT:
gvnc_ext_key_event(gvnc);
break;
+ case GVNC_ENCODING_STREAM_EVENT:
+ fprintf(stderr, "Stream event\n");
+ gvnc_stream_event(gvnc, x);
+ break;
default:
GVNC_DEBUG("Received an unknown encoding type: %d\n", etype);
gvnc->has_error = TRUE;
@@ -2295,6 +2332,58 @@ gboolean gvnc_server_message(struct gvnc *gvnc)
gvnc_server_cut_text(gvnc, data, n_text);
g_free(data);
} break;
+ case 255: {
+ int subtype;
+ subtype = gvnc_read_u8(gvnc);
+ if (subtype != 2) {
+ GVNC_DEBUG("Unknown aliguori message type %d\n", subtype);
+ gvnc->has_error = TRUE;
+ break;
+ }
+ switch (gvnc_read_u8(gvnc)) {
+ case 0: {
+ int id;
+ int n_name;
+ char *name;
+ id = gvnc_read_u32(gvnc);
+ n_name = gvnc_read_u32(gvnc);
+ if (n_name > 4096) {
+ GVNC_DEBUG("Stream name too long %d", n_name);
+ gvnc->has_error = TRUE;
+ break;
+ }
+ name = g_new(char, n_name + 1);
+ gvnc_read(gvnc, name, n_name);
+ name[n_name] = 0;
+ fprintf(stderr, "Stream on %d %s\n", id, name);
+ g_free(name);
+ } break;
+
+ case 1: {
+ int id;
+ id = gvnc_read_u32(gvnc);
+ fprintf(stderr, "Stream off %d\n", id);
+ } break;
+
+ case 2: {
+ int id;
+ int n_data;
+ char *data;
+ id = gvnc_read_u32(gvnc);
+ n_data = gvnc_read_u32(gvnc);
+ if (n_data > 4096) {
+ GVNC_DEBUG("Stream data too long %d", n_data);
+ gvnc->has_error = TRUE;
+ break;
+ }
+ data = g_new(char, n_data + 1);
+ gvnc_read(gvnc, data, n_data);
+ data[n_data] = 0;
+ fprintf(stderr, "%s", data);
+ g_free(data);
+ } break;
+ }
+ } break;
default:
GVNC_DEBUG("Received an unknown message: %u\n", msg);
gvnc->has_error = TRUE;
diff --git a/src/gvnc.h b/src/gvnc.h
index f748de0..4c3d214 100644
--- a/src/gvnc.h
+++ b/src/gvnc.h
@@ -117,6 +117,7 @@ typedef enum {
GVNC_ENCODING_POINTER_CHANGE = -257,
GVNC_ENCODING_EXT_KEY_EVENT = -258,
+ GVNC_ENCODING_STREAM_EVENT = -260,
} gvnc_encoding;
typedef enum {
diff --git a/src/vncdisplay.c b/src/vncdisplay.c
index 6c7b662..da42434 100644
--- a/src/vncdisplay.c
+++ b/src/vncdisplay.c
@@ -1306,6 +1306,7 @@ static void *vnc_coroutine(void *opaque)
/* this order is extremely important! */
int32_t encodings[] = { GVNC_ENCODING_TIGHT_JPEG5,
GVNC_ENCODING_TIGHT,
+ GVNC_ENCODING_STREAM_EVENT,
GVNC_ENCODING_EXT_KEY_EVENT,
GVNC_ENCODING_DESKTOP_RESIZE,
GVNC_ENCODING_WMVi,
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1)
2009-07-01 16:21 [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1) Daniel P. Berrange
` (2 preceding siblings ...)
2009-07-01 16:32 ` [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1) Daniel P. Berrange
@ 2009-07-01 16:42 ` Gerd Hoffmann
2009-07-01 16:50 ` Daniel P. Berrange
2009-07-01 18:36 ` Anthony Liguori
4 siblings, 1 reply; 24+ messages in thread
From: Gerd Hoffmann @ 2009-07-01 16:42 UTC (permalink / raw)
To: Daniel P. Berrange; +Cc: qemu-devel
Hi,
> The key requirement here is that it should not
> be neccessary to specifically configure each character device to make
> it available via VNC. The admin should be able to configure the char
> devices with all current available backends (file, pty, null, tcp, udp,
> unix, etc), and regardless of this config be able to snoop on data from
> any active VNC client on demand.
Hmm. What is the reason to handle vnc different from
unix/tcp/pty/whatever? I would expect something like '-serial
vnc,name=foo' here ...
cheers,
Gerd
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1)
2009-07-01 16:42 ` Gerd Hoffmann
@ 2009-07-01 16:50 ` Daniel P. Berrange
2009-07-01 17:30 ` Gerd Hoffmann
0 siblings, 1 reply; 24+ messages in thread
From: Daniel P. Berrange @ 2009-07-01 16:50 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
On Wed, Jul 01, 2009 at 06:42:31PM +0200, Gerd Hoffmann wrote:
> Hi,
>
> > The key requirement here is that it should not
> >be neccessary to specifically configure each character device to make
> >it available via VNC. The admin should be able to configure the char
> >devices with all current available backends (file, pty, null, tcp, udp,
> >unix, etc), and regardless of this config be able to snoop on data from
> >any active VNC client on demand.
>
> Hmm. What is the reason to handle vnc different from
> unix/tcp/pty/whatever? I would expect something like '-serial
> vnc,name=foo' here ...
As I tried to explain, I want to be able to configure the serial devices
using the existing backends *AND* also have the ability to occassionally
access the data using a VNC client. VNC is not intended to be the main
character device backend here - it is just a way to snooping on the data
being sent to another backend. For the same reason, audio capture over
VNC does not impact the way you configure sound cards to use SDL/pulseaudio
alsa/esd/etc, it just gives you the means to capture the audio data when
connected with VNC.
You could also envision QEMU getting the ability to add/remove display
backends like SDL/VNC on the fly. Thus VNC might not even be configured
when starting up the guest and specifying character device backend
configs. The capture approach deals with that problem trivially.
Daniel
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1)
2009-07-01 16:50 ` Daniel P. Berrange
@ 2009-07-01 17:30 ` Gerd Hoffmann
2009-07-01 18:50 ` Daniel P. Berrange
2009-07-01 18:51 ` Anthony Liguori
0 siblings, 2 replies; 24+ messages in thread
From: Gerd Hoffmann @ 2009-07-01 17:30 UTC (permalink / raw)
To: Daniel P. Berrange; +Cc: qemu-devel
On 07/01/09 18:50, Daniel P. Berrange wrote:
> On Wed, Jul 01, 2009 at 06:42:31PM +0200, Gerd Hoffmann wrote:
>> Hi,
>>
>>> The key requirement here is that it should not
>>> be neccessary to specifically configure each character device to make
>>> it available via VNC. The admin should be able to configure the char
>>> devices with all current available backends (file, pty, null, tcp, udp,
>>> unix, etc), and regardless of this config be able to snoop on data from
>>> any active VNC client on demand.
>> Hmm. What is the reason to handle vnc different from
>> unix/tcp/pty/whatever? I would expect something like '-serial
>> vnc,name=foo' here ...
>
> As I tried to explain, I want to be able to configure the serial devices
> using the existing backends *AND* also have the ability to occassionally
> access the data using a VNC client.
That doesn't answer the question why vnc should be different.
I *do* see the point of being able to have more than one way to access a
chardev at the same time. But when building up that infrastructure:
Why stop half-way through and make it a special hack for vnc? I think
it would be *far* more useful to make chardevs in qemu work that way all
the time.
Each serial-type driver gets a name tag (either user-specified or
autogenerated). chardev backends connect by name. Advantages:
(1) It is a step forward to a clear split of guest and host state.
(2) Better test coverage because everybody uses the same code paths.
(3) You can connect multiple backends to the chardev. For example
you can log the console to a file and work interactively via
pty at the same time.
(4) We can allow multiple connections for unix/tcp sockets (pretty
much like the vnc server handles multiple clients today).
Bonus points for making that configurable via monitor, so you can start
console logging on the fly. serial console via vnc data stream then
will be just the sugar on top ;)
> VNC is not intended to be the main
> character device backend here
I'd like to question the concept of a "main chardev backend".
cheers,
Gerd
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1)
2009-07-01 16:21 [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1) Daniel P. Berrange
` (3 preceding siblings ...)
2009-07-01 16:42 ` Gerd Hoffmann
@ 2009-07-01 18:36 ` Anthony Liguori
2009-07-01 18:44 ` Daniel P. Berrange
4 siblings, 1 reply; 24+ messages in thread
From: Anthony Liguori @ 2009-07-01 18:36 UTC (permalink / raw)
To: Daniel P. Berrange; +Cc: qemu-devel
Daniel P. Berrange wrote:
> The following two patches make it possible to tunnel character devices
> over VNC, using a new VNC extension. This is motivated by the existing
> QEMU support for tunnelling audio streams over VNC, and the code follows
> a very similar design. The key requirement here is that it should not
> be neccessary to specifically configure each character device to make
> it available via VNC. The admin should be able to configure the char
> devices with all current available backends (file, pty, null, tcp, udp,
> unix, etc), and regardless of this config be able to snoop on data from
> any active VNC client on demand.
>
Shouldn't it just be the character devices put on vc's?
Does snooping imply read-only? That would be pretty unfortunate.
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH 2/2] VNC char device data stream tunnelling
2009-07-01 16:27 ` [Qemu-devel] [PATCH 2/2] VNC char device data stream tunnelling Daniel P. Berrange
@ 2009-07-01 18:44 ` Anthony Liguori
0 siblings, 0 replies; 24+ messages in thread
From: Anthony Liguori @ 2009-07-01 18:44 UTC (permalink / raw)
To: Daniel P. Berrange; +Cc: qemu-devel
Daniel P. Berrange wrote:
> +/*
> + * Encoding #: -260
> + *
> + * The server notifies the client of available streams using the
> + * framebuffer update for our psuedo encoding #.
> + *
> + * The 'x' field is '0' for a device addition, '1' for removal
> + *
> + * The payload of the update is the device name
> + * - u32 - length of device name
> + * - u8 * len - text of device name, not including \0
> + *
> + * When client indicates it accepts the stream encoding,
> + * the server will send back a stream addition update for
> + * each initial device. Hotplug/unplug for streams will
> + * trigger further updates.
> + *
> + * For QEMU, the streams extension maps 1-stream to 1 char device
> + *
> + * Stream capture uses an new 'aliguori' message sub-type. There
> + * are 3 client -> server messages, and 3 server -> client messages
> + *
> + * Client starts capture by supplying a stream name. Server replies
> + * givng the stream name -> stream ID mapping. All further messages
> + * use the unique stream ID.
> + *
> + * Client -> server messages:
> + *
> + * Message == u8: 255 (aliguouri)
> + * sub-type == u8: 2 (streams)
> + * operation == u8:
> + * 0 == start capture
> + * 1 == end capture
> + * 2 == send data
> + *
> + * For operation == start capture:
> + * content:
> + * u32 - length of device name
> + * u8 *len - device name to capture
> + *
> + * For operation == end capture
> + * content:
> + * u32 - capture session ID
> + *
> + * For operation == send data
> + * content:
> + * u32 - capture session ID
> + * u32 - length of data
> + * u8*len - raw data
> + *
> + *
> + *
> + * Server -> client messages:
> + *
> + * Message == u8: 255 (aliguouri)
> + * sub-type == u8: 2 (streams)
> + * operation == u8:
> + * 0 == start capture
> + * 1 == end capture
> + * 2 == send data
> + *
> + * For operation == start capture
> + * content:
> + * u32 - capture session ID
> + * u32 - length of device name
> + * u8 *len - device name to capture
> + *
> + * For operation == end capture
> + * content:
> + * u32 - capture session ID
> + *
> + * For operation == send data
> + * content:
> + * u32 - capture session ID
> + * u32 - length of data
> + * u8*len - raw data
> + *
Acked-by: Anthony Liguori <aliguori@us.ibm.com> on the protocol encoding
Do you have gtk-vnc patches yet?
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1)
2009-07-01 18:36 ` Anthony Liguori
@ 2009-07-01 18:44 ` Daniel P. Berrange
2009-07-01 18:47 ` Anthony Liguori
0 siblings, 1 reply; 24+ messages in thread
From: Daniel P. Berrange @ 2009-07-01 18:44 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
On Wed, Jul 01, 2009 at 01:36:23PM -0500, Anthony Liguori wrote:
> Daniel P. Berrange wrote:
> >The following two patches make it possible to tunnel character devices
> >over VNC, using a new VNC extension. This is motivated by the existing
> >QEMU support for tunnelling audio streams over VNC, and the code follows
> >a very similar design. The key requirement here is that it should not
> >be neccessary to specifically configure each character device to make
> >it available via VNC. The admin should be able to configure the char
> >devices with all current available backends (file, pty, null, tcp, udp,
> >unix, etc), and regardless of this config be able to snoop on data from
> >any active VNC client on demand.
> >
>
> Shouldn't it just be the character devices put on vc's?
The 'vc' concept is a stateful one, requiring the user to switch betweeen
channels statically and is opaque to VNC clients - all they see is a
framebuffer with no idea that QEMU has this magic sequence to change
what the framebuffer displays, nor what vc's are available. The idea of
this extension is to make data streams a protocol level concept so they
can be more intelligently handled by the client, with the VNC protocol
extension not being QEMU specific, so our VNC servers could make use of
this in ways that suits.
> Does snooping imply read-only? That would be pretty unfortunate.
No, its fully read-write. My gtk-vnc client so far only does reads,
but the QEMU server allows read+write - see the comments about the
protocol messages in the 2nd patch for details.
Daniel
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1)
2009-07-01 18:44 ` Daniel P. Berrange
@ 2009-07-01 18:47 ` Anthony Liguori
2009-07-01 18:52 ` Daniel P. Berrange
0 siblings, 1 reply; 24+ messages in thread
From: Anthony Liguori @ 2009-07-01 18:47 UTC (permalink / raw)
To: Daniel P. Berrange; +Cc: qemu-devel
Daniel P. Berrange wrote:
> On Wed, Jul 01, 2009 at 01:36:23PM -0500, Anthony Liguori wrote:
>
>> Daniel P. Berrange wrote:
>>
>>> The following two patches make it possible to tunnel character devices
>>> over VNC, using a new VNC extension. This is motivated by the existing
>>> QEMU support for tunnelling audio streams over VNC, and the code follows
>>> a very similar design. The key requirement here is that it should not
>>> be neccessary to specifically configure each character device to make
>>> it available via VNC. The admin should be able to configure the char
>>> devices with all current available backends (file, pty, null, tcp, udp,
>>> unix, etc), and regardless of this config be able to snoop on data from
>>> any active VNC client on demand.
>>>
>>>
>> Shouldn't it just be the character devices put on vc's?
>>
>
> The 'vc' concept is a stateful one, requiring the user to switch betweeen
> channels statically and is opaque to VNC clients - all they see is a
> framebuffer with no idea that QEMU has this magic sequence to change
> what the framebuffer displays, nor what vc's are available.
I understand what you're suggesting, but I think the right way to handle
this use-case is to allow character devices to be redirected after
initial open making them truly dynamic.
This would be useful outside of VNC too.
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1)
2009-07-01 17:30 ` Gerd Hoffmann
@ 2009-07-01 18:50 ` Daniel P. Berrange
2009-07-01 19:27 ` Gerd Hoffmann
2009-07-01 18:51 ` Anthony Liguori
1 sibling, 1 reply; 24+ messages in thread
From: Daniel P. Berrange @ 2009-07-01 18:50 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
On Wed, Jul 01, 2009 at 07:30:23PM +0200, Gerd Hoffmann wrote:
> On 07/01/09 18:50, Daniel P. Berrange wrote:
> >On Wed, Jul 01, 2009 at 06:42:31PM +0200, Gerd Hoffmann wrote:
> >> Hi,
> >>
> >>>The key requirement here is that it should not
> >>>be neccessary to specifically configure each character device to make
> >>>it available via VNC. The admin should be able to configure the char
> >>>devices with all current available backends (file, pty, null, tcp, udp,
> >>>unix, etc), and regardless of this config be able to snoop on data from
> >>>any active VNC client on demand.
> >>Hmm. What is the reason to handle vnc different from
> >>unix/tcp/pty/whatever? I would expect something like '-serial
> >>vnc,name=foo' here ...
> >
> >As I tried to explain, I want to be able to configure the serial devices
> >using the existing backends *AND* also have the ability to occassionally
> >access the data using a VNC client.
>
> That doesn't answer the question why vnc should be different.
>
> I *do* see the point of being able to have more than one way to access a
> chardev at the same time. But when building up that infrastructure:
> Why stop half-way through and make it a special hack for vnc? I think
> it would be *far* more useful to make chardevs in qemu work that way all
> the time.
Ok, if i'm understanding correctly, you're suggesting we change the way
character devices are configured on the CLI, to be split like the NIC
device args
eg, instead of
-serial file:/tmp/foo.log,name=serial0
we'd do
-serial name=serial0 -chardev name=serial0,file:/tmp/foo.log
And allow an 1-m mapping for serial -> chardev args
This could perhaps be done by having a 'CharDriverState' implementation
that was a multiplexor, and allow further CharDriverState instances to
be added/removed to this multiplexor on the fly.
Thus the CharCaptureOps/State bit of my patch would just be another
CharDriverState impl, that gets added/removed on the fly. The
CharMonitorOps/State bit would still be needed to allow monitoring
of device creation/deletion.
Daniel
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1)
2009-07-01 17:30 ` Gerd Hoffmann
2009-07-01 18:50 ` Daniel P. Berrange
@ 2009-07-01 18:51 ` Anthony Liguori
2009-07-01 19:41 ` Gerd Hoffmann
1 sibling, 1 reply; 24+ messages in thread
From: Anthony Liguori @ 2009-07-01 18:51 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
Gerd Hoffmann wrote:
> On 07/01/09 18:50, Daniel P. Berrange wrote:
>> On Wed, Jul 01, 2009 at 06:42:31PM +0200, Gerd Hoffmann wrote:
>>> Hi,
>>>
>>>> The key requirement here is that it should not
>>>> be neccessary to specifically configure each character device to make
>>>> it available via VNC. The admin should be able to configure the char
>>>> devices with all current available backends (file, pty, null, tcp,
>>>> udp,
>>>> unix, etc), and regardless of this config be able to snoop on data
>>>> from
>>>> any active VNC client on demand.
>>> Hmm. What is the reason to handle vnc different from
>>> unix/tcp/pty/whatever? I would expect something like '-serial
>>> vnc,name=foo' here ...
>>
>> As I tried to explain, I want to be able to configure the serial devices
>> using the existing backends *AND* also have the ability to occassionally
>> access the data using a VNC client.
>
> That doesn't answer the question why vnc should be different.
>
> I *do* see the point of being able to have more than one way to access
> a chardev at the same time. But when building up that infrastructure:
> Why stop half-way through and make it a special hack for vnc? I think
> it would be *far* more useful to make chardevs in qemu work that way
> all the time.
>
> Each serial-type driver gets a name tag (either user-specified or
> autogenerated). chardev backends connect by name. Advantages:
Dynamically changing the character devices backends should be a not too
terrible thing to do today and I agree this is the right approach.
Allowing multiple readers/writers for character devices is much more
complex to get right though. The current chardev API does not have good
semantics for just handling one client that connects and disconnects.
It certainly wouldn't gracefully handle multiple client states at once.
You could do something like a mirrored mode but things get really ugly
when dealing with multiple read-write clients. Think of how that would
behave with the monitor for instance.
I agree that for something like -monitor tcp::1025,server,nowait, you
want to be able to connect multiple times and get multiple monitor
sessions. We would need a serious overhaul of the character device
infrastructure for that (and that's certainly long overdue). So IMHO,
this sort of refactoring shouldn't be a requirement for this patch series.
That doesn't mean we want to take a VNC specific hack though.
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1)
2009-07-01 18:47 ` Anthony Liguori
@ 2009-07-01 18:52 ` Daniel P. Berrange
2009-07-01 19:11 ` Anthony Liguori
0 siblings, 1 reply; 24+ messages in thread
From: Daniel P. Berrange @ 2009-07-01 18:52 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
On Wed, Jul 01, 2009 at 01:47:12PM -0500, Anthony Liguori wrote:
> Daniel P. Berrange wrote:
> >On Wed, Jul 01, 2009 at 01:36:23PM -0500, Anthony Liguori wrote:
> >
> >>Daniel P. Berrange wrote:
> >>
> >>>The following two patches make it possible to tunnel character devices
> >>>over VNC, using a new VNC extension. This is motivated by the existing
> >>>QEMU support for tunnelling audio streams over VNC, and the code follows
> >>>a very similar design. The key requirement here is that it should not
> >>>be neccessary to specifically configure each character device to make
> >>>it available via VNC. The admin should be able to configure the char
> >>>devices with all current available backends (file, pty, null, tcp, udp,
> >>>unix, etc), and regardless of this config be able to snoop on data from
> >>>any active VNC client on demand.
> >>>
> >>>
> >>Shouldn't it just be the character devices put on vc's?
> >>
> >
> >The 'vc' concept is a stateful one, requiring the user to switch betweeen
> >channels statically and is opaque to VNC clients - all they see is a
> >framebuffer with no idea that QEMU has this magic sequence to change
> >what the framebuffer displays, nor what vc's are available.
>
> I understand what you're suggesting, but I think the right way to handle
> this use-case is to allow character devices to be redirected after
> initial open making them truly dynamic.
The 'vc' reference was puzzelling to me there, but I think you're
basically suggesting the same thing as Gerd is ? To fully de-couple
the device specification vs backend configuration
Daniel
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1)
2009-07-01 18:52 ` Daniel P. Berrange
@ 2009-07-01 19:11 ` Anthony Liguori
2009-07-01 19:27 ` Daniel P. Berrange
0 siblings, 1 reply; 24+ messages in thread
From: Anthony Liguori @ 2009-07-01 19:11 UTC (permalink / raw)
To: Daniel P. Berrange; +Cc: qemu-devel
Daniel P. Berrange wrote:
> On Wed, Jul 01, 2009 at 01:47:12PM -0500, Anthony Liguori wrote:
>
>> Daniel P. Berrange wrote:
>>
>>> On Wed, Jul 01, 2009 at 01:36:23PM -0500, Anthony Liguori wrote:
>>>
>>>
>>>> Daniel P. Berrange wrote:
>>>>
>>>>
>>>>> The following two patches make it possible to tunnel character devices
>>>>> over VNC, using a new VNC extension. This is motivated by the existing
>>>>> QEMU support for tunnelling audio streams over VNC, and the code follows
>>>>> a very similar design. The key requirement here is that it should not
>>>>> be neccessary to specifically configure each character device to make
>>>>> it available via VNC. The admin should be able to configure the char
>>>>> devices with all current available backends (file, pty, null, tcp, udp,
>>>>> unix, etc), and regardless of this config be able to snoop on data from
>>>>> any active VNC client on demand.
>>>>>
>>>>>
>>>>>
>>>> Shouldn't it just be the character devices put on vc's?
>>>>
>>>>
>>> The 'vc' concept is a stateful one, requiring the user to switch betweeen
>>> channels statically and is opaque to VNC clients - all they see is a
>>> framebuffer with no idea that QEMU has this magic sequence to change
>>> what the framebuffer displays, nor what vc's are available.
>>>
>> I understand what you're suggesting, but I think the right way to handle
>> this use-case is to allow character devices to be redirected after
>> initial open making them truly dynamic.
>>
>
> The 'vc' reference was puzzelling to me there, but I think you're
> basically suggesting the same thing as Gerd is ? To fully de-couple
> the device specification vs backend configuration
>
Well, I'm saying, a character device should be exposed via VNC IIF it's
connected to a 'vc' backend device. In order to satisfy your use-case,
I'd also suggest decoupling the monitor front-end's from back-ends so
that you can reconnect a character device to a 'vc' if you want to.
The easiest way (albeit a little ugly) to do this would be to create a
pluggable character device that proxied to another character device.
Change qemu_chr_open() to return qemu_chr_open_proxy(chr, label).
You can then enumerate proxies by label and retarget the proxy to a
different device.
Regards,
Anthony Liguori
> Daniel
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1)
2009-07-01 19:11 ` Anthony Liguori
@ 2009-07-01 19:27 ` Daniel P. Berrange
0 siblings, 0 replies; 24+ messages in thread
From: Daniel P. Berrange @ 2009-07-01 19:27 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
On Wed, Jul 01, 2009 at 02:11:23PM -0500, Anthony Liguori wrote:
> Daniel P. Berrange wrote:
> >On Wed, Jul 01, 2009 at 01:47:12PM -0500, Anthony Liguori wrote:
> >
> >>Daniel P. Berrange wrote:
> >>
> >>>On Wed, Jul 01, 2009 at 01:36:23PM -0500, Anthony Liguori wrote:
> >>>
> >>>
> >>>>Daniel P. Berrange wrote:
> >>>>
> >>>>
> >>>>>The following two patches make it possible to tunnel character devices
> >>>>>over VNC, using a new VNC extension. This is motivated by the existing
> >>>>>QEMU support for tunnelling audio streams over VNC, and the code
> >>>>>follows
> >>>>>a very similar design. The key requirement here is that it should not
> >>>>>be neccessary to specifically configure each character device to make
> >>>>>it available via VNC. The admin should be able to configure the char
> >>>>>devices with all current available backends (file, pty, null, tcp, udp,
> >>>>>unix, etc), and regardless of this config be able to snoop on data from
> >>>>>any active VNC client on demand.
> >>>>>
> >>>>>
> >>>>>
> >>>>Shouldn't it just be the character devices put on vc's?
> >>>>
> >>>>
> >>>The 'vc' concept is a stateful one, requiring the user to switch betweeen
> >>>channels statically and is opaque to VNC clients - all they see is a
> >>>framebuffer with no idea that QEMU has this magic sequence to change
> >>>what the framebuffer displays, nor what vc's are available.
> >>>
> >>I understand what you're suggesting, but I think the right way to handle
> >>this use-case is to allow character devices to be redirected after
> >>initial open making them truly dynamic.
> >>
> >
> >The 'vc' reference was puzzelling to me there, but I think you're
> >basically suggesting the same thing as Gerd is ? To fully de-couple
> >the device specification vs backend configuration
> >
>
> Well, I'm saying, a character device should be exposed via VNC IIF it's
> connected to a 'vc' backend device. In order to satisfy your use-case,
> I'd also suggest decoupling the monitor front-end's from back-ends so
> that you can reconnect a character device to a 'vc' if you want to.
Ah, now I see what you mean :-) FYI, the two main deployment scenarios
I am thinking of are
- Serial port connected to a /dev/pts in host (eg, so host admin can
locally run minicom / virsh console to interact with guest,
eg QEMU is launched with -serial pty
- Serial port connected to a file to log all data that is transmitted
eg QEMU is launched with -serial file:/var/log/qemu/foo.log
Dynamically, rebinding backend to the 'vc' in order to access it from
a VNC client would certainly be doable in the first scenario, as there
is no benefit in keeping it accessible via the pty, while its used over
VNC.
I'm not sure if dynamically re-binding is sufficiently flexible for the
second case, since you'd get an interruption in data logging to the file.
Similarly if using the 'udp' char driver to log to a netconsole server.
Perhaps we could just live with that restriction for the short term
though, and worry about full concurrent usage at a later date.
> The easiest way (albeit a little ugly) to do this would be to create a
> pluggable character device that proxied to another character device.
> Change qemu_chr_open() to return qemu_chr_open_proxy(chr, label).
>
> You can then enumerate proxies by label and retarget the proxy to a
> different device.
That sounds doable to me - I'll have a go at changing it to work that
way.
Regards,
Daniel
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1)
2009-07-01 18:50 ` Daniel P. Berrange
@ 2009-07-01 19:27 ` Gerd Hoffmann
0 siblings, 0 replies; 24+ messages in thread
From: Gerd Hoffmann @ 2009-07-01 19:27 UTC (permalink / raw)
To: Daniel P. Berrange; +Cc: qemu-devel
On 07/01/09 20:50, Daniel P. Berrange wrote:
> On Wed, Jul 01, 2009 at 07:30:23PM +0200, Gerd Hoffmann wrote:
>> I *do* see the point of being able to have more than one way to access a
>> chardev at the same time. But when building up that infrastructure:
>> Why stop half-way through and make it a special hack for vnc? I think
>> it would be *far* more useful to make chardevs in qemu work that way all
>> the time.
>
> Ok, if i'm understanding correctly, you're suggesting we change the way
> character devices are configured on the CLI, to be split like the NIC
> device args
>
> eg, instead of
>
> -serial file:/tmp/foo.log,name=serial0
>
> we'd do
>
> -serial name=serial0 -chardev name=serial0,file:/tmp/foo.log
>
> And allow an 1-m mapping for serial -> chardev args
Yes.
> This could perhaps be done by having a 'CharDriverState' implementation
> that was a multiplexor, and allow further CharDriverState instances to
> be added/removed to this multiplexor on the fly.
Hmm, don't like that idea.
> Thus the CharCaptureOps/State bit of my patch would just be another
> CharDriverState impl, that gets added/removed on the fly.
I'd keep the CharCaptureOps/State and CharDriverState separation as it
is now. CharCapture would probably better named CharBackend or simliar.
CharDriverState would simply dispatch to all CharBackends connected.
We can keep the old code path working for a while. So we can switch
users one by one to the new way. When done zap the old one and make
CharDiverState a pure dispatcher for the Backends.
> The
> CharMonitorOps/State bit would still be needed to allow monitoring
> of device creation/deletion.
Yes.
cheers,
Gerd
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1)
2009-07-01 18:51 ` Anthony Liguori
@ 2009-07-01 19:41 ` Gerd Hoffmann
2009-07-01 19:59 ` Anthony Liguori
0 siblings, 1 reply; 24+ messages in thread
From: Gerd Hoffmann @ 2009-07-01 19:41 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
On 07/01/09 20:51, Anthony Liguori wrote:
> Allowing multiple readers/writers for character devices is much more
> complex to get right though. The current chardev API does not have good
> semantics for just handling one client that connects and disconnects. It
> certainly wouldn't gracefully handle multiple client states at once.
>
> You could do something like a mirrored mode but things get really ugly
> when dealing with multiple read-write clients.
I'm thinking about mirrored mode of course. Everything else doesn't
make sense for guest devices. And you have that issue with Dan's
current code already: -serial unix:, then connect via socket and via
vnc. Voila, two read-write clients.
> Think of how that would
> behave with the monitor for instance.
> I agree that for something like -monitor tcp::1025,server,nowait, you
> want to be able to connect multiple times and get multiple monitor
> sessions.
Monitor is a special case. Multiple connections to the same session are
not very useful there. Multiple sessions are a different (albeit
related) problem.
cheers,
Gerd
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1)
2009-07-01 19:41 ` Gerd Hoffmann
@ 2009-07-01 19:59 ` Anthony Liguori
2009-07-01 20:56 ` Gerd Hoffmann
2009-07-01 21:07 ` Daniel P. Berrange
0 siblings, 2 replies; 24+ messages in thread
From: Anthony Liguori @ 2009-07-01 19:59 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
Gerd Hoffmann wrote:
> Monitor is a special case. Multiple connections to the same session
> are not very useful there. Multiple sessions are a different (albeit
> related) problem.
Serial is the same. Imagine a bash shell running on the serial port
with two VNC client connected and stdio connected. Utter chaos. You
really want to use one or the other, never both at the same time. If
that's the case, then just switch the character device on the fly.
Don't pretend that we can arbitrate multiple clients at once.
Regards,
Anthony Liguori
> cheers,
> Gerd
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1)
2009-07-01 19:59 ` Anthony Liguori
@ 2009-07-01 20:56 ` Gerd Hoffmann
2009-07-01 21:32 ` Anthony Liguori
2009-07-02 2:30 ` Jamie Lokier
2009-07-01 21:07 ` Daniel P. Berrange
1 sibling, 2 replies; 24+ messages in thread
From: Gerd Hoffmann @ 2009-07-01 20:56 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
On 07/01/09 21:59, Anthony Liguori wrote:
> Gerd Hoffmann wrote:
>> Monitor is a special case. Multiple connections to the same session
>> are not very useful there. Multiple sessions are a different (albeit
>> related) problem.
>
> Serial is the same. Imagine a bash shell running on the serial port with
> two VNC client connected and stdio connected. Utter chaos. You really
> want to use one or the other, never both at the same time.
Typing to both at the same time isn't going to work well indeed. IMHO
that isn't a reason to enforce one connection only though. It is still
a useful feature. Use case:
vm running at your workstation in the office, with -serial tcp. You are
heading home, leaving telnet connected. At home you'll find you want to
check something in your vm via vpn.
With current qemu: You have to zap the telnet session somehow to be
able to connect.
With switching: You have to talk to the monitor to reconfigure things.
With multiple connections and multiplexing: You'll just connect, type a
few commands, disconnect, done. You'll even see what you have done when
you come back to the office the next day.
Also note that the vnc server accepts input from multiple clients as
well, which can lead to simliar problems. Nobody wants to kill support
for multiple clients just because of that, because in practice it isn't
a issue.
Monitor is different for two reasons:
First, we could actually open a new session. That wouldn't work for
serial as we can't hotplug a serial line into the guest on connect.
Second, if the monitor is used by libvirt or some other management app a
second connection to the same session is seriously harmful.
cheers,
Gerd
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1)
2009-07-01 19:59 ` Anthony Liguori
2009-07-01 20:56 ` Gerd Hoffmann
@ 2009-07-01 21:07 ` Daniel P. Berrange
1 sibling, 0 replies; 24+ messages in thread
From: Daniel P. Berrange @ 2009-07-01 21:07 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Gerd Hoffmann, qemu-devel
On Wed, Jul 01, 2009 at 02:59:23PM -0500, Anthony Liguori wrote:
> Gerd Hoffmann wrote:
> >Monitor is a special case. Multiple connections to the same session
> >are not very useful there. Multiple sessions are a different (albeit
> >related) problem.
>
> Serial is the same. Imagine a bash shell running on the serial port
> with two VNC client connected and stdio connected. Utter chaos. You
> really want to use one or the other, never both at the same time. If
> that's the case, then just switch the character device on the fly.
> Don't pretend that we can arbitrate multiple clients at once.
This isn't really any different to have 2 VNC clients connected at the
same time and using the same Xorg/gnome-terminal instance concurrently.
There's no QEMU level technical problem with mirroring updates to multiple
clients. For it to be useful though, it does require that the people/thing
using each client is 'intelligent', otherwise they'll just end up fighting
with each other. So I think this is more of a policy decision - for both
VNC clients on the graphical console, and multiple char device clients -
for each device you could designate 'exclusive' (only one backend at a time),
"exclusive read/write+shared readonly (one backend can read+write, others
are forced read only), or 'shared read/write' (every backend can read+write).
This kind of policy is done by many traditional VNC servers, and we could
add it to QEMU without too much trouble I reckon.
For a backend that's intended to be used by some program/service (eg RPC
message bus), then exlusive would clearly be required. For a backend
that's intended to be used interactively by a real person, then any of
the policies could be practical.
Regards,
Daniel
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1)
2009-07-01 20:56 ` Gerd Hoffmann
@ 2009-07-01 21:32 ` Anthony Liguori
2009-07-01 22:46 ` Gerd Hoffmann
2009-07-02 2:30 ` Jamie Lokier
1 sibling, 1 reply; 24+ messages in thread
From: Anthony Liguori @ 2009-07-01 21:32 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
Gerd Hoffmann wrote:
> With multiple connections and multiplexing: You'll just connect, type
> a few commands, disconnect, done. You'll even see what you have done
> when you come back to the office the next day.
>
> Also note that the vnc server accepts input from multiple clients as
> well, which can lead to simliar problems. Nobody wants to kill
> support for multiple clients just because of that, because in practice
> it isn't a issue.
I don't disagree with your use-case. What I'm pointing out, is that we
need to do some major surgery to get there.
The current chardev protocol has no real notion of flow control and
assumes a static bidirectional channel between the front-end and
back-end. Flow control policy is inconsistent and those decisions are
made in the back-end (i.e. tcp:).
We really need to push flow-control to be a proper part of the protocol
though so that the front-end can participate. For instance,
virtio-console/serial is fully capable of implementing flow control.
Punting buffering policy to the guest is IMHO the best possible solution
to the general problem.
Having multiple connections within a chardev really also needs to be
part of the monitor protocol because it's fundamental to flow-control.
We want the front-end to have enough information to know how many
clients are connected and which ones are ready to receive.
When dealing with a single I/O source, it should be front-end policy to
determine what to do. Certainly, there are some front-ends (like the
monitor) that can support multiple I/O sources. Another example is the
VNC server which really should be using chardevs.
I agree that mirroring is a pretty reasonable policy to map a single I/O
source to multiple clients for some devices. That should be a front-end
decision though.
In this model, I still don't see having two different back-ends
connected to a single front-end. I don't know if I agree there's a
whole lot of value in that although the implementation is straight
forward (a special back-end that unifies multiple front-ends as sessions).
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1)
2009-07-01 21:32 ` Anthony Liguori
@ 2009-07-01 22:46 ` Gerd Hoffmann
0 siblings, 0 replies; 24+ messages in thread
From: Gerd Hoffmann @ 2009-07-01 22:46 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
On 07/01/09 23:32, Anthony Liguori wrote:
> Gerd Hoffmann wrote:
>
>> With multiple connections and multiplexing: You'll just connect, type
>> a few commands, disconnect, done. You'll even see what you have done
>> when you come back to the office the next day.
>>
>> Also note that the vnc server accepts input from multiple clients as
>> well, which can lead to simliar problems. Nobody wants to kill support
>> for multiple clients just because of that, because in practice it
>> isn't a issue.
>
> I don't disagree with your use-case. What I'm pointing out, is that we
> need to do some major surgery to get there.
I didn't say it is easy ;)
But I want to make sure we don't miss the big picture when we start
multiplexing for vnc, so others can join the party.
> [ flow control issues ]
Tricky indeed. I think Dan's current patches don't care about flow
control at all.
> I agree that mirroring is a pretty reasonable policy to map a single I/O
> source to multiple clients for some devices. That should be a front-end
> decision though.
Dan's patches can do mirroring only.
I *think* one could build a tcp backend based on Dan's patches which can
handle multiple connections at the same time. It would basically do the
same vnc data streams do: Listen for connects, when a new connection
comes in create a new CharCaptureState instance and link it up. When
the connection drops teardown.
> In this model, I still don't see having two different back-ends
> connected to a single front-end.
The frontend shouldn't have to care at all about who owns the
CharCaptureState instances it feeds.
> I don't know if I agree there's a whole
> lot of value in that
Having a file backend writing logs and some other backend for
interactive work is a very reasonable thing IMHO.
cheers,
Gerd
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1)
2009-07-01 20:56 ` Gerd Hoffmann
2009-07-01 21:32 ` Anthony Liguori
@ 2009-07-02 2:30 ` Jamie Lokier
1 sibling, 0 replies; 24+ messages in thread
From: Jamie Lokier @ 2009-07-02 2:30 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
Gerd Hoffmann wrote:
> vm running at your workstation in the office, with -serial tcp. You are
> heading home, leaving telnet connected. At home you'll find you want to
> check something in your vm via vpn.
>
> With current qemu: You have to zap the telnet session somehow to be
> able to connect.
>
> With switching: You have to talk to the monitor to reconfigure things.
>
> With multiple connections and multiplexing: You'll just connect, type a
> few commands, disconnect, done. You'll even see what you have done when
> you come back to the office the next day.
You should have run telnet inside GNU screen :-)
Or since you have VNC, VNC to your desktop instead of the guest :-)
> Monitor is different for two reasons:
>
> First, we could actually open a new session. That wouldn't work for
> serial as we can't hotplug a serial line into the guest on connect.
virtio-serial/vmchannel... It could handle that if we wanted to. If
nothing else, as a hotplug PCI serial port, and let the guest's udev
attach a getty. I doubt anyone would bother, but perhaps if it's
useful for last-resort guest recovery.
> Second, if the monitor is used by libvirt or some other management app a
> second connection to the same session is seriously harmful.
Quite so! Right now, I deal with this (with a different management
app) by the exciting method of a qemu monitor proxy written in Perl,
which multiplexes multiple monitor client sessions onto QEMU's single
session. It works quite well.
-- Jamie
^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2009-07-02 2:30 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-01 16:21 [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1) Daniel P. Berrange
2009-07-01 16:26 ` [Qemu-devel] [PATCH 1/2] APIs to capture character device data Daniel P. Berrange
2009-07-01 16:27 ` [Qemu-devel] [PATCH 2/2] VNC char device data stream tunnelling Daniel P. Berrange
2009-07-01 18:44 ` Anthony Liguori
2009-07-01 16:32 ` [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1) Daniel P. Berrange
2009-07-01 16:42 ` Gerd Hoffmann
2009-07-01 16:50 ` Daniel P. Berrange
2009-07-01 17:30 ` Gerd Hoffmann
2009-07-01 18:50 ` Daniel P. Berrange
2009-07-01 19:27 ` Gerd Hoffmann
2009-07-01 18:51 ` Anthony Liguori
2009-07-01 19:41 ` Gerd Hoffmann
2009-07-01 19:59 ` Anthony Liguori
2009-07-01 20:56 ` Gerd Hoffmann
2009-07-01 21:32 ` Anthony Liguori
2009-07-01 22:46 ` Gerd Hoffmann
2009-07-02 2:30 ` Jamie Lokier
2009-07-01 21:07 ` Daniel P. Berrange
2009-07-01 18:36 ` Anthony Liguori
2009-07-01 18:44 ` Daniel P. Berrange
2009-07-01 18:47 ` Anthony Liguori
2009-07-01 18:52 ` Daniel P. Berrange
2009-07-01 19:11 ` Anthony Liguori
2009-07-01 19:27 ` Daniel P. Berrange
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).