Support for multiple -monitor devices

Rebased version of Anthony's patch: Allow to specify more than one
monitor terminal via the -monitor command line switch. This is
particularly useful when libvirt or some other management tool already
occupies the primary monitor but you need another one for debugging.
The current clumsy workaround is to multiplex such additional terminals
over a qemu character device (e.g. -serial mon:<device>).

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Jan Kiszka 2009-08-27 19:51:16 +02:00 committed by Anthony Liguori
parent 9da4318706
commit ddd9bbd93b
1 changed files with 46 additions and 16 deletions

62
vl.c
View File

@ -173,6 +173,9 @@ int main(int argc, char **argv)
#define DEFAULT_RAM_SIZE 128
/* Maximum number of monitor devices */
#define MAX_MONITOR_DEVICES 10
static const char *data_dir;
const char *bios_name = NULL;
/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
@ -4854,8 +4857,9 @@ int main(int argc, char **argv, char **envp)
QemuOpts *hda_opts = NULL, *opts;
int optind;
const char *r, *optarg;
CharDriverState *monitor_hd = NULL;
const char *monitor_device;
CharDriverState *monitor_hds[MAX_MONITOR_DEVICES];
const char *monitor_devices[MAX_MONITOR_DEVICES];
int monitor_device_index;
const char *serial_devices[MAX_SERIAL_PORTS];
int serial_device_index;
const char *parallel_devices[MAX_PARALLEL_PORTS];
@ -4924,7 +4928,6 @@ int main(int argc, char **argv, char **envp)
kernel_cmdline = "";
cyls = heads = secs = 0;
translation = BIOS_ATA_TRANSLATION_AUTO;
monitor_device = "vc:80Cx24C";
serial_devices[0] = "vc:80Cx24C";
for(i = 1; i < MAX_SERIAL_PORTS; i++)
@ -4940,6 +4943,12 @@ int main(int argc, char **argv, char **envp)
virtio_consoles[i] = NULL;
virtio_console_index = 0;
monitor_devices[0] = "vc:80Cx24C";
for (i = 1; i < MAX_MONITOR_DEVICES; i++) {
monitor_devices[i] = NULL;
}
monitor_device_index = 0;
for (i = 0; i < MAX_NODES; i++) {
node_mem[i] = 0;
node_cpumask[i] = 0;
@ -5352,7 +5361,12 @@ int main(int argc, char **argv, char **envp)
break;
}
case QEMU_OPTION_monitor:
monitor_device = optarg;
if (monitor_device_index >= MAX_MONITOR_DEVICES) {
fprintf(stderr, "qemu: too many monitor devices\n");
exit(1);
}
monitor_devices[monitor_device_index] = optarg;
monitor_device_index++;
break;
case QEMU_OPTION_serial:
if (serial_device_index >= MAX_SERIAL_PORTS) {
@ -5662,8 +5676,9 @@ int main(int argc, char **argv, char **envp)
serial_devices[0] = "stdio";
if (parallel_device_index == 0)
parallel_devices[0] = "null";
if (strncmp(monitor_device, "vc", 2) == 0)
monitor_device = "stdio";
if (strncmp(monitor_devices[0], "vc", 2) == 0) {
monitor_devices[0] = "stdio";
}
}
#ifndef _WIN32
@ -5809,14 +5824,14 @@ int main(int argc, char **argv, char **envp)
register_savevm_live("ram", 0, 3, ram_save_live, NULL, ram_load, NULL);
/* Maintain compatibility with multiple stdio monitors */
if (!strcmp(monitor_device,"stdio")) {
if (!strcmp(monitor_devices[0],"stdio")) {
for (i = 0; i < MAX_SERIAL_PORTS; i++) {
const char *devname = serial_devices[i];
if (devname && !strcmp(devname,"mon:stdio")) {
monitor_device = NULL;
monitor_devices[0] = NULL;
break;
} else if (devname && !strcmp(devname,"stdio")) {
monitor_device = NULL;
monitor_devices[0] = NULL;
serial_devices[i] = "mon:stdio";
break;
}
@ -5875,11 +5890,21 @@ int main(int argc, char **argv, char **envp)
}
}
if (monitor_device) {
monitor_hd = qemu_chr_open("monitor", monitor_device, NULL);
if (!monitor_hd) {
fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
exit(1);
for (i = 0; i < MAX_MONITOR_DEVICES; i++) {
const char *devname = monitor_devices[i];
if (devname && strcmp(devname, "none")) {
char label[32];
if (i == 0) {
snprintf(label, sizeof(label), "monitor");
} else {
snprintf(label, sizeof(label), "monitor%d", i);
}
monitor_hds[i] = qemu_chr_open(label, devname, NULL);
if (!monitor_hds[i]) {
fprintf(stderr, "qemu: could not open monitor device '%s'\n",
devname);
exit(1);
}
}
}
@ -6028,8 +6053,13 @@ int main(int argc, char **argv, char **envp)
text_consoles_set_display(display_state);
qemu_chr_initial_reset();
if (monitor_device && monitor_hd)
monitor_init(monitor_hd, MONITOR_USE_READLINE | MONITOR_IS_DEFAULT);
for (i = 0; i < MAX_MONITOR_DEVICES; i++) {
if (monitor_devices[i] && monitor_hds[i]) {
monitor_init(monitor_hds[i],
MONITOR_USE_READLINE |
((i == 0) ? MONITOR_IS_DEFAULT : 0));
}
}
for(i = 0; i < MAX_SERIAL_PORTS; i++) {
const char *devname = serial_devices[i];