Message ID | 1331557893-30806-5-git-send-email-marcandre.lureau@redhat.com |
---|---|
State | New |
Headers | show |
On Mon, Mar 12, 2012 at 02:11:30PM +0100, Marc-André Lureau wrote: > By using the 'unix:' prefix notation, similar to the migration uri, we > can now dump to a UNIX socket. IO is still sync > --- > hw/vga.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- > qemu-file.h | 1 + > 2 files changed, 63 insertions(+), 2 deletions(-) > > diff --git a/hw/vga.c b/hw/vga.c > index 24af4a1..bb5df70 100644 > --- a/hw/vga.c > +++ b/hw/vga.c > @@ -30,6 +30,7 @@ > #include "pixel_ops.h" > #include "qemu-timer.h" > #include "xen.h" > +#include "qemu_socket.h" > > //#define DEBUG_VGA > //#define DEBUG_VGA_MEM > @@ -37,6 +38,14 @@ > > //#define DEBUG_BOCHS_VBE > > +#ifdef DEBUG_VGA > +#define DPRINTF(fmt, ...) \ > + do { printf("vga: " fmt, ## __VA_ARGS__); } while (0) > +#else > +#define DPRINTF(fmt, ...) \ > + do { } while (0) > +#endif > + > /* > * Video Graphics Array (VGA) > * > @@ -2362,7 +2371,58 @@ void vga_init_vbe(VGACommonState *s, MemoryRegion *system_memory) > /********************************************************/ > /* vga screen dump */ > > -int ppm_save(const char *filename, struct DisplaySurface *ds) > +#if !defined(WIN32) > +static QEMUFile *qemu_fopen_unix(const char *path, const char *mode) > +{ > + struct sockaddr_un addr; > + int ret, fd; > + > + addr.sun_family = AF_UNIX; > + snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path); > + > + fd = qemu_socket(PF_UNIX, SOCK_STREAM, 0); > + if (fd == -1) { > + DPRINTF("Unable to open socket: %s\n", strerror(errno)); > + return NULL; > + } > + > + do { > + ret = connect(fd, (struct sockaddr *)&addr, sizeof(addr)); > + if (ret == -1) { > + ret = -errno; > + } > + } while (ret == -EINTR); > + > + if (ret < 0) { > + DPRINTF("connect failed: %s\n": strerror(errno)); > + return NULL; > + } > + > + return qemu_fopen_socket(fd, mode); > +} > +#endif > + > +QEMUFile *qemu_fopen_uri(const char *uri, const char *mode) > +{ > + QEMUFile *f = NULL; > + const char *p; > + > + g_return_val_if_fail(uri != NULL, NULL); > + g_return_val_if_fail(mode != NULL, NULL); > + > +#if !defined(WIN32) > + if (strstart(uri, "unix:", &p)) { > + f = qemu_fopen_unix(p, mode); > + } > +#endif > + if (f == NULL) { > + f = qemu_fopen(uri, mode); > + } > + > + return f; > +} > + > +int ppm_save(const char *uri, struct DisplaySurface *ds) > { > QEMUFile *f; > uint8_t *d, *d1; > @@ -2372,7 +2432,7 @@ int ppm_save(const char *filename, struct DisplaySurface *ds) > char *linebuf, *pbuf; > gchar *header; > > - f = qemu_fopen(filename, "wb"); > + f = qemu_fopen_uri(uri, "wb"); > g_return_val_if_fail(f != NULL, -1); > > header = g_strdup_printf("P6\n%d %d\n%d\n", ds->width, ds->height, 255); > diff --git a/qemu-file.h b/qemu-file.h > index efd6b1c..0914d83 100644 > --- a/qemu-file.h > +++ b/qemu-file.h > @@ -68,6 +68,7 @@ QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer, > QEMUFile *qemu_fopen(const char *filename, const char *mode); > QEMUFile *qemu_fdopen(int fd, const char *mode); > QEMUFile *qemu_fopen_socket(int fd, const char *mode); > +QEMUFile *qemu_fopen_uri(const char *uri, const char *mode); > QEMUFile *qemu_popen(FILE *popen_file, const char *mode); > QEMUFile *qemu_popen_cmd(const char *command, const char *mode); > int qemu_stdio_fd(QEMUFile *f); It would be even more broadly useful if the screendump command was extended to allow a file descriptor to be just passed across to QEMU, avoiding the need to interact with the filesystem namespace at all. Regards, Daniel
Hi, > By using the 'unix:' prefix notation, similar to the migration uri, we > can now dump to a UNIX socket. IO is still sync > hw/vga.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- This calls for a screendump.c IMHO. vga.c is big enougth already and screendump hasn't much to do with vga, it is a generic service which should work with every qemu-emulated display adapter (and it actually does, ppm_save takes a hardware-independant displaysurface and is called from a few non-vga places). cheers, Gerd
diff --git a/hw/vga.c b/hw/vga.c index 24af4a1..bb5df70 100644 --- a/hw/vga.c +++ b/hw/vga.c @@ -30,6 +30,7 @@ #include "pixel_ops.h" #include "qemu-timer.h" #include "xen.h" +#include "qemu_socket.h" //#define DEBUG_VGA //#define DEBUG_VGA_MEM @@ -37,6 +38,14 @@ //#define DEBUG_BOCHS_VBE +#ifdef DEBUG_VGA +#define DPRINTF(fmt, ...) \ + do { printf("vga: " fmt, ## __VA_ARGS__); } while (0) +#else +#define DPRINTF(fmt, ...) \ + do { } while (0) +#endif + /* * Video Graphics Array (VGA) * @@ -2362,7 +2371,58 @@ void vga_init_vbe(VGACommonState *s, MemoryRegion *system_memory) /********************************************************/ /* vga screen dump */ -int ppm_save(const char *filename, struct DisplaySurface *ds) +#if !defined(WIN32) +static QEMUFile *qemu_fopen_unix(const char *path, const char *mode) +{ + struct sockaddr_un addr; + int ret, fd; + + addr.sun_family = AF_UNIX; + snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path); + + fd = qemu_socket(PF_UNIX, SOCK_STREAM, 0); + if (fd == -1) { + DPRINTF("Unable to open socket: %s\n", strerror(errno)); + return NULL; + } + + do { + ret = connect(fd, (struct sockaddr *)&addr, sizeof(addr)); + if (ret == -1) { + ret = -errno; + } + } while (ret == -EINTR); + + if (ret < 0) { + DPRINTF("connect failed: %s\n": strerror(errno)); + return NULL; + } + + return qemu_fopen_socket(fd, mode); +} +#endif + +QEMUFile *qemu_fopen_uri(const char *uri, const char *mode) +{ + QEMUFile *f = NULL; + const char *p; + + g_return_val_if_fail(uri != NULL, NULL); + g_return_val_if_fail(mode != NULL, NULL); + +#if !defined(WIN32) + if (strstart(uri, "unix:", &p)) { + f = qemu_fopen_unix(p, mode); + } +#endif + if (f == NULL) { + f = qemu_fopen(uri, mode); + } + + return f; +} + +int ppm_save(const char *uri, struct DisplaySurface *ds) { QEMUFile *f; uint8_t *d, *d1; @@ -2372,7 +2432,7 @@ int ppm_save(const char *filename, struct DisplaySurface *ds) char *linebuf, *pbuf; gchar *header; - f = qemu_fopen(filename, "wb"); + f = qemu_fopen_uri(uri, "wb"); g_return_val_if_fail(f != NULL, -1); header = g_strdup_printf("P6\n%d %d\n%d\n", ds->width, ds->height, 255); diff --git a/qemu-file.h b/qemu-file.h index efd6b1c..0914d83 100644 --- a/qemu-file.h +++ b/qemu-file.h @@ -68,6 +68,7 @@ QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer, QEMUFile *qemu_fopen(const char *filename, const char *mode); QEMUFile *qemu_fdopen(int fd, const char *mode); QEMUFile *qemu_fopen_socket(int fd, const char *mode); +QEMUFile *qemu_fopen_uri(const char *uri, const char *mode); QEMUFile *qemu_popen(FILE *popen_file, const char *mode); QEMUFile *qemu_popen_cmd(const char *command, const char *mode); int qemu_stdio_fd(QEMUFile *f);