Reinitialize monitor upon reconnect
PATCH RESEND 1/1 Reinitialize monitor upon reconnect
The attached patch will reinitialize the monitor for character devices that support reconnecting (tcp, telnet, unix socket, etc). This patch is needed to be able to connect to the monitor in a deterministic way (for management tools). I've updated the patch considerably since the last time I sent it.
I've changed the character devices to emit an event whenever the device is connected. For devices like fd, pty, and vc this will only ever occur when the device is created. For the other devices, this will occur on connect() or accept(). This is done with a bottom half to ensure that a user has a chance to register for the event before the event is emitted.
I've changed the monitor device to print the banner whenever the reset event is received. Now all of the character devices work as they did before (no double banners any more).
Regards,
Anthony Liguori
console.c +2 -0
@@ -1086,5 +1086,7 @@ CharDriverState *text_console_init(Displ s->t_attrib = s->t_attrib_default;text_console_resize (s); +qemu_chr_reset (chr); +return chr; }
monitor.c +15 -5
@@ -55,6 +55,7 @@ typedef struct term_cmd_t { } term_cmd_t;static CharDriverState *monitor_hd; +static int hide_banner;static term_cmd_t term_cmds[];static term_cmd_t info_cmds[];
@@ -2402,15 +2403,24 @@ static void monitor_start_input(void)readline_start ("(qemu) " ,0 , monitor_handle_command1,NULL ); } +static void term_event (void *opaque,int event) +{ +if (event !=CHR_EVENT_RESET ) +return ; + +if (!hide_banner) +term_printf ("QEMU %s monitor - type 'help' for more information\n" , +QEMU_VERSION ); +monitor_start_input (); +} +void monitor_init (CharDriverState *hd,int show_banner) { monitor_hd = hd; -if (show_banner) { -term_printf ("QEMU %s monitor - type 'help' for more information\n" , -QEMU_VERSION ); - } + hide_banner = !show_banner; +qemu_chr_add_read_handler (hd, term_can_read, term_read,NULL ); -monitor_start_input (); +qemu_chr_add_event_handler (hd, term_event); }/* XXX: use threads ? */
vl.c +28 -0
@@ -1050,6 +1050,23 @@ void quit_timers(void)/***********************************************************/ /* character device */ +static void qemu_chr_reset_bh (void *opaque) +{ +CharDriverState *s = opaque; +if (s->chr_event) + s->chr_event (s,CHR_EVENT_RESET ); +qemu_bh_delete (s->bh); + s->bh =NULL ; +} + +void qemu_chr_reset (CharDriverState *s) +{ +if (s->bh ==NULL ) { + s->bh =qemu_bh_new (qemu_chr_reset_bh, s); +qemu_bh_schedule (s->bh); + } +} +int qemu_chr_write (CharDriverState *s,const uint8_t *buf,int len) {return s->chr_write (s, buf, len);
@@ -1287,6 +1304,9 @@ static CharDriverState *qemu_chr_open_fd chr->opaque = s; chr->chr_write = fd_chr_write; chr->chr_add_read_handler = fd_chr_add_read_handler; + +qemu_chr_reset (chr); +return chr; }
@@ -1704,6 +1724,7 @@ static CharDriverState *qemu_chr_open_ttif (!chr)return NULL ; chr->chr_ioctl = tty_serial_ioctl; +qemu_chr_reset (chr);return chr; }
@@ -1767,6 +1788,9 @@ static CharDriverState *qemu_chr_open_pp chr->chr_write = null_chr_write; chr->chr_add_read_handler = null_chr_add_read_handler; chr->chr_ioctl = pp_ioctl; + +qemu_chr_reset (chr); +return chr; }
@@ -2012,6 +2036,7 @@ static CharDriverState *qemu_chr_open_wifree (chr);return NULL ; } +qemu_chr_reset (chr);return chr; }
@@ -2115,6 +2140,7 @@ static CharDriverState *qemu_chr_open_wifree (chr);return NULL ; } +qemu_chr_reset (chr);return chr; }
@@ -2135,6 +2161,7 @@ static CharDriverState *qemu_chr_open_wi chr->opaque = s; chr->chr_write = win_chr_write; chr->chr_add_read_handler = win_chr_add_read_handler; +qemu_chr_reset (chr);return chr; }
@@ -2422,6 +2449,7 @@ static void tcp_chr_connect(void *opaque s->connected =1 ;qemu_set_fd_handler2 (s->fd, tcp_chr_read_poll, tcp_chr_read,NULL , chr); +qemu_chr_reset (chr); }#define IACSET (x,a,b,c) x[0] = a; x[1] = b; x[2] = c;
vl.h +5 -2
@@ -236,11 +236,13 @@ void qemu_del_wait_object(HANDLE handle,void qemu_del_wait_object (HANDLE handle,WaitObjectFunc *func,void *opaque);#endif +typedef struct QEMUBH QEMUBH ; +/* character device */ #define CHR_EVENT_BREAK 0/* serial break char */ #define CHR_EVENT_FOCUS 1/* focus to this terminal (modal input needed) */ - +#define CHR_EVENT_RESET 2/* new connection established */ #define CHR_IOCTL_SERIAL_SET_PARAMS 1
@@ -271,6 +273,7 @@ typedef struct CharDriverState {void (*chr_send_event)(struct CharDriverState *chr,int event);void (*chr_close)(struct CharDriverState *chr);void *opaque; +QEMUBH *bh; } CharDriverState;void qemu_chr_printf (CharDriverState *s,const char *fmt, ...);
@@ -281,6 +284,7 @@ void qemu_chr_add_read_handler(CharDrive IOReadHandler *fd_read, void *opaque);void qemu_chr_add_event_handler (CharDriverState *s,IOEventHandler *chr_event);int qemu_chr_ioctl (CharDriverState *s,int cmd,void *arg); +void qemu_chr_reset (CharDriverState *s);/* consoles */
@@ -489,7 +493,6 @@ void do_info_snapshots(void);void do_info_snapshots (void );/* bottom halves */ -typedef struct QEMUBH QEMUBH ;typedef void QEMUBHFunc (void *opaque);QEMUBH *qemu_bh_new (QEMUBHFunc *cb,void *opaque);