Commit 5ccfae10a79e52654c9edc68da6d05f29466b4f9

Authored by aliguori
1 parent 1490791f

Implement "info chardev" command. (Gerd Hoffmann)

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 <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5575 c046a42c-6fe2-441c-8c8c-71466251a162
gdbstub.c
@@ -1852,7 +1852,7 @@ int gdbserver_start(const char *port) @@ -1852,7 +1852,7 @@ int gdbserver_start(const char *port)
1852 port = gdbstub_port_name; 1852 port = gdbstub_port_name;
1853 } 1853 }
1854 1854
1855 - chr = qemu_chr_open(port); 1855 + chr = qemu_chr_open("gdb", port);
1856 if (!chr) 1856 if (!chr)
1857 return -1; 1857 return -1;
1858 1858
hw/usb-serial.c
@@ -521,6 +521,8 @@ USBDevice *usb_serial_init(const char *filename) @@ -521,6 +521,8 @@ USBDevice *usb_serial_init(const char *filename)
521 USBSerialState *s; 521 USBSerialState *s;
522 CharDriverState *cdrv; 522 CharDriverState *cdrv;
523 unsigned short vendorid = 0x0403, productid = 0x6001; 523 unsigned short vendorid = 0x0403, productid = 0x6001;
  524 + char label[32];
  525 + static int index;
524 526
525 while (*filename && *filename != ':') { 527 while (*filename && *filename != ':') {
526 const char *p; 528 const char *p;
@@ -555,7 +557,8 @@ USBDevice *usb_serial_init(const char *filename) @@ -555,7 +557,8 @@ USBDevice *usb_serial_init(const char *filename)
555 if (!s) 557 if (!s)
556 return NULL; 558 return NULL;
557 559
558 - cdrv = qemu_chr_open(filename); 560 + snprintf(label, sizeof(label), "usbserial%d", index++);
  561 + cdrv = qemu_chr_open(label, filename);
559 if (!cdrv) 562 if (!cdrv)
560 goto fail; 563 goto fail;
561 s->cs = cdrv; 564 s->cs = cdrv;
monitor.c
@@ -1469,6 +1469,8 @@ static const term_cmd_t info_cmds[] = { @@ -1469,6 +1469,8 @@ static const term_cmd_t info_cmds[] = {
1469 "", "show the version of qemu" }, 1469 "", "show the version of qemu" },
1470 { "network", "", do_info_network, 1470 { "network", "", do_info_network,
1471 "", "show the network state" }, 1471 "", "show the network state" },
  1472 + { "chardev", "", qemu_chr_info,
  1473 + "", "show the character devices" },
1472 { "block", "", do_info_block, 1474 { "block", "", do_info_block,
1473 "", "show the block devices" }, 1475 "", "show the block devices" },
1474 { "blockstats", "", do_info_blockstats, 1476 { "blockstats", "", do_info_blockstats,
qemu-char.h
1 #ifndef QEMU_CHAR_H 1 #ifndef QEMU_CHAR_H
2 #define QEMU_CHAR_H 2 #define QEMU_CHAR_H
3 3
  4 +#include "sys-queue.h"
4 /* character device */ 5 /* character device */
5 6
6 #define CHR_EVENT_BREAK 0 /* serial break char */ 7 #define CHR_EVENT_BREAK 0 /* serial break char */
@@ -55,9 +56,12 @@ struct CharDriverState { @@ -55,9 +56,12 @@ struct CharDriverState {
55 void *opaque; 56 void *opaque;
56 int focus; 57 int focus;
57 QEMUBH *bh; 58 QEMUBH *bh;
  59 + char *label;
  60 + char *filename;
  61 + TAILQ_ENTRY(CharDriverState) next;
58 }; 62 };
59 63
60 -CharDriverState *qemu_chr_open(const char *filename); 64 +CharDriverState *qemu_chr_open(const char *label, const char *filename);
61 void qemu_chr_close(CharDriverState *chr); 65 void qemu_chr_close(CharDriverState *chr);
62 void qemu_chr_printf(CharDriverState *s, const char *fmt, ...); 66 void qemu_chr_printf(CharDriverState *s, const char *fmt, ...);
63 int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len); 67 int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len);
@@ -72,6 +76,7 @@ void qemu_chr_reset(CharDriverState *s); @@ -72,6 +76,7 @@ void qemu_chr_reset(CharDriverState *s);
72 int qemu_chr_can_read(CharDriverState *s); 76 int qemu_chr_can_read(CharDriverState *s);
73 void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len); 77 void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len);
74 void qemu_chr_accept_input(CharDriverState *s); 78 void qemu_chr_accept_input(CharDriverState *s);
  79 +void qemu_chr_info(void);
