qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 1/4] Implement "info chardev" command.


From: Gerd Hoffmann
Subject: [Qemu-devel] [PATCH 1/4] Implement "info chardev" command.
Date: Tue, 28 Oct 2008 13:55:15 +0100

This patch makes qemu keep track of the character devices in use and
implements a "info chardev" monitor command to print a list.

qemu_chr_open() sticks the devices into a linked list now.  It got a new
argument (label), so there is a name for each device.  It also assigns a
filename to each character device.  By default it just copyes the
filename passed in.  Individual drivers can fill in something else
though.  qemu_chr_open_pty() sets the filename to name of the pseudo tty
allocated.

Output looks like this:

  (qemu) info chardev
  monitor: filename=unix:/tmp/run.sh-26827/monitor,server,nowait
  serial0: filename=unix:/tmp/run.sh-26827/console,server
  serial1: filename=pty:/dev/pts/5
  parallel0: filename=vc:640x480

Signed-off-by: Gerd Hoffmann <address@hidden>
---
 gdbstub.c       |    2 +-
 hw/usb-serial.c |    5 ++-
 monitor.c       |    2 +
 qemu-char.h     |    7 +++-
 vl.c            |   98 ++++++++++++++++++++++++++++++++++++------------------
 5 files changed, 78 insertions(+), 36 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 1a85eda..15d38f0 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1852,7 +1852,7 @@ int gdbserver_start(const char *port)
         port = gdbstub_port_name;
     }
 
-    chr = qemu_chr_open(port);
+    chr = qemu_chr_open("gdb", port);
     if (!chr)
         return -1;
 
diff --git a/hw/usb-serial.c b/hw/usb-serial.c
index 40d04cb..a6a756d 100644
--- a/hw/usb-serial.c
+++ b/hw/usb-serial.c
@@ -521,6 +521,8 @@ USBDevice *usb_serial_init(const char *filename)
     USBSerialState *s;
     CharDriverState *cdrv;
     unsigned short vendorid = 0x0403, productid = 0x6001;
+    char label[32];
+    static int index;
 
     while (*filename && *filename != ':') {
         const char *p;
@@ -555,7 +557,8 @@ USBDevice *usb_serial_init(const char *filename)
     if (!s)
         return NULL;
 
-    cdrv = qemu_chr_open(filename);
+    snprintf(label, sizeof(label), "usbserial%d", index++);
+    cdrv = qemu_chr_open(label, filename);
     if (!cdrv)
         goto fail;
     s->cs = cdrv;
diff --git a/monitor.c b/monitor.c
index ae034e2..611bde5 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1470,6 +1470,8 @@ static const term_cmd_t info_cmds[] = {
       "", "show the version of qemu" },
     { "network", "", do_info_network,
       "", "show the network state" },
+    { "chardev", "", qemu_chr_info,
+      "", "show the character devices" },
     { "block", "", do_info_block,
       "", "show the block devices" },
     { "blockstats", "", do_info_blockstats,
diff --git a/qemu-char.h b/qemu-char.h
index 05d6899..55d81cb 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -1,6 +1,7 @@
 #ifndef QEMU_CHAR_H
 #define QEMU_CHAR_H
 
+#include "sys-queue.h"
 /* character device */
 
 #define CHR_EVENT_BREAK 0 /* serial break char */
@@ -55,9 +56,12 @@ struct CharDriverState {
     void *opaque;
     int focus;
     QEMUBH *bh;
+    char *label;
+    char *filename;
+    TAILQ_ENTRY(CharDriverState) next;
 };
 
-CharDriverState *qemu_chr_open(const char *filename);
+CharDriverState *qemu_chr_open(const char *label, const char *filename);
 void qemu_chr_close(CharDriverState *chr);
 void qemu_chr_printf(CharDriverState *s, const char *fmt, ...);
 int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len);
@@ -72,6 +76,7 @@ void qemu_chr_reset(CharDriverState *s);
 int qemu_chr_can_read(CharDriverState *s);
 void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len);
 void qemu_chr_accept_input(CharDriverState *s);
