qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] Remote console access though socket
@ 2006-03-08 14:52 Daniel Veillard
       [not found] ` <16af12af0603081035h5f61d947y6c24b7a7675eeb14@mail.gmail.com>
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Daniel Veillard @ 2006-03-08 14:52 UTC (permalink / raw)
  To: qemu-devel

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

  Hi,

enclosed is a first version of a patch to allow remote access and control
for QEmu instances, I'm not suggesting to apply it as is (though it seems
to work in my limited testing) but would rather like to get comments back
for choices I'm facing. 
  First a bit of context, I'm working on libvirt (see
http://libvirt.org/) a library providing access to virtualization. I would
like to be able to handle QEmu instance like we do for Xen, the simpler 
would be to be able to list and connect to the console of running QEmu.
In an early mail last month Fabrice expressed interest in exporting the
console though TCP, so I hope I'm not too much off-track.
Enclosed are:
   - qemu-tcpctrl.patch: the patch to the existing code, it add tcpctrl
     as a configure option (on by default except on Windows), it plugs
     in main() of vl.c, add one entry point in console.c, and add a new
     module in the Makefile
   - tcpctrl.c: the C file, it currently use an unix socket
     /tmp/qemu-$pid-socket add a routine to start and stop the access
     and plug in the I/O handler of QEmu to wait for connections on it.
     When connections are accepted they are also plugged in the I/O
     handling, and receive commands. The commands are passed to console.c
     along with a minimal CharDriverState whose grite goes back to
     the associated connection.
   - client.c: a minimal client to send a command and get the output.
     use as './client /tmp/qemu-*-socket quit'

 There is a number of open questions which would need to be resolved before
applying any such patch:
   - First one is the unix socket, we could as easilly start normal port
     based access but:
     + I would really like to be able to list the current running instance
       without checking all process on the OS, and mapping in the file
       system seems the easiest way
     + the permission over the filesystem allows to set up the access policy
       without any special mechanism
     + in a port based access how do you guess the port numbers used by the
       QEmu instances
     the drawback of the file sockets are:
     + security: one need a directory where any user (since qemu isn't
       priviledged) can create a new file, and ensure safety over those
       accesses
     + cleanup: when qemu exits one need to clean up the socket, and 
       currently qemu has no central exit routine for this (and doesn't
       seems to trap signals leading to exit)
   - what about asynchronous events CharDriverState has structures in place
     for those, in general is that okay to keep some of the CharDriverState
     as NULL or should it trap every possible entries not just write()
   - the plug of the socket in the console framework is a bit crude, it just
     replace the global variable monitor_hd during the processing of the 
     request (c.f. monitor_process_command()).
   - the console -> socket code should try to coalesce multiple writes
     from the console into a single packet flushed at the end of the routine,
     and a marker for the end of the output from the command will help
     parsing at the client level.
   - ease of error handling on the client if possible, to generalize a
     bit go from a human targetted interaction to a machine  one.
   - command line configurations, for enabling/disabling the remote access
     and being able to specify the port number if using port, left open
     I didn't tried to address that

 So there is a bit too many open issues but IMHO nothing really hard, I would
just like to get feedback from other interested people.

Daniel

-- 
Daniel Veillard      | Red Hat http://redhat.com/
veillard@redhat.com  | libxml GNOME XML XSLT toolkit  http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine http://rpmfind.net/

[-- Attachment #2: qemu-tcpctrl.patch --]
[-- Type: text/plain, Size: 5114 bytes --]

Index: qemu/Makefile.target
===================================================================
RCS file: /sources/qemu/qemu/Makefile.target,v
retrieving revision 1.93
diff -u -r1.93 Makefile.target
--- qemu/Makefile.target	6 Feb 2006 04:11:15 -0000	1.93
+++ qemu/Makefile.target	8 Mar 2006 13:19:14 -0000
@@ -275,6 +275,9 @@
 ifdef CONFIG_WIN32
 VL_OBJS+=tap-win32.o
 endif
+ifdef CONFIG_TCPCTRL
+VL_OBJS+=tcpctrl.o
+endif
 
 SOUND_HW = sb16.o es1370.o
 AUDIODRV = audio.o noaudio.o wavaudio.o
Index: qemu/configure
===================================================================
RCS file: /sources/qemu/qemu/configure,v
retrieving revision 1.83
diff -u -r1.83 configure
--- qemu/configure	2 Mar 2006 21:52:18 -0000	1.83
+++ qemu/configure	8 Mar 2006 13:19:14 -0000
@@ -74,6 +74,7 @@
 mingw32="no"
 EXESUF=""
 gdbstub="yes"
+tcpctrl="yes"
 slirp="yes"
 adlib="no"
 oss="no"
@@ -208,6 +209,10 @@
   ;;
   --disable-gcc-check) check_gcc="no"
   ;;
+  --enable-tcpctrl) tcpctrl="yes"
+  ;;
+  --disable-tcpctrl) tcpctrl="no"
+  ;;
   esac
 done
 
@@ -224,6 +229,7 @@
     linux="no"
     EXESUF=".exe"
     gdbstub="no"
+    tcpctrl="no"
     oss="no"
     if [ "$cpu" = "i386" ] ; then
         kqemu="yes"
@@ -385,6 +391,7 @@
 echo "  --enable-alsa            enable ALSA audio driver"
 echo "  --enable-fmod            enable FMOD audio driver"
 echo "  --enabled-dsound         enable DirectSound audio driver"
+echo "  --disable-tcpctrl        disable TCP control connections"
 echo "  --fmod-lib               path to FMOD library"
 echo "  --fmod-inc               path to FMOD includes"
 echo ""
@@ -451,6 +458,7 @@
     echo -n " (lib='$fmod_lib' include='$fmod_inc')"
 fi
 echo ""
+echo "TCP control       $tcpctrl"
 echo "kqemu support     $kqemu"
 
 if test $sdl_too_old = "yes"; then
@@ -545,6 +553,10 @@
   echo "CONFIG_GDBSTUB=yes" >> $config_mak
   echo "#define CONFIG_GDBSTUB 1" >> $config_h
 fi
+if test "$tcpctrl" = "yes" ; then
+  echo "CONFIG_TCPCTRL=yes" >> $config_mak
+  echo "#define CONFIG_TCPCTRL 1" >> $config_h
+fi
 if test "$gprof" = "yes" ; then
   echo "TARGET_GPROF=yes" >> $config_mak
   echo "#define HAVE_GPROF 1" >> $config_h
Index: qemu/monitor.c
===================================================================
RCS file: /sources/qemu/qemu/monitor.c,v
retrieving revision 1.46
diff -u -r1.46 monitor.c
--- qemu/monitor.c	8 Feb 2006 22:40:15 -0000	1.46
+++ qemu/monitor.c	8 Mar 2006 13:19:14 -0000
@@ -296,6 +296,9 @@
 
 static void do_quit(void)
 {
+#ifdef CONFIG_TCPCTRL
+    tcpctrl_stop();
+#endif
     exit(0);
 }
 
@@ -2026,6 +2029,30 @@
     return;
 }
 
+/**
+ * monitor_process_command:
+ * @output: the console used to send the output
+ * @cmdline: the line of the command to process
+ *
+ * Process a command coming from a different requester than the usual console.
+ */
+
+void monitor_process_command(CharDriverState *output, const char *cmdline)
+{
+    CharDriverState *old_output = monitor_hd;
+
+    if ((output == NULL) || (cmdline == NULL))
+        return;
+
+    /*
+     * TODO: maybe it would be cleaner to inherit the current driver
+     *       in the calls than relying on a global variable ?
+     */
+    monitor_hd = output;
+    monitor_handle_command(cmdline);
+    monitor_hd = old_output;
+}
+
 static void cmd_completion(const char *name, const char *list)
 {
     const char *p, *pstart;
Index: qemu/vl.c
===================================================================
RCS file: /sources/qemu/qemu/vl.c,v
retrieving revision 1.165
diff -u -r1.165 vl.c
--- qemu/vl.c	20 Feb 2006 00:33:36 -0000	1.165
+++ qemu/vl.c	8 Mar 2006 13:19:15 -0000
@@ -4550,6 +4550,9 @@
 
 int main(int argc, char **argv)
 {
+#ifdef CONFIG_TCPCTRL
+    int use_tcpctrl = 1;
+#endif
 #ifdef CONFIG_GDBSTUB
     int use_gdbstub, gdbstub_port;
 #endif
@@ -5210,6 +5213,14 @@
     gui_timer = qemu_new_timer(rt_clock, gui_update, NULL);
     qemu_mod_timer(gui_timer, qemu_get_clock(rt_clock));
 
+#ifdef CONFIG_TCPCTRL
+    if (use_tcpctrl) {
+        if (tcpctrl_start() < 0) {
+            fprintf(stderr, "Could not open TCP control socket\n");
+	    exit(1);
+	}
+    }
+#endif
 #ifdef CONFIG_GDBSTUB
     if (use_gdbstub) {
         if (gdbserver_start(gdbstub_port) < 0) {
@@ -5232,6 +5243,11 @@
         }
     }
     main_loop();
+#ifdef CONFIG_TCPCTRL
+    if (use_tcpctrl) {
+        tcpctrl_stop();
+    }
+#endif
     quit_timers();
     return 0;
 }
Index: qemu/vl.h
===================================================================
RCS file: /sources/qemu/qemu/vl.h,v
retrieving revision 1.105
diff -u -r1.105 vl.h
--- qemu/vl.h	20 Feb 2006 00:33:36 -0000	1.105
+++ qemu/vl.h	8 Mar 2006 13:19:15 -0000
@@ -991,6 +991,14 @@
 void term_print_help(void);
 void monitor_readline(const char *prompt, int is_password,
                       char *buf, int buf_size);
+void monitor_process_command(CharDriverState *output, const char *cmdline);
+
+#ifdef CONFIG_TCPCTRL
+/* tcpctrl.c */
+int tcpctrl_start(void);
+void tcpctrl_stop(void);
+
+#endif /* CONFIG_TCPCTRL */
 
 /* readline.c */
 typedef void ReadLineFunc(void *opaque, const char *str);

[-- Attachment #3: tcpctrl.c --]
[-- Type: text/plain, Size: 5971 bytes --]

/*
 * remote TCP control connection
 * 
 * Copyright (c) 2006 Daniel Veillard <daniel@veillard.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#include "vl.h"
#ifdef CONFIG_TCPCTRL

#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netinet/tcp.h>

/* #define DEBUG_TCPCTRL */

static int tcpctrl_fd = -1;
static char tcpctrl_socket[150] = "";

typedef struct _tcp_client {
    int fd;
    CharDriverState drv;
} tcp_client;

static int
chrctr_write(struct CharDriverState *s, const uint8_t *buf, int len) {
    tcp_client *info;
    int written, sent = 0;

    if ((s == NULL) || (buf == NULL) || (len < 0) || (s->opaque == NULL))
        return(-1);
    if (tcpctrl_fd == -1)
        return(-1);

    info = s->opaque;

#ifdef DEBUG_TCPCTRL
    fprintf(stderr, "chrctr_write(fd = %d, len = %d)\n", info->fd, len);
#endif
    
retry_write:
    written = write(info->fd, buf + sent, len - sent);
    if (written < 0) {
        if ((errno == EINTR) || (errno == EAGAIN))
	    goto retry_write;
	close(info->fd);
	qemu_set_fd_handler(info->fd, NULL, NULL, NULL);
	info->fd = -1;
	return(-1);
    }
    if (written + sent < len) {
        sent += written;
	goto retry_write;
    }
    return(written);
}

static void
tcpctrl_disconnect(tcp_client *info)
{
    if ((info == NULL) || (info->fd < 0))
        return;

#ifdef DEBUG_TCPCTRL
    fprintf(stderr, "tcpctrl_disconnect(fd = %d)\n", info->fd);
#endif
    /*
     * this seems the best way to unregister this should work
     * even in the loop over iov in the main loop
     */
    if (info->fd > 0) {
	qemu_set_fd_handler(info->fd, NULL, NULL, NULL);
	close(info->fd);
    }
    qemu_free(info);
}

static int tcpctrl_process(tcp_client *info, const char *command) {
    if (tcpctrl_fd == -1)
        return(-1);

#ifdef DEBUG_TCPCTRL
    fprintf(stderr, "tcpctrl_process(command = '%s')\n", command);
#endif
    monitor_process_command(&info->drv, command);

    /* writing back to tcp connection may have failed */
    if (info->fd < 0)
        tcpctrl_disconnect(info);
}

static void tcpctrl_read(void *opaque)
{
    char buffer[4096 + 1];
    int ret;

    tcp_client *info = opaque;
#ifdef DEBUG_TCPCTRL
    fprintf(stderr, "tcpctrl_read(fd = %d)\n", info->fd);
#endif
    
    if (tcpctrl_fd == -1) {
	tcpctrl_disconnect(info);
        return;
    }

retry_read:

    ret = read(info->fd, &buffer[0], sizeof(buffer) - 1);
    if (ret < 0) {
        if ((errno == EINTR) || (errno == EAGAIN))
	    goto retry_read;
	tcpctrl_disconnect(info);
	return;
    }
    if (ret == 0) {
	tcpctrl_disconnect(info);
	return;
    }
    buffer[ret] = 0;
    tcpctrl_process(info, &buffer[0]);
}

static void
tcpctrl_accept(void *opaque)
{
    struct sockaddr_in sockaddr;
    socklen_t len;
    int val, fd;
    tcp_client *info;

#ifdef DEBUG_TCPCTRL
    fprintf(stderr, "tcpctrl_accept()\n");
#endif

    for(;;) {
        len = sizeof(sockaddr);
        fd = accept(tcpctrl_fd, (struct sockaddr *)&sockaddr, &len);
        if (fd < 0 && errno != EINTR) {
            perror("accept");
            return;
        } else if (fd >= 0) {
            break;
        }
    }

    /* set short latency */
    val = 1;
    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
    
    info = qemu_mallocz(sizeof(tcp_client));
    if (!info) {
        close(fd);
        return;
    }
    info->fd = fd;
    info->drv.chr_write = chrctr_write;
    info->drv.opaque = info;

    fcntl(fd, F_SETFL, O_NONBLOCK);

    qemu_set_fd_handler(fd, tcpctrl_read, NULL, info);

#ifdef DEBUG_TCPCTRL
    fprintf(stderr, "tcpctrl_accept(): fd = %d\n", fd);
#endif
}

static int tcpctrl_open()
{
    int fd = -1;
    int pid = getpid();
    mode_t oldmask;
    struct sockaddr_un addr;

    snprintf(tcpctrl_socket, sizeof(tcpctrl_socket) - 1,
             "%s/qemu-%d-socket", "/tmp", pid);
    tcpctrl_socket[sizeof(tcpctrl_socket) - 1] = 0;
    unlink(tcpctrl_socket);

    fd = socket(PF_UNIX, SOCK_STREAM, 0);
    if (fd < 0) {
        fprintf(stderr, "Failed to create unix socket");
	return(-1);
    }
    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    strncpy(&addr.sun_path[0], tcpctrl_socket, (sizeof(addr) - 4) - 1);
    oldmask = umask(0077);
    if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
        fprintf(stderr, "Failed to bind to socket %s\n", tcpctrl_socket);
	close(fd);
	umask(oldmask);
	return(-1);
    }
    if (listen(fd, 3) < 0) {
        fprintf(stderr, "Failed to listen to socket %s\n", tcpctrl_socket);
	close(fd);
	umask(oldmask);
	return(-1);
    }
    umask(oldmask);

#ifdef DEBUG_TCPCTRL
    fprintf(stderr, "Listening on TCP control socket %s\n", tcpctrl_socket);
#endif

    return fd;
}

int tcpctrl_start()
{

#ifdef DEBUG_TCPCTRL
    fprintf(stderr, "tcpctrl_start()\n");
#endif
    tcpctrl_fd = tcpctrl_open();
    if (tcpctrl_fd < 0)
        return -1;
    qemu_set_fd_handler(tcpctrl_fd, tcpctrl_accept, NULL, NULL);
    return 0;
}

void tcpctrl_stop()
{
    if (tcpctrl_fd < 0)
        return;
#ifdef DEBUG_TCPCTRL
    fprintf(stderr, "tcpctrl_stop()\n");
#endif
    unlink(tcpctrl_socket);
    qemu_set_fd_handler(tcpctrl_fd, NULL, NULL, NULL);
    close(tcpctrl_fd);
    tcpctrl_fd = -1;
    return;
}
#endif /* CONFIG_TCPCTRL */

[-- Attachment #4: client.c --]
[-- Type: text/plain, Size: 2087 bytes --]

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>


#define DEBUG_TCPCTRL

static int
qemu_connect(const char *path) {
    int fd;
    struct sockaddr_un addr;

    fd = socket(PF_UNIX, SOCK_STREAM, 0);
    if (fd < 0) {
        fprintf(stderr, "Failed to create unix socket\n");
	return (-1);
    }
    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    strncpy(&addr.sun_path[0], path, (sizeof(addr) - 4) - 1);

    while (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
        if (errno != EINTR) {
	    fprintf(stderr, "Failed to connect to unix socket %s\n",
	            path);
	    close(fd);
	    unlink(path);
	    return (-1);
	}
    }
#ifdef DEBUG_TCPCTRL
    fprintf(stderr, "Connected to socket %s : %d\n", path, fd);
#endif
    return(fd);
}
   
static int
qemu_command(int fd, const char *command) {
    int ret, written, sent = 0, len;
    char answer[200];

    len = strlen(command);

retry_write:
    written = write(fd, &command[sent], len - sent);
    if (written < 0) {
        if ((errno == EINTR) || (errno == EAGAIN))
	    goto retry_write;
	fprintf(stderr, "Failed to write message to socket %d\n", fd);
	return (-1);
    }

    if (written + sent < len) {
        sent += written;
	goto retry_write;
    }

retry_read:
    ret = read(fd, &answer[0], sizeof(answer) - 1);
    if (ret < 0) {
        if ((errno == EINTR) || (errno == EAGAIN))
	    goto retry_read;
	return (-1);
    }
    answer[ret] = 0;
    printf("%s\n", answer);
    return(0);
}

static void usage(const char *progname) {
    printf("Usage %s socket_path [command]\n", progname);
    exit(1);
}

int main(int argc, char **argv) {
    const char *path, *command;
    int fd;
    int ret;

    if ((argc < 2) || (argc > 3))
        usage(argv[0]);
    path = argv[1];
    if (argc == 3)
        command = argv[2];
    else
        command = "help";

    fd = qemu_connect(path);
    if (fd < 0)
        exit(1);

    ret = qemu_command(fd, command);
    return(ret);
}


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

* Re: [Qemu-devel] [PATCH] Remote console access though socket
       [not found] ` <16af12af0603081035h5f61d947y6c24b7a7675eeb14@mail.gmail.com>
