aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--migration-exec.c12
-rw-r--r--migration-tcp.c12
-rw-r--r--migration.c13
-rw-r--r--migration.h4
-rw-r--r--monitor.c146
-rw-r--r--monitor.h5
-rw-r--r--qemu-char.c2
-rw-r--r--vl.c2
8 files changed, 101 insertions, 95 deletions
diff --git a/migration-exec.c b/migration-exec.c
index e2e6e8920a..f0869a1146 100644
--- a/migration-exec.c
+++ b/migration-exec.c
@@ -18,7 +18,6 @@
#include "migration.h"
#include "qemu-char.h"
#include "sysemu.h"
-#include "monitor.h"
#include "buffered_file.h"
#include "block.h"
@@ -55,7 +54,7 @@ static int exec_close(FdMigrationState *s)
MigrationState *exec_start_outgoing_migration(const char *command,
int64_t bandwidth_limit,
- int async)
+ int detach)
{
FdMigrationState *s;
FILE *f;
@@ -89,14 +88,11 @@ MigrationState *exec_start_outgoing_migration(const char *command,
s->mig_state.release = migrate_fd_release;
s->state = MIG_STATE_ACTIVE;
- s->detach = !async;
+ s->mon_resume = NULL;
s->bandwidth_limit = bandwidth_limit;
- if (s->detach == 1) {
- dprintf("detaching from monitor\n");
- monitor_suspend(cur_mon);
- s->detach = 2;
- }
+ if (!detach)
+ migrate_fd_monitor_suspend(s);
migrate_fd_connect(s);
return &s->mig_state;
diff --git a/migration-tcp.c b/migration-tcp.c
index 7f67fd9eb6..d9c4c986db 100644
--- a/migration-tcp.c
+++ b/migration-tcp.c
@@ -16,7 +16,6 @@
#include "migration.h"
#include "qemu-char.h"
#include "sysemu.h"
-#include "monitor.h"
#include "buffered_file.h"
#include "block.h"
@@ -79,7 +78,7 @@ static void tcp_wait_for_connect(void *opaque)
MigrationState *tcp_start_outgoing_migration(const char *host_port,
int64_t bandwidth_limit,
- int async)
+ int detach)
{
struct sockaddr_in addr;
FdMigrationState *s;
@@ -98,7 +97,7 @@ MigrationState *tcp_start_outgoing_migration(const char *host_port,
s->mig_state.release = migrate_fd_release;
s->state = MIG_STATE_ACTIVE;
- s->detach = !async;
+ s->mon_resume = NULL;
s->bandwidth_limit = bandwidth_limit;
s->fd = socket(PF_INET, SOCK_STREAM, 0);
if (s->fd == -1) {
@@ -108,11 +107,8 @@ MigrationState *tcp_start_outgoing_migration(const char *host_port,
socket_set_nonblock(s->fd);
- if (s->detach == 1) {
- dprintf("detaching from monitor\n");
- monitor_suspend(cur_mon);
- s->detach = 2;
- }
+ if (!detach)
+ migrate_fd_monitor_suspend(s);
do {
ret = connect(s->fd, (struct sockaddr *)&addr, sizeof(addr));
diff --git a/migration.c b/migration.c
index cf69bbe3dc..15639c177f 100644
--- a/migration.c
+++ b/migration.c
@@ -125,6 +125,13 @@ void do_info_migrate(Monitor *mon)
/* shared migration helpers */
+void migrate_fd_monitor_suspend(FdMigrationState *s)
+{
+ s->mon_resume = cur_mon;
+ monitor_suspend(cur_mon);
+ dprintf("suspending monitor\n");
+}
+
void migrate_fd_error(FdMigrationState *s)
{
dprintf("setting error state\n");
@@ -145,10 +152,8 @@ void migrate_fd_cleanup(FdMigrationState *s)
close(s->fd);
/* Don't resume monitor until we've flushed all of the buffers */
- if (s->detach == 2) {
- monitor_resume(cur_mon);
- s->detach = 0;
- }
+ if (s->mon_resume)
+ monitor_resume(s->mon_resume);
s->fd = -1;
}
diff --git a/migration.h b/migration.h
index 32f5a72b52..696618da06 100644
--- a/migration.h
+++ b/migration.h
@@ -39,7 +39,7 @@ struct FdMigrationState
int64_t bandwidth_limit;
QEMUFile *file;
int fd;
- int detach;
+ Monitor *mon_resume;
int state;
int (*get_error)(struct FdMigrationState*);
int (*close)(struct FdMigrationState*);
@@ -69,6 +69,8 @@ MigrationState *tcp_start_outgoing_migration(const char *host_port,
int64_t bandwidth_limit,
int detach);
+void migrate_fd_monitor_suspend(FdMigrationState *s);
+
void migrate_fd_error(FdMigrationState *s);
void migrate_fd_cleanup(FdMigrationState *s);
diff --git a/monitor.c b/monitor.c
index 12a89e9364..ecd67584d2 100644
--- a/monitor.c
+++ b/monitor.c
@@ -69,6 +69,14 @@ typedef struct mon_cmd_t {
struct Monitor {
CharDriverState *chr;
+ int flags;
+ int suspend_cnt;
+ uint8_t outbuf[1024];
+ int outbuf_index;
+ ReadLineState *rs;
+ CPUState *mon_cpu;
+ BlockDriverCompletionFunc *password_completion_cb;
+ void *password_opaque;
LIST_ENTRY(Monitor) entry;
};
@@ -77,34 +85,30 @@ static LIST_HEAD(mon_list, Monitor) mon_list;
static const mon_cmd_t mon_cmds[];
static const mon_cmd_t info_cmds[];
-static uint8_t term_outbuf[1024];
-static int term_outbuf_index;
-static BlockDriverCompletionFunc *password_completion_cb;
-static void *password_opaque;
-ReadLineState *rs;
-
Monitor *cur_mon = NULL;
-static void monitor_start_input(void);
+static void monitor_command_cb(Monitor *mon, const char *cmdline,
+ void *opaque);
-static CPUState *mon_cpu = NULL;
+static void monitor_read_command(Monitor *mon, int show_prompt)
+{
+ readline_start(mon->rs, "(qemu) ", 0, monitor_command_cb, NULL);
+ if (show_prompt)
+ readline_show_prompt(mon->rs);
+}
static void monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
void *opaque)
{
- readline_start(rs, "Password: ", 1, readline_func, opaque);
+ readline_start(mon->rs, "Password: ", 1, readline_func, opaque);
+ /* prompt is printed on return from the command handler */
}
void monitor_flush(Monitor *mon)
{
- Monitor *m;
-
- if (term_outbuf_index > 0) {
- LIST_FOREACH(m, &mon_list, entry) {
- if (m->chr->focus == 0)
- qemu_chr_write(m->chr, term_outbuf, term_outbuf_index);
- }
- term_outbuf_index = 0;
+ if (mon && mon->outbuf_index != 0 && mon->chr->focus == 0) {
+ qemu_chr_write(mon->chr, mon->outbuf, mon->outbuf_index);
+ mon->outbuf_index = 0;
}
}
@@ -112,15 +116,19 @@ void monitor_flush(Monitor *mon)
static void monitor_puts(Monitor *mon, const char *str)
{
char c;
+
+ if (!mon)
+ return;
+
for(;;) {
c = *str++;
if (c == '\0')
break;
if (c == '\n')
- term_outbuf[term_outbuf_index++] = '\r';
- term_outbuf[term_outbuf_index++] = c;
- if (term_outbuf_index >= (sizeof(term_outbuf) - 1) ||
- c == '\n')
+ mon->outbuf[mon->outbuf_index++] = '\r';
+ mon->outbuf[mon->outbuf_index++] = c;
+ if (mon->outbuf_index >= (sizeof(mon->outbuf) - 1)
+ || c == '\n')
monitor_flush(mon);
}
}
@@ -291,7 +299,7 @@ static int mon_set_cpu(int cpu_index)
for(env = first_cpu; env != NULL; env = env->next_cpu) {
if (env->cpu_index == cpu_index) {
- mon_cpu = env;
+ cur_mon->mon_cpu = env;
return 0;
}
}
@@ -300,10 +308,10 @@ static int mon_set_cpu(int cpu_index)
static CPUState *mon_get_cpu(void)
{
- if (!mon_cpu) {
+ if (!cur_mon->mon_cpu) {
mon_set_cpu(0);
}
- return mon_cpu;
+ return cur_mon->mon_cpu;
}
static void do_info_registers(Monitor *mon)
@@ -330,7 +338,7 @@ static void do_info_cpus(Monitor *mon)
for(env = first_cpu; env != NULL; env = env->next_cpu) {
monitor_printf(mon, "%c CPU #%d:",
- (env == mon_cpu) ? '*' : ' ',
+ (env == mon->mon_cpu) ? '*' : ' ',
env->cpu_index);
#if defined(TARGET_I386)
monitor_printf(mon, " pc=0x" TARGET_FMT_lx,
@@ -367,7 +375,7 @@ static void do_info_history(Monitor *mon)
i = 0;
for(;;) {
- str = readline_get_history(rs, i);
+ str = readline_get_history(mon->rs, i);
if (!str)
break;
monitor_printf(mon, "%d: '%s'\n", i, str);
@@ -451,7 +459,7 @@ static void change_vnc_password_cb(Monitor *mon, const char *password,
if (vnc_display_password(NULL, password) < 0)
monitor_printf(mon, "could not set VNC server password\n");
- monitor_start_input();
+ monitor_read_command(mon, 1);
}
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)
memcpy(cmd, pstart, len);
cmd[len] = '\0';
if (name[0] == '\0' || !strncmp(name, cmd, strlen(name))) {
- readline_add_completion(rs, cmd);
+ readline_add_completion(cur_mon->rs, cmd);
}
if (*p == '\0')
break;
@@ -2741,7 +2749,7 @@ static void file_completion(const char *input)
stat(file, &sb);
if(S_ISDIR(sb.st_mode))
pstrcat(file, sizeof(file), "/");
- readline_add_completion(rs, file);
+ readline_add_completion(cur_mon->rs, file);
}
}
closedir(ffs);
@@ -2754,7 +2762,7 @@ static void block_completion_it(void *opaque, BlockDriverState *bs)
if (input[0] == '\0' ||
!strncmp(name, (char *)input, strlen(input))) {
- readline_add_completion(rs, name);
+ readline_add_completion(cur_mon->rs, name);
}
}
@@ -2814,7 +2822,7 @@ static void monitor_find_completion(const char *cmdline)
cmdname = "";
else
cmdname = args[0];
- readline_set_completion_index(rs, strlen(cmdname));
+ readline_set_completion_index(cur_mon->rs, strlen(cmdname));
for(cmd = mon_cmds; cmd->name != NULL; cmd++) {
cmd_completion(cmdname, cmd->name);
}
@@ -2838,23 +2846,23 @@ static void monitor_find_completion(const char *cmdline)
switch(*ptype) {
case 'F':
/* file completion */
- readline_set_completion_index(rs, strlen(str));
+ readline_set_completion_index(cur_mon->rs, strlen(str));
file_completion(str);
break;
case 'B':
/* block device name completion */
- readline_set_completion_index(rs, strlen(str));
+ readline_set_completion_index(cur_mon->rs, strlen(str));
bdrv_iterate(block_completion_it, (void *)str);
break;
case 's':
/* XXX: more generic ? */
if (!strcmp(cmd->name, "info")) {
- readline_set_completion_index(rs, strlen(str));
+ readline_set_completion_index(cur_mon->rs, strlen(str));
for(cmd = info_cmds; cmd->name != NULL; cmd++) {
cmd_completion(str, cmd->name);
}
} else if (!strcmp(cmd->name, "sendkey")) {
- readline_set_completion_index(rs, strlen(str));
+ readline_set_completion_index(cur_mon->rs, strlen(str));
for(key = key_defs; key->name != NULL; key++) {
cmd_completion(str, key->name);
}
@@ -2868,49 +2876,45 @@ static void monitor_find_completion(const char *cmdline)
qemu_free(args[i]);
}
-static int term_can_read(void *opaque)
+static int monitor_can_read(void *opaque)
{
- return 128;
+ Monitor *mon = opaque;
+
+ return (mon->suspend_cnt == 0) ? 128 : 0;
}
-static void term_read(void *opaque, const uint8_t *buf, int size)
+static void monitor_read(void *opaque, const uint8_t *buf, int size)
{
+ Monitor *old_mon = cur_mon;
int i;
- for(i = 0; i < size; i++)
- readline_handle_byte(rs, buf[i]);
-}
+ cur_mon = opaque;
+
+ for (i = 0; i < size; i++)
+ readline_handle_byte(cur_mon->rs, buf[i]);
-static int monitor_suspended;
+ cur_mon = old_mon;
+}
static void monitor_command_cb(Monitor *mon, const char *cmdline, void *opaque)
{
+ monitor_suspend(mon);
monitor_handle_command(mon, cmdline);
- if (!monitor_suspended)
- readline_show_prompt(rs);
- else
- monitor_suspended = 2;
+ monitor_resume(mon);
}
void monitor_suspend(Monitor *mon)
{
- monitor_suspended = 1;
+ mon->suspend_cnt++;
}
void monitor_resume(Monitor *mon)
{
- if (monitor_suspended == 2)
- monitor_start_input();
- monitor_suspended = 0;
+ if (--mon->suspend_cnt == 0)
+ readline_show_prompt(mon->rs);
}
-static void monitor_start_input(void)
-{
- readline_start(rs, "(qemu) ", 0, monitor_command_cb, NULL);
- readline_show_prompt(rs);
-}
-
-static void term_event(void *opaque, int event)
+static void monitor_event(void *opaque, int event)
{
Monitor *mon = opaque;
@@ -2919,13 +2923,12 @@ static void term_event(void *opaque, int event)
monitor_printf(mon, "QEMU %s monitor - type 'help' for more information\n",
QEMU_VERSION);
- monitor_start_input();
+ readline_show_prompt(mon->rs);
}
-static int is_first_init = 1;
-
-void monitor_init(CharDriverState *chr)
+void monitor_init(CharDriverState *chr, int flags)
{
+ static int is_first_init = 1;
Monitor *mon;
if (is_first_init) {
@@ -2936,15 +2939,16 @@ void monitor_init(CharDriverState *chr)
mon = qemu_mallocz(sizeof(*mon));
mon->chr = chr;
- rs = readline_init(mon, monitor_find_completion);
+ mon->flags = flags;
+ mon->rs = readline_init(mon, monitor_find_completion);
+ monitor_read_command(mon, 0);
- qemu_chr_add_handlers(chr, term_can_read, term_read, term_event, mon);
+ qemu_chr_add_handlers(chr, monitor_can_read, monitor_read, monitor_event,
+ mon);
LIST_INSERT_HEAD(&mon_list, mon, entry);
- if (!cur_mon)
+ if (!cur_mon || (flags & MONITOR_IS_DEFAULT))
cur_mon = mon;
-
- readline_start(rs, "", 0, monitor_command_cb, NULL);
}
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)
monitor_printf(mon, "invalid password\n");
ret = -EPERM;
}
- if (password_completion_cb)
- password_completion_cb(password_opaque, ret);
+ if (mon->password_completion_cb)
+ mon->password_completion_cb(mon->password_opaque, ret);
- monitor_start_input();
+ monitor_read_command(mon, 1);
}
void monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
@@ -2975,8 +2979,8 @@ void monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
monitor_printf(mon, "%s (%s) is encrypted.\n", bdrv_get_device_name(bs),
bdrv_get_encrypted_filename(bs));
- password_completion_cb = completion_cb;
- password_opaque = opaque;
+ mon->password_completion_cb = completion_cb;
+ mon->password_opaque = opaque;
monitor_read_password(mon, bdrv_password_cb, bs);
}
diff --git a/monitor.h b/monitor.h
index abe7193d75..95a4060998 100644
--- a/monitor.h
+++ b/monitor.h
@@ -7,7 +7,10 @@
extern Monitor *cur_mon;
-void monitor_init(CharDriverState *chr);
+/* flags for monitor_init */
+#define MONITOR_IS_DEFAULT 0x01
+
+void monitor_init(CharDriverState *chr, int flags);
void monitor_suspend(Monitor *mon);
void monitor_resume(Monitor *mon);
diff --git a/qemu-char.c b/qemu-char.c
index bb5033761c..f81564624a 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2123,7 +2123,7 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i
chr = qemu_chr_open(label, p, NULL);
if (chr) {
chr = qemu_chr_open_mux(chr);
- monitor_init(chr);
+ monitor_init(chr, 0);
} else {
printf("Unable to open driver: %s\n", p);
}
diff --git a/vl.c b/vl.c
index cea0ddd3f7..f7aeb615e8 100644
--- a/vl.c
+++ b/vl.c
@@ -5684,7 +5684,7 @@ int main(int argc, char **argv, char **envp)
qemu_chr_initial_reset();
if (monitor_device && monitor_hd)
- monitor_init(monitor_hd);
+ monitor_init(monitor_hd, MONITOR_IS_DEFAULT);
for(i = 0; i < MAX_SERIAL_PORTS; i++) {
const char *devname = serial_devices[i];