Add "info capabilities" monitor command
cover Add "info capabilities" monitor command
Hi,
Management tools need to be able to handle different versions of qemu equally well. Such a tool might need to know whether a given version supports a recently added command line option, whether it was built with kqemu support or who many vcpus is allowed.
One example of this is libvirt which does "qemu -help" and looks at the version string and which command line options are included in the output. That's a hack that works pretty well, but clearly "qemu -help" shouldn't be considered a stable interface.
This came up recently in the context of GSO support the KVM virtio network device. Essentially, libvirt needs to know whether qemu will be able to handle a tapfd with the IFF_VNET_HDR flag set. Adding something about IFF_VNET_HDR to the -help output was rejected as taking an ugly hack way too far :-)
The proposed solution is to add a new monitor command which will list exactly what this qemu binary is capable of. Rather than include every possible capability, I've limited it to:
1) New features; if a version of qemu supports the capabilities info command, you can assume that it also supports features that were added before that.
2) Compile time configurables which affect what features can be requested on the command line - e.g. kqemu support
3) Magic numbers; a managment tool might know that qemu only supports 2 IDE devices - and that may never change - but it's much nicer if the tool can be coded generically rather than hardcoding a magic number.
The patch implementing this isn't perfect by any means, but since this could be implemented in so many different ways I thought I'd post it and get people's feedback.
Cheers,
Mark.
Example output:
[qemu]
accel=kqemu,kvm
arch=x86_64 cpu=qemu64,core2duo,qemu32,coreduo,486,pentium,pentium2,pentium3,athlon,n270 machines=pc,isapc
[machine]
name=pc
max_cpus=255 nic_models=ne2k_pci,i82551,i82557b,i82559er,rtl8139,e1000,pcnet
[machine]
name=isapc
max_cpus=1
nic_models=ne2k_isa
[devices]
bluetooth=hci_null,hci_vlan,vhci_vlan,keyboard char=null,vc,tcp,telnet,mon,unix,file,pipe,pty,stdio,dev_parport,dev_tty drive_cache=off,none,writethrough,writeback drive_if=ide,scsi,floppy,pflash,mtd,sd graphics=nographics,graphics,curses,vnc,vnc_tls network=tap,socket,user,none
soundhw=pcspk,sb16,es1370
vga=std,cirrus,vmware
[limits]
max_boot_dev=q
max_bluetooth_devs=10
max_drives=32
max_ide_devs=2
max_net_clients=32
max_nics=8
max_option_roms=16
max_parallel_ports=3
max_scsi_devs=7
max_serial_ports=4
max_usb_devs=8
PATCH 1/5 Re-factor nic model listing
Add a nic_models() method to QEMUMachine and move the nic model listing from hw/pc.c to vl.c.
pci_nic_models() is hooked up to all machines which use pci_nic_init().
The isapc machine is the only one which is slightly different since it only supports the ne2k_isa model.
--- hw/boards.h | 3 +++ hw/mips_malta.c | 1 + hw/pc.c | 35 +++++++++++++++++++---------------- hw/pci.c | 14 ++++++++++---- hw/pci.h | 1 + hw/ppc_chrp.c | 1 + hw/ppc_oldworld.c | 1 + hw/ppc_prep.c | 1 + hw/realview.c | 1 + hw/sun4u.c | 3 +++ hw/versatilepb.c | 2 ++ vl.c | 18 ++++++++++++++++++ 12 files changed, 61 insertions(+), 20 deletions(-)
hw/boards.h +3 -0
@@ -10,6 +10,8 @@ typedef void QEMUMachineInitFunc(ram_addr_t ram_size, int vga_ram_size,const char *initrd_filename, const char *cpu_model); +typedef const char *const *QEMUMachineNicModelsFunc (void ); + typedef struct QEMUMachine { const char *name; const char *desc;
@@ -19,6 +21,7 @@ typedef struct QEMUMachine {int nodisk_ok;int use_scsi;int max_cpus; +QEMUMachineNicModelsFunc *nic_models;struct QEMUMachine *next; } QEMUMachine;
hw/mips_malta.c +1 -0
@@ -950,4 +950,5 @@ QEMUMachine mips_malta_machine = { .init = mips_malta_init, .ram_require = VGA_RAM_SIZE + BIOS_SIZE, .nodisk_ok = 1, + .nic_models = pci_nic_models, };
hw/pc.c +19 -16
@@ -746,6 +746,13 @@ static void pc_init_ne2k_isa(NICInfo *nd, qemu_irq *pic) nb_ne2k++; } +static const char *const *isa_nic_models (void ) +{ +static const char *const models[] = {"ne2k_isa" ,NULL }; + +return models; +} +/* PC hardware initialisation */ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds,
@@ -995,25 +1002,19 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,for (i =0 ; i < nb_nics; i++) { nd = &nd_table[i]; -if (!nd->model) { -if (pci_enabled) { +if (pci_enabled) { +if (!nd->model) nd->model ="ne2k_pci" ; - }else { - nd->model ="ne2k_isa" ; - } - } -if (strcmp (nd->model,"ne2k_isa" ) ==0 ) { -pc_init_ne2k_isa (nd, i8259); - }else if (pci_enabled) { -if (strcmp (nd->model,"?" ) ==0 ) -fprintf (stderr,"qemu: Supported ISA NICs: ne2k_isa\n" );pci_nic_init (pci_bus, nd,-1 ); - }else if (strcmp (nd->model,"?" ) ==0 ) { -fprintf (stderr,"qemu: Supported ISA NICs: ne2k_isa\n" ); -exit (1 ); }else { -fprintf (stderr,"qemu: Unsupported NIC: %s\n" , nd->model); -exit (1 ); +if (!nd->model) + nd->model ="ne2k_isa" ; +if (strcmp (nd->model,"ne2k_isa" ) ==0 ) +pc_init_ne2k_isa (nd, i8259); +else { +fprintf (stderr,"qemu: Unsupported NIC: %s\n" , nd->model); +exit (1 ); + } } }
@@ -1124,6 +1125,7 @@ QEMUMachine pc_machine = { .init = pc_init_pci, .ram_require = VGA_RAM_SIZE + PC_MAX_BIOS_SIZE, .max_cpus = 255, + .nic_models = pci_nic_models, };QEMUMachine isapc_machine = {
@@ -1132,4 +1134,5 @@ QEMUMachine isapc_machine = { .init = pc_init_isa, .ram_require = VGA_RAM_SIZE + PC_MAX_BIOS_SIZE, .max_cpus = 1, + .nic_models = isa_nic_models, };
hw/pci.c +10 -4
@@ -640,16 +640,22 @@ void pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn)pci_e1000_init (bus, nd, devfn); }else if (strcmp (nd->model,"pcnet" ) ==0 ) {pci_pcnet_init (bus, nd, devfn); - }else if (strcmp (nd->model,"?" ) ==0 ) { -fprintf (stderr,"qemu: Supported PCI NICs: i82551 i82557b i82559er" -" ne2k_pci pcnet rtl8139 e1000\n" ); -exit (1 ); }else {fprintf (stderr,"qemu: Unsupported NIC: %s\n" , nd->model);exit (1 ); } } +const char *const *pci_nic_models (void ) +{ +static const char *const models[] = { +"ne2k_pci" ,"i82551" ,"i82557b" ,"i82559er" , +"rtl8139" ,"e1000" ,"pcnet" ,NULL + }; + +return models; +} + typedef struct { PCIDevice dev; PCIBus *bus;
hw/pci.h +1 -0
@@ -86,6 +86,7 @@ typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);PCIBus *pci_register_bus (pci_set_irq_fn set_irq,pci_map_irq_fn map_irq,qemu_irq *pic,int devfn_min,int nirq); +const char *const *pci_nic_models (void );void pci_nic_init (PCIBus *bus,NICInfo *nd,int devfn);void pci_data_write (void *opaque,uint32_t addr,uint32_t val,int len);uint32_t pci_data_read (void *opaque,uint32_t addr,int len);
hw/ppc_chrp.c +1 -0
@@ -336,4 +336,5 @@ QEMUMachine core99_machine = { .init = ppc_core99_init, .ram_require = BIOS_SIZE + VGA_RAM_SIZE, .max_cpus = MAX_CPUS, + .nic_models = pci_nic_models, };
hw/ppc_oldworld.c +1 -0
@@ -371,4 +371,5 @@ QEMUMachine heathrow_machine = { .init = ppc_heathrow_init, .ram_require = BIOS_SIZE + VGA_RAM_SIZE, .max_cpus = MAX_CPUS, + .nic_models = pci_nic_models, };
hw/ppc_prep.c +1 -0
@@ -765,4 +765,5 @@ QEMUMachine prep_machine = { .init = ppc_prep_init, .ram_require = BIOS_SIZE + VGA_RAM_SIZE, .max_cpus = MAX_CPUS, + .nic_models = pci_nic_models, };
hw/realview.c +1 -0
@@ -202,4 +202,5 @@ QEMUMachine realview_machine = { .init = realview_init, .ram_require = 0x1000, .use_scsi = 1, + .nic_models = pci_nic_models, };
hw/sun4u.c +3 -0
@@ -592,6 +592,7 @@ QEMUMachine sun4u_machine = { .ram_require = PROM_SIZE_MAX + VGA_RAM_SIZE, .nodisk_ok = 1, .max_cpus = 1, // XXX for now + .nic_models = pci_nic_models, };QEMUMachine sun4v_machine = {
@@ -601,6 +602,7 @@ QEMUMachine sun4v_machine = { .ram_require = PROM_SIZE_MAX + VGA_RAM_SIZE, .nodisk_ok = 1, .max_cpus = 1, // XXX for now + .nic_models = pci_nic_models, };QEMUMachine niagara_machine = {
@@ -610,4 +612,5 @@ QEMUMachine niagara_machine = { .ram_require = PROM_SIZE_MAX + VGA_RAM_SIZE, .nodisk_ok = 1, .max_cpus = 1, // XXX for now + .nic_models = pci_nic_models, };
hw/versatilepb.c +2 -0
@@ -320,6 +320,7 @@ QEMUMachine versatilepb_machine = { .desc = "ARM Versatile/PB (ARM926EJ-S)", .init = vpb_init, .use_scsi = 1, + .nic_models = pci_nic_models, };QEMUMachine versatileab_machine = {
@@ -327,4 +328,5 @@ QEMUMachine versatileab_machine = { .desc = "ARM Versatile/AB (ARM926EJ-S)", .init = vab_init, .use_scsi = 1, + .nic_models = pci_nic_models, };
vl.c +18 -0
@@ -5226,6 +5226,24 @@ int main(int argc, char **argv) }net_client_check (); +for (i =0 ; i < nb_nics; i++) { +const char *const *model; + +if (!nd_table[i].model ||strcmp (nd_table[i].model,"?" ) !=0 ) +continue ; + +fprintf (stderr,"qemu: Supported %s NICs:" , machine->name); + + model = machine->nic_models ? machine->nic_models () :NULL ; +while (model && *model) { +fprintf (stderr,"%c%s" , i ?',' :' ' , *model); + model++; + } +fprintf (stderr,"\n" ); + +exit (0 ); + } +#ifdef TARGET_I386 /* XXX: this should be moved in the PC machine instantiation code */ if (net_boot !=0 ) {
Signature · 1 line
1.5.4.3
PATCH 2/5 Add cpu_list() for any targets that don't already have it
This allows us to remove the "#ifdef cpu_list" from vl.c
--- target-alpha/cpu.h | 2 ++ target-alpha/translate.c | 5 +++++ target-cris/cpu.h | 2 ++ target-cris/translate.c | 5 +++++ target-m68k/cpu.h | 2 ++ target-m68k/helper.c | 9 +++++++++ vl.c | 3 --- 7 files changed, 25 insertions(+), 3 deletions(-)
target-alpha/cpu.h +2 -0
@@ -296,6 +296,7 @@ struct CPUAlphaState {#define cpu_exec cpu_alpha_exec#define cpu_gen_code cpu_alpha_gen_code#define cpu_signal_handler cpu_alpha_signal_handler +#define cpu_list cpu_alpha_list/* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernel
@@ -401,6 +402,7 @@ enum {CPUAlphaState *cpu_alpha_init (const char *cpu_model);int cpu_alpha_exec (CPUAlphaState *s); +void cpu_alpha_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...));/* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero is returned if the signal was handled by the virtual CPU. */
target-alpha/translate.c +5 -0
@@ -2365,6 +2365,11 @@ void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)gen_intermediate_code_internal (env, tb,1 ); } +void cpu_alpha_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)) +{ +/* no cpu model variants */ +} +CPUAlphaState *cpu_alpha_init (const char *cpu_model) {CPUAlphaState *env;
target-cris/cpu.h +2 -0
@@ -161,6 +161,7 @@ typedef struct CPUCRISState {CPUCRISState *cpu_cris_init (const char *cpu_model);int cpu_cris_exec (CPUCRISState *s);void cpu_cris_close (CPUCRISState *s); +void cpu_cris_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...));void do_interrupt (CPUCRISState *env);/* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero
@@ -206,6 +207,7 @@ enum {#define cpu_exec cpu_cris_exec#define cpu_gen_code cpu_cris_gen_code#define cpu_signal_handler cpu_cris_signal_handler +#define cpu_list cpu_cris_list#define CPU_SAVE_VERSION 1
target-cris/translate.c +5 -0
@@ -3484,6 +3484,11 @@ void cpu_dump_state (CPUState *env, FILE *f, } +void cpu_cris_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)) +{ +/* no cpu model variants */ +} +CPUCRISState *cpu_cris_init (const char *cpu_model) {CPUCRISState *env;
target-m68k/cpu.h +2 -0
@@ -117,6 +117,7 @@ void m68k_tcg_init(void);CPUM68KState *cpu_m68k_init (const char *cpu_model);int cpu_m68k_exec (CPUM68KState *s);void cpu_m68k_close (CPUM68KState *s); +void cpu_m68k_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...));void do_interrupt (int is_hw);/* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero
@@ -212,6 +213,7 @@ void register_m68k_insns (CPUM68KState *env);#define cpu_exec cpu_m68k_exec#define cpu_gen_code cpu_m68k_gen_code#define cpu_signal_handler cpu_m68k_signal_handler +#define cpu_list cpu_m68k_list/* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernel
target-m68k/helper.c +9 -0
@@ -54,6 +54,15 @@ static m68k_def_t m68k_cpu_defs[] = { {NULL, 0}, }; +void cpu_m68k_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)) +{ +unsigned int i; + + (*cpu_fprintf)(f,"Available CPUs:\n" ); +for (i =0 ; m68k_cpu_defs[i].name; i++) + (*cpu_fprintf)(f," %s\n" , m68k_cpu_defs[i].name); +} +static int fpu_gdb_get_reg (CPUState *env,uint8_t *mem_buf,int n) {if (n <8 ) {
vl.c +0 -3
@@ -4585,10 +4585,7 @@ int main(int argc, char **argv)case QEMU_OPTION_cpu:/* hw initialization will check this */ if (*optarg =='?' ) { -/* XXX: implement xxx_cpu_list for targets that still miss it */ -#if defined(cpu_list)cpu_list (stdout, &fprintf); -#endif exit (0 ); }else { cpu_model = optarg;
Signature · 1 line
1.5.4.3
PATCH 3/5 Rename xxx_cpu_list() to cpu_xxx_list()
This naming seems more consistent with the rest of the code.
--- target-arm/cpu.h | 5 ++--- target-arm/helper.c | 2 +- target-i386/cpu.h | 5 ++--- target-i386/helper.c | 2 +- target-mips/cpu.h | 4 ++-- target-mips/translate_init.c | 2 +- target-ppc/cpu.h | 5 ++--- target-ppc/translate_init.c | 2 +- target-sh4/cpu.h | 4 ++-- target-sh4/translate.c | 2 +- target-sparc/cpu.h | 5 ++--- target-sparc/helper.c | 2 +- 12 files changed, 18 insertions(+), 22 deletions(-)
target-arm/cpu.h +2 -3
@@ -201,6 +201,7 @@ CPUARMState *cpu_arm_init(const char *cpu_model);void arm_translate_init (void );int cpu_arm_exec (CPUARMState *s);void cpu_arm_close (CPUARMState *s); +void cpu_arm_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...));void do_interrupt (CPUARMState *);void switch_mode (CPUARMState *,int );uint32_t do_arm_semihosting (CPUARMState *env);
@@ -337,8 +338,6 @@ static inline int arm_feature(CPUARMState *env, int feature)return (env->features & (1u << feature)) !=0 ; } -void arm_cpu_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)); -/* Interface between CPU and Interrupt controller. */ void armv7m_nvic_set_pending (void *opaque,int irq);int armv7m_nvic_acknowledge_irq (void *opaque);
@@ -393,7 +392,7 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,#define cpu_exec cpu_arm_exec#define cpu_gen_code cpu_arm_gen_code#define cpu_signal_handler cpu_arm_signal_handler -#define cpu_list arm_cpu_list +#define cpu_list cpu_arm_list#define CPU_SAVE_VERSION 1
target-arm/helper.c +1 -1
@@ -291,7 +291,7 @@ static const struct arm_cpu_t arm_cpu_names[] = { { 0, NULL} }; -void arm_cpu_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)) +void cpu_arm_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)) {int i;
target-i386/cpu.h +2 -3
@@ -631,8 +631,7 @@ typedef struct CPUX86State {CPUX86State *cpu_x86_init (const char *cpu_model);int cpu_x86_exec (CPUX86State *s);void cpu_x86_close (CPUX86State *s); -void x86_cpu_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, - ...)); +void cpu_x86_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...));int cpu_get_pic_interrupt (CPUX86State *s);/* MSDOS compatibility mode FPU exception support */ void cpu_set_ferr (CPUX86State *s);
@@ -760,7 +759,7 @@ static inline int cpu_get_time_fast(void)#define cpu_exec cpu_x86_exec#define cpu_gen_code cpu_x86_gen_code#define cpu_signal_handler cpu_x86_signal_handler -#define cpu_list x86_cpu_list +#define cpu_list cpu_x86_list#define CPU_SAVE_VERSION 7
target-i386/helper.c +1 -1
@@ -392,7 +392,7 @@ error:return -1 ; } -void x86_cpu_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)) +void cpu_x86_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)) {unsigned int i;
target-mips/cpu.h +2 -2
@@ -468,7 +468,6 @@ void r4k_do_tlbwi (void);void r4k_do_tlbwr (void );void r4k_do_tlbp (void );void r4k_do_tlbr (void ); -void mips_cpu_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...));void do_unassigned_access (target_phys_addr_t addr,int is_write,int is_exec,int unused,int size);
@@ -478,7 +477,7 @@ void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,#define cpu_exec cpu_mips_exec#define cpu_gen_code cpu_mips_gen_code#define cpu_signal_handler cpu_mips_signal_handler -#define cpu_list mips_cpu_list +#define cpu_list cpu_mips_list#define CPU_SAVE_VERSION 3
@@ -560,6 +559,7 @@ enum {int cpu_mips_exec (CPUMIPSState *s);CPUMIPSState *cpu_mips_init (const char *cpu_model); +void cpu_mips_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...));uint32_t cpu_mips_get_clock (void );int cpu_mips_signal_handler (int host_signum,void *pinfo,void *puc);
target-mips/translate_init.c +1 -1
@@ -429,7 +429,7 @@ static const mips_def_t *cpu_mips_find_by_name (const char *name)return NULL ; } -void mips_cpu_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)) +void cpu_mips_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)) {int i;
target-ppc/cpu.h +2 -3
@@ -692,6 +692,7 @@ CPUPPCState *cpu_ppc_init (const char *cpu_model);void ppc_translate_init (void );int cpu_ppc_exec (CPUPPCState *s);void cpu_ppc_close (CPUPPCState *s); +void cpu_ppc_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...));/* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero is returned if the signal was handled by the virtual CPU. */
@@ -732,8 +733,6 @@ void ppc_store_msr (CPUPPCState *env, target_ulong value);void cpu_ppc_reset (void *opaque); -void ppc_cpu_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)); -const ppc_def_t *cpu_ppc_find_by_name (const char *name);int cpu_ppc_register_internal (CPUPPCState *env,const ppc_def_t *def);
@@ -801,7 +800,7 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val);#define cpu_exec cpu_ppc_exec#define cpu_gen_code cpu_ppc_gen_code#define cpu_signal_handler cpu_ppc_signal_handler -#define cpu_list ppc_cpu_list +#define cpu_list cpu_ppc_list#define CPU_SAVE_VERSION 3
target-ppc/translate_init.c +1 -1
@@ -9476,7 +9476,7 @@ const ppc_def_t *cpu_ppc_find_by_name (const char *name)return ret; } -void ppc_cpu_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)) +void cpu_ppc_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)) {int i, max;
target-sh4/cpu.h +2 -2
@@ -137,7 +137,7 @@ CPUSH4State *cpu_sh4_init(const char *cpu_model);int cpu_sh4_exec (CPUSH4State * s);int cpu_sh4_signal_handler (int host_signum,void *pinfo,void *puc); -void sh4_cpu_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)); +void cpu_sh4_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...));void cpu_sh4_write_mmaped_utlb_addr (CPUSH4State *s,target_phys_addr_t addr,uint32_t mem_value);
@@ -153,7 +153,7 @@ static inline void cpu_set_tls(CPUSH4State *env, target_ulong newtls)#define cpu_exec cpu_sh4_exec#define cpu_gen_code cpu_sh4_gen_code#define cpu_signal_handler cpu_sh4_signal_handler -#define cpu_list sh4_cpu_list +#define cpu_list cpu_sh4_list/* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernel
target-sh4/translate.c +1 -1
@@ -220,7 +220,7 @@ static const sh4_def_t *cpu_sh4_find_by_name(const char *name)return NULL ; } -void sh4_cpu_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)) +void cpu_sh4_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)) {int i;
target-sparc/cpu.h +2 -3
@@ -338,8 +338,7 @@ typedef struct CPUSPARCState {/* helper.c */ CPUSPARCState *cpu_sparc_init (const char *cpu_model);void cpu_sparc_set_id (CPUSPARCState *env,unsigned int cpu); -void sparc_cpu_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, - ...)); +void cpu_sparc_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...));void cpu_lock (void );void cpu_unlock (void ); int cpu_sparc_handle_mmu_fault(CPUSPARCState *env1, target_ulong address, int rw,
@@ -438,7 +437,7 @@ int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);#define cpu_exec cpu_sparc_exec#define cpu_gen_code cpu_sparc_gen_code#define cpu_signal_handler cpu_sparc_signal_handler -#define cpu_list sparc_cpu_list +#define cpu_list cpu_sparc_list#define CPU_SAVE_VERSION 5
target-sparc/helper.c +1 -1
@@ -1332,7 +1332,7 @@ static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)return -1 ; } -void sparc_cpu_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)) +void cpu_sparc_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)) {unsigned int i;
Signature · 1 line
1.5.4.3
PATCH 4/5 Add new cpu_names() function
Add a new function, cpu_names(), which lists the available CPU names for the target.
--- target-alpha/cpu.h | 2 ++ target-alpha/translate.c | 5 +++++ target-arm/cpu.h | 2 ++ target-arm/helper.c | 15 +++++++++++++++ target-cris/cpu.h | 2 ++ target-cris/translate.c | 6 ++++++ target-i386/cpu.h | 2 ++ target-i386/helper.c | 15 +++++++++++++++ target-m68k/cpu.h | 2 ++ target-m68k/helper.c | 15 +++++++++++++++ target-mips/cpu.h | 2 ++ target-mips/translate_init.c | 15 +++++++++++++++ target-ppc/cpu.h | 2 ++ target-ppc/translate_init.c | 15 +++++++++++++++ target-sh4/cpu.h | 2 ++ target-sh4/translate.c | 15 +++++++++++++++ target-sparc/cpu.h | 2 ++ target-sparc/helper.c | 15 +++++++++++++++ 18 files changed, 134 insertions(+), 0 deletions(-)
target-alpha/cpu.h +2 -0
@@ -297,6 +297,7 @@ struct CPUAlphaState {#define cpu_gen_code cpu_alpha_gen_code#define cpu_signal_handler cpu_alpha_signal_handler#define cpu_list cpu_alpha_list +#define cpu_names cpu_alpha_names/* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernel
@@ -403,6 +404,7 @@ enum {CPUAlphaState *cpu_alpha_init (const char *cpu_model);int cpu_alpha_exec (CPUAlphaState *s);void cpu_alpha_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)); +const char *const *cpu_alpha_names (void );/* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero is returned if the signal was handled by the virtual CPU. */
target-alpha/translate.c +5 -0
@@ -2370,6 +2370,11 @@ void cpu_alpha_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))/* no cpu model variants */ } +const char *const *cpu_alpha_names (void ) +{ +/* no cpu model variants */ +} +CPUAlphaState *cpu_alpha_init (const char *cpu_model) {CPUAlphaState *env;
target-arm/cpu.h +2 -0
@@ -202,6 +202,7 @@ void arm_translate_init(void);int cpu_arm_exec (CPUARMState *s);void cpu_arm_close (CPUARMState *s);void cpu_arm_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)); +const char *const *cpu_arm_names (void );void do_interrupt (CPUARMState *);void switch_mode (CPUARMState *,int );uint32_t do_arm_semihosting (CPUARMState *env);
@@ -393,6 +394,7 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,#define cpu_gen_code cpu_arm_gen_code#define cpu_signal_handler cpu_arm_signal_handler#define cpu_list cpu_arm_list +#define cpu_names cpu_arm_names#define CPU_SAVE_VERSION 1
target-arm/helper.c +15 -0
@@ -301,6 +301,21 @@ void cpu_arm_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)) } } +const char *const *cpu_arm_names (void ) +{ +static const char *names[sizeof (arm_cpu_names)/sizeof (struct arm_cpu_t )]; + +if (!names[0 ]) { +int i; + +for (i =0 ; arm_cpu_names[i].name; i++) + names[i] = arm_cpu_names[i].name; + names[i] =NULL ; + } + +return names; +} +/* return 0 if not found */ static uint32_t cpu_arm_find_by_name (const char *name) {
target-cris/cpu.h +2 -0
@@ -162,6 +162,7 @@ CPUCRISState *cpu_cris_init(const char *cpu_model);int cpu_cris_exec (CPUCRISState *s);void cpu_cris_close (CPUCRISState *s);void cpu_cris_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)); +const char *const *cpu_cris_names (void );void do_interrupt (CPUCRISState *env);/* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero
@@ -208,6 +209,7 @@ enum {#define cpu_gen_code cpu_cris_gen_code#define cpu_signal_handler cpu_cris_signal_handler#define cpu_list cpu_cris_list +#define cpu_names cpu_cris_names#define CPU_SAVE_VERSION 1
target-cris/translate.c +6 -0
@@ -3489,6 +3489,12 @@ void cpu_cris_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))/* no cpu model variants */ } +const char *const *cpu_cris_names (void ) +{ +/* no cpu model variants */ +return NULL ; +} +CPUCRISState *cpu_cris_init (const char *cpu_model) {CPUCRISState *env;
target-i386/cpu.h +2 -0
@@ -632,6 +632,7 @@ CPUX86State *cpu_x86_init(const char *cpu_model);int cpu_x86_exec (CPUX86State *s);void cpu_x86_close (CPUX86State *s);void cpu_x86_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)); +const char *const *cpu_x86_names (void );int cpu_get_pic_interrupt (CPUX86State *s);/* MSDOS compatibility mode FPU exception support */ void cpu_set_ferr (CPUX86State *s);
@@ -760,6 +761,7 @@ static inline int cpu_get_time_fast(void)#define cpu_gen_code cpu_x86_gen_code#define cpu_signal_handler cpu_x86_signal_handler#define cpu_list cpu_x86_list +#define cpu_names cpu_x86_names#define CPU_SAVE_VERSION 7
target-i386/helper.c +15 -0
@@ -400,6 +400,21 @@ void cpu_x86_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)) (*cpu_fprintf)(f,"x86 %16s\n" , x86_defs[i].name); } +const char *const *cpu_x86_names (void ) +{ +static const char *names[sizeof (x86_defs)/sizeof (x86_def_t) +1 ]; + +if (!names[0 ]) { +int i; + +for (i =0 ; i <sizeof (x86_defs) /sizeof (x86_def_t); i++) + names[i] = x86_defs[i].name; + names[i] =NULL ; + } + +return names; +} +static int cpu_x86_register (CPUX86State *env,const char *cpu_model) {x86_def_t def1, *def = &def1;
target-m68k/cpu.h +2 -0
@@ -118,6 +118,7 @@ CPUM68KState *cpu_m68k_init(const char *cpu_model);int cpu_m68k_exec (CPUM68KState *s);void cpu_m68k_close (CPUM68KState *s);void cpu_m68k_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)); +const char *const *cpu_m68k_names (void );void do_interrupt (int is_hw);/* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero
@@ -214,6 +215,7 @@ void register_m68k_insns (CPUM68KState *env);#define cpu_gen_code cpu_m68k_gen_code#define cpu_signal_handler cpu_m68k_signal_handler#define cpu_list cpu_m68k_list +#define cpu_names cpu_m68k_names/* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernel
target-m68k/helper.c +15 -0
@@ -63,6 +63,21 @@ void cpu_m68k_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)) (*cpu_fprintf)(f," %s\n" , m68k_cpu_defs[i].name); } +const char *const *cpu_m68k_names (void ) +{ +static const char *names[sizeof (m68k_cpu_defs)/sizeof (m68k_def_t)]; + +if (!names[0 ]) { +int i; + +for (i =0 ; m68k_cpu_defs[i].name; i++) + names[i] = m68k_cpu_defs[i].name; + names[i] =NULL ; + } + +return names; +} +static int fpu_gdb_get_reg (CPUState *env,uint8_t *mem_buf,int n) {if (n <8 ) {
target-mips/cpu.h +2 -0
@@ -478,6 +478,7 @@ void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,#define cpu_gen_code cpu_mips_gen_code#define cpu_signal_handler cpu_mips_signal_handler#define cpu_list cpu_mips_list +#define cpu_names cpu_mips_names#define CPU_SAVE_VERSION 3
@@ -560,6 +561,7 @@ enum {int cpu_mips_exec (CPUMIPSState *s);CPUMIPSState *cpu_mips_init (const char *cpu_model);void cpu_mips_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)); +const char *const *cpu_mips_names (void );uint32_t cpu_mips_get_clock (void );int cpu_mips_signal_handler (int host_signum,void *pinfo,void *puc);
target-mips/translate_init.c +15 -0
@@ -439,6 +439,21 @@ void cpu_mips_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)) } } +const char *const *cpu_mips_names (void ) +{ +static const char *names[sizeof (mips_defs)/sizeof (mips_defs[0 ]) +1 ]; + +if (!names[0 ]) { +int i; + +for (i =0 ; i <sizeof (mips_defs) /sizeof (mips_defs[0 ]); i++) + names[i] = mips_defs[i].name; + names[i] =NULL ; + } + +return names; +} +#ifndef CONFIG_USER_ONLY static void no_mmu_init (CPUMIPSState *env,const mips_def_t *def) {
target-ppc/cpu.h +2 -0
@@ -693,6 +693,7 @@ void ppc_translate_init(void);int cpu_ppc_exec (CPUPPCState *s);void cpu_ppc_close (CPUPPCState *s);void cpu_ppc_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)); +const char *const *cpu_ppc_names (void );/* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero is returned if the signal was handled by the virtual CPU. */
@@ -801,6 +802,7 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val);#define cpu_gen_code cpu_ppc_gen_code#define cpu_signal_handler cpu_ppc_signal_handler#define cpu_list cpu_ppc_list +#define cpu_names cpu_ppc_names#define CPU_SAVE_VERSION 3
target-ppc/translate_init.c +15 -0
@@ -9486,3 +9486,18 @@ void cpu_ppc_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)) ppc_defs[i].name, ppc_defs[i].pvr); } } + +const char *const *cpu_ppc_names (void ) +{ +static const char *names[sizeof (ppc_defs) /sizeof (ppc_def_t) +1 ]; + +if (!names[0 ]) { +int i; + +for (i =0 ; i <sizeof (ppc_defs) /sizeof (ppc_def_t); i++) + names[i] = ppc_defs[i].name; + names[i] =NULL ; + } + +return names; +}
target-sh4/cpu.h +2 -0
@@ -138,6 +138,7 @@ int cpu_sh4_exec(CPUSH4State * s);int cpu_sh4_signal_handler (int host_signum,void *pinfo,void *puc);void cpu_sh4_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)); +const char *const *cpu_sh4_names (void );void cpu_sh4_write_mmaped_utlb_addr (CPUSH4State *s,target_phys_addr_t addr,uint32_t mem_value);
@@ -154,6 +155,7 @@ static inline void cpu_set_tls(CPUSH4State *env, target_ulong newtls)#define cpu_gen_code cpu_sh4_gen_code#define cpu_signal_handler cpu_sh4_signal_handler#define cpu_list cpu_sh4_list +#define cpu_names cpu_sh4_names/* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernel
target-sh4/translate.c +15 -0
@@ -228,6 +228,21 @@ void cpu_sh4_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)) (*cpu_fprintf)(f,"%s\n" , sh4_defs[i].name); } +const char *const *cpu_sh4_names (void ) +{ +static const char *names[sizeof (sh4_defs) /sizeof (*sh4_defs) +1 ]; + +if (!names[0 ]) { +int i; + +for (i =0 ; i <sizeof (sh4_defs) /sizeof (*sh4_defs); i++) + names[i] = sh4_defs[i].name; + names[i] =NULL ; + } + +return names; +} +static void cpu_sh4_register (CPUSH4State *env,const sh4_def_t *def) { env->pvr = def->pvr;
target-sparc/cpu.h +2 -0
@@ -339,6 +339,7 @@ typedef struct CPUSPARCState {CPUSPARCState *cpu_sparc_init (const char *cpu_model);void cpu_sparc_set_id (CPUSPARCState *env,unsigned int cpu);void cpu_sparc_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...)); +const char *const *cpu_sparc_names (void );void cpu_lock (void );void cpu_unlock (void ); int cpu_sparc_handle_mmu_fault(CPUSPARCState *env1, target_ulong address, int rw,
@@ -438,6 +439,7 @@ int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);#define cpu_gen_code cpu_sparc_gen_code#define cpu_signal_handler cpu_sparc_signal_handler#define cpu_list cpu_sparc_list +#define cpu_names cpu_sparc_names#define CPU_SAVE_VERSION 5
target-sparc/helper.c +15 -0
@@ -1359,6 +1359,21 @@ void cpu_sparc_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)) "fpu_version mmu_version nwindows\n"); } +const char *const *cpu_sparc_names (void ) +{ +static const char *names[sizeof (sparc_defs) /sizeof (sparc_def_t) +1 ]; + +if (!names[0 ]) { +int i; + +for (i =0 ; i <sizeof (sparc_defs) /sizeof (sparc_def_t); i++) + names[i] = sparc_defs[i].name; + names[i] =NULL ; + } + +return names; +} +#define GET_FLAG (a,b) ((env->psr & a)?b:'-') void cpu_dump_state(CPUState *env, FILE *f,
Signature · 1 line
1.5.4.3
PATCH 5/5 monitor: add "info capabilities" command
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
--- 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(-)
console.h +3 -0
@@ -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);
hw/boards.h +1 -0
@@ -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. */
hw/bt.h +6 -0
@@ -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);
hw/pc.h +2 -0
@@ -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,
hw/usb.h +3 -0
@@ -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,
monitor.c +138 -0
156 lines not on this page · raw message
net.c +18 -0
@@ -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 ];
net.h +3 -0
@@ -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);
qemu-char.c +25 -0
@@ -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);
qemu-char.h +1 -0
@@ -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, ...);
sysemu.h +5 -0
@@ -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);
vl.c +83 -8
133 lines not on this page · raw message
Signature · 1 line
1.5.4.3
[Qemu-devel] Re: [PATCH 5/5] monitor: add "info capabilities" command
Quoted 16 lines · Mark McLoughlin
monitor.c +15
-0+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 ());
monitor.c static void do_info_version(void) · line 365
Quoted 10 lines
monitor.c +10
-0+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" );
This makes me uneasy because it introduces a lot of dependencies that are going to be hard to break. I think this level of logic needs to be more encapsulated in the various subsystems.
Quoted 7 lines
monitor.c +6
-0+ +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 );
monitor.c static void do_info_version(void) · line 381
Quoted 10 lines
monitor.c +10
-0+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 );
While we have a lot of hard coded maximums today, I don't think we always will. How do you intend to support an unlimited number of things?
Regards,
Anthony Liguori
[Qemu-devel] Re: [PATCH 5/5] monitor: add "info capabilities" command
Quoted 23 lines · Anthony Liguori
Quoted 22 lines · Mark McLoughlin
monitor.c +22
-0+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
Quoted 8 lines
monitor.c static void do_info_version(void) · line 365
Quoted 4 lines
monitor.c +3
-0+list_printf ("vga" ,vga_list_types ()); + +term_printf ("\n" );This makes me uneasy because it introduces a lot of dependencies that are going to be hard to break. I think this level of logic needs to be more encapsulated in the various subsystems.
So, something like have [network], [block], [audio] etc. sections and call out to network_capabilities() etc.?
Cheers,
Mark.
Re: [Qemu-devel] [PATCH 5/5] monitor: add "info capabilities" command
In reply to Mark McLoughlinQuoted 11 lines · Mark McLoughlin
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
The monitor is a late interface -- you need this information to determine some of the command-line parameters that were used to start qemu and the monitor!
Signature · 2 lines
I have a truly marvellous patch that fixes the bug which this signature is too narrow to contain.
Re: [Qemu-devel] [PATCH 5/5] monitor: add "info capabilities" command
Quoted 8 lines · Avi Kivity
Quoted 7 lines · Mark McLoughlin
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
Quoted 8 lines
Quoted 4 lines
2) Compile time configurables - e.g. built with kqemu support
3) Magic numbers - e.g. the vcpu limit
The monitor is a late interface -- you need this information to determine some of the command-line parameters that were used to start qemu and the monitor!
Yes, absolutely. Anthony had earlier suggested the monitor command might be enough because we can do:
echo -e 'info capabilities\nquit' | qemu -S -hda /dev/null -monitor stdio -vnc none
I would prefer if we also had e.g. qemu -capabilities.
Cheers,
Mark.
Re: [Qemu-devel] [PATCH 5/5] monitor: add "info capabilities" command
Quoted 6 lines · Mark McLoughlin
Yes, absolutely. Anthony had earlier suggested the monitor command might be enough because we can do:
echo -e 'info capabilities\nquit' | qemu -S -hda
/dev/null-monitor stdio -vnc none
Elegant.
Quoted 2 lines
I would prefer if we also had e.g. qemu -capabilities.
Me, too.
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [PATCH 5/5] monitor: add "info capabilities" command
In reply to Mark McLoughlinQuoted 4 lines · Mark McLoughlin
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:
I think this would be better exposed as a command line flag such as "-capabilities", which just sent the '.ini' file data to stdout.
Regards,
Daniel
Signature · 4 lines
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
[Qemu-devel] Re: [PATCH 4/5] Add new cpu_names() function
In reply to Mark McLoughlinQuoted 2 lines · Mark McLoughlin
Add a new function,
cpu_names(), which lists the available CPU names for the target.
Can we get rid of cpu_list and replace it with cpu_names() printed to stdout?
Regards,
Anthony Liguori
[Qemu-devel] Re: [PATCH 4/5] Add new cpu_names() function
Quoted 6 lines · Anthony Liguori
Quoted 2 lines · Mark McLoughlin
Add a new function,
cpu_names(), which lists the available CPU names for the target.Can we get rid of
cpu_listand replace it withcpu_names()printed to stdout?
Yep, I'd much rather that ... but ppc and sparc list more than just the name ...
Cheers,
Mark.
Re: [Qemu-devel] [PATCH 1/5] Re-factor nic model listing
In reply to Mark McLoughlinQuoted 4 lines · Mark McLoughlin
.desc = "ARM Versatile/PB (ARM926EJ-S)",
.init =vpb_init,
.use_scsi = 1,
+ .nic_models =pci_nic_models,
This is wrong, an I'd expect a lot of the other non-PC machines are too.
Paul
Re: [Qemu-devel] [PATCH 1/5] Re-factor nic model listing
Quoted 10 lines · Paul Brook
Quoted 5 lines · Mark McLoughlin
.desc = "ARM Versatile/PB (ARM926EJ-S)", .init = vpb_init, .use_scsi = 1,+ .nic_models =
pci_nic_models,This is wrong, an I'd expect a lot of the other non-PC machines are too.
What's the issue? This board seems to have a PCI bridge attached to it so why can't it support any PCI nic? Is this just not something that occurs naturally?
Regards,
Anthony Liguori
Quoted 3 lines
Paul
Re: [Qemu-devel] [PATCH 1/5] Re-factor nic model listing
Quoted 7 lines · Anthony Liguori
Quoted 6 lines · Paul Brook
Quoted 4 lines · Mark McLoughlin
.desc = "ARM Versatile/PB (ARM926EJ-S)", .init = vpb_init, .use_scsi = 1,+ .nic_models =
pci_nic_models,
Quoted 5 lines
Quoted 1 line
This is wrong, an I'd expect a lot of the other non-PC machines are too.
What's the issue? This board seems to have a PCI bridge attached to it so why can't it support any PCI nic? Is this just not something that occurs naturally?
For the same reason you mentioned separately: The abstraction is all wrong. These boards also support various non-pci NICs. Admittedly this is a pre-existing bug, but if we're changing things it makes sense to get it right.
Paul
Re: [Qemu-devel] [PATCH 1/5] Re-factor nic model listing
Quoted 8 lines · Paul Brook
Quoted 8 lines
Quoted 7 lines · Mark McLoughlin
Quoted 4 lines
.desc = "ARM Versatile/PB (ARM926EJ-S)", .init = vpb_init, .use_scsi = 1,+ .nic_models =
pci_nic_models,This is wrong, an I'd expect a lot of the other non-PC machines are too.
Quoted 8 lines
Quoted 3 lines
What's the issue? This board seems to have a PCI bridge attached to it so why can't it support any PCI nic? Is this just not something that occurs naturally?
For the same reason you mentioned separately: The abstraction is all wrong. These boards also support various non-pci NICs. Admittedly this is a pre-existing bug, but if we're changing things it makes sense to get it right.
Doesn't it make sense to add pci_nic_models _automatically_ to any board with a PCI interface, and have nic_models just for additional NICs which aren't implied by having a PCI interface?
-- Jamie
Re: [Qemu-devel] [PATCH 1/5] Re-factor nic model listing
Quoted 6 lines · Jamie Lokier
Paul Brook wrote:
Doesn't it make sense to add
pci_nic_models_automatically_ to any board with a PCI interface, and havenic_modelsjust for additional NICs which aren't implied by having a PCI interface?
No, there's a more fundamental "wrongness" at work here that has to do with the QEMUMachine abstraction out-living its usefulness.
A machine is hierarchical by nature. Attaching PCI NICS to the top-level of a machine definition is wrong because it violates this hierarchical property. It doesn't matter who does it or how it happens.
What you really need is a data structure that represents the machine in a more natural way. You could have a Machine description, that contains a reference to a PCI bus description or an ISA bus description, that then contained descriptions of PCI or ISA NICS.
The problem is, a simple struct like QEMUMachine can not represent this relationship in a natural way. The real trick here is to find an incremental way to introduce this sort of modeling without forcing an all-at-once refactoring of QEMU.
A good start may be to swizzle the QEMUMachine definition to contain just a name and then a function pointer to initialize the machine type. The function pointer would initialize the machine type by setting properties of it (like maximum CPUs) and then it could add bus descriptions to it. You would have to introduce a mechanism to describe buses, of course. The bus description could then have it's own initialization function that added supported PCI devices descriptions to the bus. If these devices were tagged with a variety of types (like NIC, storage controller, etc), then you could implement something like what Mark is proposing by taking the QEMUMachine definition and walking the structure to discover all the possible NICs.
The long term goal we want to get at is one where the QEMUMachine definition is built entirely from a text-file description. Fabrice's config file patches that he posted a few months back give a good insight into what things should eventually look like.
Regards,
Anthony Liguori
Quoted 4 lines
-- Jamie
[Qemu-devel] Re: [PATCH 1/5] Re-factor nic model listing
In reply to Mark McLoughlinQuoted 9 lines · Mark McLoughlin
Add a
nic_models()method to QEMUMachine and move the nic model listing fromhw/pc.ctovl.c.
pci_nic_models()is hooked up to all machines which usepci_nic_init().The isapc machine is the only one which is slightly different since it only supports the
ne2k_isamodel.
In principle, I think this patch series is a good idea. I think the abstraction here is a little broken.
I don't think it's correct to associate nics directly with a machine type. Rather, nics have bus requirements (like PCI, ISA, or USB) and a machine may or may not contain that bus.
Regards,
Anthony Liguori
[Qemu-devel] Re: [PATCH 1/5] Re-factor nic model listing
Quoted 11 lines · Anthony Liguori
Quoted 9 lines · Mark McLoughlin
Add a
nic_models()method to QEMUMachine and move the nic model listing fromhw/pc.ctovl.c.
pci_nic_models()is hooked up to all machines which usepci_nic_init().The isapc machine is the only one which is slightly different since it only supports the
ne2k_isamodel.
Quoted 6 lines
In principle, I think this patch series is a good idea. I think the abstraction here is a little broken.
I don't think it's correct to associate nics directly with a machine type. Rather, nics have bus requirements (like PCI, ISA, or USB) and a machine may or may not contain that bus.
i.e. add a bus abstraction (with ->nic_models()) which PCI, ISA and USB would specialize and have a list of buses associated with the machine?
Cheers,
Mark.
Quoted 29 lines · Mark McLoughlin
Hi,
Management tools need to be able to handle different versions of qemu equally well. Such a tool might need to know whether a given version supports a recently added command line option, whether it was built with kqemu support or who many vcpus is allowed.
One example of this is libvirt which does "qemu -help" and looks at the version string and which command line options are included in the output. That's a hack that works pretty well, but clearly "qemu -help" shouldn't be considered a stable interface.
This came up recently in the context of GSO support the KVM virtio network device. Essentially, libvirt needs to know whether qemu will be able to handle a tapfd with the
IFF_VNET_HDRflag set. Adding something aboutIFF_VNET_HDRto the -help output was rejected as taking an ugly hack way too far :-)The proposed solution is to add a new monitor command which will list exactly what this qemu binary is capable of. Rather than include every possible capability, I've limited it to:
1) New features; if a version of qemu supports the capabilities info command, you can assume that it also supports features that were added before that.
2) Compile time configurables which affect what features can be requested on the command line - e.g. kqemu support
Quoted 8 lines
3) Magic numbers; a managment tool might know that qemu only supports 2 IDE devices - and that may never change - but it's much nicer if the tool can be coded generically rather than hardcoding a magic number.
The patch implementing this isn't perfect by any means, but since this could be implemented in so many different ways I thought I'd post it and get people's feedback.
Good idea, though perhaps the output should be compatible with the config file, which we don't have yet.
For sparc-softmmu I get:
(qemu) info capabilities
[qemu]
accel=
arch=sparc
cpu=Fujitsu MB86900,Fujitsu MB86904,Fujitsu MB86907,LSI L64811,Cypress CY7C601,Cypress CY7C611,TI SuperSparc II,TI MicroSparc I,TI MicroSparc
II,TI MicroSparc IIep,TI SuperSparc 40,TI SuperSparc 50,TI SuperSparc
51,TI SuperSparc 60,TI SuperSparc 61,Ross RT625,Ross RT620,BIT
B5010,Matsushita MN10501,Weitek W8601,LEON2,LEON3 machines=SS-5,SS-10,SS-600MP,SS-20,SS-2,Voyager,LX,SS-4,SPARCClassic,SPARCbook,SS-1000,SS-2000
[machine]
name=SS-5
max_cpus=1
nic_models=
[machine]
name=SS-10
max_cpus=4
nic_models=
[machine]
name=SS-600MP
max_cpus=4
nic_models=
[machine]
name=SS-20
max_cpus=4
nic_models=
[machine]
name=SS-2
max_cpus=0
nic_models=
[machine]
name=Voyager
max_cpus=0
nic_models=
[machine]
name=LX
max_cpus=0
nic_models=
[machine]
name=SS-4
max_cpus=0
nic_models=
[machine]
name=SPARCClassic
max_cpus=0
nic_models=
[machine]
name=SPARCbook
max_cpus=0
nic_models=
[machine]
name=SS-1000
max_cpus=8
nic_models=
[machine]
name=SS-2000
max_cpus=20
nic_models=
[devices]
bluetooth=hci_null,hci_vlan,vhci_vlan,keyboard char=null,vc,tcp,telnet,mon,unix,file,pipe,pty,stdio,dev_parport,dev_tty drive_cache=off,none,writethrough,writeback drive_if=ide,scsi,floppy,pflash,mtd,sd graphics=nographics,graphics,curses,vnc network=tap,socket,user,none
vga=std,cirrus,vmware
[limits]
max_boot_dev=q
max_bluetooth_devs=10
max_drives=32
max_ide_devs=2
max_net_clients=32
max_nics=8
max_option_roms=16
max_parallel_ports=3
max_prom_envs=128
max_scsi_devs=7
max_serial_ports=4
max_usb_devs=8
Sparc64:
(qemu) info capabilities
[qemu]
accel=
arch=sparc64
cpu=Fujitsu Sparc64,Fujitsu Sparc64 III,Fujitsu Sparc64 IV,Fujitsu Sparc64 V,TI UltraSparc I,TI UltraSparc II,TI UltraSparc IIi,TI UltraSparc IIe,Sun UltraSparc III,Sun UltraSparc III Cu,Sun UltraSparc IIIi,Sun UltraSparc IV,Sun UltraSparc IV+,Sun UltraSparc IIIi+,Sun UltraSparc T1,Sun UltraSparc T2,NEC UltraSparc I machines=sun4u,sun4v,Niagara
[machine]
name=sun4u
max_cpus=1 nic_models=ne2k_pci,i82551,i82557b,i82559er,rtl8139,e1000,pcnet
[machine]
name=sun4v
max_cpus=1 nic_models=ne2k_pci,i82551,i82557b,i82559er,rtl8139,e1000,pcnet
[machine]
name=Niagara
max_cpus=1 nic_models=ne2k_pci,i82551,i82557b,i82559er,rtl8139,e1000,pcnet
[devices]
bluetooth=hci_null,hci_vlan,vhci_vlan,keyboard char=null,vc,tcp,telnet,mon,unix,file,pipe,pty,stdio,dev_parport,dev_tty drive_cache=off,none,writethrough,writeback drive_if=ide,scsi,floppy,pflash,mtd,sd graphics=nographics,graphics,curses,vnc network=tap,socket,user,none
vga=std,cirrus,vmware
[limits]
max_boot_dev=q
max_bluetooth_devs=10
max_drives=32
max_ide_devs=2
max_net_clients=32
max_nics=8
max_option_roms=16
max_parallel_ports=3
max_prom_envs=128
max_scsi_devs=7
max_serial_ports=4
max_usb_devs=8
The lists would be more readable if there were a space after comma.
nic_models is empty for Sun4m.
max_cpus can be 1 or 0, both should be 1.
Quoted 4 lines
(qemu) info capabilities
[qemu]
accel=
arch=sparc
I'm thinking that a qemu which supports multiple target architectures becomes increasingly feasible and likely, especially for system emulation. Therefore, [qemu] should have an "archs" property, and there should be separate "[arch-sparc]" headers, like this:
[qemu]
archs=sparc
[arch]
name=sparc
cpu=Fujitsu MB86900,Fujitsu MB86904,Fujitsu MB86907,LSI L64811,Cypress CY7C601,Cypress CY7C611,TI SuperSparc II,TI MicroSparc I,TI MicroSparc II,TI MicroSparc IIep,TI SuperSparc 40,TI SuperSparc 50,TI SuperSparc 51,TI SuperSparc 60,TI SuperSparc 61,Ross RT625,Ross RT620,BIT B5010,Matsushita MN10501,Weitek W8601,LEON2,LEON3
etc...
Quoted 4 lines
[machine]
name=SS-5
max_cpus=1
nic_models=
This would be prettier as [machine:SS5] or [machine SS5] imho.
Quoted 4 lines
[machine]
name=Voyager
max_cpus=0
nic_models=
Crumbs, zero CPUs?
By the way, is there a min_cpus? And does cpus mean cores or chips?
Quoted 1 line
drive_cache=off,none,writethrough,writeback
Do we need "off" and "none" here?
(Side issue: I think these names are misleading because they hide the fact that "none" provides less underlying data integrity than "writethrough", due to O_DIRECT vs. O_DSYNC quirks. Sometimes you want _both_ O_DIRECT and O_DSYNC, as they can be combined, and the combination has a different meaning than O_DIRECT alone on some OSes and hardware, including MS Windows. So the options should be "none,direct,writethrough,writeback").
-- Jamie
Quoted 10 lines · Jamie Lokier
Quoted 4 lines
(qemu) info capabilities
[qemu]
accel=
arch=sparcI'm thinking that a qemu which supports multiple target architectures becomes increasingly feasible and likely, especially for system emulation. Therefore, [qemu] should have an "archs" property, and there should be separate "[arch-sparc]" headers, like this:
Quoted 5 lines
[qemu]
archs=sparc[arch]
name=sparc
Yep, that sounds sensible.
Quoted 6 lines
Quoted 4 lines
[machine]
name=SS-5
max_cpus=1
nic_models=This would be prettier as [machine:SS5] or [machine SS5] imho.
I'd considered that but thought it would be ugly - now that you actually type it out though, [machine foo] looks fine :-)
Quoted 6 lines
Quoted 4 lines
[machine]
name=Voyager
max_cpus=0
nic_models=Crumbs, zero CPUs?
Ah, vl.c has:
machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
I guess it should do that for all machines, not just the selected one.
Quoted 3 lines
Quoted 1 line
drive_cache=off,none,writethrough,writeback
Do we need "off" and "none" here?
"none" - yes, I think so.
"off" - probably not, it's deprecated I guess.
Cheers,
Mark.
Quoted 34 lines · Mark McLoughlin
Hi,
Management tools need to be able to handle different versions of qemu equally well. Such a tool might need to know whether a given version supports a recently added command line option, whether it was built with kqemu support or who many vcpus is allowed.
One example of this is libvirt which does "qemu -help" and looks at the version string and which command line options are included in the output. That's a hack that works pretty well, but clearly "qemu -help" shouldn't be considered a stable interface.
This came up recently in the context of GSO support the KVM virtio network device. Essentially, libvirt needs to know whether qemu will be able to handle a tapfd with the
IFF_VNET_HDRflag set. Adding something aboutIFF_VNET_HDRto the -help output was rejected as taking an ugly hack way too far :-)The proposed solution is to add a new monitor command which will list exactly what this qemu binary is capable of. Rather than include every possible capability, I've limited it to:
1) New features; if a version of qemu supports the capabilities info command, you can assume that it also supports features that were added before that.
2) Compile time configurables which affect what features can be requested on the command line - e.g. kqemu support
3) Magic numbers; a managment tool might know that qemu only supports 2 IDE devices - and that may never change - but it's much nicer if the tool can be coded generically rather than hardcoding a magic number.
Quoted 9 lines
The patch implementing this isn't perfect by any means, but since this could be implemented in so many different ways I thought I'd post it and get people's feedback.
Cheers,
Mark.Example output:
There are really two types of features/options in QEMU. There are features/options of the emulated hardware and there are features/options for how we present this hardware to the user. The former is guest visible and part of the save/restore state whereas the later is transparent to the guest.
When enumerating capabilities, there really ought to be a clean split between the two. The former should just describe the variety of hardware that can be presented to the guest. This is important for determining things like whether a migration target's QEMU instance is compatible with the source.
With respect to limits, there are two types of limits. There are architectural limits of the emulated hardware which are intrinsic to the hardware and vary for every machine. Then there are the stupid QEMU limits. The stupid QEMU limits should always be high enough such that it is greater than the architectural limits of any possible emulated hardware. If not, that is a bug and should be fixed.
So there really is no need to expose limits because they have very little relationship to reality. The stupid QEMU limits should effectively be infinite. You need to look at the machine definition to determine what the real limits of the machine type are. I don't necessarily think this should be explicitly described by QEMU either. I don't mind a management tool having to be smart enough to know that an IDE controller can only support 4 disks.
As a general piece of advise, I think where you are starting from is a bit ambitious and far too open for bike shedding to be productive. You may find it easier to start with something simpler, that has a real practical utility to libvirt, and then building on that incrementally.
Regards,
Anthony Liguori
Quoted 3 lines · Anthony Liguori
This is important for
determining things like whether a migration target's QEMU instance is compatible with the source.
It might be enough to list the emulated CPU variants, or it might need to list the capabilities of the specific CPU in some detail. For example on x86, there are lots of partially independent capabilities, but on the other hand, after an OS has checked for a specific CPU id, you really want the target QEMU to present the same CPU id.
Quoted 4 lines
As a general piece of advise, I think where you are starting from is a bit ambitious and far too open for bike shedding to be productive. You may find it easier to start with something simpler, that has a real practical utility to libvirt, and then building on that incrementally.
I think the capability list is quite a good idea, and it may stimulate something on the config file front.
If it's "wrong" the first time, well, there are other features in QEMU which have changed incompatibly between versions. Imho, there's no great harm in changing "info capability" output until it's right, provided the basic syntax unambiguously represents the QEMU version and capability text format version somehow.
While we're at it, a section describing the monitor's capabilities so we don't have to parse the _monitor's_ "help" output.... Oh, there I go bike-shedding again :-)
-- Jamie
Quoted 5 lines · Jamie Lokier
If it's "wrong" the first time, well, there are other features in QEMU which have changed incompatibly between versions. Imho, there's no great harm in changing "info capability" output until it's right, provided the basic syntax unambiguously represents the QEMU version and capability text format version somehow.
Well, the goal here is to have something actually usable by management tools and an in-flux format wouldn't help that.
But yeah, we should agree on enough of the basic details of the format to allow a format version to be exposed.
Quoted 3 lines
While we're at it, a section describing the monitor's capabilities so we don't have to parse the _monitor's_ "help" output.... Oh, there I go bike-shedding again :-)
Well, if "info capabilities" isn't implemented, simply having it fail is fine.
That's a bit different from e.g. libvirt launching qemu with cache=writethrough, detecting that qemu doesn't support that and relaunching without it.
Cheers,
Mark.
Quoted 6 lines · Mark McLoughlin
Quoted 3 lines
While we're at it, a section describing the monitor's capabilities so we don't have to parse the _monitor's_ "help" output.... Oh, there I go bike-shedding again :-)
Well, if "info capabilities" isn't implemented, simply having it fail is fine.
Sure, but there are other monitor commands, and sub-options to those commands, which come and go depending on QEMU version and development branch. It would be good to describe those in a capabilities section, as the only other option is trying the commands and discovering if sub-options are supported that way. It's possible to send TAB to the monitor to get the output of command line completions sometimes, but that's quite an ugly thing for a management tool to have to do.
-- Jamie
Quoted 11 lines · Anthony Liguori
There are really two types of features/options in QEMU. There are features/options of the emulated hardware and there are features/options for how we present this hardware to the user. The former is guest visible and part of the save/restore state whereas the later is transparent to the guest.
When enumerating capabilities, there really ought to be a clean split between the two. The former should just describe the variety of hardware that can be presented to the guest. This is important for determining things like whether a migration target's QEMU instance is compatible with the source.
I dig the distinction - but I'm not sure it's all that helpful.
e.g. the drive cache options are example of features which aren't visible to the guest, but if you go to migrate a guest using cache=writethrough and discover the target host doesn't support that, then presumably you don't proceed. Which is similar to not migrating a virtio using guest to a host without virtio support.
Quoted 7 lines
With respect to limits, there are two types of limits. There are architectural limits of the emulated hardware which are intrinsic to the hardware and vary for every machine. Then there are the stupid QEMU limits. The stupid QEMU limits should always be high enough such that it is greater than the architectural limits of any possible emulated hardware. If not, that is a bug and should be fixed.
Quoted 7 lines
So there really is no need to expose limits because they have very little relationship to reality. The stupid QEMU limits should effectively be infinite. You need to look at the machine definition to determine what the real limits of the machine type are. I don't necessarily think this should be explicitly described by QEMU either. I don't mind a management tool having to be smart enough to know that an IDE controller can only support 4 disks.
Fair enough, we can drop the limits stuff.
Quoted 4 lines
As a general piece of advise, I think where you are starting from is a bit ambitious and far too open for bike shedding to be productive. You may find it easier to start with something simpler, that has a real practical utility to libvirt, and then building on that incrementally.
Certainly in favour of that. I've very little in the way of strong opinions on this thing, except to advertise IFF_VNET_HDR :-)
Any suggestions on what the minimal starting point should be?
Cheers,
Mark.
Quoted 4 lines · Mark McLoughlin
e.g. the drive cache options are example of features which aren't visible to the guest, but if you go to migrate a guest using cache=writethrough and discover the target host doesn't support that, then presumably you don't proceed.
I disagree, and think that's a perfectly reasonable migration. Of course you might want to know in advance that the target host doesn't support this option, so you can decide what to do.
I'd go a bit further - it would be good to be able to change cache=? and all other values which are invisible to the guest _without_ having to do a migration too.
Quoted 2 lines
Which is similar to not migrating a
virtio using guest to a host without virtio support.
No, that's migrating to a host which doesn't support a particular device. Same if, say, the guest is using e1000 and the target host doesn't have e1000 support.
-- JAmie
Quoted 23 lines · Mark McLoughlin
The proposed solution is to add a new monitor command which will list exactly what this qemu binary is capable of. Rather than include every possible capability, I've limited it to:
1) New features; if a version of qemu supports the capabilities info command, you can assume that it also supports features that were added before that.
2) Compile time configurables which affect what features can be requested on the command line - e.g. kqemu support
3) Magic numbers; a managment tool might know that qemu only supports 2 IDE devices - and that may never change - but it's much nicer if the tool can be coded generically rather than hardcoding a magic number.
The patch implementing this isn't perfect by any means, but since this could be implemented in so many different ways I thought I'd post it and get people's feedback.
Cheers,
Mark.
Quoted 7 lines
Example output:
[qemu]
accel=kqemu,kvm
arch=x86_64 cpu=qemu64,core2duo,qemu32,coreduo,486,pentium,pentium2,pentium3,athlon,n270 machines=pc,isapc
I like this proprosed output format because it is very nice & easy to parse, read & understand.
Daniel
Signature · 4 lines
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|