@ 2006-03-08 20:35   ` Ed Swierk
  2006-03-11 20:53     ` Daniel Veillard
  0 siblings, 1 reply; 10+ messages in thread
From: Ed Swierk @ 2006-03-08 20:35 UTC (permalink / raw)
  To: qemu-devel

Daniel Veillard wrote:
> enclosed is a first version of a patch to allow remote access and control
> for QEmu instances, I'm not suggesting to apply it as is (though it seems
> to work in my limited testing) but would rather like to get comments back
> for choices I'm facing.

This sounds pretty nice. A few general comments:

A few weeks ago I wrote a qemu daemon manager. It's a pretty simple
script that manages multiple qemu processes, launching each one in an
instance of screen. screen does most of the dirty work of keeping
track of running processes, assigning a name to each process,
attaching to a process's console, terminating a process, etc. Of
course screen has many more features that we don't really need, but it
might be worth looking at screen as a model for implementing the
functions you describe.

The other problem my script deals with, which screen doesn't solve, is
managing resources like ports (for -redir) and network interface MAC
addresses (in cases where uniqueness matters), and providing some way
for the user to determine which resource has been assigned to a
particular qemu process.

If qemu provides access to its console via a socket, this is just
another resource that a manager can deal with, perhaps passing the
desired port number to qemu via the command line.

