qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
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 */
>   

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