75 80
76 /* async I/O support */ 81 /* async I/O support */
77 82
@@ -2581,7 +2581,7 @@ static CharDriverState *qemu_chr_open_pty(void) @@ -2581,7 +2581,7 @@ static CharDriverState *qemu_chr_open_pty(void)
2581 CharDriverState *chr; 2581 CharDriverState *chr;
2582 PtyCharDriver *s; 2582 PtyCharDriver *s;
2583 struct termios tty; 2583 struct termios tty;
2584 - int slave_fd; 2584 + int slave_fd, len;
2585 #if defined(__OpenBSD__) 2585 #if defined(__OpenBSD__)
2586 char pty_name[PATH_MAX]; 2586 char pty_name[PATH_MAX];
2587 #define q_ptsname(x) pty_name 2587 #define q_ptsname(x) pty_name
@@ -2608,6 +2608,9 @@ static CharDriverState *qemu_chr_open_pty(void) @@ -2608,6 +2608,9 @@ static CharDriverState *qemu_chr_open_pty(void)
2608 tcsetattr(slave_fd, TCSAFLUSH, &tty); 2608 tcsetattr(slave_fd, TCSAFLUSH, &tty);
2609 close(slave_fd); 2609 close(slave_fd);
2610 2610
  2611 + len = strlen(q_ptsname(s->fd)) + 5;
  2612 + chr->filename = qemu_malloc(len);
  2613 + snprintf(chr->filename, len, "pty:%s", q_ptsname(s->fd));
2611 fprintf(stderr, "char device redirected to %s\n", q_ptsname(s->fd)); 2614 fprintf(stderr, "char device redirected to %s\n", q_ptsname(s->fd));
2612 2615
2613 chr->opaque = s; 2616 chr->opaque = s;
@@ -3767,90 +3770,115 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, @@ -3767,90 +3770,115 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
3767 return NULL; 3770 return NULL;
3768 } 3771 }
3769 3772
3770 -CharDriverState *qemu_chr_open(const char *filename) 3773 +static TAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs
  3774 += TAILQ_HEAD_INITIALIZER(chardevs);
  3775 +
  3776 +CharDriverState *qemu_chr_open(const char *label, const char *filename)