--Ed

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

* Re: [Qemu-devel] [PATCH] Remote console access though socket
@ 2006-03-09 12:47 wanderer
  2006-03-09 12:55 ` Daniel Veillard
  0 siblings, 1 reply; 10+ messages in thread
From: wanderer @ 2006-03-09 12:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: daniel

I placed a patch on The Qemu Forum (qemu.dad-answers.com) that already 
provides this capability in a more inclusive manner. That is, you can remote 
the console (monitor) through any active pty or pipe process. Telnet could be 
one choice to get the functionality you are getting at here.

Then again, perhaps I misunderstood your code entirely. Take a look and see. 

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

* Re: [Qemu-devel] [PATCH] Remote console access though socket
  2006-03-09 12:47 wanderer
@ 2006-03-09 12:55 ` Daniel Veillard
  0 siblings, 0 replies; 10+ messages in thread
From: Daniel Veillard @ 2006-03-09 12:55 UTC (permalink / raw)
  To: wanderer; +Cc: qemu-devel, daniel

On Thu, Mar 09, 2006 at 03:00:13AM -0800, wanderer@ipinc.net wrote:
> I placed a patch on The Qemu Forum (qemu.dad-answers.com) that already 
> provides this capability in a more inclusive manner. That is, you can remote 
> the console (monitor) through any active pty or pipe process. Telnet could be 
> one choice to get the functionality you are getting at here.
> 
> Then again, perhaps I misunderstood your code entirely. Take a look and see. 

  Sounds different to me. For pipe, you need to launch the qemu program
