qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 5/5] monitor: add "info capabilities" command


From: Mark McLoughlin
Subject: [Qemu-devel] [PATCH 5/5] monitor: add "info capabilities" command
Date: Thu, 13 Nov 2008 16:46:03 +0000

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 <address@hidden>
---
 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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]