From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1L0fLe-00044o-PK for qemu-devel@nongnu.org; Thu, 13 Nov 2008 11:47:14 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1L0fLa-00040j-Pq for qemu-devel@nongnu.org; Thu, 13 Nov 2008 11:47:14 -0500 Received: from [199.232.76.173] (port=36055 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1L0fLa-00040X-CK for qemu-devel@nongnu.org; Thu, 13 Nov 2008 11:47:10 -0500 Received: from mail28.svc.cra.dublin.eircom.net ([159.134.118.224]:35245) by monty-python.gnu.org with smtp (Exim 4.60) (envelope-from ) id 1L0fLa-0000AP-5R for qemu-devel@nongnu.org; Thu, 13 Nov 2008 11:47:10 -0500 From: Mark McLoughlin Date: Thu, 13 Nov 2008 16:46:03 +0000 Message-Id: <1226594763-2304-6-git-send-email-markmc@redhat.com> In-Reply-To: <1226594763-2304-5-git-send-email-markmc@redhat.com> References: <> <1226594763-2304-1-git-send-email-markmc@redhat.com> <1226594763-2304-2-git-send-email-markmc@redhat.com> <1226594763-2304-3-git-send-email-markmc@redhat.com> <1226594763-2304-4-git-send-email-markmc@redhat.com> <1226594763-2304-5-git-send-email-markmc@redhat.com> Subject: [Qemu-devel] [PATCH 5/5] monitor: add "info capabilities" command Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Anthony Liguori Cc: Mark McLoughlin , qemu-devel@nongnu.org Add a monitor command which allows the user (or management tools) to query what features the given qemu binary supports. The output format is ".ini style" and is intended to list: 1) New features - e.g. cache=writethrough 2) Compile time configurables - e.g. built with kqemu support 3) Magic numbers - e.g. the vcpu limit Signed-off-by: Mark McLoughlin --- console.h | 3 + hw/boards.h | 1 + hw/bt.h | 6 +++ hw/pc.h | 2 + hw/usb.h | 3 + monitor.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ net.c | 18 ++++++++ net.h | 3 + qemu-char.c | 25 +++++++++++ qemu-char.h | 1 + sysemu.h | 5 ++ vl.c | 91 +++++++++++++++++++++++++++++++++++--- 12 files changed, 288 insertions(+), 8 deletions(-) diff --git a/console.h b/console.h index fba9e29..f6d5de9 100644 --- a/console.h +++ b/console.h @@ -144,6 +144,9 @@ void qemu_console_resize(QEMUConsole *console, int width, int height); void qemu_console_copy(QEMUConsole *console, int src_x, int src_y, int dst_x, int dst_y, int w, int h); +/* vl.c */ +const char * const *graphics_list_types(void); + /* sdl.c */ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame); diff --git a/hw/boards.h b/hw/boards.h index 0097b4b..ed471af 100644 --- a/hw/boards.h +++ b/hw/boards.h @@ -26,6 +26,7 @@ typedef struct QEMUMachine { } QEMUMachine; int qemu_register_machine(QEMUMachine *m); +QEMUMachine *qemu_list_machines(void); void register_machines(void); /* Axis ETRAX. */ diff --git a/hw/bt.h b/hw/bt.h index 2d65e10..226d2bb 100644 --- a/hw/bt.h +++ b/hw/bt.h @@ -105,6 +105,12 @@ struct bt_device_s { uint16_t clkoff; /* Note: Always little-endian */ }; +/* Max number of bluetooth switches on the commandline. */ +#define MAX_BT_CMDLINE 10 + +/* vl.c */ +const char * const *bt_list_types(void); + /* bt.c */ void bt_device_init(struct bt_device_s *dev, struct bt_scatternet_s *net); void bt_device_done(struct bt_device_s *dev); diff --git a/hw/pc.h b/hw/pc.h index d64d8a6..abcfae5 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -122,6 +122,8 @@ extern enum vga_retrace_method vga_retrace_method; #define VGA_RAM_SIZE (9 * 1024 * 1024) #endif +const char * const *vga_list_types(void); + int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base, unsigned long vga_ram_offset, int vga_ram_size); int pci_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, diff --git a/hw/usb.h b/hw/usb.h index 4204808..334c7f4 100644 --- a/hw/usb.h +++ b/hw/usb.h @@ -264,6 +264,9 @@ USBDevice *usb_wacom_init(void); /* usb-serial.c */ USBDevice *usb_serial_init(const char *filename); +/* Max number of USB devices that can be specified on the commandline. */ +#define MAX_USB_CMDLINE 8 + /* usb ports of the VM */ void qemu_register_usb_port(USBPort *port, void *opaque, int index, diff --git a/monitor.c b/monitor.c index 8fff3aa..6e83486 100644 --- a/monitor.c +++ b/monitor.c @@ -26,6 +26,8 @@ #include "hw/pcmcia.h" #include "hw/pc.h" #include "hw/pci.h" +#include "hw/boards.h" +#include "hw/bt.h" #include "gdbstub.h" #include "net.h" #include "qemu-char.h" @@ -245,6 +247,140 @@ static void do_info_version(void) term_printf("%s\n", QEMU_VERSION); } +/* join a list of strings using a comma as the separator */ +static char *list2str(const char * const *list, char *buf, int bufsize) +{ + char *p = buf; + int i; + + *p = '\0'; + + if (!list) + return buf; + + for (i = 0; list[i] != NULL; i++) { + int ret; + + ret = snprintf(p, bufsize, "%s,", list[i]); + if (ret >= bufsize) + break; + + p += ret; + bufsize -= ret; + } + + /* chop off the trailing comma */ + if (p != buf) + *(--p) = '\0'; + + return buf; +} + +static void list_printf(const char *prefix, const char * const *list) +{ + char buf[4096]; + + term_printf("%s=%s\n", prefix, list2str(list, buf, sizeof(buf))); +} + +static const char * const accel_names[] = { +#ifdef USE_KQEMU + "kqemu", +#endif +#ifdef CONFIG_KVM + "kvm", +#endif + NULL +}; + +static void machines_printf(void) +{ + QEMUMachine *machines, *m; + const char **names; + int i; + + machines = qemu_list_machines(); + + i = 0; + m = machines; + while (m != NULL) { + i++; + m = m->next; + } + i++; /* for NULL terminator */ + + names = alloca(i * sizeof(const char *)); + + i = 0; + m = machines; + while (m != NULL) { + names[i++] = m->name; + m = m->next; + } + + names[i] = NULL; + + list_printf("machines", names); +} + +static void do_machine_capabilities(void) +{ + QEMUMachine *m; + + m = qemu_list_machines(); + while (m != NULL) { + term_printf("[machine]\n"); + term_printf("name=%s\n", m->name); + term_printf("max_cpus=%d\n", m->max_cpus); + list_printf("nic_models", m->nic_models ? m->nic_models() : NULL); + term_printf("\n"); + m = m->next; + } +} + +static void do_info_capabilities(void) +{ + term_printf("[qemu]\n"); + list_printf("accel", accel_names); + term_printf("arch=%s\n", TARGET_ARCH); + list_printf("cpu", cpu_names()); + machines_printf(); + + term_printf("\n"); + + do_machine_capabilities(); + + term_printf("[devices]\n"); + list_printf("bluetooth", bt_list_types()); + list_printf("char", qemu_chr_list_types()); + list_printf("drive_cache", drive_cache_types()); + list_printf("drive_if", drive_if_types()); + list_printf("graphics", graphics_list_types()); + list_printf("network", net_client_types()); +#ifdef HAS_AUDIO + list_printf("soundhw", soundhw_list_types()); +#endif + list_printf("vga", vga_list_types()); + + term_printf("\n"); + + term_printf("[limits]\n"); + term_printf("max_boot_dev=q\n"); /* above '-boot q' not allowed */ + term_printf("max_bluetooth_devs=%d\n", MAX_BT_CMDLINE); + term_printf("max_drives=%d\n", MAX_DRIVES); + term_printf("max_ide_devs=%d\n", MAX_IDE_DEVS); + term_printf("max_net_clients=%d\n", MAX_NET_CLIENTS); + term_printf("max_nics=%d\n", MAX_NICS); + term_printf("max_option_roms=%d\n", MAX_OPTION_ROMS); + term_printf("max_parallel_ports=%d\n", MAX_PARALLEL_PORTS); +#ifdef TARGET_SPARC + term_printf("max_prom_envs=%d\n", MAX_PROM_ENVS); +#endif + term_printf("max_scsi_devs=%d\n", MAX_SCSI_DEVS); + term_printf("max_serial_ports=%d\n", MAX_SERIAL_PORTS); + term_printf("max_usb_devs=%d\n", MAX_USB_CMDLINE); +} + static void do_info_name(void) { if (qemu_name) @@ -1481,6 +1617,8 @@ static const term_cmd_t term_cmds[] = { static const term_cmd_t info_cmds[] = { { "version", "", do_info_version, "", "show the version of qemu" }, + { "capabilities", "", do_info_capabilities, + "", "show the capabilities of qemu" }, { "network", "", do_info_network, "", "show the network state" }, { "chardev", "", qemu_chr_info, diff --git a/net.c b/net.c index f94ff1b..1660976 100644 --- a/net.c +++ b/net.c @@ -1371,6 +1371,24 @@ VLANState *qemu_find_vlan(int id) return vlan; } +const char * const *net_client_types(void) +{ + static const char * const types[] = { + "tap", + "socket", +#ifdef CONFIG_SLIRP + "user", +#endif +#ifdef CONFIG_VDE + "vde", +#endif + "none", + NULL + }; + + return types; +} + int net_client_init(const char *device, const char *p) { char buf[1024]; diff --git a/net.h b/net.h index a2b01ae..f5ef353 100644 --- a/net.h +++ b/net.h @@ -23,6 +23,8 @@ struct VLANState { unsigned int nb_guest_devs, nb_host_devs; }; +#define MAX_NET_CLIENTS 32 + VLANState *qemu_find_vlan(int id); VLANClientState *qemu_new_vlan_client(VLANState *vlan, IOReadHandler *fd_read, @@ -70,6 +72,7 @@ uint16_t net_checksum_tcpudp(uint16_t length, uint16_t proto, void net_checksum_calculate(uint8_t *data, int length); /* from net.c */ +const char * const *net_client_types(void); int net_client_init(const char *device, const char *p); int net_client_parse(const char *str); void net_slirp_smb(const char *exported_dir); diff --git a/qemu-char.c b/qemu-char.c index 2cf8644..b8c4a58 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2149,6 +2149,31 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename) return chr; } +const char * const *qemu_chr_list_types(void) +{ + static const char * const types[] = { + "null", "vc", "tcp", "telnet", "mon", +#ifndef _WIN32 + "unix", "file", "pipe", "pty", "stdio", +#if defined(__linux__) + "dev_parport", +#endif +#if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \ + || defined(__NetBSD__) || defined(__OpenBSD__) + "dev_tty", +#endif +#else /* !_WIN32 */ + "COM", "pipe", "con", "file", +#endif +#ifdef CONFIG_BRLAPI + "braille", +#endif + NULL + }; + + return types; +} + void qemu_chr_close(CharDriverState *chr) { TAILQ_REMOVE(&chardevs, chr, next); diff --git a/qemu-char.h b/qemu-char.h index c64fc28..063e0c1 100644 --- a/qemu-char.h +++ b/qemu-char.h @@ -61,6 +61,7 @@ struct CharDriverState { TAILQ_ENTRY(CharDriverState) next; }; +const char * const *qemu_chr_list_types(void); CharDriverState *qemu_chr_open(const char *label, const char *filename); void qemu_chr_close(CharDriverState *chr); void qemu_chr_printf(CharDriverState *s, const char *fmt, ...); diff --git a/sysemu.h b/sysemu.h index ef0fe50..8fe55d9 100644 --- a/sysemu.h +++ b/sysemu.h @@ -143,6 +143,9 @@ extern DriveInfo drives_table[MAX_DRIVES+1]; extern int drive_get_index(BlockInterfaceType type, int bus, int unit); extern int drive_get_max_bus(BlockInterfaceType type); +const char * const *drive_if_types(void); +const char * const *drive_cache_types(void); + /* serial ports */ #define MAX_SERIAL_PORTS 4 @@ -187,6 +190,8 @@ struct soundhw { }; extern struct soundhw soundhw[]; + +const char * const *soundhw_list_types(); #endif void do_usb_add(const char *devname); diff --git a/vl.c b/vl.c index e4184d3..b1bd37c 100644 --- a/vl.c +++ b/vl.c @@ -166,12 +166,6 @@ #define DEFAULT_RAM_SIZE 128 #endif -/* Max number of USB devices that can be specified on the commandline. */ -#define MAX_USB_CMDLINE 8 - -/* Max number of bluetooth switches on the commandline. */ -#define MAX_BT_CMDLINE 10 - /* XXX: use a two level table to limit memory usage */ #define MAX_IOPORTS 65536 @@ -2122,6 +2116,22 @@ static int bt_parse(const char *opt) return 1; } +const char * const *bt_list_types(void) +{ + static const char * const bt_types[] = { + "hci_null", /* -bt hci,null */ +#ifdef CONFIG_BLUEZ + "hci_host", /* -bt hci,host[:id] */ +#endif + "hci_vlan", /* -bt hci[,vlan=n] */ + "vhci_vlan", /* -bt vhci[,vlan=n] */ + "keyboard", /* -bt device:keyboard[,vlan=n */ + NULL + }; + + return bt_types; +} + /***********************************************************/ /* QEMU Block devices */ @@ -2502,6 +2512,24 @@ static int drive_init(struct drive_opt *arg, int snapshot, return 0; } +const char * const *drive_if_types(void) +{ + static const char * const if_types[] = { + "ide", "scsi", "floppy", "pflash", "mtd", "sd", NULL + }; + + return if_types; +} + +const char * const *drive_cache_types(void) +{ + static const char * const cache_types[] = { + "off", "none", "writethrough", "writeback", NULL + }; + + return cache_types; +} + /***********************************************************/ /* USB devices */ @@ -3314,6 +3342,11 @@ int qemu_register_machine(QEMUMachine *m) return 0; } +QEMUMachine *qemu_list_machines(void) +{ + return first_machine; +} + static QEMUMachine *find_machine(const char *name) { QEMUMachine *m; @@ -4282,6 +4315,21 @@ struct soundhw soundhw[] = { { NULL, NULL, 0, 0, { NULL } } }; +const char * const *soundhw_list_types(void) +{ + static const char *types[sizeof(soundhw)/sizeof(struct soundhw)]; + + if (!types[0]) { + int i; + + for (i = 0; soundhw[i].name; i++) + types[i] = soundhw[i].name; + types[i] = NULL; + } + + return types; +} + static void select_soundhw (const char *optarg) { struct soundhw *c; @@ -4341,6 +4389,35 @@ static void select_soundhw (const char *optarg) } #endif +const char * const *graphics_list_types(void) +{ + static const char * const types[] = { + "nographics", +#if defined(CONFIG_SDL) || defined(CONFIG_COCOA) + "graphics", +#endif +#ifdef CONFIG_CURSES + "curses", +#endif + "vnc", +#ifdef CONFIG_VNC_TLS + "vnc_tls", +#endif + NULL + }; + + return types; +} + +const char * const *vga_list_types(void) +{ + static const char * const types[] = { + "std", "cirrus", "vmware", NULL + }; + + return types; +} + static void select_vgahw (const char *p) { const char *opts; @@ -4399,8 +4476,6 @@ static int qemu_uuid_parse(const char *str, uint8_t *uuid) return 0; } -#define MAX_NET_CLIENTS 32 - #ifndef _WIN32 static void termsig_handler(int signal) -- 1.5.4.3