in a given way, you can't attach to it later (and /proc/$pid/fd/* trick
is really limited to Linux).
  W.r.t. PTY access I assume only one program can locally attach to
it, my patch may allow:
   - remote access if using port based access
   - multiple simultaneous external access

So I tend to think the goals and use are differents, it's not about
redirecting console, but rather allow remote asynchonous control over
qemu instance(s).

Daniel

-- 
Daniel Veillard      | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
daniel@veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | 

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

* Re: [Qemu-devel] [PATCH] Remote console access though socket
  2006-03-08 14:52 [Qemu-devel] [PATCH] Remote console access though socket Daniel Veillard
       [not found] ` <16af12af0603081035h5f61d947y6c24b7a7675eeb14@mail.gmail.com>
@ 2006-03-11 16:24 ` Oliver Gerlich
  2006-03-11 20:59   ` Daniel Veillard
  2006-03-11 21:07 ` Daniel Veillard
  2 siblings, 1 reply; 10+ messages in thread
From: Oliver Gerlich @ 2006-03-11 16:24 UTC (permalink / raw)
  To: veillard, qemu-devel

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Daniel Veillard schrieb:
>   Hi,
> 
> enclosed is a first version of a patch to allow remote access and control
> for QEmu instances, I'm not suggesting to apply it as is (though it seems
> to work in my limited testing) but would rather like to get comments back
> for choices I'm facing. 
[...]
>  There is a number of open questions which would need to be resolved before
> applying any such patch:
>    - First one is the unix socket, we could as easilly start normal port
>      based access but:
>      + I would really like to be able to list the current running instance
>        without checking all process on the OS, and mapping in the file
>        system seems the easiest way