3771 { 3777 {
3772 const char *p; 3778 const char *p;
  3779 + CharDriverState *chr;
3773 3780
3774 if (!strcmp(filename, "vc")) { 3781 if (!strcmp(filename, "vc")) {
3775 - return text_console_init(&display_state, 0);  
3776 - } else if (strstart(filename, "vc:", &p)) {  
3777 - return text_console_init(&display_state, p);  
3778 - } else if (!strcmp(filename, "null")) {  
3779 - return qemu_chr_open_null(); 3782 + chr = text_console_init(&display_state, 0);
  3783 + } else
  3784 + if (strstart(filename, "vc:", &p)) {
  3785 + chr = text_console_init(&display_state, p);
  3786 + } else
  3787 + if (!strcmp(filename, "null")) {
  3788 + chr = qemu_chr_open_null();
3780 } else 3789 } else
3781 if (strstart(filename, "tcp:", &p)) { 3790 if (strstart(filename, "tcp:", &p)) {
3782 - return qemu_chr_open_tcp(p, 0, 0); 3791 + chr = qemu_chr_open_tcp(p, 0, 0);
3783 } else 3792 } else
3784 if (strstart(filename, "telnet:", &p)) { 3793 if (strstart(filename, "telnet:", &p)) {
3785 - return qemu_chr_open_tcp(p, 1, 0); 3794 + chr = qemu_chr_open_tcp(p, 1, 0);
3786 } else 3795 } else
3787 if (strstart(filename, "udp:", &p)) { 3796 if (strstart(filename, "udp:", &p)) {
3788 - return qemu_chr_open_udp(p); 3797 + chr = qemu_chr_open_udp(p);
3789 } else 3798 } else
3790 if (strstart(filename, "mon:", &p)) { 3799 if (strstart(filename, "mon:", &p)) {
3791 - CharDriverState *drv = qemu_chr_open(p);  
3792 - if (drv) {  
3793 - drv = qemu_chr_open_mux(drv);  
3794 - monitor_init(drv, !nographic);  
3795 - return drv; 3800 + chr = qemu_chr_open(label, p);
  3801 + if (chr) {
  3802 + chr = qemu_chr_open_mux(chr);
  3803 + monitor_init(chr, !nographic);
  3804 + } else {
  3805 + printf("Unable to open driver: %s\n", p);
3796 } 3806 }
3797 - printf("Unable to open driver: %s\n", p);  
3798 - return 0;  
3799 } else 3807 } else
3800 #ifndef _WIN32 3808 #ifndef _WIN32
3801 if (strstart(filename, "unix:", &p)) { 3809 if (strstart(filename, "unix:", &p)) {
3802 - return qemu_chr_open_tcp(p, 0, 1); 3810 + chr = qemu_chr_open_tcp(p, 0, 1);
3803 } else if (strstart(filename, "file:", &p)) { 3811 } else if (strstart(filename, "file:", &p)) {
3804 - return qemu_chr_open_file_out(p); 3812 + chr = qemu_chr_open_file_out(p);
3805 } else if (strstart(filename, "pipe:", &p)) { 3813 } else if (strstart(filename, "pipe:", &p)) {
3806 - return qemu_chr_open_pipe(p); 3814 + chr = qemu_chr_open_pipe(p);
3807 } else if (!strcmp(filename, "pty")) { 3815 } else if (!strcmp(filename, "pty")) {
3808 - return qemu_chr_open_pty(); 3816 + chr = qemu_chr_open_pty();
3809 } else if (!strcmp(filename, "stdio")) { 3817 } else if (!strcmp(filename, "stdio")) {
3810 - return qemu_chr_open_stdio(); 3818 + chr = qemu_chr_open_stdio();
3811 } else 3819 } else
3812 #if defined(__linux__) 3820 #if defined(__linux__)
3813 if (strstart(filename, "/dev/parport", NULL)) { 3821 if (strstart(filename, "/dev/parport", NULL)) {
3814 - return qemu_chr_open_pp(filename); 3822 + chr = qemu_chr_open_pp(filename);
3815 } else 3823 } else
3816 #endif 3824 #endif
3817 #if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \ 3825 #if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
3818 || defined(__NetBSD__) || defined(__OpenBSD__) 3826 || defined(__NetBSD__) || defined(__OpenBSD__)
3819 if (strstart(filename, "/dev/", NULL)) { 3827 if (strstart(filename, "/dev/", NULL)) {
3820 - return qemu_chr_open_tty(filename); 3828 + chr = qemu_chr_open_tty(filename);
3821 } else 3829 } else
3822 #endif 3830 #endif
3823 #else /* !_WIN32 */ 3831 #else /* !_WIN32 */
3824 if (strstart(filename, "COM", NULL)) { 3832 if (strstart(filename, "COM", NULL)) {
3825 - return qemu_chr_open_win(filename); 3833 + chr = qemu_chr_open_win(filename);
3826 } else 3834 } else
3827 if (strstart(filename, "pipe:", &p)) { 3835 if (strstart(filename, "pipe:", &p)) {
3828 - return qemu_chr_open_win_pipe(p); 3836 + chr = qemu_chr_open_win_pipe(p);
3829 } else 3837 } else
3830 if (strstart(filename, "con:", NULL)) { 3838 if (strstart(filename, "con:", NULL)) {
3831 - return qemu_chr_open_win_con(filename); 3839 + chr = qemu_chr_open_win_con(filename);
3832 } else 3840 } else
3833 if (strstart(filename, "file:", &p)) { 3841 if (strstart(filename, "file:", &p)) {
3834 - return qemu_chr_open_win_file_out(p); 3842 + chr = qemu_chr_open_win_file_out(p);
3835 } else 3843 } else
3836 #endif 3844 #endif
3837 #ifdef CONFIG_BRLAPI 3845 #ifdef CONFIG_BRLAPI
3838 if (!strcmp(filename, "braille")) { 3846 if (!strcmp(filename, "braille")) {
3839 - return chr_baum_init(); 3847 + chr = chr_baum_init();
3840 } else 3848 } else
3841 #endif 3849 #endif
3842 { 3850 {
3843 - return NULL; 3851 + chr = NULL;
  3852 + }
  3853 +
  3854 + if (chr) {
  3855 + if (!chr->filename)
  3856 + chr->filename = qemu_strdup(filename);
  3857 + chr->label = qemu_strdup(label);
  3858 + TAILQ_INSERT_TAIL(&chardevs, chr, next);
3844 } 3859 }
  3860 + return chr;
3845 } 3861 }
3846 3862
3847 void qemu_chr_close(CharDriverState *chr) 3863 void qemu_chr_close(CharDriverState *chr)
3848 { 3864 {
  3865 + TAILQ_REMOVE(&chardevs, chr, next);
3849 if (chr->chr_close) 3866 if (chr->chr_close)
3850 chr->chr_close(chr); 3867 chr->chr_close(chr);
  3868 + qemu_free(chr->filename);
  3869 + qemu_free(chr->label);
3851 qemu_free(chr); 3870 qemu_free(chr);
3852 } 3871 }
3853 3872
  3873 +void qemu_chr_info(void)
  3874 +{
  3875 + CharDriverState *chr;
  3876 +
  3877 + TAILQ_FOREACH(chr, &chardevs, next) {
  3878 + term_printf("%s: filename=%s\n", chr->label, chr->filename);
  3879 + }
  3880 +}
  3881 +
