mirror of https://github.com/xemu-project/xemu.git
QAPI patches for 2016-09-19
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJX4BH+AAoJEDhwtADrkYZTXmMP/0RzvxiFXLGcBKyjMPDmPXg4 mUmje9ZYCRVoR8d8EM4dTnd6WYbUMgXc0oTTrPotwx63s6joRh5o+Mc4angKpAmg FbR3mBw44uXUruxmmMNn9WQYw9Z4VkvI5o+6S7AF83RBwyx2S2yJK1FihVZB8/99 VMUsKnicu1dWlBKlFCJpTFvrv9lo8l5HqFJIzEDMT/HT6uOpiwh6unTmFGIwQ/t2 QNpd++s5oWpbBrGbSCo2JEwgd83sRZS2NV6lhFdsDTmutbbWwCerLSIJ8YydqjEc ELrzwuf6w/G0hzzPvFTaSQX5M191pzXwLtEMZt6X+82OubowASepXvcaftN+w1wt qQYaFpqAVjcLZqq4LvJBZ/B8nKxc6858txK9ApMG4XD2qEtLZ5Pr1qv8JSYEjAKW id5dSYGVB9M99bPVGaoW/BUe4FzOzG7Cod2Rrf4L8hZ7TZ0EE+occvHdBjtbpTP0 qV2FKr5N3tivNhLBNOJxnFDaw/E1k0qhDZ97QXxQDjcUu6EDQmtHIvrHc3I/mm97 bpwSeZLpCTnrg2iIstKrYsPdo0pfpp3YDk7Apm/9tNzDQ05GBBbmkMm1Hz24ZvGD kgEkXhlJ6WCKzaZB1gZpoYJJVhT4l//FkONs7maLurGi50n2WxbmDY4wFj/4OZn5 1pLasJmMGW7J+JHn4+Rm =Lojo -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2016-09-19' into staging QAPI patches for 2016-09-19 # gpg: Signature made Mon 19 Sep 2016 17:27:42 BST # gpg: using RSA key 0x3870B400EB918653 # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" # Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867 4E5F 3870 B400 EB91 8653 * remotes/armbru/tags/pull-qapi-2016-09-19: Replace qmp-commands.hx by docs/qmp-commands.txt qmp-commands.hx: fix some styling build-sys: remove qmp-commands-old.h monitor: use qmp_dispatch() tests: add a test to check invalid args qapi: check invalid arguments on no-args commands qapi: remove the "middle" mode monitor: remove mhandler.cmd_new monitor: implement 'qmp_query_commands' without qmp_cmds monitor: use qmp_find_command() (using generated qapi code) qapi: export the marshallers qmp: Hack to keep commands configuration-specific qapi: Support unregistering QMP commands monitor: register gen:false commands manually monitor: simplify invalid_qmp_mode() qapi-schema: add 'device_add' qapi-schema: use generated marshaller for 'qmp_capabilities' build-sys: define QEMU_VERSION_{MAJOR, MINOR, MICRO} Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
33e1666b42
|
@ -55,7 +55,6 @@
|
|||
/qemu-monitor-info.texi
|
||||
/qemu-version.h
|
||||
/qemu-version.h.tmp
|
||||
/qmp-commands.txt
|
||||
/vscclient
|
||||
/fsdev/virtfs-proxy-helper
|
||||
*.[1-9]
|
||||
|
|
|
@ -1245,7 +1245,6 @@ M: Markus Armbruster <armbru@redhat.com>
|
|||
S: Supported
|
||||
F: qmp.c
|
||||
F: monitor.c
|
||||
F: qmp-commands.hx
|
||||
F: docs/*qmp-*
|
||||
F: scripts/qmp/
|
||||
T: git git://repo.or.cz/qemu/armbru.git qapi-next
|
||||
|
|
8
Makefile
8
Makefile
|
@ -92,7 +92,6 @@ HELPERS-$(CONFIG_LINUX) = qemu-bridge-helper$(EXESUF)
|
|||
|
||||
ifdef BUILD_DOCS
|
||||
DOCS=qemu-doc.html qemu-tech.html qemu.1 qemu-img.1 qemu-nbd.8 qemu-ga.8
|
||||
DOCS+=qmp-commands.txt
|
||||
ifdef CONFIG_VIRTFS
|
||||
DOCS+=fsdev/virtfs-proxy-helper.1
|
||||
endif
|
||||
|
@ -312,7 +311,7 @@ $(qapi-modules) $(SRC_PATH)/scripts/qapi-event.py $(qapi-py)
|
|||
qmp-commands.h qmp-marshal.c :\
|
||||
$(qapi-modules) $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
|
||||
$(gen-out-type) -o "." -m $<, \
|
||||
$(gen-out-type) -o "." $<, \
|
||||
" GEN $@")
|
||||
qmp-introspect.h qmp-introspect.c :\
|
||||
$(qapi-modules) $(SRC_PATH)/scripts/qapi-introspect.py $(qapi-py)
|
||||
|
@ -432,7 +431,7 @@ endif
|
|||
install-doc: $(DOCS)
|
||||
$(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)"
|
||||
$(INSTALL_DATA) qemu-doc.html qemu-tech.html "$(DESTDIR)$(qemu_docdir)"
|
||||
$(INSTALL_DATA) qmp-commands.txt "$(DESTDIR)$(qemu_docdir)"
|
||||
$(INSTALL_DATA) docs/qmp-commands.txt "$(DESTDIR)$(qemu_docdir)"
|
||||
ifdef CONFIG_POSIX
|
||||
$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1"
|
||||
$(INSTALL_DATA) qemu.1 "$(DESTDIR)$(mandir)/man1"
|
||||
|
@ -555,9 +554,6 @@ qemu-monitor.texi: $(SRC_PATH)/hmp-commands.hx $(SRC_PATH)/scripts/hxtool
|
|||
qemu-monitor-info.texi: $(SRC_PATH)/hmp-commands-info.hx $(SRC_PATH)/scripts/hxtool
|
||||
$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@," GEN $@")
|
||||
|
||||
qmp-commands.txt: $(SRC_PATH)/qmp-commands.hx $(SRC_PATH)/scripts/hxtool
|
||||
$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -q < $< > $@," GEN $@")
|
||||
|
||||
qemu-img-cmds.texi: $(SRC_PATH)/qemu-img-cmds.hx $(SRC_PATH)/scripts/hxtool
|
||||
$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@," GEN $@")
|
||||
|
||||
|
|
|
@ -156,7 +156,7 @@ else
|
|||
obj-y += hw/$(TARGET_BASE_ARCH)/
|
||||
endif
|
||||
|
||||
GENERATED_HEADERS += hmp-commands.h hmp-commands-info.h qmp-commands-old.h
|
||||
GENERATED_HEADERS += hmp-commands.h hmp-commands-info.h
|
||||
|
||||
endif # CONFIG_SOFTMMU
|
||||
|
||||
|
@ -209,13 +209,10 @@ hmp-commands.h: $(SRC_PATH)/hmp-commands.hx $(SRC_PATH)/scripts/hxtool
|
|||
hmp-commands-info.h: $(SRC_PATH)/hmp-commands-info.hx $(SRC_PATH)/scripts/hxtool
|
||||
$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@")
|
||||
|
||||
qmp-commands-old.h: $(SRC_PATH)/qmp-commands.hx $(SRC_PATH)/scripts/hxtool
|
||||
$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@")
|
||||
|
||||
clean: clean-target
|
||||
rm -f *.a *~ $(PROGS)
|
||||
rm -f $(shell find . -name '*.[od]')
|
||||
rm -f hmp-commands.h qmp-commands-old.h gdbstub-xml.c
|
||||
rm -f hmp-commands.h gdbstub-xml.c
|
||||
ifdef CONFIG_TRACE_SYSTEMTAP
|
||||
rm -f *.stp
|
||||
endif
|
||||
|
|
|
@ -964,9 +964,9 @@ Example:
|
|||
|
||||
Used to generate the marshaling/dispatch functions for the commands
|
||||
defined in the schema. The generated code implements
|
||||
qmp_marshal_COMMAND() (mentioned in qmp-commands.hx, and registered
|
||||
automatically), and declares qmp_COMMAND() that the user must
|
||||
implement. The following files are generated:
|
||||
qmp_marshal_COMMAND() (registered automatically), and declares
|
||||
qmp_COMMAND() that the user must implement. The following files are
|
||||
generated:
|
||||
|
||||
$(prefix)qmp-marshal.c: command marshal/dispatch functions for each
|
||||
QMP command defined in the schema. Functions
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -119,17 +119,6 @@ There are a few things to be noticed:
|
|||
5. Printing to the terminal is discouraged for QMP commands, we do it here
|
||||
because it's the easiest way to demonstrate a QMP command
|
||||
|
||||
Now a little hack is needed. As we're still using the old QMP server we need
|
||||
to add the new command to its internal dispatch table. This step won't be
|
||||
required in the near future. Open the qmp-commands.hx file and add the
|
||||
following at the bottom:
|
||||
|
||||
{
|
||||
.name = "hello-world",
|
||||
.args_type = "",
|
||||
.mhandler.cmd_new = qmp_marshal_hello_world,
|
||||
},
|
||||
|
||||
You're done. Now build qemu, run it as suggested in the "Testing" section,
|
||||
and then type the following QMP command:
|
||||
|
||||
|
@ -174,21 +163,6 @@ There are two important details to be noticed:
|
|||
2. The C implementation signature must follow the schema's argument ordering,
|
||||
which is defined by the "data" member
|
||||
|
||||
The last step is to update the qmp-commands.hx file:
|
||||
|
||||
{
|
||||
.name = "hello-world",
|
||||
.args_type = "message:s?",
|
||||
.mhandler.cmd_new = qmp_marshal_hello_world,
|
||||
},
|
||||
|
||||
Notice that the "args_type" member got our "message" argument. The character
|
||||
"s" stands for "string" and "?" means it's optional. This too must be ordered
|
||||
according to the C implementation and schema file. You can look for more
|
||||
examples in the qmp-commands.hx file if you need to define more arguments.
|
||||
|
||||
Again, this step won't be required in the future.
|
||||
|
||||
Time to test our new version of the "hello-world" command. Build qemu, run it as
|
||||
described in the "Testing" section and then send two commands:
|
||||
|
||||
|
@ -337,7 +311,7 @@ we should add it to the hmp-commands.hx file:
|
|||
.args_type = "message:s?",
|
||||
.params = "hello-world [message]",
|
||||
.help = "Print message to the standard output",
|
||||
.mhandler.cmd = hmp_hello_world,
|
||||
.cmd = hmp_hello_world,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -454,14 +428,6 @@ There are a number of things to be noticed:
|
|||
6. You have to include the "qmp-commands.h" header file in qemu-timer.c,
|
||||
otherwise qemu won't build
|
||||
|
||||
The last step is to add the correspoding entry in the qmp-commands.hx file:
|
||||
|
||||
{
|
||||
.name = "query-alarm-clock",
|
||||
.args_type = "",
|
||||
.mhandler.cmd_new = qmp_marshal_query_alarm_clock,
|
||||
},
|
||||
|
||||
Time to test the new command. Build qemu, run it as described in the "Testing"
|
||||
section and try this:
|
||||
|
||||
|
@ -518,7 +484,7 @@ in the monitor.c file. The entry for the "info alarmclock" follows:
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show information about the alarm clock",
|
||||
.mhandler.info = hmp_info_alarm_clock,
|
||||
.cmd = hmp_info_alarm_clock,
|
||||
},
|
||||
|
||||
To test this, run qemu and type "info alarmclock" in the user monitor.
|
||||
|
@ -600,14 +566,6 @@ iteration of the loop. That's because the alarm timer method in use is the
|
|||
first element of the alarm_timers array. Also notice that QAPI lists are handled
|
||||
by hand and we return the head of the list.
|
||||
|
||||
To test this you have to add the corresponding qmp-commands.hx entry:
|
||||
|
||||
{
|
||||
.name = "query-alarm-methods",
|
||||
.args_type = "",
|
||||
.mhandler.cmd_new = qmp_marshal_query_alarm_methods,
|
||||
},
|
||||
|
||||
Now Build qemu, run it as explained in the "Testing" section and try our new
|
||||
command:
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the version of QEMU",
|
||||
.mhandler.cmd = hmp_info_version,
|
||||
.cmd = hmp_info_version,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -32,7 +32,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the network state",
|
||||
.mhandler.cmd = hmp_info_network,
|
||||
.cmd = hmp_info_network,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -46,7 +46,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the character devices",
|
||||
.mhandler.cmd = hmp_info_chardev,
|
||||
.cmd = hmp_info_chardev,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -61,7 +61,7 @@ ETEXI
|
|||
.params = "[-n] [-v] [device]",
|
||||
.help = "show info of one block device or all block devices "
|
||||
"(-n: show named nodes; -v: show details)",
|
||||
.mhandler.cmd = hmp_info_block,
|
||||
.cmd = hmp_info_block,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -75,7 +75,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show block device statistics",
|
||||
.mhandler.cmd = hmp_info_blockstats,
|
||||
.cmd = hmp_info_blockstats,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -89,7 +89,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show progress of ongoing block device operations",
|
||||
.mhandler.cmd = hmp_info_block_jobs,
|
||||
.cmd = hmp_info_block_jobs,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -103,7 +103,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the cpu registers",
|
||||
.mhandler.cmd = hmp_info_registers,
|
||||
.cmd = hmp_info_registers,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -118,7 +118,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show local apic state",
|
||||
.mhandler.cmd = hmp_info_local_apic,
|
||||
.cmd = hmp_info_local_apic,
|
||||
},
|
||||
#endif
|
||||
|
||||
|
@ -134,7 +134,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show io apic state",
|
||||
.mhandler.cmd = hmp_info_io_apic,
|
||||
.cmd = hmp_info_io_apic,
|
||||
},
|
||||
#endif
|
||||
|
||||
|
@ -149,7 +149,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show infos for each CPU",
|
||||
.mhandler.cmd = hmp_info_cpus,
|
||||
.cmd = hmp_info_cpus,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -163,7 +163,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the command line history",
|
||||
.mhandler.cmd = hmp_info_history,
|
||||
.cmd = hmp_info_history,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -180,11 +180,11 @@ ETEXI
|
|||
.params = "",
|
||||
.help = "show the interrupts statistics (if available)",
|
||||
#ifdef TARGET_SPARC
|
||||
.mhandler.cmd = sun4m_hmp_info_irq,
|
||||
.cmd = sun4m_hmp_info_irq,
|
||||
#elif defined(TARGET_LM32)
|
||||
.mhandler.cmd = lm32_hmp_info_irq,
|
||||
.cmd = lm32_hmp_info_irq,
|
||||
#else
|
||||
.mhandler.cmd = hmp_info_irq,
|
||||
.cmd = hmp_info_irq,
|
||||
#endif
|
||||
},
|
||||
|
||||
|
@ -200,11 +200,11 @@ ETEXI
|
|||
.params = "",
|
||||
.help = "show i8259 (PIC) state",
|
||||
#ifdef TARGET_SPARC
|
||||
.mhandler.cmd = sun4m_hmp_info_pic,
|
||||
.cmd = sun4m_hmp_info_pic,
|
||||
#elif defined(TARGET_LM32)
|
||||
.mhandler.cmd = lm32_hmp_info_pic,
|
||||
.cmd = lm32_hmp_info_pic,
|
||||
#else
|
||||
.mhandler.cmd = hmp_info_pic,
|
||||
.cmd = hmp_info_pic,
|
||||
#endif
|
||||
},
|
||||
#endif
|
||||
|
@ -220,7 +220,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show PCI info",
|
||||
.mhandler.cmd = hmp_info_pci,
|
||||
.cmd = hmp_info_pci,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -236,7 +236,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show virtual to physical memory mappings",
|
||||
.mhandler.cmd = hmp_info_tlb,
|
||||
.cmd = hmp_info_tlb,
|
||||
},
|
||||
#endif
|
||||
|
||||
|
@ -252,7 +252,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the active virtual memory mappings",
|
||||
.mhandler.cmd = hmp_info_mem,
|
||||
.cmd = hmp_info_mem,
|
||||
},
|
||||
#endif
|
||||
|
||||
|
@ -267,7 +267,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show memory tree",
|
||||
.mhandler.cmd = hmp_info_mtree,
|
||||
.cmd = hmp_info_mtree,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -281,7 +281,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show dynamic compiler info",
|
||||
.mhandler.cmd = hmp_info_jit,
|
||||
.cmd = hmp_info_jit,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -295,7 +295,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show dynamic compiler opcode counters",
|
||||
.mhandler.cmd = hmp_info_opcount,
|
||||
.cmd = hmp_info_opcount,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -309,7 +309,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show KVM information",
|
||||
.mhandler.cmd = hmp_info_kvm,
|
||||
.cmd = hmp_info_kvm,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -323,7 +323,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show NUMA information",
|
||||
.mhandler.cmd = hmp_info_numa,
|
||||
.cmd = hmp_info_numa,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -337,7 +337,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show guest USB devices",
|
||||
.mhandler.cmd = hmp_info_usb,
|
||||
.cmd = hmp_info_usb,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -351,7 +351,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show host USB devices",
|
||||
.mhandler.cmd = hmp_info_usbhost,
|
||||
.cmd = hmp_info_usbhost,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -365,7 +365,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show profiling information",
|
||||
.mhandler.cmd = hmp_info_profile,
|
||||
.cmd = hmp_info_profile,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -379,7 +379,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show capture information",
|
||||
.mhandler.cmd = hmp_info_capture,
|
||||
.cmd = hmp_info_capture,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -393,7 +393,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the currently saved VM snapshots",
|
||||
.mhandler.cmd = hmp_info_snapshots,
|
||||
.cmd = hmp_info_snapshots,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -407,7 +407,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the current VM status (running|paused)",
|
||||
.mhandler.cmd = hmp_info_status,
|
||||
.cmd = hmp_info_status,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -421,7 +421,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show which guest mouse is receiving events",
|
||||
.mhandler.cmd = hmp_info_mice,
|
||||
.cmd = hmp_info_mice,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -435,7 +435,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the vnc server status",
|
||||
.mhandler.cmd = hmp_info_vnc,
|
||||
.cmd = hmp_info_vnc,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -450,7 +450,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the spice server status",
|
||||
.mhandler.cmd = hmp_info_spice,
|
||||
.cmd = hmp_info_spice,
|
||||
},
|
||||
#endif
|
||||
|
||||
|
@ -465,7 +465,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the current VM name",
|
||||
.mhandler.cmd = hmp_info_name,
|
||||
.cmd = hmp_info_name,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -479,7 +479,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the current VM UUID",
|
||||
.mhandler.cmd = hmp_info_uuid,
|
||||
.cmd = hmp_info_uuid,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -493,7 +493,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show CPU statistics",
|
||||
.mhandler.cmd = hmp_info_cpustats,
|
||||
.cmd = hmp_info_cpustats,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -508,7 +508,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show user network stack connection states",
|
||||
.mhandler.cmd = hmp_info_usernet,
|
||||
.cmd = hmp_info_usernet,
|
||||
},
|
||||
#endif
|
||||
|
||||
|
@ -523,7 +523,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show migration status",
|
||||
.mhandler.cmd = hmp_info_migrate,
|
||||
.cmd = hmp_info_migrate,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -537,7 +537,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show current migration capabilities",
|
||||
.mhandler.cmd = hmp_info_migrate_capabilities,
|
||||
.cmd = hmp_info_migrate_capabilities,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -551,7 +551,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show current migration parameters",
|
||||
.mhandler.cmd = hmp_info_migrate_parameters,
|
||||
.cmd = hmp_info_migrate_parameters,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -565,7 +565,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show current migration xbzrle cache size",
|
||||
.mhandler.cmd = hmp_info_migrate_cache_size,
|
||||
.cmd = hmp_info_migrate_cache_size,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -579,7 +579,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show balloon information",
|
||||
.mhandler.cmd = hmp_info_balloon,
|
||||
.cmd = hmp_info_balloon,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -593,7 +593,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show device tree",
|
||||
.mhandler.cmd = hmp_info_qtree,
|
||||
.cmd = hmp_info_qtree,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -607,7 +607,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show qdev device model list",
|
||||
.mhandler.cmd = hmp_info_qdm,
|
||||
.cmd = hmp_info_qdm,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -621,7 +621,7 @@ ETEXI
|
|||
.args_type = "path:s?",
|
||||
.params = "[path]",
|
||||
.help = "show QOM composition tree",
|
||||
.mhandler.cmd = hmp_info_qom_tree,
|
||||
.cmd = hmp_info_qom_tree,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -635,7 +635,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show roms",
|
||||
.mhandler.cmd = hmp_info_roms,
|
||||
.cmd = hmp_info_roms,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -650,7 +650,7 @@ ETEXI
|
|||
.params = "[name] [vcpu]",
|
||||
.help = "show available trace-events & their state "
|
||||
"(name: event name pattern; vcpu: vCPU to query, default is any)",
|
||||
.mhandler.cmd = hmp_info_trace_events,
|
||||
.cmd = hmp_info_trace_events,
|
||||
.command_completion = info_trace_events_completion,
|
||||
},
|
||||
|
||||
|
@ -665,7 +665,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the TPM device",
|
||||
.mhandler.cmd = hmp_info_tpm,
|
||||
.cmd = hmp_info_tpm,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -679,7 +679,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show memory backends",
|
||||
.mhandler.cmd = hmp_info_memdev,
|
||||
.cmd = hmp_info_memdev,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -693,7 +693,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show memory devices",
|
||||
.mhandler.cmd = hmp_info_memory_devices,
|
||||
.cmd = hmp_info_memory_devices,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -707,7 +707,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show iothreads",
|
||||
.mhandler.cmd = hmp_info_iothreads,
|
||||
.cmd = hmp_info_iothreads,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -721,7 +721,7 @@ ETEXI
|
|||
.args_type = "name:s",
|
||||
.params = "name",
|
||||
.help = "Show rocker switch",
|
||||
.mhandler.cmd = hmp_rocker,
|
||||
.cmd = hmp_rocker,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -735,7 +735,7 @@ ETEXI
|
|||
.args_type = "name:s",
|
||||
.params = "name",
|
||||
.help = "Show rocker ports",
|
||||
.mhandler.cmd = hmp_rocker_ports,
|
||||
.cmd = hmp_rocker_ports,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -749,7 +749,7 @@ ETEXI
|
|||
.args_type = "name:s,tbl_id:i?",
|
||||
.params = "name [tbl_id]",
|
||||
.help = "Show rocker OF-DPA flow tables",
|
||||
.mhandler.cmd = hmp_rocker_of_dpa_flows,
|
||||
.cmd = hmp_rocker_of_dpa_flows,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -763,7 +763,7 @@ ETEXI
|
|||
.args_type = "name:s,type:i?",
|
||||
.params = "name [type]",
|
||||
.help = "Show rocker OF-DPA groups",
|
||||
.mhandler.cmd = hmp_rocker_of_dpa_groups,
|
||||
.cmd = hmp_rocker_of_dpa_groups,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -778,7 +778,7 @@ ETEXI
|
|||
.args_type = "addr:l",
|
||||
.params = "address",
|
||||
.help = "Display the value of a storage key",
|
||||
.mhandler.cmd = hmp_info_skeys,
|
||||
.cmd = hmp_info_skeys,
|
||||
},
|
||||
#endif
|
||||
|
||||
|
@ -793,7 +793,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "Display the latest dump status",
|
||||
.mhandler.cmd = hmp_info_dump,
|
||||
.cmd = hmp_info_dump,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -807,7 +807,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "Show information about hotpluggable CPUs",
|
||||
.mhandler.cmd = hmp_hotpluggable_cpus,
|
||||
.cmd = hmp_hotpluggable_cpus,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
|
208
hmp-commands.hx
208
hmp-commands.hx
|
@ -14,7 +14,7 @@ ETEXI
|
|||
.args_type = "name:S?",
|
||||
.params = "[cmd]",
|
||||
.help = "show the help",
|
||||
.mhandler.cmd = do_help_cmd,
|
||||
.cmd = do_help_cmd,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -28,7 +28,7 @@ ETEXI
|
|||
.args_type = "device:B",
|
||||
.params = "device|all",
|
||||
.help = "commit changes to the disk images (if -snapshot is used) or backing files",
|
||||
.mhandler.cmd = hmp_commit,
|
||||
.cmd = hmp_commit,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -47,7 +47,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "quit the emulator",
|
||||
.mhandler.cmd = hmp_quit,
|
||||
.cmd = hmp_quit,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -61,7 +61,7 @@ ETEXI
|
|||
.args_type = "device:B,size:o",
|
||||
.params = "device size",
|
||||
.help = "resize a block image",
|
||||
.mhandler.cmd = hmp_block_resize,
|
||||
.cmd = hmp_block_resize,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -78,7 +78,7 @@ ETEXI
|
|||
.args_type = "device:B,speed:o?,base:s?",
|
||||
.params = "device [speed [base]]",
|
||||
.help = "copy data from a backing file into a block device",
|
||||
.mhandler.cmd = hmp_block_stream,
|
||||
.cmd = hmp_block_stream,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -92,7 +92,7 @@ ETEXI
|
|||
.args_type = "device:B,speed:o",
|
||||
.params = "device speed",
|
||||
.help = "set maximum speed for a background block operation",
|
||||
.mhandler.cmd = hmp_block_job_set_speed,
|
||||
.cmd = hmp_block_job_set_speed,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -107,7 +107,7 @@ ETEXI
|
|||
.params = "[-f] device",
|
||||
.help = "stop an active background block operation (use -f"
|
||||
"\n\t\t\t if the operation is currently paused)",
|
||||
.mhandler.cmd = hmp_block_job_cancel,
|
||||
.cmd = hmp_block_job_cancel,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -121,7 +121,7 @@ ETEXI
|
|||
.args_type = "device:B",
|
||||
.params = "device",
|
||||
.help = "stop an active background block operation",
|
||||
.mhandler.cmd = hmp_block_job_complete,
|
||||
.cmd = hmp_block_job_complete,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -136,7 +136,7 @@ ETEXI
|
|||
.args_type = "device:B",
|
||||
.params = "device",
|
||||
.help = "pause an active background block operation",
|
||||
.mhandler.cmd = hmp_block_job_pause,
|
||||
.cmd = hmp_block_job_pause,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -150,7 +150,7 @@ ETEXI
|
|||
.args_type = "device:B",
|
||||
.params = "device",
|
||||
.help = "resume a paused background block operation",
|
||||
.mhandler.cmd = hmp_block_job_resume,
|
||||
.cmd = hmp_block_job_resume,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -164,7 +164,7 @@ ETEXI
|
|||
.args_type = "force:-f,device:B",
|
||||
.params = "[-f] device",
|
||||
.help = "eject a removable medium (use -f to force it)",
|
||||
.mhandler.cmd = hmp_eject,
|
||||
.cmd = hmp_eject,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -178,7 +178,7 @@ ETEXI
|
|||
.args_type = "id:B",
|
||||
.params = "device",
|
||||
.help = "remove host block device",
|
||||
.mhandler.cmd = hmp_drive_del,
|
||||
.cmd = hmp_drive_del,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -197,7 +197,7 @@ ETEXI
|
|||
.args_type = "device:B,target:F,arg:s?,read-only-mode:s?",
|
||||
.params = "device filename [format [read-only-mode]]",
|
||||
.help = "change a removable medium, optional format",
|
||||
.mhandler.cmd = hmp_change,
|
||||
.cmd = hmp_change,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -256,7 +256,7 @@ ETEXI
|
|||
.args_type = "filename:F",
|
||||
.params = "filename",
|
||||
.help = "save screen into PPM image 'filename'",
|
||||
.mhandler.cmd = hmp_screendump,
|
||||
.cmd = hmp_screendump,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -270,7 +270,7 @@ ETEXI
|
|||
.args_type = "filename:F",
|
||||
.params = "filename",
|
||||
.help = "output logs to 'filename'",
|
||||
.mhandler.cmd = hmp_logfile,
|
||||
.cmd = hmp_logfile,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -285,7 +285,7 @@ ETEXI
|
|||
.params = "name on|off [vcpu]",
|
||||
.help = "changes status of a specific trace event "
|
||||
"(vcpu: vCPU to set, default is all)",
|
||||
.mhandler.cmd = hmp_trace_event,
|
||||
.cmd = hmp_trace_event,
|
||||
.command_completion = trace_event_completion,
|
||||
},
|
||||
|
||||
|
@ -301,7 +301,7 @@ ETEXI
|
|||
.args_type = "op:s?,arg:F?",
|
||||
.params = "on|off|flush|set [arg]",
|
||||
.help = "open, close, or flush trace file, or set a new file name",
|
||||
.mhandler.cmd = hmp_trace_file,
|
||||
.cmd = hmp_trace_file,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -316,7 +316,7 @@ ETEXI
|
|||
.args_type = "items:s",
|
||||
.params = "item1[,...]",
|
||||
.help = "activate logging of the specified items",
|
||||
.mhandler.cmd = hmp_log,
|
||||
.cmd = hmp_log,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -330,7 +330,7 @@ ETEXI
|
|||
.args_type = "name:s?",
|
||||
.params = "[tag|id]",
|
||||
.help = "save a VM snapshot. If no tag or id are provided, a new snapshot is created",
|
||||
.mhandler.cmd = hmp_savevm,
|
||||
.cmd = hmp_savevm,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -347,7 +347,7 @@ ETEXI
|
|||
.args_type = "name:s",
|
||||
.params = "tag|id",
|
||||
.help = "restore a VM snapshot from its tag or id",
|
||||
.mhandler.cmd = hmp_loadvm,
|
||||
.cmd = hmp_loadvm,
|
||||
.command_completion = loadvm_completion,
|
||||
},
|
||||
|
||||
|
@ -363,7 +363,7 @@ ETEXI
|
|||
.args_type = "name:s",
|
||||
.params = "tag|id",
|
||||
.help = "delete a VM snapshot from its tag or id",
|
||||
.mhandler.cmd = hmp_delvm,
|
||||
.cmd = hmp_delvm,
|
||||
.command_completion = delvm_completion,
|
||||
},
|
||||
|
||||
|
@ -378,7 +378,7 @@ ETEXI
|
|||
.args_type = "option:s?",
|
||||
.params = "[on|off]",
|
||||
.help = "run emulation in singlestep mode or switch to normal mode",
|
||||
.mhandler.cmd = hmp_singlestep,
|
||||
.cmd = hmp_singlestep,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -393,7 +393,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "stop emulation",
|
||||
.mhandler.cmd = hmp_stop,
|
||||
.cmd = hmp_stop,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -407,7 +407,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "resume emulation",
|
||||
.mhandler.cmd = hmp_cont,
|
||||
.cmd = hmp_cont,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -421,7 +421,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "wakeup guest from suspend",
|
||||
.mhandler.cmd = hmp_system_wakeup,
|
||||
.cmd = hmp_system_wakeup,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -435,7 +435,7 @@ ETEXI
|
|||
.args_type = "device:s?",
|
||||
.params = "[device]",
|
||||
.help = "start gdbserver on given device (default 'tcp::1234'), stop with 'none'",
|
||||
.mhandler.cmd = hmp_gdbserver,
|
||||
.cmd = hmp_gdbserver,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -449,7 +449,7 @@ ETEXI
|
|||
.args_type = "fmt:/,addr:l",
|
||||
.params = "/fmt addr",
|
||||
.help = "virtual memory dump starting at 'addr'",
|
||||
.mhandler.cmd = hmp_memory_dump,
|
||||
.cmd = hmp_memory_dump,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -463,7 +463,7 @@ ETEXI
|
|||
.args_type = "fmt:/,addr:l",
|
||||
.params = "/fmt addr",
|
||||
.help = "physical memory dump starting at 'addr'",
|
||||
.mhandler.cmd = hmp_physical_memory_dump,
|
||||
.cmd = hmp_physical_memory_dump,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -530,7 +530,7 @@ ETEXI
|
|||
.args_type = "fmt:/,val:l",
|
||||
.params = "/fmt expr",
|
||||
.help = "print expression value (use $reg for CPU register access)",
|
||||
.mhandler.cmd = do_print,
|
||||
.cmd = do_print,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -545,7 +545,7 @@ ETEXI
|
|||
.args_type = "fmt:/,addr:i,index:i.",
|
||||
.params = "/fmt addr",
|
||||
.help = "I/O port read",
|
||||
.mhandler.cmd = hmp_ioport_read,
|
||||
.cmd = hmp_ioport_read,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -559,7 +559,7 @@ ETEXI
|
|||
.args_type = "fmt:/,addr:i,val:i",
|
||||
.params = "/fmt addr value",
|
||||
.help = "I/O port write",
|
||||
.mhandler.cmd = hmp_ioport_write,
|
||||
.cmd = hmp_ioport_write,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -573,7 +573,7 @@ ETEXI
|
|||
.args_type = "keys:s,hold-time:i?",
|
||||
.params = "keys [hold_ms]",
|
||||
.help = "send keys to the VM (e.g. 'sendkey ctrl-alt-f1', default hold time=100 ms)",
|
||||
.mhandler.cmd = hmp_sendkey,
|
||||
.cmd = hmp_sendkey,
|
||||
.command_completion = sendkey_completion,
|
||||
},
|
||||
|
||||
|
@ -596,7 +596,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "reset the system",
|
||||
.mhandler.cmd = hmp_system_reset,
|
||||
.cmd = hmp_system_reset,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -610,7 +610,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "send system power down event",
|
||||
.mhandler.cmd = hmp_system_powerdown,
|
||||
.cmd = hmp_system_powerdown,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -624,7 +624,7 @@ ETEXI
|
|||
.args_type = "start:i,size:i",
|
||||
.params = "addr size",
|
||||
.help = "compute the checksum of a memory region",
|
||||
.mhandler.cmd = hmp_sum,
|
||||
.cmd = hmp_sum,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -638,7 +638,7 @@ ETEXI
|
|||
.args_type = "devname:s",
|
||||
.params = "device",
|
||||
.help = "add USB device (e.g. 'host:bus.addr' or 'host:vendor_id:product_id')",
|
||||
.mhandler.cmd = hmp_usb_add,
|
||||
.cmd = hmp_usb_add,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -653,7 +653,7 @@ ETEXI
|
|||
.args_type = "devname:s",
|
||||
.params = "device",
|
||||
.help = "remove USB device 'bus.addr'",
|
||||
.mhandler.cmd = hmp_usb_del,
|
||||
.cmd = hmp_usb_del,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -669,7 +669,7 @@ ETEXI
|
|||
.args_type = "device:O",
|
||||
.params = "driver[,prop=value][,...]",
|
||||
.help = "add device, like -device on the command line",
|
||||
.mhandler.cmd = hmp_device_add,
|
||||
.cmd = hmp_device_add,
|
||||
.command_completion = device_add_completion,
|
||||
},
|
||||
|
||||
|
@ -684,7 +684,7 @@ ETEXI
|
|||
.args_type = "id:s",
|
||||
.params = "device",
|
||||
.help = "remove device",
|
||||
.mhandler.cmd = hmp_device_del,
|
||||
.cmd = hmp_device_del,
|
||||
.command_completion = device_del_completion,
|
||||
},
|
||||
|
||||
|
@ -700,7 +700,7 @@ ETEXI
|
|||
.args_type = "index:i",
|
||||
.params = "index",
|
||||
.help = "set the default CPU",
|
||||
.mhandler.cmd = hmp_cpu,
|
||||
.cmd = hmp_cpu,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -714,7 +714,7 @@ ETEXI
|
|||
.args_type = "dx_str:s,dy_str:s,dz_str:s?",
|
||||
.params = "dx dy [dz]",
|
||||
.help = "send mouse move events",
|
||||
.mhandler.cmd = hmp_mouse_move,
|
||||
.cmd = hmp_mouse_move,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -729,7 +729,7 @@ ETEXI
|
|||
.args_type = "button_state:i",
|
||||
.params = "state",
|
||||
.help = "change mouse button state (1=L, 2=M, 4=R)",
|
||||
.mhandler.cmd = hmp_mouse_button,
|
||||
.cmd = hmp_mouse_button,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -743,7 +743,7 @@ ETEXI
|
|||
.args_type = "index:i",
|
||||
.params = "index",
|
||||
.help = "set which mouse device receives events",
|
||||
.mhandler.cmd = hmp_mouse_set,
|
||||
.cmd = hmp_mouse_set,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -761,7 +761,7 @@ ETEXI
|
|||
.args_type = "path:F,freq:i?,bits:i?,nchannels:i?",
|
||||
.params = "path [frequency [bits [channels]]]",
|
||||
.help = "capture audio to a wave file (default frequency=44100 bits=16 channels=2)",
|
||||
.mhandler.cmd = hmp_wavcapture,
|
||||
.cmd = hmp_wavcapture,
|
||||
},
|
||||
STEXI
|
||||
@item wavcapture @var{filename} [@var{frequency} [@var{bits} [@var{channels}]]]
|
||||
|
@ -782,7 +782,7 @@ ETEXI
|
|||
.args_type = "n:i",
|
||||
.params = "capture index",
|
||||
.help = "stop capture",
|
||||
.mhandler.cmd = hmp_stopcapture,
|
||||
.cmd = hmp_stopcapture,
|
||||
},
|
||||
STEXI
|
||||
@item stopcapture @var{index}
|
||||
|
@ -798,7 +798,7 @@ ETEXI
|
|||
.args_type = "val:l,size:i,filename:s",
|
||||
.params = "addr size file",
|
||||
.help = "save to disk virtual memory dump starting at 'addr' of size 'size'",
|
||||
.mhandler.cmd = hmp_memsave,
|
||||
.cmd = hmp_memsave,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -812,7 +812,7 @@ ETEXI
|
|||
.args_type = "val:l,size:i,filename:s",
|
||||
.params = "addr size file",
|
||||
.help = "save to disk physical memory dump starting at 'addr' of size 'size'",
|
||||
.mhandler.cmd = hmp_pmemsave,
|
||||
.cmd = hmp_pmemsave,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -826,7 +826,7 @@ ETEXI
|
|||
.args_type = "bootdevice:s",
|
||||
.params = "bootdevice",
|
||||
.help = "define new values for the boot device list",
|
||||
.mhandler.cmd = hmp_boot_set,
|
||||
.cmd = hmp_boot_set,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -844,7 +844,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "inject an NMI",
|
||||
.mhandler.cmd = hmp_nmi,
|
||||
.cmd = hmp_nmi,
|
||||
},
|
||||
STEXI
|
||||
@item nmi @var{cpu}
|
||||
|
@ -858,7 +858,7 @@ ETEXI
|
|||
.args_type = "device:s,data:s",
|
||||
.params = "device data",
|
||||
.help = "Write to a ring buffer character device",
|
||||
.mhandler.cmd = hmp_ringbuf_write,
|
||||
.cmd = hmp_ringbuf_write,
|
||||
.command_completion = ringbuf_write_completion,
|
||||
},
|
||||
|
||||
|
@ -875,7 +875,7 @@ ETEXI
|
|||
.args_type = "device:s,size:i",
|
||||
.params = "device size",
|
||||
.help = "Read from a ring buffer character device",
|
||||
.mhandler.cmd = hmp_ringbuf_read,
|
||||
.cmd = hmp_ringbuf_read,
|
||||
.command_completion = ringbuf_write_completion,
|
||||
},
|
||||
|
||||
|
@ -901,7 +901,7 @@ ETEXI
|
|||
" full copy of disk\n\t\t\t -i for migration without "
|
||||
"shared storage with incremental copy of disk "
|
||||
"(base image shared between src and destination)",
|
||||
.mhandler.cmd = hmp_migrate,
|
||||
.cmd = hmp_migrate,
|
||||
},
|
||||
|
||||
|
||||
|
@ -918,7 +918,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "cancel the current VM migration",
|
||||
.mhandler.cmd = hmp_migrate_cancel,
|
||||
.cmd = hmp_migrate_cancel,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -933,7 +933,7 @@ ETEXI
|
|||
.args_type = "uri:s",
|
||||
.params = "uri",
|
||||
.help = "Continue an incoming migration from an -incoming defer",
|
||||
.mhandler.cmd = hmp_migrate_incoming,
|
||||
.cmd = hmp_migrate_incoming,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -954,7 +954,7 @@ ETEXI
|
|||
"The cache size affects the number of cache misses."
|
||||
"In case of a high cache miss ratio you need to increase"
|
||||
" the cache size",
|
||||
.mhandler.cmd = hmp_migrate_set_cache_size,
|
||||
.cmd = hmp_migrate_set_cache_size,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -969,7 +969,7 @@ ETEXI
|
|||
.params = "value",
|
||||
.help = "set maximum speed (in bytes) for migrations. "
|
||||
"Defaults to MB if no size suffix is specified, ie. B/K/M/G/T",
|
||||
.mhandler.cmd = hmp_migrate_set_speed,
|
||||
.cmd = hmp_migrate_set_speed,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -983,7 +983,7 @@ ETEXI
|
|||
.args_type = "value:T",
|
||||
.params = "value",
|
||||
.help = "set maximum tolerated downtime (in seconds) for migrations",
|
||||
.mhandler.cmd = hmp_migrate_set_downtime,
|
||||
.cmd = hmp_migrate_set_downtime,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -997,7 +997,7 @@ ETEXI
|
|||
.args_type = "capability:s,state:b",
|
||||
.params = "capability state",
|
||||
.help = "Enable/Disable the usage of a capability for migration",
|
||||
.mhandler.cmd = hmp_migrate_set_capability,
|
||||
.cmd = hmp_migrate_set_capability,
|
||||
.command_completion = migrate_set_capability_completion,
|
||||
},
|
||||
|
||||
|
@ -1012,7 +1012,7 @@ ETEXI
|
|||
.args_type = "parameter:s,value:s",
|
||||
.params = "parameter value",
|
||||
.help = "Set the parameter for migration",
|
||||
.mhandler.cmd = hmp_migrate_set_parameter,
|
||||
.cmd = hmp_migrate_set_parameter,
|
||||
.command_completion = migrate_set_parameter_completion,
|
||||
},
|
||||
|
||||
|
@ -1029,7 +1029,7 @@ ETEXI
|
|||
.help = "Followup to a migration command to switch the migration"
|
||||
" to postcopy mode. The postcopy-ram capability must "
|
||||
"be set before the original migration command.",
|
||||
.mhandler.cmd = hmp_migrate_start_postcopy,
|
||||
.cmd = hmp_migrate_start_postcopy,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -1044,7 +1044,7 @@ ETEXI
|
|||
.args_type = "protocol:s,hostname:s,port:i?,tls-port:i?,cert-subject:s?",
|
||||
.params = "protocol hostname port tls-port cert-subject",
|
||||
.help = "set migration information for remote display",
|
||||
.mhandler.cmd = hmp_client_migrate_info,
|
||||
.cmd = hmp_client_migrate_info,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -1067,7 +1067,7 @@ ETEXI
|
|||
"-s: dump in kdump-compressed format, with snappy compression.\n\t\t\t"
|
||||
"begin: the starting physical address.\n\t\t\t"
|
||||
"length: the memory size, in bytes.",
|
||||
.mhandler.cmd = hmp_dump_guest_memory,
|
||||
.cmd = hmp_dump_guest_memory,
|
||||
},
|
||||
|
||||
|
||||
|
@ -1094,7 +1094,7 @@ ETEXI
|
|||
.args_type = "filename:F",
|
||||
.params = "",
|
||||
.help = "Save guest storage keys into file 'filename'.\n",
|
||||
.mhandler.cmd = hmp_dump_skeys,
|
||||
.cmd = hmp_dump_skeys,
|
||||
},
|
||||
#endif
|
||||
|
||||
|
@ -1116,7 +1116,7 @@ ETEXI
|
|||
"The default format is qcow2. The -n flag requests QEMU\n\t\t\t"
|
||||
"to reuse the image found in new-image-file, instead of\n\t\t\t"
|
||||
"recreating it from scratch.",
|
||||
.mhandler.cmd = hmp_snapshot_blkdev,
|
||||
.cmd = hmp_snapshot_blkdev,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -1132,7 +1132,7 @@ ETEXI
|
|||
.help = "take an internal snapshot of device.\n\t\t\t"
|
||||
"The format of the image used by device must\n\t\t\t"
|
||||
"support it, such as qcow2.\n\t\t\t",
|
||||
.mhandler.cmd = hmp_snapshot_blkdev_internal,
|
||||
.cmd = hmp_snapshot_blkdev_internal,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -1150,7 +1150,7 @@ ETEXI
|
|||
"the snapshot matching both id and name.\n\t\t\t"
|
||||
"The format of the image used by device must\n\t\t\t"
|
||||
"support it, such as qcow2.\n\t\t\t",
|
||||
.mhandler.cmd = hmp_snapshot_delete_blkdev_internal,
|
||||
.cmd = hmp_snapshot_delete_blkdev_internal,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -1171,7 +1171,7 @@ ETEXI
|
|||
"in new-image-file, instead of recreating it from scratch.\n\t\t\t"
|
||||
"The -f flag requests QEMU to copy the whole disk,\n\t\t\t"
|
||||
"so that the result does not need a backing file.\n\t\t\t",
|
||||
.mhandler.cmd = hmp_drive_mirror,
|
||||
.cmd = hmp_drive_mirror,
|
||||
},
|
||||
STEXI
|
||||
@item drive_mirror
|
||||
|
@ -1194,7 +1194,7 @@ ETEXI
|
|||
"so that the result does not need a backing file.\n\t\t\t"
|
||||
"The -c flag requests QEMU to compress backup data\n\t\t\t"
|
||||
"(if the target format supports it).\n\t\t\t",
|
||||
.mhandler.cmd = hmp_drive_backup,
|
||||
.cmd = hmp_drive_backup,
|
||||
},
|
||||
STEXI
|
||||
@item drive_backup
|
||||
|
@ -1212,7 +1212,7 @@ ETEXI
|
|||
"[,snapshot=on|off][,cache=on|off]\n"
|
||||
"[,readonly=on|off][,copy-on-read=on|off]",
|
||||
.help = "add drive to PCI storage controller",
|
||||
.mhandler.cmd = hmp_drive_add,
|
||||
.cmd = hmp_drive_add,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -1236,7 +1236,7 @@ ETEXI
|
|||
"<error_status> = error string or 32bit\n\t\t\t"
|
||||
"<tlb header> = 32bit x 4\n\t\t\t"
|
||||
"<tlb header prefix> = 32bit x 4",
|
||||
.mhandler.cmd = hmp_pcie_aer_inject_error,
|
||||
.cmd = hmp_pcie_aer_inject_error,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -1250,7 +1250,7 @@ ETEXI
|
|||
.args_type = "device:s,opts:s?",
|
||||
.params = "tap|user|socket|vde|netmap|bridge|vhost-user|dump [options]",
|
||||
.help = "add host VLAN client",
|
||||
.mhandler.cmd = hmp_host_net_add,
|
||||
.cmd = hmp_host_net_add,
|
||||
.command_completion = host_net_add_completion,
|
||||
},
|
||||
|
||||
|
@ -1265,7 +1265,7 @@ ETEXI
|
|||
.args_type = "vlan_id:i,device:s",
|
||||
.params = "vlan_id name",
|
||||
.help = "remove host VLAN client",
|
||||
.mhandler.cmd = hmp_host_net_remove,
|
||||
.cmd = hmp_host_net_remove,
|
||||
.command_completion = host_net_remove_completion,
|
||||
},
|
||||
|
||||
|
@ -1280,7 +1280,7 @@ ETEXI
|
|||
.args_type = "netdev:O",
|
||||
.params = "[user|tap|socket|vde|bridge|hubport|netmap|vhost-user],id=str[,prop=value][,...]",
|
||||
.help = "add host network device",
|
||||
.mhandler.cmd = hmp_netdev_add,
|
||||
.cmd = hmp_netdev_add,
|
||||
.command_completion = netdev_add_completion,
|
||||
},
|
||||
|
||||
|
@ -1295,7 +1295,7 @@ ETEXI
|
|||
.args_type = "id:s",
|
||||
.params = "id",
|
||||
.help = "remove host network device",
|
||||
.mhandler.cmd = hmp_netdev_del,
|
||||
.cmd = hmp_netdev_del,
|
||||
.command_completion = netdev_del_completion,
|
||||
},
|
||||
|
||||
|
@ -1310,7 +1310,7 @@ ETEXI
|
|||
.args_type = "object:O",
|
||||
.params = "[qom-type=]type,id=str[,prop=value][,...]",
|
||||
.help = "create QOM object",
|
||||
.mhandler.cmd = hmp_object_add,
|
||||
.cmd = hmp_object_add,
|
||||
.command_completion = object_add_completion,
|
||||
},
|
||||
|
||||
|
@ -1325,7 +1325,7 @@ ETEXI
|
|||
.args_type = "id:s",
|
||||
.params = "id",
|
||||
.help = "destroy QOM object",
|
||||
.mhandler.cmd = hmp_object_del,
|
||||
.cmd = hmp_object_del,
|
||||
.command_completion = object_del_completion,
|
||||
},
|
||||
|
||||
|
@ -1341,7 +1341,7 @@ ETEXI
|
|||
.args_type = "arg1:s,arg2:s?,arg3:s?",
|
||||
.params = "[vlan_id name] [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport",
|
||||
.help = "redirect TCP or UDP connections from host to guest (requires -net user)",
|
||||
.mhandler.cmd = hmp_hostfwd_add,
|
||||
.cmd = hmp_hostfwd_add,
|
||||
},
|
||||
#endif
|
||||
STEXI
|
||||
|
@ -1356,7 +1356,7 @@ ETEXI
|
|||
.args_type = "arg1:s,arg2:s?,arg3:s?",
|
||||
.params = "[vlan_id name] [tcp|udp]:[hostaddr]:hostport",
|
||||
.help = "remove host-to-guest TCP or UDP redirection",
|
||||
.mhandler.cmd = hmp_hostfwd_remove,
|
||||
.cmd = hmp_hostfwd_remove,
|
||||
},
|
||||
|
||||
#endif
|
||||
|
@ -1371,7 +1371,7 @@ ETEXI
|
|||
.args_type = "value:M",
|
||||
.params = "target",
|
||||
.help = "request VM to change its memory allocation (in MB)",
|
||||
.mhandler.cmd = hmp_balloon,
|
||||
.cmd = hmp_balloon,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -1385,7 +1385,7 @@ ETEXI
|
|||
.args_type = "name:s,up:b",
|
||||
.params = "name on|off",
|
||||
.help = "change the link status of a network adapter",
|
||||
.mhandler.cmd = hmp_set_link,
|
||||
.cmd = hmp_set_link,
|
||||
.command_completion = set_link_completion,
|
||||
},
|
||||
|
||||
|
@ -1400,7 +1400,7 @@ ETEXI
|
|||
.args_type = "action:s",
|
||||
.params = "[reset|shutdown|poweroff|pause|debug|none]",
|
||||
.help = "change watchdog action",
|
||||
.mhandler.cmd = hmp_watchdog_action,
|
||||
.cmd = hmp_watchdog_action,
|
||||
.command_completion = watchdog_action_completion,
|
||||
},
|
||||
|
||||
|
@ -1415,7 +1415,7 @@ ETEXI
|
|||
.args_type = "aclname:s",
|
||||
.params = "aclname",
|
||||
.help = "list rules in the access control list",
|
||||
.mhandler.cmd = hmp_acl_show,
|
||||
.cmd = hmp_acl_show,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -1432,7 +1432,7 @@ ETEXI
|
|||
.args_type = "aclname:s,policy:s",
|
||||
.params = "aclname allow|deny",
|
||||
.help = "set default access control list policy",
|
||||
.mhandler.cmd = hmp_acl_policy,
|
||||
.cmd = hmp_acl_policy,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -1448,7 +1448,7 @@ ETEXI
|
|||
.args_type = "aclname:s,match:s,policy:s,index:i?",
|
||||
.params = "aclname match allow|deny [index]",
|
||||
.help = "add a match rule to the access control list",
|
||||
.mhandler.cmd = hmp_acl_add,
|
||||
.cmd = hmp_acl_add,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -1467,7 +1467,7 @@ ETEXI
|
|||
.args_type = "aclname:s,match:s",
|
||||
.params = "aclname match",
|
||||
.help = "remove a match rule from the access control list",
|
||||
.mhandler.cmd = hmp_acl_remove,
|
||||
.cmd = hmp_acl_remove,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -1481,7 +1481,7 @@ ETEXI
|
|||
.args_type = "aclname:s",
|
||||
.params = "aclname",
|
||||
.help = "reset the access control list",
|
||||
.mhandler.cmd = hmp_acl_reset,
|
||||
.cmd = hmp_acl_reset,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -1496,7 +1496,7 @@ ETEXI
|
|||
.args_type = "all:-a,writable:-w,uri:s",
|
||||
.params = "nbd_server_start [-a] [-w] host:port",
|
||||
.help = "serve block devices on the given host and port",
|
||||
.mhandler.cmd = hmp_nbd_server_start,
|
||||
.cmd = hmp_nbd_server_start,
|
||||
},
|
||||
STEXI
|
||||
@item nbd_server_start @var{host}:@var{port}
|
||||
|
@ -1512,7 +1512,7 @@ ETEXI
|
|||
.args_type = "writable:-w,device:B",
|
||||
.params = "nbd_server_add [-w] device",
|
||||
.help = "export a block device via NBD",
|
||||
.mhandler.cmd = hmp_nbd_server_add,
|
||||
.cmd = hmp_nbd_server_add,
|
||||
},
|
||||
STEXI
|
||||
@item nbd_server_add @var{device}
|
||||
|
@ -1527,7 +1527,7 @@ ETEXI
|
|||
.args_type = "",
|
||||
.params = "nbd_server_stop",
|
||||
.help = "stop serving block devices using the NBD protocol",
|
||||
.mhandler.cmd = hmp_nbd_server_stop,
|
||||
.cmd = hmp_nbd_server_stop,
|
||||
},
|
||||
STEXI
|
||||
@item nbd_server_stop
|
||||
|
@ -1543,7 +1543,7 @@ ETEXI
|
|||
.args_type = "broadcast:-b,cpu_index:i,bank:i,status:l,mcg_status:l,addr:l,misc:l",
|
||||
.params = "[-b] cpu bank status mcgstatus addr misc",
|
||||
.help = "inject a MCE on the given CPU [and broadcast to other CPUs with -b option]",
|
||||
.mhandler.cmd = hmp_mce,
|
||||
.cmd = hmp_mce,
|
||||
},
|
||||
|
||||
#endif
|
||||
|
@ -1558,7 +1558,7 @@ ETEXI
|
|||
.args_type = "fdname:s",
|
||||
.params = "getfd name",
|
||||
.help = "receive a file descriptor via SCM rights and assign it a name",
|
||||
.mhandler.cmd = hmp_getfd,
|
||||
.cmd = hmp_getfd,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -1574,7 +1574,7 @@ ETEXI
|
|||
.args_type = "fdname:s",
|
||||
.params = "closefd name",
|
||||
.help = "close a file descriptor previously passed via SCM rights",
|
||||
.mhandler.cmd = hmp_closefd,
|
||||
.cmd = hmp_closefd,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -1590,7 +1590,7 @@ ETEXI
|
|||
.args_type = "device:B,password:s",
|
||||
.params = "block_passwd device password",
|
||||
.help = "set the password of encrypted block devices",
|
||||
.mhandler.cmd = hmp_block_passwd,
|
||||
.cmd = hmp_block_passwd,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -1604,7 +1604,7 @@ ETEXI
|
|||
.args_type = "device:B,bps:l,bps_rd:l,bps_wr:l,iops:l,iops_rd:l,iops_wr:l",
|
||||
.params = "device bps bps_rd bps_wr iops iops_rd iops_wr",
|
||||
.help = "change I/O throttle limits for a block drive",
|
||||
.mhandler.cmd = hmp_block_set_io_throttle,
|
||||
.cmd = hmp_block_set_io_throttle,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -1618,7 +1618,7 @@ ETEXI
|
|||
.args_type = "protocol:s,password:s,connected:s?",
|
||||
.params = "protocol password action-if-connected",
|
||||
.help = "set spice/vnc password",
|
||||
.mhandler.cmd = hmp_set_password,
|
||||
.cmd = hmp_set_password,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -1637,7 +1637,7 @@ ETEXI
|
|||
.args_type = "protocol:s,time:s",
|
||||
.params = "protocol time",
|
||||
.help = "set spice/vnc password expire-time",
|
||||
.mhandler.cmd = hmp_expire_password,
|
||||
.cmd = hmp_expire_password,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -1668,7 +1668,7 @@ ETEXI
|
|||
.args_type = "args:s",
|
||||
.params = "args",
|
||||
.help = "add chardev",
|
||||
.mhandler.cmd = hmp_chardev_add,
|
||||
.cmd = hmp_chardev_add,
|
||||
.command_completion = chardev_add_completion,
|
||||
},
|
||||
|
||||
|
@ -1684,7 +1684,7 @@ ETEXI
|
|||
.args_type = "id:s",
|
||||
.params = "id",
|
||||
.help = "remove chardev",
|
||||
.mhandler.cmd = hmp_chardev_remove,
|
||||
.cmd = hmp_chardev_remove,
|
||||
.command_completion = chardev_remove_completion,
|
||||
},
|
||||
|
||||
|
@ -1700,7 +1700,7 @@ ETEXI
|
|||
.args_type = "device:B,command:s",
|
||||
.params = "[device] \"[command]\"",
|
||||
.help = "run a qemu-io command on a block device",
|
||||
.mhandler.cmd = hmp_qemu_io,
|
||||
.cmd = hmp_qemu_io,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -1715,7 +1715,7 @@ ETEXI
|
|||
.args_type = "id:i",
|
||||
.params = "id",
|
||||
.help = "add cpu",
|
||||
.mhandler.cmd = hmp_cpu_add,
|
||||
.cmd = hmp_cpu_add,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -1729,7 +1729,7 @@ ETEXI
|
|||
.args_type = "path:s?",
|
||||
.params = "path",
|
||||
.help = "list QOM properties",
|
||||
.mhandler.cmd = hmp_qom_list,
|
||||
.cmd = hmp_qom_list,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -1742,7 +1742,7 @@ ETEXI
|
|||
.args_type = "path:s,property:s,value:s",
|
||||
.params = "path property value",
|
||||
.help = "set QOM property",
|
||||
.mhandler.cmd = hmp_qom_set,
|
||||
.cmd = hmp_qom_set,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -1755,8 +1755,8 @@ ETEXI
|
|||
.args_type = "item:s?",
|
||||
.params = "[subcommand]",
|
||||
.help = "show various information about the system state",
|
||||
.mhandler.cmd = hmp_info_help,
|
||||
.sub_table = info_cmds,
|
||||
.cmd = hmp_info_help,
|
||||
.sub_table = info_cmds,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
|
|
@ -36,6 +36,7 @@ typedef struct QmpCommand
|
|||
|
||||
void qmp_register_command(const char *name, QmpCommandFunc *fn,
|
||||
QmpCommandOptions options);
|
||||
void qmp_unregister_command(const char *name);
|
||||
QmpCommand *qmp_find_command(const char *name);
|
||||
QObject *qmp_dispatch(QObject *request);
|
||||
void qmp_disable_command(const char *name);
|
||||
|
|
428
monitor.c
428
monitor.c
|
@ -79,6 +79,7 @@
|
|||
#include "sysemu/block-backend.h"
|
||||
#include "sysemu/qtest.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "qapi/qmp/dispatch.h"
|
||||
|
||||
/* for hmp_info_irq/pic */
|
||||
#if defined(TARGET_SPARC)
|
||||
|
@ -129,13 +130,10 @@ typedef struct mon_cmd_t {
|
|||
const char *args_type;
|
||||
const char *params;
|
||||
const char *help;
|
||||
union {
|
||||
void (*cmd)(Monitor *mon, const QDict *qdict);
|
||||
void (*cmd_new)(QDict *params, QObject **ret_data, Error **errp);
|
||||
} mhandler;
|
||||
/* @sub_table is a list of 2nd level of commands. If it do not exist,
|
||||
* mhandler should be used. If it exist, sub_table[?].mhandler should be
|
||||
* used, and mhandler of 1st level plays the role of help function.
|
||||
void (*cmd)(Monitor *mon, const QDict *qdict);
|
||||
/* @sub_table is a list of 2nd level of commands. If it does not exist,
|
||||
* cmd should be used. If it exists, sub_table[?].cmd should be
|
||||
* used, and cmd of 1st level plays the role of help function.
|
||||
*/
|
||||
struct mon_cmd_t *sub_table;
|
||||
void (*command_completion)(ReadLineState *rs, int nb_args, const char *str);
|
||||
|
@ -168,7 +166,6 @@ struct MonFdset {
|
|||
};
|
||||
|
||||
typedef struct {
|
||||
QObject *id;
|
||||
JSONMessageParser parser;
|
||||
/*
|
||||
* When a client connects, we're in capabilities negotiation mode.
|
||||
|
@ -231,8 +228,6 @@ static int mon_refcount;
|
|||
static mon_cmd_t mon_cmds[];
|
||||
static mon_cmd_t info_cmds[];
|
||||
|
||||
static const mon_cmd_t qmp_cmds[];
|
||||
|
||||
Monitor *cur_mon;
|
||||
|
||||
static QEMUClockType event_clock_type = QEMU_CLOCK_REALTIME;
|
||||
|
@ -403,49 +398,6 @@ static void monitor_json_emitter(Monitor *mon, const QObject *data)
|
|||
QDECREF(json);
|
||||
}
|
||||
|
||||
static QDict *build_qmp_error_dict(Error *err)
|
||||
{
|
||||
QObject *obj;
|
||||
|
||||
obj = qobject_from_jsonf("{ 'error': { 'class': %s, 'desc': %s } }",
|
||||
QapiErrorClass_lookup[error_get_class(err)],
|
||||
error_get_pretty(err));
|
||||
|
||||
return qobject_to_qdict(obj);
|
||||
}
|
||||
|
||||
static void monitor_protocol_emitter(Monitor *mon, QObject *data,
|
||||
Error *err)
|
||||
{
|
||||
QDict *qmp;
|
||||
|
||||
trace_monitor_protocol_emitter(mon);
|
||||
|
||||
if (!err) {
|
||||
/* success response */
|
||||
qmp = qdict_new();
|
||||
if (data) {
|
||||
qobject_incref(data);
|
||||
qdict_put_obj(qmp, "return", data);
|
||||
} else {
|
||||
/* return an empty QDict by default */
|
||||
qdict_put(qmp, "return", qdict_new());
|
||||
}
|
||||
} else {
|
||||
/* error response */
|
||||
qmp = build_qmp_error_dict(err);
|
||||
}
|
||||
|
||||
if (mon->qmp.id) {
|
||||
qdict_put_obj(qmp, "id", mon->qmp.id);
|
||||
mon->qmp.id = NULL;
|
||||
}
|
||||
|
||||
monitor_json_emitter(mon, QOBJECT(qmp));
|
||||
QDECREF(qmp);
|
||||
}
|
||||
|
||||
|
||||
static MonitorQAPIEventConf monitor_qapi_event_conf[QAPI_EVENT__MAX] = {
|
||||
/* Limit guest-triggerable events to 1 per second */
|
||||
[QAPI_EVENT_RTC_CHANGE] = { 1000 * SCALE_MS },
|
||||
|
@ -617,7 +569,7 @@ static void monitor_qapi_event_init(void)
|
|||
qmp_event_set_func_emit(monitor_qapi_event_queue);
|
||||
}
|
||||
|
||||
static void qmp_capabilities(QDict *params, QObject **ret_data, Error **errp)
|
||||
void qmp_qmp_capabilities(Error **errp)
|
||||
{
|
||||
cur_mon->qmp.in_command_mode = true;
|
||||
}
|
||||
|
@ -956,21 +908,28 @@ static void hmp_info_help(Monitor *mon, const QDict *qdict)
|
|||
help_cmd(mon, "info");
|
||||
}
|
||||
|
||||
CommandInfoList *qmp_query_commands(Error **errp)
|
||||
static void query_commands_cb(QmpCommand *cmd, void *opaque)
|
||||
{
|
||||
CommandInfoList *info, *cmd_list = NULL;
|
||||
const mon_cmd_t *cmd;
|
||||
CommandInfoList *info, **list = opaque;
|
||||
|
||||
for (cmd = qmp_cmds; cmd->name != NULL; cmd++) {
|
||||
info = g_malloc0(sizeof(*info));
|
||||
info->value = g_malloc0(sizeof(*info->value));
|
||||
info->value->name = g_strdup(cmd->name);
|
||||
|
||||
info->next = cmd_list;
|
||||
cmd_list = info;
|
||||
if (!cmd->enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
return cmd_list;
|
||||
info = g_malloc0(sizeof(*info));
|
||||
info->value = g_malloc0(sizeof(*info->value));
|
||||
info->value->name = g_strdup(cmd->name);
|
||||
info->next = *list;
|
||||
*list = info;
|
||||
}
|
||||
|
||||
CommandInfoList *qmp_query_commands(Error **errp)
|
||||
{
|
||||
CommandInfoList *list = NULL;
|
||||
|
||||
qmp_for_each_command(query_commands_cb, &list);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
EventInfoList *qmp_query_events(Error **errp)
|
||||
|
@ -1007,6 +966,49 @@ static void qmp_query_qmp_schema(QDict *qdict, QObject **ret_data,
|
|||
*ret_data = qobject_from_json(qmp_schema_json);
|
||||
}
|
||||
|
||||
/*
|
||||
* We used to define commands in qmp-commands.hx in addition to the
|
||||
* QAPI schema. This permitted defining some of them only in certain
|
||||
* configurations. query-commands has always reflected that (good,
|
||||
* because it lets QMP clients figure out what's actually available),
|
||||
* while query-qmp-schema never did (not so good). This function is a
|
||||
* hack to keep the configuration-specific commands defined exactly as
|
||||
* before, even though qmp-commands.hx is gone.
|
||||
*
|
||||
* FIXME Educate the QAPI schema on configuration-specific commands,
|
||||
* and drop this hack.
|
||||
*/
|
||||
static void qmp_unregister_commands_hack(void)
|
||||
{
|
||||
#ifndef CONFIG_SPICE
|
||||
qmp_unregister_command("query-spice");
|
||||
#endif
|
||||
#ifndef TARGET_I386
|
||||
qmp_unregister_command("rtc-reset-reinjection");
|
||||
#endif
|
||||
#ifndef TARGET_S390X
|
||||
qmp_unregister_command("dump-skeys");
|
||||
#endif
|
||||
#ifndef TARGET_ARM
|
||||
qmp_unregister_command("query-gic-capabilities");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void qmp_init_marshal(void)
|
||||
{
|
||||
qmp_register_command("query-qmp-schema", qmp_query_qmp_schema,
|
||||
QCO_NO_OPTIONS);
|
||||
qmp_register_command("device_add", qmp_device_add,
|
||||
QCO_NO_OPTIONS);
|
||||
qmp_register_command("netdev_add", qmp_netdev_add,
|
||||
QCO_NO_OPTIONS);
|
||||
|
||||
/* call it after the rest of qapi_init() */
|
||||
register_module_init(qmp_unregister_commands_hack, MODULE_INIT_QAPI);
|
||||
}
|
||||
|
||||
qapi_init(qmp_init_marshal);
|
||||
|
||||
/* set the current CPU defined by the user */
|
||||
int monitor_set_cpu(int cpu_index)
|
||||
{
|
||||
|
@ -2163,11 +2165,6 @@ static mon_cmd_t mon_cmds[] = {
|
|||
{ NULL, NULL, },
|
||||
};
|
||||
|
||||
static const mon_cmd_t qmp_cmds[] = {
|
||||
#include "qmp-commands-old.h"
|
||||
{ /* NULL */ },
|
||||
};
|
||||
|
||||
/*******************************************************************/
|
||||
|
||||
static const char *pch;
|
||||
|
@ -2518,11 +2515,6 @@ static const mon_cmd_t *search_dispatch_table(const mon_cmd_t *disp_table,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const mon_cmd_t *qmp_find_cmd(const char *cmdname)
|
||||
{
|
||||
return search_dispatch_table(qmp_cmds, cmdname);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse command name from @cmdp according to command table @table.
|
||||
* If blank, return NULL.
|
||||
|
@ -2954,7 +2946,7 @@ static void handle_hmp_command(Monitor *mon, const char *cmdline)
|
|||
return;
|
||||
}
|
||||
|
||||
cmd->mhandler.cmd(mon, qdict);
|
||||
cmd->cmd(mon, qdict);
|
||||
QDECREF(qdict);
|
||||
}
|
||||
|
||||
|
@ -3653,219 +3645,26 @@ static int monitor_can_read(void *opaque)
|
|||
return (mon->suspend_cnt == 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
static bool invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd,
|
||||
static bool invalid_qmp_mode(const Monitor *mon, const char *cmd,
|
||||
Error **errp)
|
||||
{
|
||||
bool is_cap = cmd->mhandler.cmd_new == qmp_capabilities;
|
||||
bool is_cap = g_str_equal(cmd, "qmp_capabilities");
|
||||
|
||||
if (is_cap && mon->qmp.in_command_mode) {
|
||||
error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND,
|
||||
"Capabilities negotiation is already complete, command "
|
||||
"'%s' ignored", cmd->name);
|
||||
"'%s' ignored", cmd);
|
||||
return true;
|
||||
}
|
||||
if (!is_cap && !mon->qmp.in_command_mode) {
|
||||
error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND,
|
||||
"Expecting capabilities negotiation with "
|
||||
"'qmp_capabilities' before command '%s'", cmd->name);
|
||||
"'qmp_capabilities' before command '%s'", cmd);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Argument validation rules:
|
||||
*
|
||||
* 1. The argument must exist in cmd_args qdict
|
||||
* 2. The argument type must be the expected one
|
||||
*
|
||||
* Special case: If the argument doesn't exist in cmd_args and
|
||||
* the QMP_ACCEPT_UNKNOWNS flag is set, then the
|
||||
* checking is skipped for it.
|
||||
*/
|
||||
static void check_client_args_type(const QDict *client_args,
|
||||
const QDict *cmd_args, int flags,
|
||||
Error **errp)
|
||||
{
|
||||
const QDictEntry *ent;
|
||||
|
||||
for (ent = qdict_first(client_args); ent;ent = qdict_next(client_args,ent)){
|
||||
QObject *obj;
|
||||
QString *arg_type;
|
||||
const QObject *client_arg = qdict_entry_value(ent);
|
||||
const char *client_arg_name = qdict_entry_key(ent);
|
||||
|
||||
obj = qdict_get(cmd_args, client_arg_name);
|
||||
if (!obj) {
|
||||
if (flags & QMP_ACCEPT_UNKNOWNS) {
|
||||
/* handler accepts unknowns */
|
||||
continue;
|
||||
}
|
||||
/* client arg doesn't exist */
|
||||
error_setg(errp, QERR_INVALID_PARAMETER, client_arg_name);
|
||||
return;
|
||||
}
|
||||
|
||||
arg_type = qobject_to_qstring(obj);
|
||||
assert(arg_type != NULL);
|
||||
|
||||
/* check if argument's type is correct */
|
||||
switch (qstring_get_str(arg_type)[0]) {
|
||||
case 'F':
|
||||
case 'B':
|
||||
case 's':
|
||||
if (qobject_type(client_arg) != QTYPE_QSTRING) {
|
||||
error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
|
||||
client_arg_name, "string");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 'i':
|
||||
case 'l':
|
||||
case 'M':
|
||||
case 'o':
|
||||
if (qobject_type(client_arg) != QTYPE_QINT) {
|
||||
error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
|
||||
client_arg_name, "int");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 'T':
|
||||
if (qobject_type(client_arg) != QTYPE_QINT &&
|
||||
qobject_type(client_arg) != QTYPE_QFLOAT) {
|
||||
error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
|
||||
client_arg_name, "number");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 'b':
|
||||
case '-':
|
||||
if (qobject_type(client_arg) != QTYPE_QBOOL) {
|
||||
error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
|
||||
client_arg_name, "bool");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 'O':
|
||||
assert(flags & QMP_ACCEPT_UNKNOWNS);
|
||||
break;
|
||||
case 'q':
|
||||
/* Any QObject can be passed. */
|
||||
break;
|
||||
case '/':
|
||||
case '.':
|
||||
/*
|
||||
* These types are not supported by QMP and thus are not
|
||||
* handled here. Fall through.
|
||||
*/
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* - Check if the client has passed all mandatory args
|
||||
* - Set special flags for argument validation
|
||||
*/
|
||||
static void check_mandatory_args(const QDict *cmd_args,
|
||||
const QDict *client_args, int *flags,
|
||||
Error **errp)
|
||||
{
|
||||
const QDictEntry *ent;
|
||||
|
||||
for (ent = qdict_first(cmd_args); ent; ent = qdict_next(cmd_args, ent)) {
|
||||
const char *cmd_arg_name = qdict_entry_key(ent);
|
||||
QString *type = qobject_to_qstring(qdict_entry_value(ent));
|
||||
assert(type != NULL);
|
||||
|
||||
if (qstring_get_str(type)[0] == 'O') {
|
||||
assert((*flags & QMP_ACCEPT_UNKNOWNS) == 0);
|
||||
*flags |= QMP_ACCEPT_UNKNOWNS;
|
||||
} else if (qstring_get_str(type)[0] != '-' &&
|
||||
qstring_get_str(type)[1] != '?' &&
|
||||
!qdict_haskey(client_args, cmd_arg_name)) {
|
||||
error_setg(errp, QERR_MISSING_PARAMETER, cmd_arg_name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static QDict *qdict_from_args_type(const char *args_type)
|
||||
{
|
||||
int i;
|
||||
QDict *qdict;
|
||||
QString *key, *type, *cur_qs;
|
||||
|
||||
assert(args_type != NULL);
|
||||
|
||||
qdict = qdict_new();
|
||||
|
||||
if (args_type == NULL || args_type[0] == '\0') {
|
||||
/* no args, empty qdict */
|
||||
goto out;
|
||||
}
|
||||
|
||||
key = qstring_new();
|
||||
type = qstring_new();
|
||||
|
||||
cur_qs = key;
|
||||
|
||||
for (i = 0;; i++) {
|
||||
switch (args_type[i]) {
|
||||
case ',':
|
||||
case '\0':
|
||||
qdict_put(qdict, qstring_get_str(key), type);
|
||||
QDECREF(key);
|
||||
if (args_type[i] == '\0') {
|
||||
goto out;
|
||||
}
|
||||
type = qstring_new(); /* qdict has ref */
|
||||
cur_qs = key = qstring_new();
|
||||
break;
|
||||
case ':':
|
||||
cur_qs = type;
|
||||
break;
|
||||
default:
|
||||
qstring_append_chr(cur_qs, args_type[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return qdict;
|
||||
}
|
||||
|
||||
/*
|
||||
* Client argument checking rules:
|
||||
*
|
||||
* 1. Client must provide all mandatory arguments
|
||||
* 2. Each argument provided by the client must be expected
|
||||
* 3. Each argument provided by the client must have the type expected
|
||||
* by the command
|
||||
*/
|
||||
static void qmp_check_client_args(const mon_cmd_t *cmd, QDict *client_args,
|
||||
Error **errp)
|
||||
{
|
||||
Error *err = NULL;
|
||||
int flags;
|
||||
QDict *cmd_args;
|
||||
|
||||
cmd_args = qdict_from_args_type(cmd->args_type);
|
||||
|
||||
flags = 0;
|
||||
check_mandatory_args(cmd_args, client_args, &flags, &err);
|
||||
if (err) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
check_client_args_type(client_args, cmd_args, flags, &err);
|
||||
|
||||
out:
|
||||
error_propagate(errp, err);
|
||||
QDECREF(cmd_args);
|
||||
}
|
||||
|
||||
/*
|
||||
* Input object checking rules
|
||||
*
|
||||
|
@ -3924,65 +3723,58 @@ static QDict *qmp_check_input_obj(QObject *input_obj, Error **errp)
|
|||
|
||||
static void handle_qmp_command(JSONMessageParser *parser, GQueue *tokens)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
QObject *obj, *data;
|
||||
QDict *input, *args;
|
||||
const mon_cmd_t *cmd;
|
||||
QObject *req, *rsp = NULL, *id = NULL;
|
||||
QDict *qdict = NULL;
|
||||
const char *cmd_name;
|
||||
Monitor *mon = cur_mon;
|
||||
Error *err = NULL;
|
||||
|
||||
args = input = NULL;
|
||||
data = NULL;
|
||||
|
||||
obj = json_parser_parse(tokens, NULL);
|
||||
if (!obj) {
|
||||
// FIXME: should be triggered in json_parser_parse()
|
||||
error_setg(&local_err, QERR_JSON_PARSING);
|
||||
req = json_parser_parse_err(tokens, NULL, &err);
|
||||
if (err || !req || qobject_type(req) != QTYPE_QDICT) {
|
||||
if (!err) {
|
||||
error_setg(&err, QERR_JSON_PARSING);
|
||||
}
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
input = qmp_check_input_obj(obj, &local_err);
|
||||
if (!input) {
|
||||
qobject_decref(obj);
|
||||
qdict = qmp_check_input_obj(req, &err);
|
||||
if (!qdict) {
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
mon->qmp.id = qdict_get(input, "id");
|
||||
qobject_incref(mon->qmp.id);
|
||||
id = qdict_get(qdict, "id");
|
||||
qobject_incref(id);
|
||||
qdict_del(qdict, "id");
|
||||
|
||||
cmd_name = qdict_get_str(input, "execute");
|
||||
cmd_name = qdict_get_str(qdict, "execute");
|
||||
trace_handle_qmp_command(mon, cmd_name);
|
||||
cmd = qmp_find_cmd(cmd_name);
|
||||
if (!cmd) {
|
||||
error_set(&local_err, ERROR_CLASS_COMMAND_NOT_FOUND,
|
||||
"The command %s has not been found", cmd_name);
|
||||
goto err_out;
|
||||
}
|
||||
if (invalid_qmp_mode(mon, cmd, &local_err)) {
|
||||
|
||||
if (invalid_qmp_mode(mon, cmd_name, &err)) {
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
obj = qdict_get(input, "arguments");
|
||||
if (!obj) {
|
||||
args = qdict_new();
|
||||
} else {
|
||||
args = qobject_to_qdict(obj);
|
||||
QINCREF(args);
|
||||
}
|
||||
|
||||
qmp_check_client_args(cmd, args, &local_err);
|
||||
if (local_err) {
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
cmd->mhandler.cmd_new(args, &data, &local_err);
|
||||
rsp = qmp_dispatch(req);
|
||||
|
||||
err_out:
|
||||
monitor_protocol_emitter(mon, data, local_err);
|
||||
qobject_decref(data);
|
||||
error_free(local_err);
|
||||
QDECREF(input);
|
||||
QDECREF(args);
|
||||
if (err) {
|
||||
qdict = qdict_new();
|
||||
qdict_put_obj(qdict, "error", qmp_build_error_object(err));
|
||||
error_free(err);
|
||||
rsp = QOBJECT(qdict);
|
||||
}
|
||||
|
||||
if (rsp) {
|
||||
if (id) {
|
||||
qdict_put_obj(qobject_to_qdict(rsp), "id", id);
|
||||
id = NULL;
|
||||
}
|
||||
|
||||
monitor_json_emitter(mon, rsp);
|
||||
}
|
||||
|
||||
qobject_decref(id);
|
||||
qobject_decref(rsp);
|
||||
qobject_decref(req);
|
||||
}
|
||||
|
||||
static void monitor_qmp_read(void *opaque, const uint8_t *buf, int size)
|
||||
|
@ -4047,7 +3839,9 @@ static QObject *get_qmp_greeting(void)
|
|||
QObject *ver = NULL;
|
||||
|
||||
qmp_marshal_query_version(NULL, &ver, NULL);
|
||||
return qobject_from_jsonf("{'QMP':{'version': %p,'capabilities': []}}",ver);
|
||||
|
||||
return qobject_from_jsonf("{'QMP': {'version': %p, 'capabilities': []}}",
|
||||
ver);
|
||||
}
|
||||
|
||||
static void monitor_qmp_event(void *opaque, int event)
|
||||
|
|
|
@ -20,6 +20,27 @@
|
|||
# QAPI introspection
|
||||
{ 'include': 'qapi/introspect.json' }
|
||||
|
||||
##
|
||||
# @qmp_capabilities:
|
||||
#
|
||||
# Enable QMP capabilities.
|
||||
#
|
||||
# Arguments: None.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# -> { "execute": "qmp_capabilities" }
|
||||
# <- { "return": {} }
|
||||
#
|
||||
# Notes: This command is valid exactly when first connecting: it must be
|
||||
# issued before any other command will be accepted, and will fail once the
|
||||
# monitor is accepting other commands. (see qemu docs/qmp-spec.txt)
|
||||
#
|
||||
# Since: 0.13
|
||||
#
|
||||
##
|
||||
{ 'command': 'qmp_capabilities' }
|
||||
|
||||
##
|
||||
# @LostTickPolicy:
|
||||
#
|
||||
|
@ -2179,6 +2200,46 @@
|
|||
##
|
||||
{ 'command': 'xen-set-global-dirty-log', 'data': { 'enable': 'bool' } }
|
||||
|
||||
##
|
||||
# @device_add:
|
||||
#
|
||||
# @driver: the name of the new device's driver
|
||||
#
|
||||
# @bus: #optional the device's parent bus (device tree path)
|
||||
#
|
||||
# @id: the device's ID, must be unique
|
||||
#
|
||||
# Additional arguments depend on the type.
|
||||
#
|
||||
# Add a device.
|
||||
#
|
||||
# Notes:
|
||||
# 1. For detailed information about this command, please refer to the
|
||||
# 'docs/qdev-device-use.txt' file.
|
||||
#
|
||||
# 2. It's possible to list device properties by running QEMU with the
|
||||
# "-device DEVICE,help" command-line argument, where DEVICE is the
|
||||
# device's name
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# -> { "execute": "device_add",
|
||||
# "arguments": { "driver": "e1000", "id": "net1",
|
||||
# "bus": "pci.0",
|
||||
# "mac": "52:54:00:12:34:56" } }
|
||||
# <- { "return": {} }
|
||||
#
|
||||
# TODO This command effectively bypasses QAPI completely due to its
|
||||
# "additional arguments" business. It shouldn't have been added to
|
||||
# the schema in this form. It should be qapified properly, or
|
||||
# replaced by a properly qapified command.
|
||||
#
|
||||
# Since: 0.13
|
||||
##
|
||||
{ 'command': 'device_add',
|
||||
'data': {'driver': 'str', 'id': 'str'},
|
||||
'gen': false } # so we can get the additional arguments
|
||||
|
||||
##
|
||||
# @device_del:
|
||||
#
|
||||
|
|
|
@ -30,6 +30,14 @@ void qmp_register_command(const char *name, QmpCommandFunc *fn,
|
|||
QTAILQ_INSERT_TAIL(&qmp_commands, cmd, node);
|
||||
}
|
||||
|
||||
void qmp_unregister_command(const char *name)
|
||||
{
|
||||
QmpCommand *cmd = qmp_find_command(name);
|
||||
|
||||
QTAILQ_REMOVE(&qmp_commands, cmd, node);
|
||||
g_free(cmd);
|
||||
}
|
||||
|
||||
QmpCommand *qmp_find_command(const char *name)
|
||||
{
|
||||
QmpCommand *cmd;
|
||||
|
|
16
qmp.c
16
qmp.c
|
@ -51,21 +51,11 @@ NameInfo *qmp_query_name(Error **errp)
|
|||
VersionInfo *qmp_query_version(Error **errp)
|
||||
{
|
||||
VersionInfo *info = g_new0(VersionInfo, 1);
|
||||
const char *version = QEMU_VERSION;
|
||||
const char *tmp;
|
||||
int err;
|
||||
|
||||
info->qemu = g_new0(VersionTriple, 1);
|
||||
err = qemu_strtoll(version, &tmp, 10, &info->qemu->major);
|
||||
assert(err == 0);
|
||||
tmp++;
|
||||
|
||||
err = qemu_strtoll(tmp, &tmp, 10, &info->qemu->minor);
|
||||
assert(err == 0);
|
||||
tmp++;
|
||||
|
||||
err = qemu_strtoll(tmp, &tmp, 10, &info->qemu->micro);
|
||||
assert(err == 0);
|
||||
info->qemu->major = QEMU_VERSION_MAJOR;
|
||||
info->qemu->minor = QEMU_VERSION_MINOR;
|
||||
info->qemu->micro = QEMU_VERSION_MICRO;
|
||||
info->package = g_strdup(QEMU_PKGVERSION);
|
||||
|
||||
return info;
|
||||
|
|
|
@ -7,7 +7,13 @@ while read line; do
|
|||
case $line in
|
||||
VERSION=*) # configuration
|
||||
version=${line#*=}
|
||||
major=$(echo "$version" | cut -d. -f1)
|
||||
minor=$(echo "$version" | cut -d. -f2)
|
||||
micro=$(echo "$version" | cut -d. -f3)
|
||||
echo "#define QEMU_VERSION \"$version\""
|
||||
echo "#define QEMU_VERSION_MAJOR $major"
|
||||
echo "#define QEMU_VERSION_MINOR $minor"
|
||||
echo "#define QEMU_VERSION_MICRO $micro"
|
||||
;;
|
||||
qemu_*dir=*) # qemu-specific directory configuration
|
||||
name=${line%=*}
|
||||
|
|
|
@ -84,10 +84,7 @@ static void qmp_marshal_output_%(c_name)s(%(c_type)s ret_in, QObject **ret_out,
|
|||
|
||||
|
||||
def gen_marshal_proto(name):
|
||||
ret = 'void qmp_marshal_%s(QDict *args, QObject **ret, Error **errp)' % c_name(name)
|
||||
if not middle_mode:
|
||||
ret = 'static ' + ret
|
||||
return ret
|
||||
return 'void qmp_marshal_%s(QDict *args, QObject **ret, Error **errp)' % c_name(name)
|
||||
|
||||
|
||||
def gen_marshal_decl(name):
|
||||
|
@ -98,6 +95,8 @@ def gen_marshal_decl(name):
|
|||
|
||||
|
||||
def gen_marshal(name, arg_type, boxed, ret_type):
|
||||
have_args = arg_type and not arg_type.is_empty()
|
||||
|
||||
ret = mcgen('''
|
||||
|
||||
%(proto)s
|
||||
|
@ -112,17 +111,31 @@ def gen_marshal(name, arg_type, boxed, ret_type):
|
|||
''',
|
||||
c_type=ret_type.c_type())
|
||||
|
||||
if arg_type and not arg_type.is_empty():
|
||||
if have_args:
|
||||
visit_members = ('visit_type_%s_members(v, &arg, &err);'
|
||||
% arg_type.c_name())
|
||||
ret += mcgen('''
|
||||
Visitor *v;
|
||||
%(c_name)s arg = {0};
|
||||
|
||||
''',
|
||||
c_name=arg_type.c_name())
|
||||
else:
|
||||
visit_members = ''
|
||||
ret += mcgen('''
|
||||
Visitor *v = NULL;
|
||||
|
||||
if (args) {
|
||||
''')
|
||||
push_indent()
|
||||
|
||||
ret += mcgen('''
|
||||
v = qmp_input_visitor_new(QOBJECT(args), true);
|
||||
visit_start_struct(v, NULL, NULL, 0, &err);
|
||||
if (err) {
|
||||
goto out;
|
||||
}
|
||||
visit_type_%(c_name)s_members(v, &arg, &err);
|
||||
%(visit_members)s
|
||||
if (!err) {
|
||||
visit_check_struct(v, &err);
|
||||
}
|
||||
|
@ -131,35 +144,47 @@ def gen_marshal(name, arg_type, boxed, ret_type):
|
|||
goto out;
|
||||
}
|
||||
''',
|
||||
c_name=arg_type.c_name())
|
||||
visit_members=visit_members)
|
||||
|
||||
else:
|
||||
if not have_args:
|
||||
pop_indent()
|
||||
ret += mcgen('''
|
||||
|
||||
(void)args;
|
||||
}
|
||||
''')
|
||||
|
||||
ret += gen_call(name, arg_type, boxed, ret_type)
|
||||
|
||||
# 'goto out' produced above for arg_type, and by gen_call() for ret_type
|
||||
if (arg_type and not arg_type.is_empty()) or ret_type:
|
||||
ret += mcgen('''
|
||||
ret += mcgen('''
|
||||
|
||||
out:
|
||||
''')
|
||||
ret += mcgen('''
|
||||
error_propagate(errp, err);
|
||||
''')
|
||||
if arg_type and not arg_type.is_empty():
|
||||
ret += mcgen('''
|
||||
visit_free(v);
|
||||
''')
|
||||
|
||||
if have_args:
|
||||
visit_members = ('visit_type_%s_members(v, &arg, NULL);'
|
||||
% arg_type.c_name())
|
||||
else:
|
||||
visit_members = ''
|
||||
ret += mcgen('''
|
||||
if (args) {
|
||||
''')
|
||||
push_indent()
|
||||
|
||||
ret += mcgen('''
|
||||
v = qapi_dealloc_visitor_new();
|
||||
visit_start_struct(v, NULL, NULL, 0, NULL);
|
||||
visit_type_%(c_name)s_members(v, &arg, NULL);
|
||||
%(visit_members)s
|
||||
visit_end_struct(v, NULL);
|
||||
visit_free(v);
|
||||
''',
|
||||
c_name=arg_type.c_name())
|
||||
visit_members=visit_members)
|
||||
|
||||
if not have_args:
|
||||
pop_indent()
|
||||
ret += mcgen('''
|
||||
}
|
||||
''')
|
||||
|
||||
ret += mcgen('''
|
||||
}
|
||||
|
@ -209,8 +234,7 @@ class QAPISchemaGenCommandVisitor(QAPISchemaVisitor):
|
|||
self._visited_ret_types = set()
|
||||
|
||||
def visit_end(self):
|
||||
if not middle_mode:
|
||||
self.defn += gen_registry(self._regy)
|
||||
self.defn += gen_registry(self._regy)
|
||||
self._regy = None
|
||||
self._visited_ret_types = None
|
||||
|
||||
|
@ -222,21 +246,12 @@ class QAPISchemaGenCommandVisitor(QAPISchemaVisitor):
|
|||
if ret_type and ret_type not in self._visited_ret_types:
|
||||
self._visited_ret_types.add(ret_type)
|
||||
self.defn += gen_marshal_output(ret_type)
|
||||
if middle_mode:
|
||||
self.decl += gen_marshal_decl(name)
|
||||
self.decl += gen_marshal_decl(name)
|
||||
self.defn += gen_marshal(name, arg_type, boxed, ret_type)
|
||||
if not middle_mode:
|
||||
self._regy += gen_register_command(name, success_response)
|
||||
self._regy += gen_register_command(name, success_response)
|
||||
|
||||
|
||||
middle_mode = False
|
||||
|
||||
(input_file, output_dir, do_c, do_h, prefix, opts) = \
|
||||
parse_command_line("m", ["middle"])
|
||||
|
||||
for o, a in opts:
|
||||
if o in ("-m", "--middle"):
|
||||
middle_mode = True
|
||||
(input_file, output_dir, do_c, do_h, prefix, opts) = parse_command_line()
|
||||
|
||||
c_comment = '''
|
||||
/*
|
||||
|
|
|
@ -198,6 +198,26 @@ static void test_qga_ping(gconstpointer fix)
|
|||
QDECREF(ret);
|
||||
}
|
||||
|
||||
static void test_qga_invalid_args(gconstpointer fix)
|
||||
{
|
||||
const TestFixture *fixture = fix;
|
||||
QDict *ret, *error;
|
||||
const gchar *class, *desc;
|
||||
|
||||
ret = qmp_fd(fixture->fd, "{'execute': 'guest-ping', "
|
||||
"'arguments': {'foo': 42 }}");
|
||||
g_assert_nonnull(ret);
|
||||
|
||||
error = qdict_get_qdict(ret, "error");
|
||||
class = qdict_get_try_str(error, "class");
|
||||
desc = qdict_get_try_str(error, "desc");
|
||||
|
||||
g_assert_cmpstr(class, ==, "GenericError");
|
||||
g_assert_cmpstr(desc, ==, "QMP input object member 'foo' is unexpected");
|
||||
|
||||
QDECREF(ret);
|
||||
}
|
||||
|
||||
static void test_qga_invalid_cmd(gconstpointer fix)
|
||||
{
|
||||
const TestFixture *fixture = fix;
|
||||
|
@ -911,6 +931,7 @@ int main(int argc, char **argv)
|
|||
g_test_add_data_func("/qga/file-write-read", &fix, test_qga_file_write_read);
|
||||
g_test_add_data_func("/qga/get-time", &fix, test_qga_get_time);
|
||||
g_test_add_data_func("/qga/invalid-cmd", &fix, test_qga_invalid_cmd);
|
||||
g_test_add_data_func("/qga/invalid-args", &fix, test_qga_invalid_args);
|
||||
g_test_add_data_func("/qga/fsfreeze-status", &fix,
|
||||
test_qga_fsfreeze_status);
|
||||
|
||||
|
|
|
@ -106,6 +106,7 @@ static void test_dispatch_cmd(void)
|
|||
static void test_dispatch_cmd_failure(void)
|
||||
{
|
||||
QDict *req = qdict_new();
|
||||
QDict *args = qdict_new();
|
||||
QObject *resp;
|
||||
|
||||
qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd2")));
|
||||
|
@ -116,6 +117,20 @@ static void test_dispatch_cmd_failure(void)
|
|||
|
||||
qobject_decref(resp);
|
||||
QDECREF(req);
|
||||
|
||||
/* check that with extra arguments it throws an error */
|
||||
req = qdict_new();
|
||||
qdict_put(args, "a", qint_from_int(66));
|
||||
qdict_put(req, "arguments", args);
|
||||
|
||||
qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd")));
|
||||
|
||||
resp = qmp_dispatch(QOBJECT(req));
|
||||
assert(resp != NULL);
|
||||
assert(qdict_haskey(qobject_to_qdict(resp), "error"));
|
||||
|
||||
qobject_decref(resp);
|
||||
QDECREF(req);
|
||||
}
|
||||
|
||||
static QObject *test_qmp_dispatch(QDict *req)
|
||||
|
|
|
@ -98,7 +98,6 @@ qemu_co_mutex_unlock_return(void *mutex, void *self) "mutex %p self %p"
|
|||
|
||||
# monitor.c
|
||||
handle_qmp_command(void *mon, const char *cmd_name) "mon %p cmd_name \"%s\""
|
||||
monitor_protocol_emitter(void *mon) "mon %p"
|
||||
monitor_protocol_event_handler(uint32_t event, void *qdict) "event=%d data=%p"
|
||||
monitor_protocol_event_emit(uint32_t event, void *data) "event=%d data=%p"
|
||||
monitor_protocol_event_queue(uint32_t event, void *qdict, uint64_t rate) "event=%d data=%p rate=%" PRId64
|
||||
|
|
Loading…
Reference in New Issue