Just an idea: how about using "Multicast DNS" (see multicastdns.org)?
IIUC it provides a generic way to find services on a net; and it's
supported at least by MacOSX and with eg. Avahi (see avahi.org) also on
Linux. Not sure about Windows, though...

Regards,
Oliver Gerlich
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iD8DBQFEEvnHTFOM6DcNJ6cRAhe4AJ9LAQwIb25gCuIHKiRoIMLwJzkt4wCgoEXh
kjk2Gejn8X+p1tyCeryHqYA=
=z3wY
-----END PGP SIGNATURE-----

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

* Re: [Qemu-devel] [PATCH] Remote console access though socket
  2006-03-08 20:35   ` Ed Swierk
@ 2006-03-11 20:53     ` Daniel Veillard
  0 siblings, 0 replies; 10+ messages in thread
From: Daniel Veillard @ 2006-03-11 20:53 UTC (permalink / raw)
  To: qemu-devel

On Wed, Mar 08, 2006 at 12:35:13PM -0800, Ed Swierk wrote:
> Daniel Veillard wrote:
> > enclosed is a first version of a patch to allow remote access and control
> > for QEmu instances, I'm not suggesting to apply it as is (though it seems
> > to work in my limited testing) but would rather like to get comments back
> > for choices I'm facing.
> 
> This sounds pretty nice. A few general comments:
> 
> A few weeks ago I wrote a qemu daemon manager. It's a pretty simple
> script that manages multiple qemu processes, launching each one in an
> instance of screen. screen does most of the dirty work of keeping
> track of running processes, assigning a name to each process,
> attaching to a process's console, terminating a process, etc. Of
> course screen has many more features that we don't really need, but it
> might be worth looking at screen as a model for implementing the
> functions you describe.

  I don't see how this would solve the problems I asked about:
    - discovery of running instances if not using a filesystem based socket
    - being able to hook up to qemu instances which are older than
      the program you're trying to control them from.