3854 /***********************************************************/ 3882 /***********************************************************/
3855 /* network device redirectors */ 3883 /* network device redirectors */
3856 3884
@@ -9689,7 +9717,7 @@ int main(int argc, char **argv) @@ -9689,7 +9717,7 @@ int main(int argc, char **argv)
9689 } 9717 }
9690 } 9718 }
9691 if (monitor_device) { 9719 if (monitor_device) {
9692 - monitor_hd = qemu_chr_open(monitor_device); 9720 + monitor_hd = qemu_chr_open("monitor", monitor_device);
9693 if (!monitor_hd) { 9721 if (!monitor_hd) {
9694 fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device); 9722 fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
9695 exit(1); 9723 exit(1);
@@ -9700,7 +9728,9 @@ int main(int argc, char **argv) @@ -9700,7 +9728,9 @@ int main(int argc, char **argv)
9700 for(i = 0; i < MAX_SERIAL_PORTS; i++) { 9728 for(i = 0; i < MAX_SERIAL_PORTS; i++) {
9701 const char *devname = serial_devices[i]; 9729 const char *devname = serial_devices[i];
9702 if (devname && strcmp(devname, "none")) { 9730 if (devname && strcmp(devname, "none")) {
9703 - serial_hds[i] = qemu_chr_open(devname); 9731 + char label[32];
  9732 + snprintf(label, sizeof(label), "serial%d", i);
  9733 + serial_hds[i] = qemu_chr_open(label, devname);
9704 if (!serial_hds[i]) { 9734 if (!serial_hds[i]) {
9705 fprintf(stderr, "qemu: could not open serial device '%s'\n", 9735 fprintf(stderr, "qemu: could not open serial device '%s'\n",
9706 devname); 9736 devname);
@@ -9714,7 +9744,9 @@ int main(int argc, char **argv) @@ -9714,7 +9744,9 @@ int main(int argc, char **argv)
9714 for(i = 0; i < MAX_PARALLEL_PORTS; i++) { 9744 for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
9715 const char *devname = parallel_devices[i]; 9745 const char *devname = parallel_devices[i];
9716 if (devname && strcmp(devname, "none")) { 9746 if (devname && strcmp(devname, "none")) {
9717 - parallel_hds[i] = qemu_chr_open(devname); 9747 + char label[32];
  9748 + snprintf(label, sizeof(label), "parallel%d", i);
  9749 + parallel_hds[i] = qemu_chr_open(label, devname);
9718 if (!parallel_hds[i]) { 9750 if (!parallel_hds[i]) {
9719 fprintf(stderr, "qemu: could not open parallel device '%s'\n", 9751 fprintf(stderr, "qemu: could not open parallel device '%s'\n",
9720 devname); 9752 devname);