From: Anthony Liguori <anthony@codemonkey.ws>
To: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH] starting qemu vnc session on a pre-allocated port
Date: Sun, 24 Jun 2007 09:07:44 -0500 [thread overview]
Message-ID: <467E7AB0.1000909@codemonkey.ws> (raw)
In-Reply-To: <467E6C25.3010908@codefidence.com>
Shahar Livne wrote:
> Hi,
>
> I am working on a project that runs many concurrent qemu sessions with
> vnc.
> Handling the vnc ports for the different sessions is an issue that
> also project like qemudo tries to solve.
> The solution chosen there was to handle a pool of ports and manage
> them internally.
> Such a solution ignores the fact that these ports may be occupied by
> other processes on the same OS, and it actually duplicates an OS task.
> A solution that uses external port handling facility (like a native OS
> free ports selection), by using a pre-allocated port is suggested.
>
> Currently there is the following vnc option:
> -vnc display [start a VNC server on display]
>
> Adding the following option:
> -vnc-socket sd [force VNC server on an already opened Socket Descriptor]
Just redirect each port to a unique unix domain socket and then you can
forward traffic to TCP sockets to your heart's content.
Regards,
Anthony Liguori
> overrides the new socket opening for the vnc on 5900+display port, and
> uses the given sd socket descriptor instead.
>
> In this way, one can create a socket, bind it to any specific port
> (e.g. arbitrary free port given by the OS), and only then start the
> qemu with the socket descriptor. Doing this, all the ports accounting
> is done by the OS.
>
> The patch is against cvs 2007-06-21, but I think nothing relevant has
> changed since.
>
> Comments are welcome,
> Shahar
> ------------------------------------------------------------------------
>
> Index: vnc.c
> ===================================================================
> --- vnc.c (revision 6)
> +++ vnc.c (revision 8)
> @@ -59,6 +59,7 @@
> QEMUTimer *timer;
> int lsock;
> int csock;
> + int fsock;
> DisplayState *ds;
> int need_update;
> int width;
> @@ -99,9 +100,14 @@
> if (vnc_state == NULL)
> term_printf("VNC server disabled\n");
> else {
> - term_printf("VNC server active on: ");
> - term_print_filename(vnc_state->display);
> - term_printf("\n");
> + if (vnc_state->fsock == -1) {
> + term_printf("VNC server active on: ");
> + term_print_filename(vnc_state->display);
> + term_printf("\n");
> + } else {
> + term_printf("VNC server active on socket descriptor: %d", vnc_state->fsock);
> + term_printf("\n");
> + }
>
> if (vnc_state->csock == -1)
> term_printf("No client connected\n");
> @@ -1169,7 +1175,7 @@
>
> extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
>
> -void vnc_display_init(DisplayState *ds, const char *arg)
> +void vnc_display_init(DisplayState *ds, const char *arg, int forced_vnc_socket)
> {
> struct sockaddr *addr;
> struct sockaddr_in iaddr;
> @@ -1191,6 +1197,7 @@
>
> vs->lsock = -1;
> vs->csock = -1;
> + vs->fsock = forced_vnc_socket;
> vs->depth = 4;
> vs->last_x = -1;
> vs->last_y = -1;
> @@ -1213,60 +1220,67 @@
>
> vnc_dpy_resize(vs->ds, 640, 400);
>
> -#ifndef _WIN32
> - if (strstart(arg, "unix:", &p)) {
> - addr = (struct sockaddr *)&uaddr;
> - addrlen = sizeof(uaddr);
> -
> - vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);
> - if (vs->lsock == -1) {
> - fprintf(stderr, "Could not create socket\n");
> - exit(1);
> - }
> -
> - uaddr.sun_family = AF_UNIX;
> - memset(uaddr.sun_path, 0, 108);
> - snprintf(uaddr.sun_path, 108, "%s", p);
>
> - unlink(uaddr.sun_path);
> - } else
> + if (vs->fsock == -1) {
> +#ifndef _WIN32
> + if (strstart(arg, "unix:", &p)) {
> + addr = (struct sockaddr *)&uaddr;
> + addrlen = sizeof(uaddr);
> +
> + vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);
> + if (vs->lsock == -1) {
> + fprintf(stderr, "Could not create socket\n");
> + exit(1);
> + }
> +
> + uaddr.sun_family = AF_UNIX;
> + memset(uaddr.sun_path, 0, 108);
> + snprintf(uaddr.sun_path, 108, "%s", p);
> +
> + unlink(uaddr.sun_path);
> + } else
> #endif
> - {
> - addr = (struct sockaddr *)&iaddr;
> - addrlen = sizeof(iaddr);
> -
> - vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
> - if (vs->lsock == -1) {
> - fprintf(stderr, "Could not create socket\n");
> - exit(1);
> - }
> -
> - if (parse_host_port(&iaddr, arg) < 0) {
> - fprintf(stderr, "Could not parse VNC address\n");
> - exit(1);
> - }
> -
> - iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900);
> -
> - reuse_addr = 1;
> - ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
> - (const char *)&reuse_addr, sizeof(reuse_addr));
> - if (ret == -1) {
> - fprintf(stderr, "setsockopt() failed\n");
> - exit(1);
> - }
> - }
> -
> - if (bind(vs->lsock, addr, addrlen) == -1) {
> - fprintf(stderr, "bind() failed\n");
> - exit(1);
> - }
> + {
> + addr = (struct sockaddr *)&iaddr;
> + addrlen = sizeof(iaddr);
> +
> + vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
> + if (vs->lsock == -1) {
> + fprintf(stderr, "Could not create socket\n");
> + exit(1);
> + }
> +
> + if (parse_host_port(&iaddr, arg) < 0) {
> + fprintf(stderr, "Could not parse VNC address\n");
> + exit(1);
> + }
> +
> + iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900);
> +
> + reuse_addr = 1;
> + ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
> + (const char *)&reuse_addr, sizeof(reuse_addr));
> + if (ret == -1) {
> + fprintf(stderr, "setsockopt() failed\n");
> + exit(1);
> + }
> + }
> +
> + if (bind(vs->lsock, addr, addrlen) == -1) {
> + fprintf(stderr, "bind() failed\n");
> + exit(1);
> + }
> +
> + if (listen(vs->lsock, 1) == -1) {
> + fprintf(stderr, "listen() failed\n");
> + exit(1);
> + }
>
> - if (listen(vs->lsock, 1) == -1) {
> - fprintf(stderr, "listen() failed\n");
> - exit(1);
> + } else {
> + vs->lsock = vs->fsock;
> + fprintf(stdout, "using forced socket %d\n",vs->fsock);
> }
> -
> +
> ret = qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);
> if (ret == -1) {
> exit(1);
> Index: vl.c
> ===================================================================
> --- vl.c (revision 6)
> +++ vl.c (revision 8)
> @@ -178,6 +178,7 @@
> static VLANState *first_vlan;
> int smp_cpus = 1;
> const char *vnc_display;
> +int vnc_socket = -1;
> #if defined(TARGET_SPARC)
> #define MAX_CPUS 16
> #elif defined(TARGET_I386)
> @@ -6651,6 +6652,7 @@
> "-no-reboot exit instead of rebooting\n"
> "-loadvm file start right away with a saved state (loadvm in monitor)\n"
> "-vnc display start a VNC server on display\n"
> + "-vnc-socket sd force VNC server on an already opened Socket Descriptor\n"
> #ifndef _WIN32
> "-daemonize daemonize QEMU after initializing\n"
> #endif
> @@ -6745,6 +6747,7 @@
> QEMU_OPTION_usbdevice,
> QEMU_OPTION_smp,
> QEMU_OPTION_vnc,
> + QEMU_OPTION_vnc_socket,
> QEMU_OPTION_no_acpi,
> QEMU_OPTION_no_reboot,
> QEMU_OPTION_show_cursor,
> @@ -6836,6 +6839,7 @@
> { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
> { "smp", HAS_ARG, QEMU_OPTION_smp },
> { "vnc", HAS_ARG, QEMU_OPTION_vnc },
> + { "vnc-socket", HAS_ARG, QEMU_OPTION_vnc_socket },
>
> /* temporary options */
> { "usb", 0, QEMU_OPTION_usb },
> @@ -7588,6 +7592,18 @@
> case QEMU_OPTION_vnc:
> vnc_display = optarg;
> break;
> + case QEMU_OPTION_vnc_socket:
> + {
> + int sd;
> + sd = atoi(optarg);
> + if (sd < 0) {
> + fprintf(stderr, "Bad argument to vnc socket descriptor\n");
> + exit(1);
> + } else {
> + vnc_socket = sd;
> + }
> + break;
> + }
> case QEMU_OPTION_no_acpi:
> acpi_enabled = 0;
> break;
> @@ -7879,7 +7895,7 @@
> if (nographic) {
> /* nothing to do */
> } else if (vnc_display != NULL) {
> - vnc_display_init(ds, vnc_display);
> + vnc_display_init(ds, vnc_display, vnc_socket);
> } else {
> #if defined(CONFIG_SDL)
> sdl_display_init(ds, full_screen, no_frame);
> Index: vl.h
> ===================================================================
> --- vl.h (revision 6)
> +++ vl.h (revision 8)
> @@ -965,7 +965,7 @@
> void cocoa_display_init(DisplayState *ds, int full_screen);
>
> /* vnc.c */
> -void vnc_display_init(DisplayState *ds, const char *display);
> +void vnc_display_init(DisplayState *ds, const char *display, int forced_vnc_socket);
> void do_info_vnc(void);
>
> /* x_keymap.c */
>
next prev parent reply other threads:[~2007-06-24 14:07 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-06-24 13:05 [Qemu-devel] [PATCH] starting qemu vnc session on a pre-allocated port Shahar Livne
2007-06-24 14:07 ` Anthony Liguori [this message]
2007-06-24 21:45 ` Shahar Livne
2007-06-24 22:40 ` Anthony Liguori
2007-06-25 8:28 ` Gilad Ben-Yossef
2007-06-25 11:55 ` Anthony Liguori
2007-06-26 10:17 ` Gilad Ben-Yossef
2007-06-26 10:48 ` Jannes Faber
2007-06-28 15:25 ` Anthony Liguori
2007-06-30 21:15 ` Gilad Ben-Yossef
2007-07-01 15:33 ` Anthony Liguori
2007-06-24 19:16 ` Paul Brook
2007-06-24 20:12 ` Anthony Liguori
-- strict thread matches above, loose matches on Subject: below --
2007-06-25 14:58 n schembr
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=467E7AB0.1000909@codemonkey.ws \
--to=anthony@codemonkey.ws \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.