I know screen, it's good for handling a few number of console, but it's
not really what I'm trying to get at, really.

[...]
> If qemu provides access to its console via a socket, this is just
> another resource that a manager can deal with, perhaps passing the
> desired port number to qemu via the command line.

  But for that you need to know the given port a priori, i.e. before lauch
which limits a lot the usefulness of the control tool. So far I only see
filesystem based discoveey access, I was hoping for something better, maybe
there isn't a better way ...

Daniel

-- 
Daniel Veillard      | Red Hat http://redhat.com/
veillard@redhat.com  | libxml GNOME XML XSLT toolkit  http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine http://rpmfind.net/

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

* Re: [Qemu-devel] [PATCH] Remote console access though socket
  2006-03-11 16:24 ` Oliver Gerlich
@ 2006-03-11 20:59   ` Daniel Veillard
  2006-03-11 22:22     ` Oliver Gerlich
  0 siblings, 1 reply; 10+ messages in thread
From: Daniel Veillard @ 2006-03-11 20:59 UTC (permalink / raw)
  To: Oliver Gerlich; +Cc: qemu-devel

On Sat, Mar 11, 2006 at 05:24:40PM +0100, Oliver Gerlich wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Daniel Veillard schrieb:
> >   Hi,
> > 
> > enclosed is a first version of a patch to allow remote access and control
> > for QEmu instances, I'm not suggesting to apply it as is (though it seems
> > to work in my limited testing) but would rather like to get comments back
> > for choices I'm facing. 
> [...]
> >  There is a number of open questions which would need to be resolved before
> > applying any such patch:
> >    - First one is the unix socket, we could as easilly start normal port
> >      based access but:
> >      + I would really like to be able to list the current running instance
> >        without checking all process on the OS, and mapping in the file
> >        system seems the easiest way
> 
> Just an idea: how about using "Multicast DNS" (see multicastdns.org)?
> IIUC it provides a generic way to find services on a net; and it's
> supported at least by MacOSX and with eg. Avahi (see avahi.org) also on
> Linux. Not sure about Windows, though...

  It's rather LAN oriented, I need first to find the ports of the 
QEmu instances (plural, if you limit to one per box, then you can block the
default port number and there would be no problem) on a local machine. I
don't think that "Multicast DNS"/RendezVous works with random port numbers,
all it does over normal TCP is scan for local hosts without using DNS
resolution. Again I don't think it's really the problem I'm trying to solve,
maybe I just didn't expressed myself clearly :-)

Daniel

-- 
Daniel Veillard      | Red Hat http://redhat.com/
veillard@redhat.com  | libxml GNOME XML XSLT toolkit  http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine http://rpmfind.net/

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

* Re: [Qemu-devel] [PATCH] Remote console access though socket
  2006-03-08 14:52 [Qemu-devel] [PATCH] Remote console access though socket Daniel Veillard
       [not found] ` <16af12af0603081035h5f61d947y6c24b7a7675eeb14@mail.gmail.com>
  2006-03-11 16:24 ` Oliver Gerlich
@ 2006-03-11 21:07 ` Daniel Veillard
  2 siblings, 0 replies; 10+ messages in thread
