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 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).