qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] starting qemu vnc session on a pre-allocated port
@ 2007-06-24 13:05 Shahar Livne
  2007-06-24 14:07 ` Anthony Liguori
  2007-06-24 19:16 ` Paul Brook
  0 siblings, 2 replies; 14+ messages in thread
From: Shahar Livne @ 2007-06-24 13:05 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1216 bytes --]

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]

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

[-- Attachment #2: qemu_vnc_forced_socket.patch --]
[-- Type: text/plain, Size: 6958 bytes --]

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 */

^ permalink raw reply	[flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH] starting qemu vnc session on a pre-allocated port
@ 2007-06-25 14:58 n schembr
  0 siblings, 0 replies; 14+ messages in thread
From: n schembr @ 2007-06-25 14:58 UTC (permalink / raw)
  To: qemu-devel

Gilad Ben-Yossef wrote:
>If you think users other then us will use the patch (and we believe they will),
>we think it'll be useful for this to be included in qemu mainline.

I have more then 100 images on one box. It would make it much easer to
write my startup scripts. :)

Background

10 host with 10 guests.  I have it setup that any guest can run on any host. 
I would love to use port xx200 for the host running on ip 10.200.1.200

It is not intuitive to start xvncviewer 10.200.1.xxx:6100 but it works.

Nicholas A. Schembri
State College PA USA

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2007-07-01 15:33 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
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

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