From: Daniel Veillard @ 2006-03-11 21:07 UTC (permalink / raw)
  To: qemu-devel

On Wed, Mar 08, 2006 at 09:52:11AM -0500, Daniel Veillard wrote:
>   Hi,
> 
> enclosed is a first version of a patch to allow remote access and control
> for QEmu instances,

  I have put an updated version of the patch and client code example at
    ftp://veillard.com/libvirt/qemu-patch
it fixed the client-server interaction by adding an end of command marker
in the stream sent back. This seems to work well, but I still don't know
if the use of a /tmp/qemu-$$-socket entry point is really acceptable.

Daniel

-- 
Daniel Veillard      | Red Hat http://redhat.com/
veillard@redhat.com  | libxml GNOME XML XSLT toolkit  http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine http://rpmfind.net/

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

* Re: [Qemu-devel] [PATCH] Remote console access though socket
  2006-03-11 20:59   ` Daniel Veillard
@ 2006-03-11 22:22     ` Oliver Gerlich
  2006-03-12 11:03       ` Daniel Veillard
  0 siblings, 1 reply; 10+ messages in thread
From: Oliver Gerlich @ 2006-03-11 22:22 UTC (permalink / raw)
  To: veillard; +Cc: qemu-devel

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Daniel Veillard schrieb:
> On Sat, Mar 11, 2006 at 05:24:40PM +0100, Oliver Gerlich wrote:
> 
>>-----BEGIN PGP SIGNED MESSAGE-----
>>Hash: SHA1
>>
>>Daniel Veillard schrieb:
>>
>>>  Hi,
>>>
>>>enclosed is a first version of a patch to allow remote access and control
>>>for QEmu instances, I'm not suggesting to apply it as is (though it seems
>>>to work in my limited testing) but would rather like to get comments back
>>>for choices I'm facing. 
>>
>>[...]
>>
>>> There is a number of open questions which would need to be resolved before
>>>applying any such patch:
>>>   - First one is the unix socket, we could as easilly start normal port
>>>     based access but:
>>>     + I would really like to be able to list the current running instance
>>>       without checking all process on the OS, and mapping in the file
>>>       system seems the easiest way
>>
>>Just an idea: how about using "Multicast DNS" (see multicastdns.org)?
>>IIUC it provides a generic way to find services on a net; and it's
>>supported at least by MacOSX and with eg. Avahi (see avahi.org) also on
>>Linux. Not sure about Windows, though...
> 
> 
>   It's rather LAN oriented,
Yes, that's a bit ugly.

> I need first to find the ports of the 
> QEmu instances (plural, if you limit to one per box, then you can block the
> default port number and there would be no problem) on a local machine. I
> don't think that "Multicast DNS"/RendezVous works with random port numbers,
> all it does over normal TCP is scan for local hosts without using DNS
> resolution. Again I don't think it's really the problem I'm trying to solve,
> maybe I just didn't expressed myself clearly :-)
> 
> Daniel
> 

After experimenting with the avahi apps a bit, I think mDNS can indeed
advertise several services on the same host with different ports! I ran
"avahi-publish -s -H localhost myserver1 _http._tcp 80" in one terminal,
then "avahi-publish -s -H localhost myserver2 _http._tcp 12345" in
another terminal. This advertised two HTTP servers which were running on
my local host, on ports 80 and 12345, under the names myserver1 and
myserver2.
avahi-discover then displayed these two services, with their names and
the correct port numbers. And in konqueror, browsing to "zeroconf:/"
also showed the two "WWW servers" correctly.

So, this could provide the functionality you were looking for... But it
still has the drawback that zeroconf seems to be quite a big framework,
and it requires multicast DNS in the kernel and such stuff...

Regards,
Oliver
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iD8DBQFEE02jTFOM6DcNJ6cRAtgLAJ9e8YlWFi6Is9+w2yDcOTIJFr9h8QCgvz18
hXvZb+16P1W5QDhnkac1ywc=
=d+pp
-----END PGP SIGNATURE-----

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

* Re: [Qemu-devel] [PATCH] Remote console access though socket
  2006-03-11 22:22     ` Oliver Gerlich
