aboutsummaryrefslogtreecommitdiff
path: root/monitor.c
AgeCommit message (Collapse)AuthorFilesLines
2018-12-16Merge remote-tracking branch 'remotes/pmaydell/tags/pull-misc-20181214' into ↵Peter Maydell1-1/+7
staging miscellaneous patches: * checkpatch.pl: Enforce multiline comment syntax * Rename cpu_physical_memory_write_rom() to address_space_write_rom() * disas, monitor, elf_ops: Use address_space_read() to read memory * Remove load_image() in favour of load_image_size() * Fix some minor memory leaks in arm boards/devices * virt: fix broken indentation # gpg: Signature made Fri 14 Dec 2018 14:41:20 GMT # gpg: using RSA key 3C2525ED14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" # gpg: aka "Peter Maydell <pmaydell@gmail.com>" # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-misc-20181214: (22 commits) virt: Fix broken indentation target/arm: Create timers in realize, not init tests/test-arm-mptimer: Don't leak string memory hw/sd/sdhci: Don't leak memory region in sdhci_sysbus_realize() hw/arm/mps2-tz.c: Free mscname string in make_dma() target/arm: Free name string in ARMCPRegInfo hashtable entries include/hw/loader.h: Document load_image_size() hw/core/loader.c: Remove load_image() device_tree.c: Don't use load_image() hw/block/tc58128.c: Don't use load_image() hw/i386/multiboot.c: Don't use load_image() hw/i386/pc.c: Don't use load_image() hw/pci/pci.c: Don't use load_image() hw/smbios/smbios.c: Don't use load_image() hw/ppc/ppc405_boards: Don't use load_image() hw/ppc/mac_newworld, mac_oldworld: Don't use load_image() elf_ops.h: Use address_space_write() to write memory monitor: Use address_space_read() to read memory disas.c: Use address_space_read() to read memory Rename cpu_physical_memory_write_rom() to address_space_write_rom() ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-12-14monitor: Use address_space_read() to read memoryPeter Maydell1-1/+7
Currently monitor.c reads physical memory using cpu_physical_memory_read(). This effectively hard-codes assuming that all CPUs have the same view of physical memory. Switch to address_space_read() instead, which lets us use the AddressSpace for the CPU we're reading memory for (falling back to address_space_memory if there is no CPU, as happens with the "none" board). As a bonus, this allows us to detect failures to read memory. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Message-id: 20181122172653.3413-3-peter.maydell@linaro.org
2018-12-14qapi: add conditions to REPLICATION type/commands on the schemaMarc-André Lureau1-5/+0
Add #if defined(CONFIG_REPLICATION) in generated code, and adjust the code accordingly. Made conditional: * xen-set-replication, query-xen-replication-status, xen-colo-do-checkpoint Before the patch, we first register the commands unconditionally in generated code (requires a stub), then conditionally unregister in qmp_unregister_commands_hack(). Afterwards, we register only when CONFIG_REPLICATION. The command fails exactly the same, with CommandNotFound. Improvement, because now query-qmp-schema is accurate, and we're one step closer to killing qmp_unregister_commands_hack(). * enum BlockdevDriver value "replication" in command blockdev-add * BlockdevOptions variant @replication and related structures. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20181213123724.4866-23-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-13cutils: Fix qemu_strtosz() & friends to reject non-finite sizesDavid Hildenbrand1-1/+1
qemu_strtosz() & friends reject NaNs, but happily accept infinities. They shouldn't. Fix that. The fix makes use of qemu_strtod_finite(). To avoid ugly casts, change the @end parameter of qemu_strtosz() & friends from char ** to const char **. Also, add two test cases, testing that "inf" and "NaN" are properly rejected. While at it, also fixup the function documentation. Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: David Hildenbrand <david@redhat.com> Message-Id: <20181121164421.20780-3-david@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-12monitor: Remove "x-oob", offer capability "oob" unconditionallyPeter Xu1-18/+5
Out-of-band command execution was introduced in commit cf869d53172. Unfortunately, we ran into a regression, and had to turn it into an experimental option for 2.12 (commit be933ffc23). http://lists.gnu.org/archive/html/qemu-devel/2018-03/msg06231.html The regression has since been fixed (commit 951702f39c7 "monitor: bind dispatch bh to iohandler context"). A thorough re-review of OOB commands led to a few more issues, which have also been addressed. This patch partly reverts be933ffc23 (monitor: new parameter "x-oob"), and makes QMP monitors again offer capability "oob" whenever they can provide it, i.e. when the monitor's character device is capable of running in an I/O thread. Some trivial touch-up in the test code is required to make sure qmp-test won't break. Reviewed-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Signed-off-by: Peter Xu <peterx@redhat.com> Message-Id: <20181009062718.1914-4-peterx@redhat.com> [Conflict with "monitor: check if chardev can switch gcontext for OOB" resolved, commit message updated] Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-12monitor: Suspend monitor instead dropping commandsPeter Xu1-29/+23
When a QMP client sends in-band commands more quickly that we can process them, we can either queue them without limit (QUEUE), drop commands when the queue is full (DROP), or suspend receiving commands when the queue is full (SUSPEND). None of them is ideal: * QUEUE lets a misbehaving client make QEMU eat memory without bounds. Not such a hot idea. * With DROP, the client has to cope with dropped in-band commands. To inform the client, we send a COMMAND_DROPPED event then. The event is flawed by design in two ways: it's ambiguous (see commit d621cfe0a17), and it brings back the "eat memory without bounds" problem. * With SUSPEND, the client has to manage the flow of in-band commands to keep the monitor available for out-of-band commands. We currently DROP. Switch to SUSPEND. Managing the flow of in-band commands to keep the monitor available for out-of-band commands isn't really hard: just count the number of "outstanding" in-band commands (commands sent minus replies received), and if it exceeds the limit, hold back additional ones until it drops below the limit again. Note that we need to be careful pairing the suspend with a resume, or else the monitor will hang, possibly forever. And here since we need to make sure both: (1) popping request from the req queue, and (2) reading length of the req queue will be in the same critical section, we let the pop function take the corresponding queue lock when there is a request, then we release the lock from the caller. Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Signed-off-by: Peter Xu <peterx@redhat.com> Message-Id: <20181009062718.1914-2-peterx@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-12monitor: avoid potential dead-lock when cleaning upMarc-André Lureau1-0/+3
When a monitor is connected to a Spice chardev, the monitor cleanup can dead-lock: #0 0x00007f43446637fd in __lll_lock_wait () at /lib64/libpthread.so.0 #1 0x00007f434465ccf4 in pthread_mutex_lock () at /lib64/libpthread.so.0 #2 0x0000556dd79f22ba in qemu_mutex_lock_impl (mutex=0x556dd81c9220 <monitor_lock>, file=0x556dd7ae3648 "/home/elmarco/src/qq/monitor.c", line=645) at /home/elmarco/src/qq/util/qemu-thread-posix.c:66 #3 0x0000556dd7431bd5 in monitor_qapi_event_queue (event=QAPI_EVENT_SPICE_DISCONNECTED, qdict=0x556dd9abc850, errp=0x7fffb7bbddd8) at /home/elmarco/src/qq/monitor.c:645 #4 0x0000556dd79d476b in qapi_event_send_spice_disconnected (server=0x556dd98ee760, client=0x556ddaaa8560, errp=0x556dd82180d0 <error_abort>) at qapi/qapi-events-ui.c:149 #5 0x0000556dd7870fc1 in channel_event (event=3, info=0x556ddad1b590) at /home/elmarco/src/qq/ui/spice-core.c:235 #6 0x00007f434560a6bb in reds_handle_channel_event (reds=<optimized out>, event=3, info=0x556ddad1b590) at reds.c:316 #7 0x00007f43455f393b in main_dispatcher_self_handle_channel_event (info=0x556ddad1b590, event=3, self=0x556dd9a7d8c0) at main-dispatcher.c:197 #8 0x00007f43455f393b in main_dispatcher_channel_event (self=0x556dd9a7d8c0, event=event@entry=3, info=0x556ddad1b590) at main-dispatcher.c:197 #9 0x00007f4345612833 in red_stream_push_channel_event (s=s@entry=0x556ddae2ef40, event=event@entry=3) at red-stream.c:414 #10 0x00007f434561286b in red_stream_free (s=0x556ddae2ef40) at red-stream.c:388 #11 0x00007f43455f9ddc in red_channel_client_finalize (object=0x556dd9bb21a0) at red-channel-client.c:347 #12 0x00007f434b5f9fb9 in g_object_unref () at /lib64/libgobject-2.0.so.0 #13 0x00007f43455fc212 in red_channel_client_push (rcc=0x556dd9bb21a0) at red-channel-client.c:1341 #14 0x0000556dd76081ba in spice_port_set_fe_open (chr=0x556dd9925e20, fe_open=0) at /home/elmarco/src/qq/chardev/spice.c:241 #15 0x0000556dd796d74a in qemu_chr_fe_set_open (be=0x556dd9a37c00, fe_open=0) at /home/elmarco/src/qq/chardev/char-fe.c:340 #16 0x0000556dd796d4d9 in qemu_chr_fe_set_handlers (b=0x556dd9a37c00, fd_can_read=0x0, fd_read=0x0, fd_event=0x0, be_change=0x0, opaque=0x0, context=0x0, set_open=true) at /home/elmarco/src/qq/chardev/char-fe.c:280 #17 0x0000556dd796d359 in qemu_chr_fe_deinit (b=0x556dd9a37c00, del=false) at /home/elmarco/src/qq/chardev/char-fe.c:233 #18 0x0000556dd7432240 in monitor_data_destroy (mon=0x556dd9a37c00) at /home/elmarco/src/qq/monitor.c:786 #19 0x0000556dd743b968 in monitor_cleanup () at /home/elmarco/src/qq/monitor.c:4683 #20 0x0000556dd75ce776 in main (argc=3, argv=0x7fffb7bbe458, envp=0x7fffb7bbe478) at /home/elmarco/src/qq/vl.c:4660 Because spice code tries to emit a "disconnected" signal on the monitors. Fix this dead-lock by releasing the monitor lock for flush/destroy. monitor_lock protects mon_list, monitor_qapi_event_state and monitor_destroyed. monitor_flush() and monitor_data_destroy() don't access any of those variables. monitor_cleanup()'s loop is safe because it uses QTAILQ_FOREACH_SAFE(), and no further monitor can be added after calling monitor_cleanup() thanks to monitor_destroyed check in monitor_list_append(). Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20181205203737.9011-8-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-12monitor: prevent inserting new monitors after cleanupMarc-André Lureau1-2/+17
monitor_cleanup() is one of the last things main() calls before it returns. In the following patch, monitor_cleanup() will release the monitor_lock during flushing. There may be pending commands to insert new monitors, which would modify the mon_list during iteration, and the clean-up could thus miss those new insertions. Add a monitor_destroyed global to check if monitor_cleanup() has been already called. In this case, don't insert the new monitor in the list, but free it instead. A cleaner solution would involve the main thread telling other threads to terminate, waiting for their termination. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20181205203737.9011-7-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-12monitor: check if chardev can switch gcontext for OOBMarc-André Lureau1-2/+3
Not all backends are able to switch gcontext. Those backends cannot drive a OOB monitor (the monitor would then be blocking on main thread). For example, ringbuf, spice, or more esoteric input chardevs like braille or MUX. We already forbid MUX because not all frontends are ready to run outside main loop. Replace that by a context-switching feature check. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20181205203737.9011-5-marcandre.lureau@redhat.com> [Error condition simplified, commit message adjusted accordingly] Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-12monitor: accept chardev input from iothreadMarc-André Lureau1-10/+19
Chardev backends may not handle safely IO events from concurrent threads (may not handle I/O events from concurrent threads safely, only the write path is since commit > 9005b2a7589540a3733b3abdcfbccfe7746cd1a1). Better to wake up the chardev from the monitor IO thread if it's being used as the chardev context. Unify code paths by using a BH in all cases. Drop the now redundant aio_notify() call. Clean up control flow not to rely on mon->use_io_thread implying monitor_is_qmp(mon). Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20181205203737.9011-3-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-12monitor: inline ambiguous helper functionsMarc-André Lureau1-12/+2
The function were not named with "mon_iothread", or following the AIO vs GMainContext distinction. Inline them instead. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20181205203737.9011-2-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-11-06monitor: delay monitor iothread creationWolfgang Bumiller1-14/+21
Commit d32749deb615 moved the call to monitor_init_globals() to before os_daemonize(), making it an unsuitable place to spawn the monitor iothread as it won't be inherited over the fork() in os_daemonize(). We now spawn the thread the first time we instantiate a monitor which actually has use_io_thread == true. Instantiation of monitors happens only after os_daemonize(). We still need to create the qmp_dispatcher_bh when not using iothreads, so this now still happens in monitor_init_globals(). Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com> Fixes: d32749deb615 ("monitor: move init global earlier") Message-Id: <20180925081507.11873-3-w.bumiller@proxmox.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com> Tested-by: Peter Xu <peterx@redhat.com> [This fixes a crash on shutdown with --daemonize] Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-11-06monitor: guard iothread access by mon->use_io_threadWolfgang Bumiller1-1/+1
monitor_resume() and monitor_suspend() both want to "kick" the I/O thread if it is there, but in monitor_suspend() lacked the use_io_thread flag condition. This is required when we later only spawn the thread on first use. Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com> Message-Id: <20180925081507.11873-2-w.bumiller@proxmox.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-10-18tcg: distribute tcg_time into TCG contextsEmilio G. Cota1-3/+10
When we implemented per-vCPU TCG contexts, we forgot to also distribute the tcg_time counter, which has remained as a global accessed without any serialization, leading to potentially missed counts. Fix it by distributing the field over the TCG contexts, embedding it into TCGProfile with a field called "cpu_exec_time", which is more descriptive than "tcg_time". Add a function to query this value directly, and for completeness, fill in the field in tcg_profile_snapshot, even though its callers do not use it. Signed-off-by: Emilio G. Cota <cota@braap.org> Message-Id: <20181010144853.13005-5-cota@braap.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2018-10-05qdev-monitor: print help to stdoutMarc-André Lureau1-3/+13
qdev_device_help() is used from command line "-device help", or from HMP "device_add". If used from command line, print help to stdout (it is only printed on explicit demand). Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
2018-09-25monitor: print message when using 'help' with an unknown commandCollin Walling1-1/+8
When typing 'help' followed by an unknown command, QEMU will not print anything to the command line to let the user know they typed a bad command. Let's fix this by printing a message to the monitor when this happens. For example: (qemu) help xyz unknown command: 'xyz' Reported-by: Stefan Zimmermann <stzi@linux.ibm.com> Signed-off-by: Collin Walling <walling@linux.ibm.com> Message-Id: <1532115624-27568-1-git-send-email-walling@linux.ibm.com> Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
2018-09-24Merge remote-tracking branch 'remotes/armbru/tags/pull-monitor-2018-09-01' ↵Peter Maydell1-137/+13
into staging Monitor patches for 2018-09-01 # gpg: Signature made Sat 01 Sep 2018 12:06:52 BST # gpg: using RSA key 3870B400EB918653 # 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-monitor-2018-09-01: monitor: no need to save need_resume Revert "qmp: isolate responses into io thread" qmp: constify qmp_is_oob() monitor: consitify qmp_send_response() QDict argument monitor: accept input on resume monitor: simplify monitor_qmp_setup_handlers_bh Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-08-30monitor: no need to save need_resumeMarc-André Lureau1-9/+4
There is no need for per-command need_resume granularity, it should resume after running an non-oob command on oob-disabled monitor. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20180829134043.31706-5-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-08-30Revert "qmp: isolate responses into io thread"Marc-André Lureau1-117/+3
This reverts commit abe3cd0ff7f774966da6842620806ab7576fe4f3. There is no need to add an additional queue to send the reply to the IOThread, because QMP response is thread safe, and chardev write path is thread safe. It will schedule the watcher in the associated IOThread. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20180829134043.31706-4-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-08-30monitor: consitify qmp_send_response() QDict argumentMarc-André Lureau1-2/+2
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20180829134043.31706-2-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-08-28monitor: accept input on resumeMarc-André Lureau1-0/+1
A chardev may stop trying to write if the associated can_read() callback returned 0. This happens when the monitor is suspended. The frontend is supposed to call qemu_chr_fe_accept_input() when it is ready to accept data again. An issue was observed with a spice port: pending commands may be delayed, as the chardev is not flushed. Most chardev don't use the accept_input() callback, and instead check regularly if they can write. The ones that do use it are braille, mux, msmouse, spice (abstract), spicevmc, spiceport, wctablet. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20180817173752.19136-1-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-08-28qapi: Drop qapi_event_send_FOO()'s Error ** argumentPeter Xu1-3/+2
The generated qapi_event_send_FOO() take an Error ** argument. They can't actually fail, because all they do with the argument is passing it to functions that can't fail: the QObject output visitor, and the @qmp_emit callback, which is either monitor_qapi_event_queue() or event_test_emit(). Drop the argument, and pass &error_abort to the QObject output visitor and @qmp_emit instead. Suggested-by: Eric Blake <eblake@redhat.com> Suggested-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Peter Xu <peterx@redhat.com> Message-Id: <20180815133747.25032-4-peterx@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> [Commit message rewritten, update to qapi-code-gen.txt corrected] Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-08-28monitor: simplify monitor_qmp_setup_handlers_bhPeter Xu1-9/+3
When we reach monitor_qmp_setup_handlers_bh() we must be using the IOThread then, so no need to check against it any more. Instead, we assert. Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Peter Xu <peterx@redhat.com> Message-Id: <20180815133747.25032-2-peterx@redhat.com> [Insufficiently useful comment dropped] Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-08-24json: Clean up headersMarkus Armbruster1-1/+1
The JSON parser has three public headers, json-lexer.h, json-parser.h, json-streamer.h. They all contain stuff that is of no interest outside qobject/json-*.c. Collect the public interface in include/qapi/qmp/json-parser.h, and everything else in qobject/json-parser-int.h. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20180823164025.12553-54-armbru@redhat.com>
2018-08-24json: Pass lexical errors and limit violations to callbackMarkus Armbruster1-4/+1
The callback to consume JSON values takes QObject *json, Error *err. If both are null, the callback is supposed to make up an error by itself. This sucks. qjson.c's consume_json() neglects to do so, which makes qobject_from_json() null instead of failing. I consider that a bug. The culprit is json_message_process_token(): it passes two null pointers when it runs into a lexical error or a limit violation. Fix it to pass a proper Error object then. Update the callbacks: * monitor.c's handle_qmp_command(): the code to make up an error is now dead, drop it. * qga/main.c's process_event(): lumps the "both null" case together with the "not a JSON object" case. The former is now gone. The error message "Invalid JSON syntax" is misleading for the latter. Improve it to "Input must be a JSON object". * qobject/qjson.c's consume_json(): no update; check-qjson demonstrates qobject_from_json() now sets an error on lexical errors, but still doesn't on some other errors. * tests/libqtest.c's qmp_response(): the Error object is now reliable, so use it to improve the error message. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20180823164025.12553-40-armbru@redhat.com>
2018-08-24json: Redesign the callback to consume JSON valuesMarkus Armbruster1-10/+8
The classical way to structure parser and lexer is to have the client call the parser to get an abstract syntax tree, the parser call the lexer to get the next token, and the lexer call some function to get input characters. Another way to structure them would be to have the client feed characters to the lexer, the lexer feed tokens to the parser, and the parser feed abstract syntax trees to some callback provided by the client. This way is more easily integrated into an event loop that dispatches input characters as they arrive. Our JSON parser is kind of between the two. The lexer feeds tokens to a "streamer" instead of a real parser. The streamer accumulates tokens until it got the sequence of tokens that comprise a single JSON value (it counts curly braces and square brackets to decide). It feeds those token sequences to a callback provided by the client. The callback passes each token sequence to the parser, and gets back an abstract syntax tree. I figure it was done that way to make a straightforward recursive descent parser possible. "Get next token" becomes "pop the first token off the token sequence". Drawback: we need to store a complete token sequence. Each token eats 13 + input characters + malloc overhead bytes. Observations: 1. This is not the only way to use recursive descent. If we replaced "get next token" by a coroutine yield, we could do without a streamer. 2. The lexer reports errors by passing a JSON_ERROR token to the streamer. This communicates the offending input characters and their location, but no more. 3. The streamer reports errors by passing a null token sequence to the callback. The (already poor) lexical error information is thrown away. 4. Having the callback receive a token sequence duplicates the code to convert token sequence to abstract syntax tree in every callback. 5. Known bug: the streamer silently drops incomplete token sequences. This commit rectifies 4. by lifting the call of the parser from the callbacks into the streamer. Later commits will address 3. and 5. The lifting removes a bug from qjson.c's parse_json(): it passed a pointer to a non-null Error * in certain cases, as demonstrated by check-qjson.c. json_parser_parse() is now unused. It's a stupid wrapper around json_parser_parse_err(). Drop it, and rename json_parser_parse_err() to json_parser_parse(). Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20180823164025.12553-35-armbru@redhat.com>
2018-08-23hmp-commands-info: add sync-profileEmilio G. Cota1-0/+11
The command introduced here is just for developers. This means that: - the info displayed and the output format could change in the future - the command is only meant to be used from HMP, not from QMP Sample output: (qemu) sync-profile sync-profile is off (qemu) info sync-profile Type Object Call site Wait Time (s) Count Average (us) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- (qemu) sync-profile on (qemu) sync-profile sync-profile is on (qemu) info sync-profile 15 Type Object Call site Wait Time (s) Count Average (us) ---------------------------------------------------------------------------------------------- condvar 0x55a01813ced0 cpus.c:1165 91.38235 2842 32154.24 BQL mutex 0x55a0171b7140 cpus.c:1434 12.56490 5787 2171.23 BQL mutex 0x55a0171b7140 accel/tcg/cpu-exec.c:432 7.75846 2844 2728.01 BQL mutex 0x55a0171b7140 accel/tcg/cputlb.c:870 5.09889 2884 1767.99 BQL mutex 0x55a0171b7140 accel/tcg/cpu-exec.c:529 3.46140 3254 1063.74 BQL mutex 0x55a0171b7140 accel/tcg/cputlb.c:804 0.76333 8655 88.20 BQL mutex 0x55a0171b7140 cpus.c:1466 0.60893 2941 207.05 BQL mutex 0x55a0171b7140 util/main-loop.c:236 0.00894 6425 1.39 mutex [ 3] util/qemu-timer.c:520 0.00342 50611 0.07 mutex [ 2] util/qemu-timer.c:426 0.00254 31336 0.08 mutex [ 3] util/qemu-timer.c:234 0.00107 19275 0.06 mutex 0x55a0171d9960 vl.c:763 0.00043 6425 0.07 mutex 0x55a0180d1bb0 monitor.c:458 0.00015 1603 0.09 mutex 0x55a0180e4c78 chardev/char.c:109 0.00002 217 0.08 mutex 0x55a0180d1bb0 monitor.c:448 0.00001 162 0.08 ---------------------------------------------------------------------------------------------- (qemu) info sync-profile -m 15 Type Object Call site Wait Time (s) Count Average (us) ---------------------------------------------------------------------------------------------- condvar 0x55a01813ced0 cpus.c:1165 95.11196 3051 31174.03 BQL mutex 0x55a0171b7140 accel/tcg/cpu-exec.c:432 7.92108 3052 2595.37 BQL mutex 0x55a0171b7140 cpus.c:1434 13.38253 6210 2155.00 BQL mutex 0x55a0171b7140 accel/tcg/cputlb.c:870 5.09901 3093 1648.57 BQL mutex 0x55a0171b7140 accel/tcg/cpu-exec.c:529 4.21123 3468 1214.31 BQL mutex 0x55a0171b7140 cpus.c:1466 0.60895 3156 192.95 BQL mutex 0x55a0171b7140 accel/tcg/cputlb.c:804 0.76337 9282 82.24 BQL mutex 0x55a0171b7140 util/main-loop.c:236 0.00944 6889 1.37 mutex 0x55a01813ce80 tcg/tcg.c:397 0.00000 24 0.15 mutex 0x55a0180d1bb0 monitor.c:458 0.00018 1922 0.09 mutex [ 2] util/qemu-timer.c:426 0.00266 32710 0.08 mutex 0x55a0180e4c78 chardev/char.c:109 0.00002 260 0.08 mutex 0x55a0180d1bb0 monitor.c:448 0.00001 187 0.08 mutex 0x55a0171d9960 vl.c:763 0.00047 6889 0.07 mutex [ 3] util/qemu-timer.c:520 0.00362 53377 0.07 ---------------------------------------------------------------------------------------------- (qemu) info sync-profile -m -n 15 Type Object Call site Wait Time (s) Count Average (us) ---------------------------------------------------------------------------------------------- condvar 0x55a01813ced0 cpus.c:1165 101.39331 3398 29839.12 BQL mutex 0x55a0171b7140 accel/tcg/cpu-exec.c:432 7.92112 3399 2330.43 BQL mutex 0x55a0171b7140 cpus.c:1434 14.28280 6922 2063.39 BQL mutex 0x55a0171b7140 accel/tcg/cputlb.c:870 5.77505 3445 1676.36 BQL mutex 0x55a0171b7140 accel/tcg/cpu-exec.c:529 5.66139 3883 1457.99 BQL mutex 0x55a0171b7140 cpus.c:1466 0.60901 3519 173.06 BQL mutex 0x55a0171b7140 accel/tcg/cputlb.c:804 0.76351 10338 73.85 BQL mutex 0x55a0171b7140 util/main-loop.c:236 0.01032 7664 1.35 mutex 0x55a0180e4f08 util/qemu-timer.c:426 0.00041 901 0.45 mutex 0x55a01813ce80 tcg/tcg.c:397 0.00000 24 0.15 mutex 0x55a0180d1bb0 monitor.c:458 0.00022 2319 0.09 mutex 0x55a0180e4c78 chardev/char.c:109 0.00003 306 0.08 mutex 0x55a0180e4f08 util/qemu-timer.c:520 0.00068 8565 0.08 mutex 0x55a0180d1bb0 monitor.c:448 0.00002 215 0.08 mutex 0x55a0180e4f78 util/qemu-timer.c:426 0.00247 34224 0.07 ---------------------------------------------------------------------------------------------- (qemu) sync-profile reset (qemu) info sync-profile -m 2 Type Object Call site Wait Time (s) Count Average (us) -------------------------------------------------------------------------------------------- condvar 0x55a01813ced0 cpus.c:1165 2.78756 99 28157.12 BQL mutex 0x55a0171b7140 accel/tcg/cputlb.c:870 0.33054 102 3240.55 -------------------------------------------------------------------------------------------- (qemu) sync-profile off (qemu) sync-profile sync-profile is off (qemu) sync-profile reset (qemu) info sync-profile Type Object Call site Wait Time (s) Count Average (us) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Signed-off-by: Emilio G. Cota <cota@braap.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2018-08-15monitor: fix oob command leakMarc-André Lureau1-0/+2
Spotted by ASAN, during make check... Direct leak of 40 byte(s) in 1 object(s) allocated from: #0 0x7f8e27262c48 in malloc (/lib64/libasan.so.5+0xeec48) #1 0x7f8e26a5f3c5 in g_malloc (/lib64/libglib-2.0.so.0+0x523c5) #2 0x555ab67078a8 in qstring_from_str /home/elmarco/src/qq/qobject/qstring.c:67 #3 0x555ab67071e4 in qstring_new /home/elmarco/src/qq/qobject/qstring.c:24 #4 0x555ab6713fbf in qstring_from_escaped_str /home/elmarco/src/qq/qobject/json-parser.c:144 #5 0x555ab671738c in parse_literal /home/elmarco/src/qq/qobject/json-parser.c:506 #6 0x555ab67179c3 in parse_value /home/elmarco/src/qq/qobject/json-parser.c:569 #7 0x555ab6715123 in parse_pair /home/elmarco/src/qq/qobject/json-parser.c:306 #8 0x555ab6715483 in parse_object /home/elmarco/src/qq/qobject/json-parser.c:357 #9 0x555ab671798b in parse_value /home/elmarco/src/qq/qobject/json-parser.c:561 #10 0x555ab6717a6b in json_parser_parse_err /home/elmarco/src/qq/qobject/json-parser.c:592 #11 0x555ab4fd4dcf in handle_qmp_command /home/elmarco/src/qq/monitor.c:4257 #12 0x555ab6712c4d in json_message_process_token /home/elmarco/src/qq/qobject/json-streamer.c:105 #13 0x555ab67e01e2 in json_lexer_feed_char /home/elmarco/src/qq/qobject/json-lexer.c:323 #14 0x555ab67e0af6 in json_lexer_feed /home/elmarco/src/qq/qobject/json-lexer.c:373 #15 0x555ab6713010 in json_message_parser_feed /home/elmarco/src/qq/qobject/json-streamer.c:124 #16 0x555ab4fd58ec in monitor_qmp_read /home/elmarco/src/qq/monitor.c:4337 #17 0x555ab6559df2 in qemu_chr_be_write_impl /home/elmarco/src/qq/chardev/char.c:175 #18 0x555ab6559e95 in qemu_chr_be_write /home/elmarco/src/qq/chardev/char.c:187 #19 0x555ab6560127 in fd_chr_read /home/elmarco/src/qq/chardev/char-fd.c:66 #20 0x555ab65d9c73 in qio_channel_fd_source_dispatch /home/elmarco/src/qq/io/channel-watch.c:84 #21 0x7f8e26a598ac in g_main_context_dispatch (/lib64/libglib-2.0.so.0+0x4c8ac) Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20180809114417.28718-4-marcandre.lureau@redhat.com> [Screwed up in commit b27314567d4] Cc: qemu-stable@nongnu.org Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-07-31monitor: temporary fix for dead-lock on event recursionMarc-André Lureau1-1/+43
With a Spice port chardev, it is possible to reenter monitor_qapi_event_queue() (when the client disconnects for example). This will dead-lock on monitor_lock. Instead, use some TLS variables to check for recursion and queue the events. Fixes: (gdb) bt #0 0x00007fa69e7217fd in __lll_lock_wait () at /lib64/libpthread.so.0 #1 0x00007fa69e71acf4 in pthread_mutex_lock () at /lib64/libpthread.so.0 #2 0x0000563303567619 in qemu_mutex_lock_impl (mutex=0x563303d3e220 <monitor_lock>, file=0x5633036589a8 "/home/elmarco/src/qq/monitor.c", line=645) at /home/elmarco/src/qq/util/qemu-thread-posix.c:66 #3 0x0000563302fa6c25 in monitor_qapi_event_queue (event=QAPI_EVENT_SPICE_DISCONNECTED, qdict=0x56330602bde0, errp=0x7ffc6ab5e728) at /home/elmarco/src/qq/monitor.c:645 #4 0x0000563303549aca in qapi_event_send_spice_disconnected (server=0x563305afd630, client=0x563305745360, errp=0x563303d8d0f0 <error_abort>) at qapi/qapi-events-ui.c:149 #5 0x00005633033e600f in channel_event (event=3, info=0x5633061b0050) at /home/elmarco/src/qq/ui/spice-core.c:235 #6 0x00007fa69f6c86bb in reds_handle_channel_event (reds=<optimized out>, event=3, info=0x5633061b0050) at reds.c:316 #7 0x00007fa69f6b193b in main_dispatcher_self_handle_channel_event (info=0x5633061b0050, event=3, self=0x563304e088c0) at main-dispatcher.c:197 #8 0x00007fa69f6b193b in main_dispatcher_channel_event (self=0x563304e088c0, event=event@entry=3, info=0x5633061b0050) at main-dispatcher.c:197 #9 0x00007fa69f6d0833 in red_stream_push_channel_event (s=s@entry=0x563305ad8f50, event=event@entry=3) at red-stream.c:414 #10 0x00007fa69f6d086b in red_stream_free (s=0x563305ad8f50) at red-stream.c:388 #11 0x00007fa69f6b7ddc in red_channel_client_finalize (object=0x563304df2360) at red-channel-client.c:347 #12 0x00007fa6a56b7fb9 in g_object_unref () at /lib64/libgobject-2.0.so.0 #13 0x00007fa69f6ba212 in red_channel_client_push (rcc=0x563304df2360) at red-channel-client.c:1341 #14 0x00007fa69f68b259 in red_char_device_send_msg_to_client (client=<optimized out>, msg=0x5633059b6310, dev=0x563304e08bc0) at char-device.c:305 #15 0x00007fa69f68b259 in red_char_device_send_msg_to_clients (msg=0x5633059b6310, dev=0x563304e08bc0) at char-device.c:305 #16 0x00007fa69f68b259 in red_char_device_read_from_device (dev=0x563304e08bc0) at char-device.c:353 #17 0x000056330317d01d in spice_chr_write (chr=0x563304cafe20, buf=0x563304cc50b0 "{\"timestamp\": {\"seconds\": 1532944763, \"microseconds\": 326636}, \"event\": \"SHUTDOWN\", \"data\": {\"guest\": false}}\r\n", len=111) at /home/elmarco/src/qq/chardev/spice.c:199 #18 0x00005633034deee7 in qemu_chr_write_buffer (s=0x563304cafe20, buf=0x563304cc50b0 "{\"timestamp\": {\"seconds\": 1532944763, \"microseconds\": 326636}, \"event\": \"SHUTDOWN\", \"data\": {\"guest\": false}}\r\n", len=111, offset=0x7ffc6ab5ea70, write_all=false) at /home/elmarco/src/qq/chardev/char.c:112 #19 0x00005633034df054 in qemu_chr_write (s=0x563304cafe20, buf=0x563304cc50b0 "{\"timestamp\": {\"seconds\": 1532944763, \"microseconds\": 326636}, \"event\": \"SHUTDOWN\", \"data\": {\"guest\": false}}\r\n", len=111, write_all=false) at /home/elmarco/src/qq/chardev/char.c:147 #20 0x00005633034e1e13 in qemu_chr_fe_write (be=0x563304dbb800, buf=0x563304cc50b0 "{\"timestamp\": {\"seconds\": 1532944763, \"microseconds\": 326636}, \"event\": \"SHUTDOWN\", \"data\": {\"guest\": false}}\r\n", len=111) at /home/elmarco/src/qq/chardev/char-fe.c:42 #21 0x0000563302fa6334 in monitor_flush_locked (mon=0x563304dbb800) at /home/elmarco/src/qq/monitor.c:425 #22 0x0000563302fa6520 in monitor_puts (mon=0x563304dbb800, str=0x563305de7e9e "") at /home/elmarco/src/qq/monitor.c:468 #23 0x0000563302fa680c in qmp_send_response (mon=0x563304dbb800, rsp=0x563304df5730) at /home/elmarco/src/qq/monitor.c:517 #24 0x0000563302fa6905 in qmp_queue_response (mon=0x563304dbb800, rsp=0x563304df5730) at /home/elmarco/src/qq/monitor.c:538 #25 0x0000563302fa6b5b in monitor_qapi_event_emit (event=QAPI_EVENT_SHUTDOWN, qdict=0x563304df5730) at /home/elmarco/src/qq/monitor.c:624 #26 0x0000563302fa6c4b in monitor_qapi_event_queue (event=QAPI_EVENT_SHUTDOWN, qdict=0x563304df5730, errp=0x7ffc6ab5ed00) at /home/elmarco/src/qq/monitor.c:649 #27 0x0000563303548cce in qapi_event_send_shutdown (guest=false, errp=0x563303d8d0f0 <error_abort>) at qapi/qapi-events-run-state.c:58 #28 0x000056330313bcd7 in main_loop_should_exit () at /home/elmarco/src/qq/vl.c:1822 #29 0x000056330313bde3 in main_loop () at /home/elmarco/src/qq/vl.c:1862 #30 0x0000563303143781 in main (argc=3, argv=0x7ffc6ab5f068, envp=0x7ffc6ab5f088) at /home/elmarco/src/qq/vl.c:4644 Note that error report is now moved to the first caller, which may receive an error for a recursed event. This is probably fine (95% of callers use &error_abort, the rest have NULL error and ignore it) Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20180731150144.14022-1-marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> [*_no_recurse renamed to *_no_reenter, local variables reordered] Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-07-23monitor: Fix unsafe sharing of @cur_mon among threadsPeter Xu1-1/+1
@cur_mon is null unless the main thread is running monitor code, either HMP code within monitor_read(), or QMP code within monitor_qmp_dispatch(). Use of @cur_mon outside the main thread is therefore unsafe. Most of its uses are in monitor command handlers. These run in the main thread. However, there are also uses hiding elsewhere, such as in error_vprintf(), and thus error_report(), making these functions unsafe outside the main thread. No such unsafe uses are known at this time. Regardless, this is an unnecessary trap. It's an ancient trap, though. More recently, commit cf869d53172 "qmp: support out-of-band (oob) execution" spiced things up: the monitor I/O thread assigns to @cur_mon when executing commands out-of-band. Having two threads save, set and restore @cur_mon without synchronization is definitely unsafe. We can end up with @cur_mon null while the main thread runs monitor code, or non-null while it runs non-monitor code. We could fix this by making the I/O thread not mess with @cur_mon, but that would leave the trap armed and ready. Instead, make @cur_mon thread-local. It's now reliably null unless the thread is running monitor code. Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> [peterx: update subject and commit message written by Markus] Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Peter Xu <peterx@redhat.com> Message-Id: <20180720033451.32710-1-peterx@redhat.com>
2018-07-16monitor: Fix tracepoint crash on JSON syntax errorMarkus Armbruster1-1/+1
When tracepoint handle_qmp_command is enabled, we crash on JSON syntax errors. Broken in commit 1cc37471525. Fix by skipping the tracepoint on JSON syntax error. Before the flawed commit, we skipped it by returning early. Fixes: CID 1394216 Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20180716091012.29510-1-armbru@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com>
2018-07-11monitor: fix double-free of request errorMarc-André Lureau1-0/+1
qmp_error_response() will free the given error. Fix double-free in later qmp_request_free(). Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20180705164201.9853-1-marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Fixes: 1cc37471525d03f963bc71d724f0dc9eab888fc1 Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-07-05Merge remote-tracking branch ↵Peter Maydell1-295/+212
'remotes/armbru/tags/pull-monitor-2018-07-03-v2' into staging Monitor patches for 2018-07-03 # gpg: Signature made Tue 03 Jul 2018 22:20:13 BST # gpg: using RSA key 3870B400EB918653 # 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-monitor-2018-07-03-v2: (32 commits) qapi: Polish command flags documentation in qapi-code-gen.txt monitor: Improve some comments qmp: Clean up capability negotiation after commit 02130314d8c qobject: Let qobject_from_jsonf() fail instead of abort qmp: Switch timestamp_put() to qdict_from_jsonf_nofail() qmp: Add some comments around null responses qmp: Simplify monitor_qmp_respond() qmp: Replace get_qmp_greeting() by qmp_greeting() qmp: Replace monitor_json_emitter{,raw}() by qmp_{queue,send}_response() qmp: Use QDict * instead of QObject * for response objects qmp: De-duplicate error response building qobject: New qdict_from_jsonf_nofail() monitor: Peel off @mon_global wrapper monitor: Rename use_io_thr to use_io_thread qmp: Don't let JSON errors jump the queue qmp: Don't let malformed in-band commands jump the queue tests/qmp-test: Demonstrate QMP errors jumping the queue qmp: Simplify code around monitor_qmp_dispatch_one() qmp: Always free QMPRequest with qmp_request_free() qmp: Revert change to handle_qmp_command tracepoint ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-07-03monitor: Improve some commentsMarkus Armbruster1-55/+45
Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20180703085358.13941-32-armbru@redhat.com>
2018-07-03qmp: Clean up capability negotiation after commit 02130314d8cMarkus Armbruster1-51/+38
qmp_greeting() offers capabilities to the client, and qmp_qmp_capabilities() accepts or denies capabilities requested by the client. The two compute the set of available capabilities independently. Not nice. Clean this up as follows. Compute available capabilities just once in monitor_qmp_caps_reset(), and store them in Monitor member qmp.capab_offered[]. Have qmp_greeting() and qmp_qmp_capabilities() use that. Both are now oblivious of capability details. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20180703085358.13941-31-armbru@redhat.com>
2018-07-03qmp: Simplify monitor_qmp_respond()Markus Armbruster1-16/+10
monitor_qmp_respond() takes both a response object and an error object. If an error object is non-null, the response object must be null, and the response is built from the error object. Of the two callers, one always passes a null response object, and one a null error object. Move building the response object from the error object to the latter, and drop the error object parameter. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20180703085358.13941-27-armbru@redhat.com>
2018-07-03qmp: Replace get_qmp_greeting() by qmp_greeting()Markus Armbruster1-6/+7
get_qmp_greeting() returns a QDict * as QObject *. It's caller converts it right back. Return QDict * instead. While there, rename to qmp_greeting(). Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20180703085358.13941-26-armbru@redhat.com>
2018-07-03qmp: Replace monitor_json_emitter{,raw}() by qmp_{queue,send}_response()Markus Armbruster1-11/+10
monitor_json_emitter() and monitor_json_emitter_raw() are unnecessarily general: they can send arbitrary JSON values, even though we only ever use them for QMP, which may send only JSON objects. Specialize the argument from QObject * to QDict *, and rename to qmp_queue_response(), qmp_send_response(). All callers but one lose an upcast. The lone exception gains a downcast; the next commit will get rid of it. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20180703085358.13941-25-armbru@redhat.com>
2018-07-03qmp: Use QDict * instead of QObject * for response objectsMarkus Armbruster1-15/+16
By using the more specific type, we get fewer downcasts. The downcasts are safe, but not obviously so, at least not locally. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20180703085358.13941-24-armbru@redhat.com>
2018-07-03qmp: De-duplicate error response buildingMarkus Armbruster1-6/+1
All callers of qmp_build_error_object() duplicate the code to wrap it in a response object. Replace it by qmp_error_response() that captures the duplicated code, including error_free(). Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20180703085358.13941-23-armbru@redhat.com>
2018-07-03monitor: Peel off @mon_global wrapperMarkus Armbruster1-31/+29
Wrapping global variables in a struct without a use for the wrapper struct buys us nothing but longer lines. Unwrap them. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20180703085358.13941-21-armbru@redhat.com>
2018-07-03monitor: Rename use_io_thr to use_io_threadMarkus Armbruster1-11/+11
Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20180703085358.13941-20-armbru@redhat.com>
2018-07-03qmp: Don't let JSON errors jump the queueMarkus Armbruster1-8/+15
handle_qmp_command() reports JSON syntax errors right away. This is wrong when OOB is enabled, because the errors can "jump the queue" then. The previous commit fixed the same bug for semantic errors, by delaying the checking until dispatch. We can't delay the checking, so delay the reporting. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20180703085358.13941-19-armbru@redhat.com>
2018-07-03qmp: Don't let malformed in-band commands jump the queueMarkus Armbruster1-61/+18
handle_qmp_command() reports certain errors right away. This is wrong when OOB is enabled, because the errors can "jump the queue" then, as the previous commit demonstrates. To fix, we need to delay errors until dispatch. Do that for semantic errors, mostly by reverting ill-advised parts of commit cf869d53172 "qmp: support out-of-band (oob) execution". Bonus: doesn't run qmp_dispatch_check_obj() twice, once in handle_qmp_command(), and again in do_qmp_dispatch(). That's also due to commit cf869d53172. The next commit will fix queue jumping for syntax errors. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20180703085358.13941-18-armbru@redhat.com>
2018-07-03tests/qmp-test: Demonstrate QMP errors jumping the queueMarkus Armbruster1-0/+1
When OOB is enabled, out-of-band commands are executed right away, everything else is queued. This lets out-of-band commands "jump the queue". However, certain errors are always reported right away, and therefore can jump the queue even when the erroneous input does not request out-of-band execution. These errors are pretty unlikely to occur in production, but it's wrong all the same. Mark FIXME. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com> Message-Id: <20180703085358.13941-17-armbru@redhat.com>
2018-07-03qmp: Simplify code around monitor_qmp_dispatch_one()Markus Armbruster1-34/+24
Change monitor_qmp_dispatch_one() to take its parameters unwrapped, move monitor_resume() to the one caller that needs it, rename the function to monitor_qmp_dispatch(). Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20180703085358.13941-16-armbru@redhat.com>
2018-07-03qmp: Always free QMPRequest with qmp_request_free()Markus Armbruster1-4/+2
monitor_qmp_dispatch_one() frees a QMPRequest manually, because it needs to keep a reference to ->id. Premature optimization. Take an additional reference so we can use qmp_request_free(). Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20180703085358.13941-15-armbru@redhat.com>
2018-07-03qmp: Revert change to handle_qmp_command tracepointMarkus Armbruster1-6/+6
Commit 71da4667db6 "monitor: separate QMP parser and dispatcher" moved the handle_qmp_command tracepoint from handle_qmp_command() to monitor_qmp_dispatch_one(). This delays tracing from enqueue time to dequeue time. Revert that. Dequeue remains adequately visible via tracepoint monitor_qmp_cmd_in_band. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20180703085358.13941-14-armbru@redhat.com>
2018-07-03qmp: Redo how the client requests out-of-band executionMarkus Armbruster1-0/+3
Commit cf869d53172 "qmp: support out-of-band (oob) execution" added a general mechanism for command-independent arguments just for an out-of-band flag: The "control" key is introduced to store this extra flag. "control" field is used to store arguments that are shared by all the commands, rather than command specific arguments. Let "run-oob" be the first. However, it failed to reject unknown members of "control". For instance, in QMP command {"execute": "query-name", "id": 42, "control": {"crap": true}} "crap" gets silently ignored. Instead of fixing this, revert the general "control" mechanism (because YAGNI), and do it the way I initially proposed, with key "exec-oob". Simpler code, simpler interface. An out-of-band command {"execute": "migrate-pause", "id": 42, "control": {"run-oob": true}} becomes {"exec-oob": "migrate-pause", "id": 42} Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20180703085358.13941-13-armbru@redhat.com> [Commit message typo fixed]
2018-07-03qmp qemu-ga: Fix qemu-ga not to accept "control"Markus Armbruster1-7/+2
Commit cf869d53172 "qmp: support out-of-band (oob) execution" accidentally made qemu-ga accept and ignore "control". Fix that. Out-of-band execution in a monitor that doesn't support it now fails with {"error": {"class": "GenericError", "desc": "QMP input member 'control' is unexpected"}} instead of {"error": {"class": "GenericError", "desc": "Please enable out-of-band first for the session during capabilities negotiation"}} The old description is suboptimal when out-of-band cannot not be enabled, or the command doesn't support out-of-band execution. The new description is a bit unspecific, but it'll do. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20180703085358.13941-12-armbru@redhat.com>