+void qemu_chr_info(void);
 
 /* async I/O support */
 
diff --git a/vl.c b/vl.c
index d870d0f..114f6db 100644
--- a/vl.c
+++ b/vl.c
@@ -2582,7 +2582,7 @@ static CharDriverState *qemu_chr_open_pty(void)
     CharDriverState *chr;
     PtyCharDriver *s;
     struct termios tty;
-    int slave_fd;
+    int slave_fd, len;
 #if defined(__OpenBSD__)
     char pty_name[PATH_MAX];
 #define q_ptsname(x) pty_name
@@ -2609,6 +2609,9 @@ static CharDriverState *qemu_chr_open_pty(void)
     tcsetattr(slave_fd, TCSAFLUSH, &tty);
     close(slave_fd);
 
+    len = strlen(q_ptsname(s->fd)) + 5;
+    chr->filename = qemu_malloc(len);
+    snprintf(chr->filename, len, "pty:%s", q_ptsname(s->fd));
     fprintf(stderr, "char device redirected to %s\n", q_ptsname(s->fd));
 
     chr->opaque = s;
@@ -3768,90 +3771,115 @@ static CharDriverState *qemu_chr_open_tcp(const char 
*host_str,
     return NULL;
 }
 
-CharDriverState *qemu_chr_open(const char *filename)
+static TAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs
+= TAILQ_HEAD_INITIALIZER(chardevs);
+
+CharDriverState *qemu_chr_open(const char *label, const char *filename)
 {
     const char *p;
+    CharDriverState *chr;
 
     if (!strcmp(filename, "vc")) {
-        return text_console_init(&display_state, 0);
-    } else if (strstart(filename, "vc:", &p)) {
-        return text_console_init(&display_state, p);
-    } else if (!strcmp(filename, "null")) {
-        return qemu_chr_open_null();
+        chr = text_console_init(&display_state, 0);
+    } else
+    if (strstart(filename, "vc:", &p)) {
+        chr = text_console_init(&display_state, p);
+    } else
+    if (!strcmp(filename, "null")) {
+        chr = qemu_chr_open_null();
     } else
     if (strstart(filename, "tcp:", &p)) {
-        return qemu_chr_open_tcp(p, 0, 0);
+        chr = qemu_chr_open_tcp(p, 0, 0);
     } else
     if (strstart(filename, "telnet:", &p)) {
-        return qemu_chr_open_tcp(p, 1, 0);
+        chr = qemu_chr_open_tcp(p, 1, 0);
     } else
     if (strstart(filename, "udp:", &p)) {
-        return qemu_chr_open_udp(p);
+        chr = qemu_chr_open_udp(p);
     } else
     if (strstart(filename, "mon:", &p)) {
-        CharDriverState *drv = qemu_chr_open(p);
-        if (drv) {
-            drv = qemu_chr_open_mux(drv);
-            monitor_init(drv, !nographic);
-            return drv;
+        chr = qemu_chr_open(label, p);
+        if (chr) {
+            chr = qemu_chr_open_mux(chr);
+            monitor_init(chr, !nographic);
+        } else {
+            printf("Unable to open driver: %s\n", p);
         }
-        printf("Unable to open driver: %s\n", p);
-        return 0;
     } else
 #ifndef _WIN32
     if (strstart(filename, "unix:", &p)) {
-       return qemu_chr_open_tcp(p, 0, 1);
+       chr = qemu_chr_open_tcp(p, 0, 1);
     } else if (strstart(filename, "file:", &p)) {
-        return qemu_chr_open_file_out(p);
+        chr = qemu_chr_open_file_out(p);
     } else if (strstart(filename, "pipe:", &p)) {
-        return qemu_chr_open_pipe(p);
+        chr = qemu_chr_open_pipe(p);
     } else if (!strcmp(filename, "pty")) {
-        return qemu_chr_open_pty();
+        chr = qemu_chr_open_pty();
     } else if (!strcmp(filename, "stdio")) {
-        return qemu_chr_open_stdio();
+        chr = qemu_chr_open_stdio();
     } else
 #if defined(__linux__)
     if (strstart(filename, "/dev/parport", NULL)) {
-        return qemu_chr_open_pp(filename);
+        chr = qemu_chr_open_pp(filename);
     } else
 #endif
 #if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
     || defined(__NetBSD__) || defined(__OpenBSD__)
     if (strstart(filename, "/dev/", NULL)) {
-        return qemu_chr_open_tty(filename);
+        chr = qemu_chr_open_tty(filename);
     } else
 #endif
 #else /* !_WIN32 */
     if (strstart(filename, "COM", NULL)) {
-        return qemu_chr_open_win(filename);
+        chr = qemu_chr_open_win(filename);
     } else
     if (strstart(filename, "pipe:", &p)) {
-        return qemu_chr_open_win_pipe(p);
+        chr = qemu_chr_open_win_pipe(p);
     } else
     if (strstart(filename, "con:", NULL)) {
-        return qemu_chr_open_win_con(filename);
+        chr = qemu_chr_open_win_con(filename);
     } else
     if (strstart(filename, "file:", &p)) {
-        return qemu_chr_open_win_file_out(p);
+        chr = qemu_chr_open_win_file_out(p);
     } else
 #endif
 #ifdef CONFIG_BRLAPI
     if (!strcmp(filename, "braille")) {
-        return chr_baum_init();
+        chr = chr_baum_init();
     } else
 #endif
     {
-        return NULL;
+        chr = NULL;
+    }
+
+    if (chr) {
+        if (!chr->filename)
+            chr->filename = qemu_strdup(filename);
+        chr->label = qemu_strdup(label);
+        TAILQ_INSERT_TAIL(&chardevs, chr, next);
     }
+    return chr;
 }
 
 void qemu_chr_close(CharDriverState *chr)
 {
+    TAILQ_REMOVE(&chardevs, chr, next);
     if (chr->chr_close)
         chr->chr_close(chr);
+    qemu_free(chr->filename);
+    qemu_free(chr->label);
     qemu_free(chr);
 }
 
+void qemu_chr_info(void)
+{
+    CharDriverState *chr;
+
+    TAILQ_FOREACH(chr, &chardevs, next) {
+        term_printf("%s: filename=%s\n", chr->label, chr->filename);
+    }
+}
+
 /***********************************************************/
 /* network device redirectors */
 
@@ -9718,7 +9746,7 @@ int main(int argc, char **argv)
         }
     }
     if (monitor_device) {
-        monitor_hd = qemu_chr_open(monitor_device);
+        monitor_hd = qemu_chr_open("monitor", monitor_device);
         if (!monitor_hd) {
             fprintf(stderr, "qemu: could not open monitor device '%s'\n", 
monitor_device);
             exit(1);
@@ -9729,7 +9757,9 @@ int main(int argc, char **argv)
     for(i = 0; i < MAX_SERIAL_PORTS; i++) {
         const char *devname = serial_devices[i];
         if (devname && strcmp(devname, "none")) {
-            serial_hds[i] = qemu_chr_open(devname);
+            char label[32];
+            snprintf(label, sizeof(label), "serial%d", i);
+            serial_hds[i] = qemu_chr_open(label, devname);
             if (!serial_hds[i]) {
                 fprintf(stderr, "qemu: could not open serial device '%s'\n",
                         devname);
@@ -9743,7 +9773,9 @@ int main(int argc, char **argv)
     for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
         const char *devname = parallel_devices[i];
         if (devname && strcmp(devname, "none")) {
-            parallel_hds[i] = qemu_chr_open(devname);
+            char label[32];
+            snprintf(label, sizeof(label), "parallel%d", i);
+            parallel_hds[i] = qemu_chr_open(label, devname);
             if (!parallel_hds[i]) {
                 fprintf(stderr, "qemu: could not open parallel device '%s'\n",
                         devname);
-- 
1.5.6.5





reply via email to

[Prev in Thread] Current Thread [Next in Thread]