@ 2006-03-12 11:03       ` Daniel Veillard
  0 siblings, 0 replies; 10+ messages in thread
From: Daniel Veillard @ 2006-03-12 11:03 UTC (permalink / raw)
  To: Oliver Gerlich; +Cc: qemu-devel

On Sat, Mar 11, 2006 at 11:22:29PM +0100, Oliver Gerlich wrote:
> Daniel Veillard schrieb:
> > I need first to find the ports of the 
> > QEmu instances (plural, if you limit to one per box, then you can block the
> > default port number and there would be no problem) on a local machine. I
> > don't think that "Multicast DNS"/RendezVous works with random port numbers,
> > all it does over normal TCP is scan for local hosts without using DNS
> > resolution. Again I don't think it's really the problem I'm trying to solve,
> > maybe I just didn't expressed myself clearly :-)
> 
> After experimenting with the avahi apps a bit, I think mDNS can indeed
> advertise several services on the same host with different ports! I ran
> "avahi-publish -s -H localhost myserver1 _http._tcp 80" in one terminal,
> then "avahi-publish -s -H localhost myserver2 _http._tcp 12345" in
> another terminal. This advertised two HTTP servers which were running on
> my local host, on ports 80 and 12345, under the names myserver1 and
> myserver2.
> avahi-discover then displayed these two services, with their names and
> the correct port numbers. And in konqueror, browsing to "zeroconf:/"
> also showed the two "WWW servers" correctly.
> 
> So, this could provide the functionality you were looking for... But it
> still has the drawback that zeroconf seems to be quite a big framework,
> and it requires multicast DNS in the kernel and such stuff...

  Ah, okay, well basically once you run you own DNS like service locally 
this kind of things becomes possible. But yes this is quite a big framework,
adding this as a dependency sounds a bit extreme, and I assume it won't
work if you don't have an avahi or zeroconf server running. One of the main
advantage of QEmu is that its requirement at the system level are very low,
I'm not sure we can put gracefully such requirement there :-)

  But thanks for updating me on this, that's good to know !

Daniel

-- 
Daniel Veillard      | Red Hat http://redhat.com/
veillard@redhat.com  | libxml GNOME XML XSLT toolkit  http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine http://rpmfind.net/

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

end of thread, other threads:[~2006-03-12 11:03 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-03-08 14:52 [Qemu-devel] [PATCH] Remote console access though socket Daniel Veillard
     [not found] ` <16af12af0603081035h5f61d947y6c24b7a7675eeb14@mail.gmail.com>
2006-03-08 20:35   ` Ed Swierk
2006-03-11 20:53     ` Daniel Veillard
2006-03-11 16:24 ` Oliver Gerlich
2006-03-11 20:59   ` Daniel Veillard
2006-03-11 22:22     ` Oliver Gerlich
2006-03-12 11:03       ` Daniel Veillard
2006-03-11 21:07 ` Daniel Veillard
  -- strict thread matches above, loose matches on Subject: below --
2006-03-09 12:47 wanderer
2006-03-09 12:55 ` Daniel Veillard

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