Commit 731b03642d0ac0365294c7b39713fede769a3f39

Authored by aliguori
1 parent 4c36ba32

monitor: Decouple terminals (Jan Kiszka)

Currently all registered (and activate) monitor terminals work in
broadcast mode: Everyone sees what someone else types on some other
terminal and what the monitor reports back. This model is broken when
you have a management monitor terminal that is automatically operated
and some other terminal used for independent guest inspection. Such
additional terminals can be multiplexed device channels or a gdb
frontend connected to QEMU's stub.

Therefore, this patch decouples the buffers and states of all monitor
terminals, allowing the user to operate them independently. It finally
starts to use the 'mon' parameter that was introduced earlier with the
API rework. It also defines the default monitor: the first instantance
that has the MONITOR_IS_DEFAULT flag set, and that is the monitor
created via the "-monitor" command line switch (or "vc" if none is
given).

As the patch requires to rework the monitor suspension interface, it
also takes the freedom to make it "truely" suspending (so far suspending
meant suppressing the prompt, but inputs were still processed).

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6715 c046a42c-6fe2-441c-8c8c-71466251a162
migration-exec.c
@@ -18,7 +18,6 @@ @@ -18,7 +18,6 @@
18 #include "migration.h" 18 #include "migration.h"
19 #include "qemu-char.h" 19 #include "qemu-char.h"
20 #include "sysemu.h" 20 #include "sysemu.h"
21 -#include "monitor.h"  
22 #include "buffered_file.h" 21 #include "buffered_file.h"
23 #include "block.h" 22 #include "block.h"
24 23
@@ -55,7 +54,7 @@ static int exec_close(FdMigrationState *s) @@ -55,7 +54,7 @@ static int exec_close(FdMigrationState *s)
55 54
56 MigrationState *exec_start_outgoing_migration(const char *command, 55 MigrationState *exec_start_outgoing_migration(const char *command,
57 int64_t bandwidth_limit, 56 int64_t bandwidth_limit,
58 - int async) 57 + int detach)
59 { 58 {
60 FdMigrationState *s; 59 FdMigrationState *s;
61 FILE *f; 60 FILE *f;
@@ -89,14 +88,11 @@ MigrationState *exec_start_outgoing_migration(const char *command, @@ -89,14 +88,11 @@ MigrationState *exec_start_outgoing_migration(const char *command,
89 s->mig_state.release = migrate_fd_release; 88 s->mig_state.release = migrate_fd_release;
90 89
91 s->state = MIG_STATE_ACTIVE; 90 s->state = MIG_STATE_ACTIVE;
92 - s->detach = !async; 91 + s->mon_resume = NULL;
93 s->bandwidth_limit = bandwidth_limit; 92 s->bandwidth_limit = bandwidth_limit;
94 93
95 - if (s->detach == 1) {  
96 - dprintf("detaching from monitor\n");  
97 - monitor_suspend(cur_mon);  
98 - s->detach = 2;  
99 - } 94 + if (!detach)
  95 + migrate_fd_monitor_suspend(s);
100 96
101 migrate_fd_connect(s); 97 migrate_fd_connect(s);
102 return &s->mig_state; 98 return &s->mig_state;
migration-tcp.c
@@ -16,7 +16,6 @@ @@ -16,7 +16,6 @@
16 #include "migration.h" 16 #include "migration.h"
17 #include "qemu-char.h" 17 #include "qemu-char.h"
18 #include "sysemu.h" 18 #include "sysemu.h"
19 -#include "monitor.h"  
20 #include "buffered_file.h" 19 #include "buffered_file.h"
21 #include "block.h" 20 #include "block.h"
22 21
@@ -79,7 +78,7 @@ static void tcp_wait_for_connect(void *opaque) @@ -79,7 +78,7 @@ static void tcp_wait_for_connect(void *opaque)
79 78
80 MigrationState *tcp_start_outgoing_migration(const char *host_port, 79 MigrationState *tcp_start_outgoing_migration(const char *host_port,
81 int64_t bandwidth_limit, 80 int64_t bandwidth_limit,
82 - int async) 81 + int detach)
83 { 82 {
84 struct sockaddr_in addr; 83 struct sockaddr_in addr;
85 FdMigrationState *s; 84 FdMigrationState *s;
@@ -98,7 +97,7 @@ MigrationState *tcp_start_outgoing_migration(const char *host_port, @@ -98,7 +97,7 @@ MigrationState *tcp_start_outgoing_migration(const char *host_port,
98 s->mig_state.release = migrate_fd_release; 97 s->mig_state.release = migrate_fd_release;
99 98
100 s->state = MIG_STATE_ACTIVE; 99 s->state = MIG_STATE_ACTIVE;
101 - s->detach = !async; 100 + s->mon_resume = NULL;
102 s->bandwidth_limit = bandwidth_limit; 101 s->bandwidth_limit = bandwidth_limit;
103 s->fd = socket(PF_INET, SOCK_STREAM, 0); 102 s->fd = socket(PF_INET, SOCK_STREAM, 0);
104 if (s->fd == -1) { 103 if (s->fd == -1) {
@@ -108,11 +107,8 @@ MigrationState *tcp_start_outgoing_migration(const char *host_port, @@ -108,11 +107,8 @@ MigrationState *tcp_start_outgoing_migration(const char *host_port,
108 107
109 socket_set_nonblock(s->fd); 108 socket_set_nonblock(s->fd);
110 109
111 - if (s->detach == 1) {  
112 - dprintf("detaching from monitor\n");  
113 - monitor_suspend(cur_mon);  
114 - s->detach = 2;  
115 - } 110 + if (!detach)
  111 + migrate_fd_monitor_suspend(s);
116 112
117 do { 113 do {
118 ret = connect(s->fd, (struct sockaddr *)&addr, sizeof(addr)); 114 ret = connect(s->fd, (struct sockaddr *)&addr, sizeof(addr));
migration.c
@@ -125,6 +125,13 @@ void do_info_migrate(Monitor *mon) @@ -125,6 +125,13 @@ void do_info_migrate(Monitor *mon)
125 125
126 /* shared migration helpers */ 126 /* shared migration helpers */
127 127
  128 +void migrate_fd_monitor_suspend(FdMigrationState *s)
  129 +{
  130 + s->mon_resume = cur_mon;
  131 + monitor_suspend(cur_mon);
  132 + dprintf("suspending monitor\n");
  133 +}
  134 +
128 void migrate_fd_error(FdMigrationState *s) 135 void migrate_fd_error(FdMigrationState *s)
129 { 136 {
130 dprintf("setting error state\n"); 137 dprintf("setting error state\n");
@@ -145,10 +152,8 @@ void migrate_fd_cleanup(FdMigrationState *s) @@ -145,10 +152,8 @@ void migrate_fd_cleanup(FdMigrationState *s)
145 close(s->fd); 152 close(s->fd);
146 153
147 /* Don't resume monitor until we've flushed all of the buffers */ 154 /* Don't resume monitor until we've flushed all of the buffers */
148 - if (s->detach == 2) {  
149 - monitor_resume(cur_mon);  
150 - s->detach = 0;  
151 - } 155 + if (s->mon_resume)
  156 + monitor_resume(s->mon_resume);
152 157
153 s->fd = -1; 158 s->fd = -1;
154 } 159 }
migration.h
@@ -39,7 +39,7 @@ struct FdMigrationState @@ -39,7 +39,7 @@ struct FdMigrationState
39 int64_t bandwidth_limit; 39 int64_t bandwidth_limit;
40 QEMUFile *file; 40 QEMUFile *file;
41 int fd; 41 int fd;
42 - int detach; 42 + Monitor *mon_resume;
43 int state; 43 int state;
44 int (*get_error)(struct FdMigrationState*); 44 int (*get_error)(struct FdMigrationState*);
45 int (*close)(struct FdMigrationState*); 45 int (*close)(struct FdMigrationState*);
@@ -69,6 +69,8 @@ MigrationState *tcp_start_outgoing_migration(const char *host_port, @@ -69,6 +69,8 @@ MigrationState *tcp_start_outgoing_migration(const char *host_port,
69 int64_t bandwidth_limit, 69 int64_t bandwidth_limit,
70 int detach); 70 int detach);
71 71
  72 +void migrate_fd_monitor_suspend(FdMigrationState *s);
  73 +
72 void migrate_fd_error(FdMigrationState *s); 74 void migrate_fd_error(FdMigrationState *s);
73 75
74 void migrate_fd_cleanup(FdMigrationState *s); 76 void migrate_fd_cleanup(FdMigrationState *s);
monitor.c
@@ -69,6 +69,14 @@ typedef struct mon_cmd_t { @@ -69,6 +69,14 @@ typedef struct mon_cmd_t {
69 69
70 struct Monitor { 70 struct Monitor {
71 CharDriverState *chr; 71 CharDriverState *chr;
  72 + int flags;
  73 + int suspend_cnt;
  74 + uint8_t outbuf[1024];
  75 + int outbuf_index;
  76 + ReadLineState *rs;
  77 + CPUState *mon_cpu;
  78 + BlockDriverCompletionFunc *password_completion_cb;
  79 + void *password_opaque;
72 LIST_ENTRY(Monitor) entry; 80 LIST_ENTRY(Monitor) entry;
73 }; 81 };
74 82
@@ -77,34 +85,30 @@ static LIST_HEAD(mon_list, Monitor) mon_list; @@ -77,34 +85,30 @@ static LIST_HEAD(mon_list, Monitor) mon_list;
77 static const mon_cmd_t mon_cmds[]; 85 static const mon_cmd_t mon_cmds[];
78 static const mon_cmd_t info_cmds[]; 86 static const mon_cmd_t info_cmds[];
79 87
80 -static uint8_t term_outbuf[1024];  
81 -static int term_outbuf_index;  
82 -static BlockDriverCompletionFunc *password_completion_cb;  
83 -static void *password_opaque;  
84 -ReadLineState *rs;  
85 -  
86 Monitor *cur_mon = NULL; 88 Monitor *cur_mon = NULL;
87 89
88 -static void monitor_start_input(void); 90 +static void monitor_command_cb(Monitor *mon, const char *cmdline,
  91 + void *opaque);
89 92
90 -static CPUState *mon_cpu = NULL; 93 +static void monitor_read_command(Monitor *mon, int show_prompt)
  94 +{
  95 + readline_start(mon->rs, "(qemu) ", 0, monitor_command_cb, NULL);
  96 + if (show_prompt)
  97 + readline_show_prompt(mon->rs);
  98 +}
91 99
92 static void monitor_read_password(Monitor *mon, ReadLineFunc *readline_func, 100 static void monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
93 void *opaque) 101 void *opaque)
94 { 102 {
95 - readline_start(rs, "Password: ", 1, readline_func, opaque); 103 + readline_start(mon->rs, "Password: ", 1, readline_func, opaque);
  104 + /* prompt is printed on return from the command handler */
96 } 105 }
97 106
98 void monitor_flush(Monitor *mon) 107 void monitor_flush(Monitor *mon)
99 { 108 {
100 - Monitor *m;  
101 -  
102 - if (term_outbuf_index > 0) {  
103 - LIST_FOREACH(m, &mon_list, entry) {  
104 - if (m->chr->focus == 0)  
105 - qemu_chr_write(m->chr, term_outbuf, term_outbuf_index);  
106 - }  
107 - term_outbuf_index = 0; 109 + if (mon && mon->outbuf_index != 0 && mon->chr->focus == 0) {
  110 + qemu_chr_write(mon->chr, mon->outbuf, mon->outbuf_index);
  111 + mon->outbuf_index = 0;
108 } 112 }
109 } 113 }
110 114
@@ -112,15 +116,19 @@ void monitor_flush(Monitor *mon) @@ -112,15 +116,19 @@ void monitor_flush(Monitor *mon)
112 static void monitor_puts(Monitor *mon, const char *str) 116 static void monitor_puts(Monitor *mon, const char *str)
113 { 117 {
114 char c; 118 char c;
  119 +
  120 + if (!mon)
  121 + return;
  122 +
115 for(;;) { 123 for(;;) {
116 c = *str++; 124 c = *str++;
117 if (c == '\0') 125 if (c == '\0')
118 break; 126 break;
119 if (c == '\n') 127 if (c == '\n')
120 - term_outbuf[term_outbuf_index++] = '\r';  
121 - term_outbuf[term_outbuf_index++] = c;  
122 - if (term_outbuf_index >= (sizeof(term_outbuf) - 1) ||  
123 - c == '\n') 128 + mon->outbuf[mon->outbuf_index++] = '\r';
  129 + mon->outbuf[mon->outbuf_index++] = c;
  130 + if (mon->outbuf_index >= (sizeof(mon->outbuf) - 1)
  131 + || c == '\n')
124 monitor_flush(mon); 132 monitor_flush(mon);
125 } 133 }
126 } 134 }
@@ -291,7 +299,7 @@ static int mon_set_cpu(int cpu_index) @@ -291,7 +299,7 @@ static int mon_set_cpu(int cpu_index)
291 299
292 for(env = first_cpu; env != NULL; env = env->next_cpu) { 300 for(env = first_cpu; env != NULL; env = env->next_cpu) {
293 if (env->cpu_index == cpu_index) { 301 if (env->cpu_index == cpu_index) {
294 - mon_cpu = env; 302 + cur_mon->mon_cpu = env;
295 return 0; 303 return 0;
296 } 304 }
297 } 305 }
@@ -300,10 +308,10 @@ static int mon_set_cpu(int cpu_index) @@ -300,10 +308,10 @@ static int mon_set_cpu(int cpu_index)
300 308
301 static CPUState *mon_get_cpu(void) 309 static CPUState *mon_get_cpu(void)
302 { 310 {
303 - if (!mon_cpu) { 311 + if (!cur_mon->mon_cpu) {
304 mon_set_cpu(0); 312 mon_set_cpu(0);
305 } 313 }
306 - return mon_cpu; 314 + return cur_mon->mon_cpu;
307 } 315 }
308 316
309 static void do_info_registers(Monitor *mon) 317 static void do_info_registers(Monitor *mon)
@@ -330,7 +338,7 @@ static void do_info_cpus(Monitor *mon) @@ -330,7 +338,7 @@ static void do_info_cpus(Monitor *mon)
330 338
331 for(env = first_cpu; env != NULL; env = env->next_cpu) { 339 for(env = first_cpu; env != NULL; env = env->next_cpu) {
332 monitor_printf(mon, "%c CPU #%d:", 340 monitor_printf(mon, "%c CPU #%d:",
333 - (env == mon_cpu) ? '*' : ' ', 341 + (env == mon->mon_cpu) ? '*' : ' ',
334 env->cpu_index); 342 env->cpu_index);
335 #if defined(TARGET_I386) 343 #if defined(TARGET_I386)
336 monitor_printf(mon, " pc=0x" TARGET_FMT_lx, 344 monitor_printf(mon, " pc=0x" TARGET_FMT_lx,
@@ -367,7 +375,7 @@ static void do_info_history(Monitor *mon) @@ -367,7 +375,7 @@ static void do_info_history(Monitor *mon)
367 375
368 i = 0; 376 i = 0;
369 for(;;) { 377 for(;;) {
370 - str = readline_get_history(rs, i); 378 + str = readline_get_history(mon->rs, i);
371 if (!str) 379 if (!str)
372 break; 380 break;
373 monitor_printf(mon, "%d: '%s'\n", i, str); 381 monitor_printf(mon, "%d: '%s'\n", i, str);
@@ -451,7 +459,7 @@ static void change_vnc_password_cb(Monitor *mon, const char *password, @@ -451,7 +459,7 @@ static void change_vnc_password_cb(Monitor *mon, const char *password,
451 if (vnc_display_password(NULL, password) < 0) 459 if (vnc_display_password(NULL, password) < 0)
452 monitor_printf(mon, "could not set VNC server password\n"); 460 monitor_printf(mon, "could not set VNC server password\n");
453 461
454 - monitor_start_input(); 462 + monitor_read_command(mon, 1);
455 } 463 }
456 464
457 static void do_change_vnc(Monitor *mon, const char *target, const char *arg) 465 static void do_change_vnc(Monitor *mon, const char *target, const char *arg)
@@ -2688,7 +2696,7 @@ static void cmd_completion(const char *name, const char *list) @@ -2688,7 +2696,7 @@ static void cmd_completion(const char *name, const char *list)
2688 memcpy(cmd, pstart, len); 2696 memcpy(cmd, pstart, len);
2689 cmd[len] = '\0'; 2697 cmd[len] = '\0';
2690 if (name[0] == '\0' || !strncmp(name, cmd, strlen(name))) { 2698 if (name[0] == '\0' || !strncmp(name, cmd, strlen(name))) {
2691 - readline_add_completion(rs, cmd); 2699 + readline_add_completion(cur_mon->rs, cmd);
2692 } 2700 }
2693 if (*p == '\0') 2701 if (*p == '\0')
2694 break; 2702 break;
@@ -2741,7 +2749,7 @@ static void file_completion(const char *input) @@ -2741,7 +2749,7 @@ static void file_completion(const char *input)
2741 stat(file, &sb); 2749 stat(file, &sb);
2742 if(S_ISDIR(sb.st_mode)) 2750 if(S_ISDIR(sb.st_mode))
2743 pstrcat(file, sizeof(file), "/"); 2751 pstrcat(file, sizeof(file), "/");
2744 - readline_add_completion(rs, file); 2752 + readline_add_completion(cur_mon->rs, file);
2745 } 2753 }
2746 } 2754 }
2747 closedir(ffs); 2755 closedir(ffs);
@@ -2754,7 +2762,7 @@ static void block_completion_it(void *opaque, BlockDriverState *bs) @@ -2754,7 +2762,7 @@ static void block_completion_it(void *opaque, BlockDriverState *bs)
2754 2762
2755 if (input[0] == '\0' || 2763 if (input[0] == '\0' ||
2756 !strncmp(name, (char *)input, strlen(input))) { 2764 !strncmp(name, (char *)input, strlen(input))) {
2757 - readline_add_completion(rs, name); 2765 + readline_add_completion(cur_mon->rs, name);
2758 } 2766 }
2759 } 2767 }
2760 2768
@@ -2814,7 +2822,7 @@ static void monitor_find_completion(const char *cmdline) @@ -2814,7 +2822,7 @@ static void monitor_find_completion(const char *cmdline)
2814 cmdname = ""; 2822 cmdname = "";
2815 else 2823 else
2816 cmdname = args[0]; 2824 cmdname = args[0];
2817 - readline_set_completion_index(rs, strlen(cmdname)); 2825 + readline_set_completion_index(cur_mon->rs, strlen(cmdname));
2818 for(cmd = mon_cmds; cmd->name != NULL; cmd++) { 2826 for(cmd = mon_cmds; cmd->name != NULL; cmd++) {
2819 cmd_completion(cmdname, cmd->name); 2827 cmd_completion(cmdname, cmd->name);
2820 } 2828 }
@@ -2838,23 +2846,23 @@ static void monitor_find_completion(const char *cmdline) @@ -2838,23 +2846,23 @@ static void monitor_find_completion(const char *cmdline)
2838 switch(*ptype) { 2846 switch(*ptype) {
2839 case 'F': 2847 case 'F':
2840 /* file completion */ 2848 /* file completion */
2841 - readline_set_completion_index(rs, strlen(str)); 2849 + readline_set_completion_index(cur_mon->rs, strlen(str));
2842 file_completion(str); 2850 file_completion(str);
2843 break; 2851 break;
2844 case 'B': 2852 case 'B':
2845 /* block device name completion */ 2853 /* block device name completion */
2846 - readline_set_completion_index(rs, strlen(str)); 2854 + readline_set_completion_index(cur_mon->rs, strlen(str));
2847 bdrv_iterate(block_completion_it, (void *)str); 2855 bdrv_iterate(block_completion_it, (void *)str);
2848 break; 2856 break;
2849 case 's': 2857 case 's':
2850 /* XXX: more generic ? */ 2858 /* XXX: more generic ? */
2851 if (!strcmp(cmd->name, "info")) { 2859 if (!strcmp(cmd->name, "info")) {
2852 - readline_set_completion_index(rs, strlen(str)); 2860 + readline_set_completion_index(cur_mon->rs, strlen(str));
2853 for(cmd = info_cmds; cmd->name != NULL; cmd++) { 2861 for(cmd = info_cmds; cmd->name != NULL; cmd++) {
2854 cmd_completion(str, cmd->name); 2862 cmd_completion(str, cmd->name);
2855 } 2863 }
2856 } else if (!strcmp(cmd->name, "sendkey")) { 2864 } else if (!strcmp(cmd->name, "sendkey")) {
2857 - readline_set_completion_index(rs, strlen(str)); 2865 + readline_set_completion_index(cur_mon->rs, strlen(str));
2858 for(key = key_defs; key->name != NULL; key++) { 2866 for(key = key_defs; key->name != NULL; key++) {
2859 cmd_completion(str, key->name); 2867 cmd_completion(str, key->name);
2860 } 2868 }
@@ -2868,49 +2876,45 @@ static void monitor_find_completion(const char *cmdline) @@ -2868,49 +2876,45 @@ static void monitor_find_completion(const char *cmdline)
2868 qemu_free(args[i]); 2876 qemu_free(args[i]);
2869 } 2877 }
2870 2878
2871 -static int term_can_read(void *opaque) 2879 +static int monitor_can_read(void *opaque)
2872 { 2880 {
2873 - return 128; 2881 + Monitor *mon = opaque;
  2882 +
  2883 + return (mon->suspend_cnt == 0) ? 128 : 0;
2874 } 2884 }
2875 2885
2876 -static void term_read(void *opaque, const uint8_t *buf, int size) 2886 +static void monitor_read(void *opaque, const uint8_t *buf, int size)
2877 { 2887 {
  2888 + Monitor *old_mon = cur_mon;
2878 int i; 2889 int i;
2879 2890
2880 - for(i = 0; i < size; i++)  
2881 - readline_handle_byte(rs, buf[i]);  
2882 -} 2891 + cur_mon = opaque;
  2892 +
  2893 + for (i = 0; i < size; i++)
  2894 + readline_handle_byte(cur_mon->rs, buf[i]);
2883 2895
2884 -static int monitor_suspended; 2896 + cur_mon = old_mon;
  2897 +}
2885 2898
2886 static void monitor_command_cb(Monitor *mon, const char *cmdline, void *opaque) 2899 static void monitor_command_cb(Monitor *mon, const char *cmdline, void *opaque)
2887 { 2900 {
  2901 + monitor_suspend(mon);
2888 monitor_handle_command(mon, cmdline); 2902 monitor_handle_command(mon, cmdline);
2889 - if (!monitor_suspended)  
2890 - readline_show_prompt(rs);  
2891 - else  
2892 - monitor_suspended = 2; 2903 + monitor_resume(mon);
2893 } 2904 }
2894 2905
2895 void monitor_suspend(Monitor *mon) 2906 void monitor_suspend(Monitor *mon)
2896 { 2907 {
2897 - monitor_suspended = 1; 2908 + mon->suspend_cnt++;
2898 } 2909 }
2899 2910
2900 void monitor_resume(Monitor *mon) 2911 void monitor_resume(Monitor *mon)
2901 { 2912 {
2902 - if (monitor_suspended == 2)  
2903 - monitor_start_input();  
2904 - monitor_suspended = 0; 2913 + if (--mon->suspend_cnt == 0)
  2914 + readline_show_prompt(mon->rs);
2905 } 2915 }
2906 2916
2907 -static void monitor_start_input(void)  
2908 -{  
2909 - readline_start(rs, "(qemu) ", 0, monitor_command_cb, NULL);  
2910 - readline_show_prompt(rs);  
2911 -}  
2912 -  
2913 -static void term_event(void *opaque, int event) 2917 +static void monitor_event(void *opaque, int event)
2914 { 2918 {
2915 Monitor *mon = opaque; 2919 Monitor *mon = opaque;
2916 2920
@@ -2919,13 +2923,12 @@ static void term_event(void *opaque, int event) @@ -2919,13 +2923,12 @@ static void term_event(void *opaque, int event)
2919 2923
2920 monitor_printf(mon, "QEMU %s monitor - type 'help' for more information\n", 2924 monitor_printf(mon, "QEMU %s monitor - type 'help' for more information\n",
2921 QEMU_VERSION); 2925 QEMU_VERSION);
2922 - monitor_start_input(); 2926 + readline_show_prompt(mon->rs);
2923 } 2927 }
2924 2928
2925 -static int is_first_init = 1;  
2926 -  
2927 -void monitor_init(CharDriverState *chr) 2929 +void monitor_init(CharDriverState *chr, int flags)
2928 { 2930 {
  2931 + static int is_first_init = 1;
2929 Monitor *mon; 2932 Monitor *mon;
2930 2933
2931 if (is_first_init) { 2934 if (is_first_init) {
@@ -2936,15 +2939,16 @@ void monitor_init(CharDriverState *chr) @@ -2936,15 +2939,16 @@ void monitor_init(CharDriverState *chr)
2936 mon = qemu_mallocz(sizeof(*mon)); 2939 mon = qemu_mallocz(sizeof(*mon));
2937 2940
2938 mon->chr = chr; 2941 mon->chr = chr;
2939 - rs = readline_init(mon, monitor_find_completion); 2942 + mon->flags = flags;
  2943 + mon->rs = readline_init(mon, monitor_find_completion);
  2944 + monitor_read_command(mon, 0);
2940 2945
2941 - qemu_chr_add_handlers(chr, term_can_read, term_read, term_event, mon); 2946 + qemu_chr_add_handlers(chr, monitor_can_read, monitor_read, monitor_event,
  2947 + mon);
2942 2948
2943 LIST_INSERT_HEAD(&mon_list, mon, entry); 2949 LIST_INSERT_HEAD(&mon_list, mon, entry);
2944 - if (!cur_mon) 2950 + if (!cur_mon || (flags & MONITOR_IS_DEFAULT))
2945 cur_mon = mon; 2951 cur_mon = mon;
2946 -  
2947 - readline_start(rs, "", 0, monitor_command_cb, NULL);  
2948 } 2952 }
2949 2953
2950 static void bdrv_password_cb(Monitor *mon, const char *password, void *opaque) 2954 static void bdrv_password_cb(Monitor *mon, const char *password, void *opaque)
@@ -2956,10 +2960,10 @@ static void bdrv_password_cb(Monitor *mon, const char *password, void *opaque) @@ -2956,10 +2960,10 @@ static void bdrv_password_cb(Monitor *mon, const char *password, void *opaque)
2956 monitor_printf(mon, "invalid password\n"); 2960 monitor_printf(mon, "invalid password\n");
2957 ret = -EPERM; 2961 ret = -EPERM;
2958 } 2962 }
2959 - if (password_completion_cb)  
2960 - password_completion_cb(password_opaque, ret); 2963 + if (mon->password_completion_cb)
  2964 + mon->password_completion_cb(mon->password_opaque, ret);
2961 2965
2962 - monitor_start_input(); 2966 + monitor_read_command(mon, 1);
2963 } 2967 }
2964 2968
2965 void monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs, 2969 void monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
@@ -2975,8 +2979,8 @@ void monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs, @@ -2975,8 +2979,8 @@ void monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
2975 monitor_printf(mon, "%s (%s) is encrypted.\n", bdrv_get_device_name(bs), 2979 monitor_printf(mon, "%s (%s) is encrypted.\n", bdrv_get_device_name(bs),
2976 bdrv_get_encrypted_filename(bs)); 2980 bdrv_get_encrypted_filename(bs));
2977 2981
2978 - password_completion_cb = completion_cb;  
2979 - password_opaque = opaque; 2982 + mon->password_completion_cb = completion_cb;
  2983 + mon->password_opaque = opaque;
2980 2984
2981 monitor_read_password(mon, bdrv_password_cb, bs); 2985 monitor_read_password(mon, bdrv_password_cb, bs);
2982 } 2986 }
monitor.h
@@ -7,7 +7,10 @@ @@ -7,7 +7,10 @@
7 7
8 extern Monitor *cur_mon; 8 extern Monitor *cur_mon;
9 9
10 -void monitor_init(CharDriverState *chr); 10 +/* flags for monitor_init */
  11 +#define MONITOR_IS_DEFAULT 0x01
  12 +
  13 +void monitor_init(CharDriverState *chr, int flags);
11 14
12 void monitor_suspend(Monitor *mon); 15 void monitor_suspend(Monitor *mon);
13 void monitor_resume(Monitor *mon); 16 void monitor_resume(Monitor *mon);
qemu-char.c
@@ -2123,7 +2123,7 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i @@ -2123,7 +2123,7 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i
2123 chr = qemu_chr_open(label, p, NULL); 2123 chr = qemu_chr_open(label, p, NULL);
2124 if (chr) { 2124 if (chr) {
2125 chr = qemu_chr_open_mux(chr); 2125 chr = qemu_chr_open_mux(chr);
2126 - monitor_init(chr); 2126 + monitor_init(chr, 0);
2127 } else { 2127 } else {
2128 printf("Unable to open driver: %s\n", p); 2128 printf("Unable to open driver: %s\n", p);
2129 } 2129 }
@@ -5684,7 +5684,7 @@ int main(int argc, char **argv, char **envp) @@ -5684,7 +5684,7 @@ int main(int argc, char **argv, char **envp)
5684 qemu_chr_initial_reset(); 5684 qemu_chr_initial_reset();
5685 5685
5686 if (monitor_device && monitor_hd) 5686 if (monitor_device && monitor_hd)
5687 - monitor_init(monitor_hd); 5687 + monitor_init(monitor_hd, MONITOR_IS_DEFAULT);
5688 5688
5689 for(i = 0; i < MAX_SERIAL_PORTS; i++) { 5689 for(i = 0; i < MAX_SERIAL_PORTS; i++) {
5690 const char *devname = serial_devices[i]; 5690 const char *devname = serial_devices[i];