blob: 525d8e486dd8a154f6e037f40dfe5d0edcdfb500 [file] [log] [blame]
bellard9dc39cb2004-03-14 21:38:27 +00001/*
2 * QEMU monitor
ths5fafdf22007-09-16 21:08:06 +00003 *
bellard9dc39cb2004-03-14 21:38:27 +00004 * Copyright (c) 2003-2004 Fabrice Bellard
ths5fafdf22007-09-16 21:08:06 +00005 *
bellard9dc39cb2004-03-14 21:38:27 +00006 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
blueswir1511d2b12009-03-07 15:32:56 +000024#include <dirent.h>
pbrook87ecb682007-11-17 17:14:51 +000025#include "hw/hw.h"
Paolo Bonzinib4a42f82013-02-04 11:37:52 +010026#include "monitor/qdev.h"
pbrook87ecb682007-11-17 17:14:51 +000027#include "hw/usb.h"
Paolo Bonzini0d09e412013-02-05 17:06:20 +010028#include "hw/i386/pc.h"
Michael S. Tsirkina2cb15b2012-12-12 14:24:50 +020029#include "hw/pci/pci.h"
Paolo Bonzini0d09e412013-02-05 17:06:20 +010030#include "sysemu/watchdog.h"
Gerd Hoffmann45a50b12009-10-01 16:42:33 +020031#include "hw/loader.h"
Paolo Bonzini022c62c2012-12-17 18:19:49 +010032#include "exec/gdbstub.h"
Paolo Bonzini1422e322012-10-24 08:43:34 +020033#include "net/net.h"
Mark McLoughlin68ac40d2009-11-25 18:48:54 +000034#include "net/slirp.h"
Paolo Bonzinidccfcd02013-04-08 16:55:25 +020035#include "sysemu/char.h"
Gerd Hoffmann75721502010-10-07 12:22:54 +020036#include "ui/qemu-spice.h"
Paolo Bonzini9c17d612012-12-17 18:20:04 +010037#include "sysemu/sysemu.h"
Eduardo Habkoste35704b2015-02-08 16:51:16 -020038#include "sysemu/numa.h"
Paolo Bonzini83c90892012-12-17 18:19:49 +010039#include "monitor/monitor.h"
Stefan Hajnoczi0150cd82013-11-14 11:54:15 +010040#include "qemu/readline.h"
Paolo Bonzini28ecbae2012-11-28 12:06:30 +010041#include "ui/console.h"
Gerd Hoffmannc751a742013-12-04 15:02:28 +010042#include "ui/input.h"
Paolo Bonzini9c17d612012-12-17 18:20:04 +010043#include "sysemu/blockdev.h"
pbrook87ecb682007-11-17 17:14:51 +000044#include "audio/audio.h"
Paolo Bonzini76cad712012-10-24 11:12:21 +020045#include "disas/disas.h"
Paolo Bonzini9c17d612012-12-17 18:20:04 +010046#include "sysemu/balloon.h"
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010047#include "qemu/timer.h"
Paolo Bonzinicaf71f82012-12-17 18:19:50 +010048#include "migration/migration.h"
Paolo Bonzini9c17d612012-12-17 18:20:04 +010049#include "sysemu/kvm.h"
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010050#include "qemu/acl.h"
Paolo Bonzinibdee56f2013-04-02 18:28:41 +020051#include "sysemu/tpm.h"
Markus Armbrustercc7a8ea2015-03-17 17:22:46 +010052#include "qapi/qmp/qerror.h"
Paolo Bonzini7b1b5d12012-12-17 18:19:43 +010053#include "qapi/qmp/qint.h"
54#include "qapi/qmp/qfloat.h"
55#include "qapi/qmp/qlist.h"
56#include "qapi/qmp/qbool.h"
57#include "qapi/qmp/qstring.h"
58#include "qapi/qmp/qjson.h"
59#include "qapi/qmp/json-streamer.h"
60#include "qapi/qmp/json-parser.h"
Hani Benhabiles1094fd32014-02-06 23:30:13 +010061#include <qom/object_interfaces.h>
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010062#include "qemu/osdep.h"
Blue Swirl2b41f102011-06-19 20:38:22 +000063#include "cpu.h"
Stefan Hajnoczi89bd8202011-09-23 08:23:06 +010064#include "trace.h"
Lluís31965ae2011-08-31 20:31:24 +020065#include "trace/control.h"
Pavel Butsykinbf957282015-09-10 18:38:59 +030066#include "monitor/hmp-target.h"
Lluís6d8a7642011-08-31 20:30:43 +020067#ifdef CONFIG_TRACE_SIMPLE
Lluís31965ae2011-08-31 20:31:24 +020068#include "trace/simple.h"
Prerna Saxena22890ab2010-06-24 17:04:53 +053069#endif
Paolo Bonzini022c62c2012-12-17 18:19:49 +010070#include "exec/memory.h"
Anthony Liguori48a32be2011-09-02 12:34:48 -050071#include "qmp-commands.h"
72#include "hmp.h"
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010073#include "qemu/thread.h"
Hani Benhabilesb21631f2014-05-27 23:39:37 +010074#include "block/qapi.h"
Wenchao Xia43a14cf2014-06-18 08:43:31 +020075#include "qapi/qmp-event.h"
76#include "qapi-event.h"
Markus Armbruster39a18152015-09-16 13:06:28 +020077#include "qmp-introspect.h"
Fam Zheng55606252015-03-02 19:36:46 +080078#include "sysemu/block-backend.h"
ths6a5bd302007-12-03 17:05:38 +000079
Markus Armbruster1ce6be22015-02-06 14:18:24 +010080/* for hmp_info_irq/pic */
Jan Kiszka661f1922011-10-16 11:53:13 +020081#if defined(TARGET_SPARC)
Paolo Bonzini0d09e412013-02-05 17:06:20 +010082#include "hw/sparc/sun4m.h"
Jan Kiszka661f1922011-10-16 11:53:13 +020083#endif
Paolo Bonzini0d09e412013-02-05 17:06:20 +010084#include "hw/lm32/lm32_pic.h"
Jan Kiszka661f1922011-10-16 11:53:13 +020085
Jason J. Hernea4538a52015-06-26 14:07:21 -040086#if defined(TARGET_S390X)
87#include "hw/s390x/storage-keys.h"
88#endif
89
bellard9307c4c2004-04-04 12:57:25 +000090/*
91 * Supported types:
ths5fafdf22007-09-16 21:08:06 +000092 *
bellard9307c4c2004-04-04 12:57:25 +000093 * 'F' filename
bellard81d09122004-07-14 17:21:37 +000094 * 'B' block device name
bellard9307c4c2004-04-04 12:57:25 +000095 * 's' string (accept optional quote)
Wenchao Xia129be002013-08-27 20:38:26 +080096 * 'S' it just appends the rest of the string (accept optional quote)
Markus Armbruster361127d2010-02-10 20:24:35 +010097 * 'O' option string of the form NAME=VALUE,...
98 * parsed according to QemuOptsList given by its name
99 * Example: 'device:O' uses qemu_device_opts.
100 * Restriction: only lists with empty desc are supported
101 * TODO lift the restriction
bellard92a31b12005-02-10 22:00:52 +0000102 * 'i' 32 bit integer
103 * 'l' target long (32 or 64 bit)
Luiz Capitulino91162842012-04-26 17:34:30 -0300104 * 'M' Non-negative target long (32 or 64 bit), in user mode the
105 * value is multiplied by 2^20 (think Mebibyte)
Jes Sorensendbc0c672010-10-21 17:15:47 +0200106 * 'o' octets (aka bytes)
Kevin Wolf5e009842013-06-05 14:19:27 +0200107 * user mode accepts an optional E, e, P, p, T, t, G, g, M, m,
108 * K, k suffix, which multiplies the value by 2^60 for suffixes E
109 * and e, 2^50 for suffixes P and p, 2^40 for suffixes T and t,
110 * 2^30 for suffixes G and g, 2^20 for M and m, 2^10 for K and k
Markus Armbrusterfccfb11e2010-01-25 14:23:06 +0100111 * 'T' double
112 * user mode accepts an optional ms, us, ns suffix,
113 * which divides the value by 1e3, 1e6, 1e9, respectively
bellard9307c4c2004-04-04 12:57:25 +0000114 * '/' optional gdb-like print format (like "/10x")
115 *
Luiz Capitulinofb466602009-08-28 15:27:27 -0300116 * '?' optional type (for all types, except '/')
117 * '.' other form of optional type (for 'i' and 'l')
Markus Armbruster942cd1f2010-03-26 09:07:09 +0100118 * 'b' boolean
119 * user mode accepts "on" or "off"
Luiz Capitulinofb466602009-08-28 15:27:27 -0300120 * '-' optional parameter (eg. '-f')
bellard9307c4c2004-04-04 12:57:25 +0000121 *
122 */
123
Anthony Liguoric227f092009-10-01 16:12:16 -0500124typedef struct mon_cmd_t {
bellard9dc39cb2004-03-14 21:38:27 +0000125 const char *name;
bellard9307c4c2004-04-04 12:57:25 +0000126 const char *args_type;
bellard9dc39cb2004-03-14 21:38:27 +0000127 const char *params;
128 const char *help;
Luiz Capitulino910df892009-10-07 13:41:51 -0300129 union {
Luiz Capitulinoaf4ce882009-10-07 13:41:52 -0300130 void (*cmd)(Monitor *mon, const QDict *qdict);
Markus Armbruster485febc2015-03-13 17:25:50 +0100131 void (*cmd_new)(QDict *params, QObject **ret_data, Error **errp);
Luiz Capitulino910df892009-10-07 13:41:51 -0300132 } mhandler;
Wenchao Xia5f3d3352013-01-14 14:06:27 +0800133 /* @sub_table is a list of 2nd level of commands. If it do not exist,
134 * mhandler should be used. If it exist, sub_table[?].mhandler should be
135 * used, and mhandler of 1st level plays the role of help function.
136 */
137 struct mon_cmd_t *sub_table;
Hani Benhabilesbfa40f72014-04-13 16:25:06 +0100138 void (*command_completion)(ReadLineState *rs, int nb_args, const char *str);
Anthony Liguoric227f092009-10-01 16:12:16 -0500139} mon_cmd_t;
bellard9dc39cb2004-03-14 21:38:27 +0000140
Mark McLoughlinf07918f2009-07-22 09:11:40 +0100141/* file descriptors passed via SCM_RIGHTS */
Anthony Liguoric227f092009-10-01 16:12:16 -0500142typedef struct mon_fd_t mon_fd_t;
143struct mon_fd_t {
Mark McLoughlinf07918f2009-07-22 09:11:40 +0100144 char *name;
145 int fd;
Anthony Liguoric227f092009-10-01 16:12:16 -0500146 QLIST_ENTRY(mon_fd_t) next;
Mark McLoughlinf07918f2009-07-22 09:11:40 +0100147};
148
Corey Bryantba1c0482012-08-14 16:43:43 -0400149/* file descriptor associated with a file descriptor set */
150typedef struct MonFdsetFd MonFdsetFd;
151struct MonFdsetFd {
152 int fd;
153 bool removed;
154 char *opaque;
155 QLIST_ENTRY(MonFdsetFd) next;
156};
157
158/* file descriptor set containing fds passed via SCM_RIGHTS */
159typedef struct MonFdset MonFdset;
160struct MonFdset {
161 int64_t id;
162 QLIST_HEAD(, MonFdsetFd) fds;
Corey Bryantadb696f2012-08-14 16:43:47 -0400163 QLIST_HEAD(, MonFdsetFd) dup_fds;
Corey Bryantba1c0482012-08-14 16:43:43 -0400164 QLIST_ENTRY(MonFdset) next;
165};
166
Markus Armbruster74358f22015-03-06 19:35:59 +0100167typedef struct {
Luiz Capitulino5fa737a2009-11-26 22:59:01 -0200168 QObject *id;
169 JSONMessageParser parser;
Markus Armbrusterf994b252015-03-06 19:51:51 +0100170 /*
171 * When a client connects, we're in capabilities negotiation mode.
172 * When command qmp_capabilities succeeds, we go into command
173 * mode.
174 */
175 bool in_command_mode; /* are we in command mode? */
Markus Armbruster74358f22015-03-06 19:35:59 +0100176} MonitorQMP;
Luiz Capitulino5fa737a2009-11-26 22:59:01 -0200177
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100178/*
179 * To prevent flooding clients, events can be throttled. The
180 * throttling is calculated globally, rather than per-Monitor
181 * instance.
182 */
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200183typedef struct MonitorQAPIEventState {
184 QAPIEvent event; /* Event being tracked */
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100185 QEMUTimer *timer; /* Timer for handling delayed events */
Markus Armbruster688b4b72015-10-15 17:08:30 +0200186 QDict *qdict; /* Delayed event (if any) */
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200187} MonitorQAPIEventState;
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100188
Markus Armbrusterb9b03ab2015-10-15 17:08:33 +0200189typedef struct {
190 int64_t rate; /* Minimum time (in ns) between two events */
191} MonitorQAPIEventConf;
192
aliguori87127162009-03-05 23:01:29 +0000193struct Monitor {
194 CharDriverState *chr;
Gerd Hoffmanna7aec5d2009-09-10 10:58:54 +0200195 int reset_seen;
aliguori731b0362009-03-05 23:01:42 +0000196 int flags;
197 int suspend_cnt;
Luiz Capitulino48c043d2013-04-02 15:07:33 -0400198 bool skip_flush;
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200199
200 QemuMutex out_lock;
Luiz Capitulinoe1f26412013-03-25 13:52:26 -0400201 QString *outbuf;
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200202 guint out_watch;
203
204 /* Read under either BQL or out_lock, written with BQL+out_lock. */
205 int mux_out;
206
aliguori731b0362009-03-05 23:01:42 +0000207 ReadLineState *rs;
Markus Armbruster74358f22015-03-06 19:35:59 +0100208 MonitorQMP qmp;
Andreas Färbercb446ec2013-05-01 14:24:52 +0200209 CPUState *mon_cpu;
Markus Armbruster097310b2014-10-07 13:59:15 +0200210 BlockCompletionFunc *password_completion_cb;
aliguori731b0362009-03-05 23:01:42 +0000211 void *password_opaque;
Wenchao Xia77172392013-08-27 20:38:20 +0800212 mon_cmd_t *cmd_table;
Anthony Liguoric227f092009-10-01 16:12:16 -0500213 QLIST_HEAD(,mon_fd_t) fds;
Blue Swirl72cf2d42009-09-12 07:36:22 +0000214 QLIST_ENTRY(Monitor) entry;
aliguori87127162009-03-05 23:01:29 +0000215};
216
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -0300217/* QMP checker flags */
218#define QMP_ACCEPT_UNKNOWNS 1
219
Paolo Bonzinid622cb52014-06-18 08:44:00 +0200220/* Protects mon_list, monitor_event_state. */
221static QemuMutex monitor_lock;
222
Blue Swirl72cf2d42009-09-12 07:36:22 +0000223static QLIST_HEAD(mon_list, Monitor) mon_list;
Corey Bryantba1c0482012-08-14 16:43:43 -0400224static QLIST_HEAD(mon_fdsets, MonFdset) mon_fdsets;
Corey Bryantefb87c12012-08-14 16:43:48 -0400225static int mon_refcount;
bellard7e2515e2004-08-01 21:52:19 +0000226
Wayne Xia816f8922011-10-12 11:32:41 +0800227static mon_cmd_t mon_cmds[];
228static mon_cmd_t info_cmds[];
bellard9dc39cb2004-03-14 21:38:27 +0000229
Luiz Capitulinof36b4af2010-09-15 17:17:45 -0300230static const mon_cmd_t qmp_cmds[];
231
Markus Armbruster8631b602010-02-18 11:41:55 +0100232Monitor *cur_mon;
aliguori376253e2009-03-05 23:01:23 +0000233
Stefan Hajnoczic60bf332013-11-14 11:54:14 +0100234static void monitor_command_cb(void *opaque, const char *cmdline,
235 void *readline_opaque);
aliguori83ab7952008-08-19 14:44:22 +0000236
Markus Armbruster9f3982f2015-03-06 19:56:38 +0100237/**
238 * Is @mon a QMP monitor?
239 */
240static inline bool monitor_is_qmp(const Monitor *mon)
Luiz Capitulino418173c2009-11-26 22:58:51 -0200241{
242 return (mon->flags & MONITOR_USE_CONTROL);
243}
244
Markus Armbruster489653b2015-03-06 20:01:05 +0100245/**
246 * Is the current monitor, if any, a QMP monitor?
247 */
248bool monitor_cur_is_qmp(void)
Markus Armbruster6620d3c2010-02-11 17:05:43 +0100249{
Markus Armbruster9f3982f2015-03-06 19:56:38 +0100250 return cur_mon && monitor_is_qmp(cur_mon);
Markus Armbruster6620d3c2010-02-11 17:05:43 +0100251}
252
Anthony Liguori7060b472011-09-02 12:34:50 -0500253void monitor_read_command(Monitor *mon, int show_prompt)
aliguori731b0362009-03-05 23:01:42 +0000254{
Luiz Capitulino183e6e52009-12-14 18:53:23 -0200255 if (!mon->rs)
256 return;
257
aliguori731b0362009-03-05 23:01:42 +0000258 readline_start(mon->rs, "(qemu) ", 0, monitor_command_cb, NULL);
259 if (show_prompt)
260 readline_show_prompt(mon->rs);
261}
bellard6a00d602005-11-21 23:25:50 +0000262
Anthony Liguori7060b472011-09-02 12:34:50 -0500263int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
264 void *opaque)
aliguoribb5fc202009-03-05 23:01:15 +0000265{
Markus Armbrusterbcf5d192015-03-12 17:26:46 +0100266 if (mon->rs) {
aliguoricde76ee2009-03-05 23:01:51 +0000267 readline_start(mon->rs, "Password: ", 1, readline_func, opaque);
268 /* prompt is printed on return from the command handler */
269 return 0;
270 } else {
271 monitor_printf(mon, "terminal does not support password prompting\n");
272 return -ENOTTY;
273 }
aliguoribb5fc202009-03-05 23:01:15 +0000274}
275
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200276static void monitor_flush_locked(Monitor *mon);
277
Gerd Hoffmannf6289262013-03-19 10:57:56 +0100278static gboolean monitor_unblocked(GIOChannel *chan, GIOCondition cond,
279 void *opaque)
280{
Laszlo Ersek293d2a02013-07-16 20:19:41 +0200281 Monitor *mon = opaque;
282
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200283 qemu_mutex_lock(&mon->out_lock);
284 mon->out_watch = 0;
285 monitor_flush_locked(mon);
286 qemu_mutex_unlock(&mon->out_lock);
Gerd Hoffmannf6289262013-03-19 10:57:56 +0100287 return FALSE;
288}
289
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200290/* Called with mon->out_lock held. */
291static void monitor_flush_locked(Monitor *mon)
bellard9dc39cb2004-03-14 21:38:27 +0000292{
Gerd Hoffmannf6289262013-03-19 10:57:56 +0100293 int rc;
Luiz Capitulinoe1f26412013-03-25 13:52:26 -0400294 size_t len;
295 const char *buf;
Gerd Hoffmannf6289262013-03-19 10:57:56 +0100296
Luiz Capitulino48c043d2013-04-02 15:07:33 -0400297 if (mon->skip_flush) {
298 return;
299 }
300
Luiz Capitulinoe1f26412013-03-25 13:52:26 -0400301 buf = qstring_get_str(mon->outbuf);
302 len = qstring_get_length(mon->outbuf);
303
Paolo Bonzinia4cc73d2013-05-31 14:00:27 +0200304 if (len && !mon->mux_out) {
Luiz Capitulinoe1f26412013-03-25 13:52:26 -0400305 rc = qemu_chr_fe_write(mon->chr, (const uint8_t *) buf, len);
Stratos Psomadakis056f49f2014-01-27 12:30:15 +0200306 if ((rc < 0 && errno != EAGAIN) || (rc == len)) {
307 /* all flushed or error */
Luiz Capitulinoe1f26412013-03-25 13:52:26 -0400308 QDECREF(mon->outbuf);
309 mon->outbuf = qstring_new();
Gerd Hoffmannf6289262013-03-19 10:57:56 +0100310 return;
311 }
312 if (rc > 0) {
313 /* partinal write */
Luiz Capitulinoe1f26412013-03-25 13:52:26 -0400314 QString *tmp = qstring_from_str(buf + rc);
315 QDECREF(mon->outbuf);
316 mon->outbuf = tmp;
Gerd Hoffmannf6289262013-03-19 10:57:56 +0100317 }
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200318 if (mon->out_watch == 0) {
Roger Pau Monnee02bc6d2014-05-23 17:57:49 +0200319 mon->out_watch = qemu_chr_fe_add_watch(mon->chr, G_IO_OUT|G_IO_HUP,
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200320 monitor_unblocked, mon);
Laszlo Ersek293d2a02013-07-16 20:19:41 +0200321 }
bellard7e2515e2004-08-01 21:52:19 +0000322 }
323}
324
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200325void monitor_flush(Monitor *mon)
326{
327 qemu_mutex_lock(&mon->out_lock);
328 monitor_flush_locked(mon);
329 qemu_mutex_unlock(&mon->out_lock);
330}
331
Luiz Capitulinoe1f26412013-03-25 13:52:26 -0400332/* flush at every end of line */
aliguori376253e2009-03-05 23:01:23 +0000333static void monitor_puts(Monitor *mon, const char *str)
bellard7e2515e2004-08-01 21:52:19 +0000334{
ths60fe76f2007-12-16 03:02:09 +0000335 char c;
aliguori731b0362009-03-05 23:01:42 +0000336
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200337 qemu_mutex_lock(&mon->out_lock);
bellard7e2515e2004-08-01 21:52:19 +0000338 for(;;) {
339 c = *str++;
340 if (c == '\0')
341 break;
Luiz Capitulinoe1f26412013-03-25 13:52:26 -0400342 if (c == '\n') {
343 qstring_append_chr(mon->outbuf, '\r');
344 }
345 qstring_append_chr(mon->outbuf, c);
346 if (c == '\n') {
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200347 monitor_flush_locked(mon);
Luiz Capitulinoe1f26412013-03-25 13:52:26 -0400348 }
bellard7e2515e2004-08-01 21:52:19 +0000349 }
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200350 qemu_mutex_unlock(&mon->out_lock);
bellard7e2515e2004-08-01 21:52:19 +0000351}
352
aliguori376253e2009-03-05 23:01:23 +0000353void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
bellard7e2515e2004-08-01 21:52:19 +0000354{
Luiz Capitulinoe1f26412013-03-25 13:52:26 -0400355 char *buf;
Luiz Capitulinob8b08262010-02-10 23:50:04 -0200356
Luiz Capitulino2daa1192009-12-14 18:53:24 -0200357 if (!mon)
358 return;
359
Markus Armbruster9f3982f2015-03-06 19:56:38 +0100360 if (monitor_is_qmp(mon)) {
Luiz Capitulinob8b08262010-02-10 23:50:04 -0200361 return;
Luiz Capitulino4a29a852009-11-26 22:59:05 -0200362 }
Luiz Capitulinob8b08262010-02-10 23:50:04 -0200363
Luiz Capitulinoe1f26412013-03-25 13:52:26 -0400364 buf = g_strdup_vprintf(fmt, ap);
Luiz Capitulinob8b08262010-02-10 23:50:04 -0200365 monitor_puts(mon, buf);
Luiz Capitulinoe1f26412013-03-25 13:52:26 -0400366 g_free(buf);
bellard7e2515e2004-08-01 21:52:19 +0000367}
368
aliguori376253e2009-03-05 23:01:23 +0000369void monitor_printf(Monitor *mon, const char *fmt, ...)
bellard7e2515e2004-08-01 21:52:19 +0000370{
371 va_list ap;
372 va_start(ap, fmt);
aliguori376253e2009-03-05 23:01:23 +0000373 monitor_vprintf(mon, fmt, ap);
bellard7e2515e2004-08-01 21:52:19 +0000374 va_end(ap);
bellard9dc39cb2004-03-14 21:38:27 +0000375}
376
Pavel Butsykincaf15312015-09-22 16:18:17 +0300377int monitor_fprintf(FILE *stream, const char *fmt, ...)
bellard7fe48482004-10-09 18:08:01 +0000378{
379 va_list ap;
380 va_start(ap, fmt);
aliguori376253e2009-03-05 23:01:23 +0000381 monitor_vprintf((Monitor *)stream, fmt, ap);
bellard7fe48482004-10-09 18:08:01 +0000382 va_end(ap);
383 return 0;
384}
385
Luiz Capitulino9b57c022009-11-26 22:58:58 -0200386static void monitor_json_emitter(Monitor *mon, const QObject *data)
387{
388 QString *json;
389
Luiz Capitulino83a27d42010-11-22 17:10:37 -0200390 json = mon->flags & MONITOR_USE_PRETTY ? qobject_to_json_pretty(data) :
391 qobject_to_json(data);
Luiz Capitulino9b57c022009-11-26 22:58:58 -0200392 assert(json != NULL);
393
Luiz Capitulinob8b08262010-02-10 23:50:04 -0200394 qstring_append_chr(json, '\n');
395 monitor_puts(mon, qstring_get_str(json));
Luiz Capitulino4a29a852009-11-26 22:59:05 -0200396
Luiz Capitulino9b57c022009-11-26 22:58:58 -0200397 QDECREF(json);
398}
399
Markus Armbruster710aec92015-03-06 11:28:00 +0100400static QDict *build_qmp_error_dict(Error *err)
Luiz Capitulinode253f12012-07-27 16:18:16 -0300401{
402 QObject *obj;
403
Markus Armbruster710aec92015-03-06 11:28:00 +0100404 obj = qobject_from_jsonf("{ 'error': { 'class': %s, 'desc': %s } }",
405 ErrorClass_lookup[error_get_class(err)],
406 error_get_pretty(err));
Luiz Capitulinode253f12012-07-27 16:18:16 -0300407
408 return qobject_to_qdict(obj);
409}
410
Markus Armbruster70ea0c52015-03-06 10:47:08 +0100411static void monitor_protocol_emitter(Monitor *mon, QObject *data,
Markus Armbruster710aec92015-03-06 11:28:00 +0100412 Error *err)
Luiz Capitulino25b422e2009-11-26 22:58:59 -0200413{
414 QDict *qmp;
415
Stefan Hajnoczi89bd8202011-09-23 08:23:06 +0100416 trace_monitor_protocol_emitter(mon);
417
Markus Armbruster70ea0c52015-03-06 10:47:08 +0100418 if (!err) {
Luiz Capitulino25b422e2009-11-26 22:58:59 -0200419 /* success response */
Luiz Capitulinode253f12012-07-27 16:18:16 -0300420 qmp = qdict_new();
Luiz Capitulino25b422e2009-11-26 22:58:59 -0200421 if (data) {
422 qobject_incref(data);
423 qdict_put_obj(qmp, "return", data);
424 } else {
Luiz Capitulino0abc6572009-12-18 13:25:00 -0200425 /* return an empty QDict by default */
426 qdict_put(qmp, "return", qdict_new());
Luiz Capitulino25b422e2009-11-26 22:58:59 -0200427 }
428 } else {
429 /* error response */
Markus Armbruster70ea0c52015-03-06 10:47:08 +0100430 qmp = build_qmp_error_dict(err);
Luiz Capitulino25b422e2009-11-26 22:58:59 -0200431 }
432
Markus Armbruster74358f22015-03-06 19:35:59 +0100433 if (mon->qmp.id) {
434 qdict_put_obj(qmp, "id", mon->qmp.id);
435 mon->qmp.id = NULL;
Luiz Capitulino5fa737a2009-11-26 22:59:01 -0200436 }
437
Luiz Capitulino25b422e2009-11-26 22:58:59 -0200438 monitor_json_emitter(mon, QOBJECT(qmp));
439 QDECREF(qmp);
440}
441
Luiz Capitulino0d1ea872009-11-26 22:59:03 -0200442
Markus Armbrusterb9b03ab2015-10-15 17:08:33 +0200443static MonitorQAPIEventConf monitor_qapi_event_conf[QAPI_EVENT_MAX] = {
444 /* Limit guest-triggerable events to 1 per second */
445 [QAPI_EVENT_RTC_CHANGE] = { 1000 * SCALE_MS },
446 [QAPI_EVENT_WATCHDOG] = { 1000 * SCALE_MS },
447 [QAPI_EVENT_BALLOON_CHANGE] = { 1000 * SCALE_MS },
448 [QAPI_EVENT_QUORUM_REPORT_BAD] = { 1000 * SCALE_MS },
449 [QAPI_EVENT_QUORUM_FAILURE] = { 1000 * SCALE_MS },
450 [QAPI_EVENT_VSERPORT_CHANGE] = { 1000 * SCALE_MS },
451};
452
Markus Armbrustera24712a2015-10-15 17:08:34 +0200453GHashTable *monitor_qapi_event_state;
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100454
455/*
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200456 * Emits the event to every monitor instance, @event is only used for trace
Paolo Bonzinid622cb52014-06-18 08:44:00 +0200457 * Called with monitor_lock held.
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100458 */
Markus Armbruster688b4b72015-10-15 17:08:30 +0200459static void monitor_qapi_event_emit(QAPIEvent event, QDict *qdict)
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100460{
461 Monitor *mon;
462
Markus Armbruster688b4b72015-10-15 17:08:30 +0200463 trace_monitor_protocol_event_emit(event, qdict);
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100464 QLIST_FOREACH(mon, &mon_list, entry) {
Markus Armbruster9f3982f2015-03-06 19:56:38 +0100465 if (monitor_is_qmp(mon) && mon->qmp.in_command_mode) {
Markus Armbruster688b4b72015-10-15 17:08:30 +0200466 monitor_json_emitter(mon, QOBJECT(qdict));
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100467 }
468 }
469}
470
Markus Armbrustera24712a2015-10-15 17:08:34 +0200471static void monitor_qapi_event_handler(void *opaque);
472
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100473/*
474 * Queue a new event for emission to Monitor instances,
475 * applying any rate limiting if required.
476 */
477static void
Markus Armbruster688b4b72015-10-15 17:08:30 +0200478monitor_qapi_event_queue(QAPIEvent event, QDict *qdict, Error **errp)
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100479{
Markus Armbrusterb9b03ab2015-10-15 17:08:33 +0200480 MonitorQAPIEventConf *evconf;
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200481 MonitorQAPIEventState *evstate;
Markus Armbruster93f8f982015-10-15 17:08:31 +0200482
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200483 assert(event < QAPI_EVENT_MAX);
Markus Armbrusterb9b03ab2015-10-15 17:08:33 +0200484 evconf = &monitor_qapi_event_conf[event];
Markus Armbrusterb9b03ab2015-10-15 17:08:33 +0200485 trace_monitor_protocol_event_queue(event, qdict, evconf->rate);
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100486
Paolo Bonzinid622cb52014-06-18 08:44:00 +0200487 qemu_mutex_lock(&monitor_lock);
Markus Armbruster93f8f982015-10-15 17:08:31 +0200488
Markus Armbrusterb9b03ab2015-10-15 17:08:33 +0200489 if (!evconf->rate) {
Markus Armbruster93f8f982015-10-15 17:08:31 +0200490 /* Unthrottled event */
Markus Armbruster688b4b72015-10-15 17:08:30 +0200491 monitor_qapi_event_emit(event, qdict);
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100492 } else {
Markus Armbrustera24712a2015-10-15 17:08:34 +0200493 MonitorQAPIEventState key = { .event = event };
494
495 evstate = g_hash_table_lookup(monitor_qapi_event_state, &key);
496 assert(!evstate || timer_pending(evstate->timer));
497
498 if (evstate) {
Markus Armbruster93f8f982015-10-15 17:08:31 +0200499 /*
Markus Armbrusterb9b03ab2015-10-15 17:08:33 +0200500 * Timer is pending for (at least) evconf->rate ns after
Markus Armbruster93f8f982015-10-15 17:08:31 +0200501 * last send. Store event for sending when timer fires,
502 * replacing a prior stored event if any.
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100503 */
Markus Armbruster93f8f982015-10-15 17:08:31 +0200504 QDECREF(evstate->qdict);
Markus Armbruster688b4b72015-10-15 17:08:30 +0200505 evstate->qdict = qdict;
506 QINCREF(evstate->qdict);
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100507 } else {
Markus Armbruster93f8f982015-10-15 17:08:31 +0200508 /*
Markus Armbrusterb9b03ab2015-10-15 17:08:33 +0200509 * Last send was (at least) evconf->rate ns ago.
Markus Armbruster93f8f982015-10-15 17:08:31 +0200510 * Send immediately, and arm the timer to call
Markus Armbrusterb9b03ab2015-10-15 17:08:33 +0200511 * monitor_qapi_event_handler() in evconf->rate ns. Any
Markus Armbruster93f8f982015-10-15 17:08:31 +0200512 * events arriving before then will be delayed until then.
513 */
514 int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
515
Markus Armbruster688b4b72015-10-15 17:08:30 +0200516 monitor_qapi_event_emit(event, qdict);
Markus Armbrustera24712a2015-10-15 17:08:34 +0200517
518 evstate = g_new(MonitorQAPIEventState, 1);
519 evstate->event = event;
520 evstate->qdict = NULL;
521 evstate->timer = timer_new_ns(QEMU_CLOCK_REALTIME,
522 monitor_qapi_event_handler,
523 evstate);
524 g_hash_table_add(monitor_qapi_event_state, evstate);
Markus Armbrusterb9b03ab2015-10-15 17:08:33 +0200525 timer_mod_ns(evstate->timer, now + evconf->rate);
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100526 }
527 }
Markus Armbruster93f8f982015-10-15 17:08:31 +0200528
Paolo Bonzinid622cb52014-06-18 08:44:00 +0200529 qemu_mutex_unlock(&monitor_lock);
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100530}
531
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100532/*
Markus Armbrusterb9b03ab2015-10-15 17:08:33 +0200533 * This function runs evconf->rate ns after sending a throttled
Markus Armbruster93f8f982015-10-15 17:08:31 +0200534 * event.
535 * If another event has since been stored, send it.
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100536 */
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200537static void monitor_qapi_event_handler(void *opaque)
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100538{
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200539 MonitorQAPIEventState *evstate = opaque;
Markus Armbrusterb9b03ab2015-10-15 17:08:33 +0200540 MonitorQAPIEventConf *evconf = &monitor_qapi_event_conf[evstate->event];
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100541
Markus Armbruster93f8f982015-10-15 17:08:31 +0200542 trace_monitor_protocol_event_handler(evstate->event, evstate->qdict);
Paolo Bonzinid622cb52014-06-18 08:44:00 +0200543 qemu_mutex_lock(&monitor_lock);
Markus Armbruster93f8f982015-10-15 17:08:31 +0200544
Markus Armbruster688b4b72015-10-15 17:08:30 +0200545 if (evstate->qdict) {
Markus Armbruster93f8f982015-10-15 17:08:31 +0200546 int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
547
Markus Armbruster688b4b72015-10-15 17:08:30 +0200548 monitor_qapi_event_emit(evstate->event, evstate->qdict);
549 QDECREF(evstate->qdict);
550 evstate->qdict = NULL;
Markus Armbrusterb9b03ab2015-10-15 17:08:33 +0200551 timer_mod_ns(evstate->timer, now + evconf->rate);
Markus Armbrustera24712a2015-10-15 17:08:34 +0200552 } else {
553 g_hash_table_remove(monitor_qapi_event_state, evstate);
554 timer_free(evstate->timer);
555 g_free(evstate);
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100556 }
Markus Armbruster93f8f982015-10-15 17:08:31 +0200557
Paolo Bonzinid622cb52014-06-18 08:44:00 +0200558 qemu_mutex_unlock(&monitor_lock);
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100559}
560
Markus Armbrustera24712a2015-10-15 17:08:34 +0200561static unsigned int qapi_event_throttle_hash(const void *key)
562{
563 const MonitorQAPIEventState *evstate = key;
564
565 return evstate->event * 255;
566}
567
568static gboolean qapi_event_throttle_equal(const void *a, const void *b)
569{
570 const MonitorQAPIEventState *eva = a;
571 const MonitorQAPIEventState *evb = b;
572
573 return eva->event == evb->event;
574}
575
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200576static void monitor_qapi_event_init(void)
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100577{
Markus Armbrustera24712a2015-10-15 17:08:34 +0200578 monitor_qapi_event_state = g_hash_table_new(qapi_event_throttle_hash,
579 qapi_event_throttle_equal);
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200580 qmp_event_set_func_emit(monitor_qapi_event_queue);
Luiz Capitulino0d1ea872009-11-26 22:59:03 -0200581}
582
Markus Armbruster485febc2015-03-13 17:25:50 +0100583static void qmp_capabilities(QDict *params, QObject **ret_data, Error **errp)
Luiz Capitulino4a7e1192010-02-04 18:10:05 -0200584{
Markus Armbruster485febc2015-03-13 17:25:50 +0100585 cur_mon->qmp.in_command_mode = true;
Luiz Capitulino4a7e1192010-02-04 18:10:05 -0200586}
587
Markus Armbruster7ef6cf62015-03-06 19:12:36 +0100588static void handle_hmp_command(Monitor *mon, const char *cmdline);
Luiz Capitulino0268d972010-10-22 10:08:02 -0200589
Wenchao Xiab01fe892013-08-27 20:38:19 +0800590static void monitor_data_init(Monitor *mon)
591{
592 memset(mon, 0, sizeof(Monitor));
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200593 qemu_mutex_init(&mon->out_lock);
Wenchao Xiab01fe892013-08-27 20:38:19 +0800594 mon->outbuf = qstring_new();
Wenchao Xia77172392013-08-27 20:38:20 +0800595 /* Use *mon_cmds by default. */
596 mon->cmd_table = mon_cmds;
Wenchao Xiab01fe892013-08-27 20:38:19 +0800597}
598
599static void monitor_data_destroy(Monitor *mon)
600{
601 QDECREF(mon->outbuf);
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200602 qemu_mutex_destroy(&mon->out_lock);
Wenchao Xiab01fe892013-08-27 20:38:19 +0800603}
604
Luiz Capitulinod51a67b2011-11-25 17:52:45 -0200605char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index,
606 int64_t cpu_index, Error **errp)
Luiz Capitulino0268d972010-10-22 10:08:02 -0200607{
Luiz Capitulinod51a67b2011-11-25 17:52:45 -0200608 char *output = NULL;
Luiz Capitulino0268d972010-10-22 10:08:02 -0200609 Monitor *old_mon, hmp;
Luiz Capitulino0268d972010-10-22 10:08:02 -0200610
Wenchao Xiab01fe892013-08-27 20:38:19 +0800611 monitor_data_init(&hmp);
Luiz Capitulino48c043d2013-04-02 15:07:33 -0400612 hmp.skip_flush = true;
Luiz Capitulino0268d972010-10-22 10:08:02 -0200613
614 old_mon = cur_mon;
615 cur_mon = &hmp;
616
Luiz Capitulinod51a67b2011-11-25 17:52:45 -0200617 if (has_cpu_index) {
618 int ret = monitor_set_cpu(cpu_index);
Luiz Capitulino0268d972010-10-22 10:08:02 -0200619 if (ret < 0) {
620 cur_mon = old_mon;
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +0100621 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index",
622 "a CPU number");
Luiz Capitulino0268d972010-10-22 10:08:02 -0200623 goto out;
624 }
625 }
626
Markus Armbruster7ef6cf62015-03-06 19:12:36 +0100627 handle_hmp_command(&hmp, command_line);
Luiz Capitulino0268d972010-10-22 10:08:02 -0200628 cur_mon = old_mon;
629
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200630 qemu_mutex_lock(&hmp.out_lock);
Luiz Capitulino48c043d2013-04-02 15:07:33 -0400631 if (qstring_get_length(hmp.outbuf) > 0) {
632 output = g_strdup(qstring_get_str(hmp.outbuf));
Luiz Capitulinod51a67b2011-11-25 17:52:45 -0200633 } else {
634 output = g_strdup("");
Luiz Capitulino0268d972010-10-22 10:08:02 -0200635 }
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200636 qemu_mutex_unlock(&hmp.out_lock);
Luiz Capitulino0268d972010-10-22 10:08:02 -0200637
638out:
Wenchao Xiab01fe892013-08-27 20:38:19 +0800639 monitor_data_destroy(&hmp);
Luiz Capitulinod51a67b2011-11-25 17:52:45 -0200640 return output;
Luiz Capitulino0268d972010-10-22 10:08:02 -0200641}
642
bellard9dc39cb2004-03-14 21:38:27 +0000643static int compare_cmd(const char *name, const char *list)
644{
645 const char *p, *pstart;
646 int len;
647 len = strlen(name);
648 p = list;
649 for(;;) {
650 pstart = p;
651 p = strchr(p, '|');
652 if (!p)
653 p = pstart + strlen(pstart);
654 if ((p - pstart) == len && !memcmp(pstart, name, len))
655 return 1;
656 if (*p == '\0')
657 break;
658 p++;
659 }
660 return 0;
661}
662
Wenchao Xiaf5438c02013-08-27 20:38:21 +0800663static int get_str(char *buf, int buf_size, const char **pp)
664{
665 const char *p;
666 char *q;
667 int c;
668
669 q = buf;
670 p = *pp;
671 while (qemu_isspace(*p)) {
672 p++;
673 }
674 if (*p == '\0') {
675 fail:
676 *q = '\0';
677 *pp = p;
678 return -1;
679 }
680 if (*p == '\"') {
681 p++;
682 while (*p != '\0' && *p != '\"') {
683 if (*p == '\\') {
684 p++;
685 c = *p++;
686 switch (c) {
687 case 'n':
688 c = '\n';
689 break;
690 case 'r':
691 c = '\r';
692 break;
693 case '\\':
694 case '\'':
695 case '\"':
696 break;
697 default:
Peter Maydell71baf782015-08-19 16:20:19 +0100698 printf("unsupported escape code: '\\%c'\n", c);
Wenchao Xiaf5438c02013-08-27 20:38:21 +0800699 goto fail;
700 }
701 if ((q - buf) < buf_size - 1) {
702 *q++ = c;
703 }
704 } else {
705 if ((q - buf) < buf_size - 1) {
706 *q++ = *p;
707 }
708 p++;
709 }
710 }
711 if (*p != '\"') {
Peter Maydell71baf782015-08-19 16:20:19 +0100712 printf("unterminated string\n");
Wenchao Xiaf5438c02013-08-27 20:38:21 +0800713 goto fail;
714 }
715 p++;
716 } else {
717 while (*p != '\0' && !qemu_isspace(*p)) {
718 if ((q - buf) < buf_size - 1) {
719 *q++ = *p;
720 }
721 p++;
722 }
723 }
724 *q = '\0';
725 *pp = p;
726 return 0;
727}
728
729#define MAX_ARGS 16
730
Wenchao Xiadcc70cd2013-08-27 20:38:22 +0800731static void free_cmdline_args(char **args, int nb_args)
732{
733 int i;
734
735 assert(nb_args <= MAX_ARGS);
736
737 for (i = 0; i < nb_args; i++) {
738 g_free(args[i]);
739 }
740
741}
742
743/*
744 * Parse the command line to get valid args.
745 * @cmdline: command line to be parsed.
746 * @pnb_args: location to store the number of args, must NOT be NULL.
747 * @args: location to store the args, which should be freed by caller, must
748 * NOT be NULL.
749 *
750 * Returns 0 on success, negative on failure.
751 *
752 * NOTE: this parser is an approximate form of the real command parser. Number
753 * of args have a limit of MAX_ARGS. If cmdline contains more, it will
754 * return with failure.
755 */
756static int parse_cmdline(const char *cmdline,
757 int *pnb_args, char **args)
Wenchao Xiaf5438c02013-08-27 20:38:21 +0800758{
759 const char *p;
760 int nb_args, ret;
761 char buf[1024];
762
763 p = cmdline;
764 nb_args = 0;
765 for (;;) {
766 while (qemu_isspace(*p)) {
767 p++;
768 }
769 if (*p == '\0') {
770 break;
771 }
772 if (nb_args >= MAX_ARGS) {
Wenchao Xiadcc70cd2013-08-27 20:38:22 +0800773 goto fail;
Wenchao Xiaf5438c02013-08-27 20:38:21 +0800774 }
775 ret = get_str(buf, sizeof(buf), &p);
Wenchao Xiadcc70cd2013-08-27 20:38:22 +0800776 if (ret < 0) {
777 goto fail;
778 }
Wenchao Xiaf5438c02013-08-27 20:38:21 +0800779 args[nb_args] = g_strdup(buf);
780 nb_args++;
Wenchao Xiaf5438c02013-08-27 20:38:21 +0800781 }
782 *pnb_args = nb_args;
Wenchao Xiadcc70cd2013-08-27 20:38:22 +0800783 return 0;
784
785 fail:
786 free_cmdline_args(args, nb_args);
787 return -1;
Wenchao Xiaf5438c02013-08-27 20:38:21 +0800788}
789
Wenchao Xia66855492013-08-27 20:38:23 +0800790static void help_cmd_dump_one(Monitor *mon,
791 const mon_cmd_t *cmd,
792 char **prefix_args,
793 int prefix_args_nb)
794{
795 int i;
796
797 for (i = 0; i < prefix_args_nb; i++) {
798 monitor_printf(mon, "%s ", prefix_args[i]);
799 }
800 monitor_printf(mon, "%s %s -- %s\n", cmd->name, cmd->params, cmd->help);
801}
802
803/* @args[@arg_index] is the valid command need to find in @cmds */
Anthony Liguoric227f092009-10-01 16:12:16 -0500804static void help_cmd_dump(Monitor *mon, const mon_cmd_t *cmds,
Wenchao Xia66855492013-08-27 20:38:23 +0800805 char **args, int nb_args, int arg_index)
bellard9dc39cb2004-03-14 21:38:27 +0000806{
Anthony Liguoric227f092009-10-01 16:12:16 -0500807 const mon_cmd_t *cmd;
bellard9dc39cb2004-03-14 21:38:27 +0000808
Wenchao Xia66855492013-08-27 20:38:23 +0800809 /* No valid arg need to compare with, dump all in *cmds */
810 if (arg_index >= nb_args) {
811 for (cmd = cmds; cmd->name != NULL; cmd++) {
812 help_cmd_dump_one(mon, cmd, args, arg_index);
813 }
814 return;
815 }
816
817 /* Find one entry to dump */
818 for (cmd = cmds; cmd->name != NULL; cmd++) {
819 if (compare_cmd(args[arg_index], cmd->name)) {
820 if (cmd->sub_table) {
821 /* continue with next arg */
822 help_cmd_dump(mon, cmd->sub_table,
823 args, nb_args, arg_index + 1);
824 } else {
825 help_cmd_dump_one(mon, cmd, args, arg_index);
826 }
827 break;
828 }
bellard9dc39cb2004-03-14 21:38:27 +0000829 }
830}
831
aliguori376253e2009-03-05 23:01:23 +0000832static void help_cmd(Monitor *mon, const char *name)
bellard9dc39cb2004-03-14 21:38:27 +0000833{
Wenchao Xia66855492013-08-27 20:38:23 +0800834 char *args[MAX_ARGS];
835 int nb_args = 0;
836
837 /* 1. parse user input */
838 if (name) {
839 /* special case for log, directly dump and return */
840 if (!strcmp(name, "log")) {
Peter Maydell38dad9e2013-02-11 16:41:25 +0000841 const QEMULogItem *item;
aliguori376253e2009-03-05 23:01:23 +0000842 monitor_printf(mon, "Log items (comma separated):\n");
843 monitor_printf(mon, "%-10s %s\n", "none", "remove all logs");
Peter Maydell38dad9e2013-02-11 16:41:25 +0000844 for (item = qemu_log_items; item->mask != 0; item++) {
aliguori376253e2009-03-05 23:01:23 +0000845 monitor_printf(mon, "%-10s %s\n", item->name, item->help);
bellardf193c792004-03-21 17:06:25 +0000846 }
Wenchao Xia66855492013-08-27 20:38:23 +0800847 return;
848 }
849
850 if (parse_cmdline(name, &nb_args, args) < 0) {
851 return;
bellardf193c792004-03-21 17:06:25 +0000852 }
bellard9dc39cb2004-03-14 21:38:27 +0000853 }
Wenchao Xia66855492013-08-27 20:38:23 +0800854
855 /* 2. dump the contents according to parsed args */
856 help_cmd_dump(mon, mon->cmd_table, args, nb_args, 0);
857
858 free_cmdline_args(args, nb_args);
bellard9dc39cb2004-03-14 21:38:27 +0000859}
860
Luiz Capitulinod54908a2009-08-28 15:27:13 -0300861static void do_help_cmd(Monitor *mon, const QDict *qdict)
Luiz Capitulino38183182009-08-28 15:27:08 -0300862{
Luiz Capitulinod54908a2009-08-28 15:27:13 -0300863 help_cmd(mon, qdict_get_try_str(qdict, "name"));
Luiz Capitulino38183182009-08-28 15:27:08 -0300864}
865
Markus Armbruster3e5a50d2015-02-06 13:55:43 +0100866static void hmp_trace_event(Monitor *mon, const QDict *qdict)
Prerna Saxena22890ab2010-06-24 17:04:53 +0530867{
868 const char *tp_name = qdict_get_str(qdict, "name");
869 bool new_state = qdict_get_bool(qdict, "option");
Lluís Vilanova14101d02014-08-25 13:20:03 +0200870 Error *local_err = NULL;
Blue Swirlf871d682010-10-13 19:14:29 +0000871
Lluís Vilanova14101d02014-08-25 13:20:03 +0200872 qmp_trace_event_set_state(tp_name, new_state, true, true, &local_err);
873 if (local_err) {
Markus Armbruster091e38b2015-02-10 15:15:43 +0100874 error_report_err(local_err);
Blue Swirlf871d682010-10-13 19:14:29 +0000875 }
Prerna Saxena22890ab2010-06-24 17:04:53 +0530876}
Stefan Hajnoczic5ceb522010-07-13 09:26:33 +0100877
Michael Rothc45a8162011-10-02 08:44:37 -0500878#ifdef CONFIG_TRACE_SIMPLE
Markus Armbruster3e5a50d2015-02-06 13:55:43 +0100879static void hmp_trace_file(Monitor *mon, const QDict *qdict)
Stefan Hajnoczic5ceb522010-07-13 09:26:33 +0100880{
881 const char *op = qdict_get_try_str(qdict, "op");
882 const char *arg = qdict_get_try_str(qdict, "arg");
883
884 if (!op) {
885 st_print_trace_file_status((FILE *)mon, &monitor_fprintf);
886 } else if (!strcmp(op, "on")) {
887 st_set_trace_file_enabled(true);
888 } else if (!strcmp(op, "off")) {
889 st_set_trace_file_enabled(false);
890 } else if (!strcmp(op, "flush")) {
891 st_flush_trace_buffer();
892 } else if (!strcmp(op, "set")) {
893 if (arg) {
894 st_set_trace_file(arg);
895 }
896 } else {
897 monitor_printf(mon, "unexpected argument \"%s\"\n", op);
898 help_cmd(mon, "trace-file");
899 }
900}
Prerna Saxena22890ab2010-06-24 17:04:53 +0530901#endif
902
Markus Armbruster3e5a50d2015-02-06 13:55:43 +0100903static void hmp_info_help(Monitor *mon, const QDict *qdict)
bellard9dc39cb2004-03-14 21:38:27 +0000904{
Luiz Capitulino13c74252009-10-07 13:41:55 -0300905 help_cmd(mon, "info");
bellard9dc39cb2004-03-14 21:38:27 +0000906}
907
Luiz Capitulinoaa9b79b2011-09-21 14:31:51 -0300908CommandInfoList *qmp_query_commands(Error **errp)
bellard9bc9d1c2004-10-10 15:15:51 +0000909{
Luiz Capitulinoaa9b79b2011-09-21 14:31:51 -0300910 CommandInfoList *info, *cmd_list = NULL;
Luiz Capitulinoe3bba9d2009-11-26 22:58:56 -0200911 const mon_cmd_t *cmd;
912
Luiz Capitulinof36b4af2010-09-15 17:17:45 -0300913 for (cmd = qmp_cmds; cmd->name != NULL; cmd++) {
Luiz Capitulino40e5a012011-10-21 16:15:31 -0200914 info = g_malloc0(sizeof(*info));
915 info->value = g_malloc0(sizeof(*info->value));
916 info->value->name = g_strdup(cmd->name);
Luiz Capitulinoe3bba9d2009-11-26 22:58:56 -0200917
Luiz Capitulinoaa9b79b2011-09-21 14:31:51 -0300918 info->next = cmd_list;
919 cmd_list = info;
Luiz Capitulinoe3bba9d2009-11-26 22:58:56 -0200920 }
921
Luiz Capitulinoaa9b79b2011-09-21 14:31:51 -0300922 return cmd_list;
thsa36e69d2007-12-02 05:18:19 +0000923}
924
Daniel P. Berrange48608532012-05-21 17:59:51 +0100925EventInfoList *qmp_query_events(Error **errp)
926{
927 EventInfoList *info, *ev_list = NULL;
Wenchao Xia75175172014-06-18 08:43:54 +0200928 QAPIEvent e;
Daniel P. Berrange48608532012-05-21 17:59:51 +0100929
Wenchao Xia75175172014-06-18 08:43:54 +0200930 for (e = 0 ; e < QAPI_EVENT_MAX ; e++) {
931 const char *event_name = QAPIEvent_lookup[e];
Daniel P. Berrange48608532012-05-21 17:59:51 +0100932 assert(event_name != NULL);
933 info = g_malloc0(sizeof(*info));
934 info->value = g_malloc0(sizeof(*info->value));
935 info->value->name = g_strdup(event_name);
936
937 info->next = ev_list;
938 ev_list = info;
939 }
940
941 return ev_list;
942}
943
Markus Armbruster39a18152015-09-16 13:06:28 +0200944/*
945 * Minor hack: generated marshalling suppressed for this command
946 * ('gen': false in the schema) so we can parse the JSON string
947 * directly into QObject instead of first parsing it with
948 * visit_type_SchemaInfoList() into a SchemaInfoList, then marshal it
949 * to QObject with generated output marshallers, every time. Instead,
950 * we do it in test-qmp-input-visitor.c, just to make sure
951 * qapi-introspect.py's output actually conforms to the schema.
952 */
953static void qmp_query_qmp_schema(QDict *qdict, QObject **ret_data,
954 Error **errp)
955{
956 *ret_data = qobject_from_json(qmp_schema_json);
957}
958
Luiz Capitulinob025c8b2011-10-06 14:02:57 -0300959/* set the current CPU defined by the user */
960int monitor_set_cpu(int cpu_index)
bellard6a00d602005-11-21 23:25:50 +0000961{
Andreas Färber55e5c282012-12-17 06:18:02 +0100962 CPUState *cpu;
bellard6a00d602005-11-21 23:25:50 +0000963
Andreas Färber1c8bb3c2013-02-15 17:01:09 +0100964 cpu = qemu_get_cpu(cpu_index);
965 if (cpu == NULL) {
966 return -1;
bellard6a00d602005-11-21 23:25:50 +0000967 }
Andreas Färbercb446ec2013-05-01 14:24:52 +0200968 cur_mon->mon_cpu = cpu;
Andreas Färber1c8bb3c2013-02-15 17:01:09 +0100969 return 0;
bellard6a00d602005-11-21 23:25:50 +0000970}
971
Pavel Butsykincaf15312015-09-22 16:18:17 +0300972CPUState *mon_get_cpu(void)
bellard6a00d602005-11-21 23:25:50 +0000973{
aliguori731b0362009-03-05 23:01:42 +0000974 if (!cur_mon->mon_cpu) {
Luiz Capitulinob025c8b2011-10-06 14:02:57 -0300975 monitor_set_cpu(0);
bellard6a00d602005-11-21 23:25:50 +0000976 }
Avi Kivity4c0960c2009-08-17 23:19:53 +0300977 cpu_synchronize_state(cur_mon->mon_cpu);
Peter Crosthwaite5bcda5f2015-05-24 14:20:40 -0700978 return cur_mon->mon_cpu;
979}
980
Pavel Butsykinbf957282015-09-10 18:38:59 +0300981CPUArchState *mon_get_cpu_env(void)
Peter Crosthwaite5bcda5f2015-05-24 14:20:40 -0700982{
983 return mon_get_cpu()->env_ptr;
bellard6a00d602005-11-21 23:25:50 +0000984}
985
Luiz Capitulino99b77962011-10-24 10:53:44 -0200986int monitor_get_cpu_index(void)
987{
Peter Crosthwaite5bcda5f2015-05-24 14:20:40 -0700988 return mon_get_cpu()->cpu_index;
Luiz Capitulino99b77962011-10-24 10:53:44 -0200989}
990
Markus Armbruster1ce6be22015-02-06 14:18:24 +0100991static void hmp_info_registers(Monitor *mon, const QDict *qdict)
bellard9307c4c2004-04-04 12:57:25 +0000992{
Peter Crosthwaite5bcda5f2015-05-24 14:20:40 -0700993 cpu_dump_state(mon_get_cpu(), (FILE *)mon, monitor_fprintf, CPU_DUMP_FPU);
bellard9307c4c2004-04-04 12:57:25 +0000994}
995
Markus Armbruster1ce6be22015-02-06 14:18:24 +0100996static void hmp_info_jit(Monitor *mon, const QDict *qdict)
bellarde3db7222005-01-26 22:00:47 +0000997{
aliguori376253e2009-03-05 23:01:23 +0000998 dump_exec_info((FILE *)mon, monitor_fprintf);
Sebastian Tanase27498be2014-07-25 11:56:33 +0200999 dump_drift_info((FILE *)mon, monitor_fprintf);
bellarde3db7222005-01-26 22:00:47 +00001000}
1001
Markus Armbruster1ce6be22015-02-06 14:18:24 +01001002static void hmp_info_opcount(Monitor *mon, const QDict *qdict)
Max Filippov246ae242014-11-02 11:04:18 +03001003{
1004 dump_opcount_info((FILE *)mon, monitor_fprintf);
1005}
1006
Markus Armbruster1ce6be22015-02-06 14:18:24 +01001007static void hmp_info_history(Monitor *mon, const QDict *qdict)
bellardaa455482004-04-04 13:07:25 +00001008{
1009 int i;
bellard7e2515e2004-08-01 21:52:19 +00001010 const char *str;
ths3b46e622007-09-17 08:09:54 +00001011
aliguoricde76ee2009-03-05 23:01:51 +00001012 if (!mon->rs)
1013 return;
bellard7e2515e2004-08-01 21:52:19 +00001014 i = 0;
1015 for(;;) {
aliguori731b0362009-03-05 23:01:42 +00001016 str = readline_get_history(mon->rs, i);
bellard7e2515e2004-08-01 21:52:19 +00001017 if (!str)
1018 break;
aliguori376253e2009-03-05 23:01:23 +00001019 monitor_printf(mon, "%d: '%s'\n", i, str);
bellard8e3a9fd2004-10-09 17:32:58 +00001020 i++;
bellardaa455482004-04-04 13:07:25 +00001021 }
1022}
1023
Markus Armbruster1ce6be22015-02-06 14:18:24 +01001024static void hmp_info_cpustats(Monitor *mon, const QDict *qdict)
j_mayer76a66252007-03-07 08:32:30 +00001025{
Peter Crosthwaite5bcda5f2015-05-24 14:20:40 -07001026 cpu_dump_statistics(mon_get_cpu(), (FILE *)mon, &monitor_fprintf, 0);
j_mayer76a66252007-03-07 08:32:30 +00001027}
j_mayer76a66252007-03-07 08:32:30 +00001028
Markus Armbruster1ce6be22015-02-06 14:18:24 +01001029static void hmp_info_trace_events(Monitor *mon, const QDict *qdict)
Prerna Saxena22890ab2010-06-24 17:04:53 +05301030{
Lluís Vilanova14101d02014-08-25 13:20:03 +02001031 TraceEventInfoList *events = qmp_trace_event_get_state("*", NULL);
1032 TraceEventInfoList *elem;
1033
1034 for (elem = events; elem != NULL; elem = elem->next) {
1035 monitor_printf(mon, "%s : state %u\n",
1036 elem->value->name,
1037 elem->value->state == TRACE_EVENT_STATE_ENABLED ? 1 : 0);
1038 }
1039 qapi_free_TraceEventInfoList(events);
Prerna Saxena22890ab2010-06-24 17:04:53 +05301040}
Prerna Saxena22890ab2010-06-24 17:04:53 +05301041
Markus Armbrusterb8a185b2015-03-05 17:29:02 +01001042void qmp_client_migrate_info(const char *protocol, const char *hostname,
1043 bool has_port, int64_t port,
1044 bool has_tls_port, int64_t tls_port,
1045 bool has_cert_subject, const char *cert_subject,
1046 Error **errp)
Gerd Hoffmanne866e232010-04-23 13:28:21 +02001047{
Gerd Hoffmanne866e232010-04-23 13:28:21 +02001048 if (strcmp(protocol, "spice") == 0) {
Markus Armbrusterb8a185b2015-03-05 17:29:02 +01001049 if (!qemu_using_spice(errp)) {
1050 return;
Gerd Hoffmanne866e232010-04-23 13:28:21 +02001051 }
1052
Markus Armbrusterb8a185b2015-03-05 17:29:02 +01001053 if (!has_port && !has_tls_port) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01001054 error_setg(errp, QERR_MISSING_PARAMETER, "port/tls-port");
Markus Armbrusterb8a185b2015-03-05 17:29:02 +01001055 return;
Yonit Halperin6ec5dae2012-03-18 09:42:39 +02001056 }
1057
Markus Armbrusterb8a185b2015-03-05 17:29:02 +01001058 if (qemu_spice_migrate_info(hostname,
1059 has_port ? port : -1,
1060 has_tls_port ? tls_port : -1,
1061 cert_subject)) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01001062 error_setg(errp, QERR_UNDEFINED_ERROR);
Markus Armbrusterb8a185b2015-03-05 17:29:02 +01001063 return;
Gerd Hoffmanne866e232010-04-23 13:28:21 +02001064 }
Markus Armbrusterb8a185b2015-03-05 17:29:02 +01001065 return;
Gerd Hoffmanne866e232010-04-23 13:28:21 +02001066 }
1067
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01001068 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "protocol", "spice");
Gerd Hoffmanne866e232010-04-23 13:28:21 +02001069}
1070
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001071static void hmp_logfile(Monitor *mon, const QDict *qdict)
pbrooke735b912007-06-30 13:53:24 +00001072{
Peter Maydell9a7e5422013-02-11 16:41:20 +00001073 qemu_set_log_filename(qdict_get_str(qdict, "filename"));
pbrooke735b912007-06-30 13:53:24 +00001074}
1075
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001076static void hmp_log(Monitor *mon, const QDict *qdict)
bellardf193c792004-03-21 17:06:25 +00001077{
1078 int mask;
Luiz Capitulinod54908a2009-08-28 15:27:13 -03001079 const char *items = qdict_get_str(qdict, "items");
ths3b46e622007-09-17 08:09:54 +00001080
bellard9307c4c2004-04-04 12:57:25 +00001081 if (!strcmp(items, "none")) {
bellardf193c792004-03-21 17:06:25 +00001082 mask = 0;
1083 } else {
Peter Maydell4fde1eb2013-02-11 16:41:22 +00001084 mask = qemu_str_to_log_mask(items);
bellardf193c792004-03-21 17:06:25 +00001085 if (!mask) {
aliguori376253e2009-03-05 23:01:23 +00001086 help_cmd(mon, "log");
bellardf193c792004-03-21 17:06:25 +00001087 return;
1088 }
1089 }
Peter Maydell24537a02013-02-11 16:41:23 +00001090 qemu_set_log(mask);
bellardf193c792004-03-21 17:06:25 +00001091}
1092
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001093static void hmp_singlestep(Monitor *mon, const QDict *qdict)
aurel321b530a62009-04-05 20:08:59 +00001094{
Luiz Capitulinod54908a2009-08-28 15:27:13 -03001095 const char *option = qdict_get_try_str(qdict, "option");
aurel321b530a62009-04-05 20:08:59 +00001096 if (!option || !strcmp(option, "on")) {
1097 singlestep = 1;
1098 } else if (!strcmp(option, "off")) {
1099 singlestep = 0;
1100 } else {
1101 monitor_printf(mon, "unexpected option %s\n", option);
1102 }
1103}
1104
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001105static void hmp_gdbserver(Monitor *mon, const QDict *qdict)
bellard8a7ddc32004-03-31 19:00:16 +00001106{
Luiz Capitulinod54908a2009-08-28 15:27:13 -03001107 const char *device = qdict_get_try_str(qdict, "device");
aliguori59030a82009-04-05 18:43:41 +00001108 if (!device)
1109 device = "tcp::" DEFAULT_GDBSTUB_PORT;
1110 if (gdbserver_start(device) < 0) {
1111 monitor_printf(mon, "Could not open gdbserver on device '%s'\n",
1112 device);
1113 } else if (strcmp(device, "none") == 0) {
aliguori36556b22009-03-28 18:05:53 +00001114 monitor_printf(mon, "Disabled gdbserver\n");
bellard8a7ddc32004-03-31 19:00:16 +00001115 } else {
aliguori59030a82009-04-05 18:43:41 +00001116 monitor_printf(mon, "Waiting for gdb connection on device '%s'\n",
1117 device);
bellard8a7ddc32004-03-31 19:00:16 +00001118 }
1119}
1120
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001121static void hmp_watchdog_action(Monitor *mon, const QDict *qdict)
Richard W.M. Jones9dd986c2009-04-25 13:56:19 +01001122{
Luiz Capitulinod54908a2009-08-28 15:27:13 -03001123 const char *action = qdict_get_str(qdict, "action");
Richard W.M. Jones9dd986c2009-04-25 13:56:19 +01001124 if (select_watchdog_action(action) == -1) {
1125 monitor_printf(mon, "Unknown watchdog action '%s'\n", action);
1126 }
1127}
1128
aliguori376253e2009-03-05 23:01:23 +00001129static void monitor_printc(Monitor *mon, int c)
bellard9307c4c2004-04-04 12:57:25 +00001130{
aliguori376253e2009-03-05 23:01:23 +00001131 monitor_printf(mon, "'");
bellard9307c4c2004-04-04 12:57:25 +00001132 switch(c) {
1133 case '\'':
aliguori376253e2009-03-05 23:01:23 +00001134 monitor_printf(mon, "\\'");
bellard9307c4c2004-04-04 12:57:25 +00001135 break;
1136 case '\\':
aliguori376253e2009-03-05 23:01:23 +00001137 monitor_printf(mon, "\\\\");
bellard9307c4c2004-04-04 12:57:25 +00001138 break;
1139 case '\n':
aliguori376253e2009-03-05 23:01:23 +00001140 monitor_printf(mon, "\\n");
bellard9307c4c2004-04-04 12:57:25 +00001141 break;
1142 case '\r':
aliguori376253e2009-03-05 23:01:23 +00001143 monitor_printf(mon, "\\r");
bellard9307c4c2004-04-04 12:57:25 +00001144 break;
1145 default:
1146 if (c >= 32 && c <= 126) {
aliguori376253e2009-03-05 23:01:23 +00001147 monitor_printf(mon, "%c", c);
bellard9307c4c2004-04-04 12:57:25 +00001148 } else {
aliguori376253e2009-03-05 23:01:23 +00001149 monitor_printf(mon, "\\x%02x", c);
bellard9307c4c2004-04-04 12:57:25 +00001150 }
1151 break;
1152 }
aliguori376253e2009-03-05 23:01:23 +00001153 monitor_printf(mon, "'");
bellard9307c4c2004-04-04 12:57:25 +00001154}
1155
aliguori376253e2009-03-05 23:01:23 +00001156static void memory_dump(Monitor *mon, int count, int format, int wsize,
Avi Kivitya8170e52012-10-23 12:30:10 +02001157 hwaddr addr, int is_physical)
bellard9307c4c2004-04-04 12:57:25 +00001158{
Blue Swirl23842aa2010-01-12 20:27:43 +00001159 int l, line_size, i, max_digits, len;
bellard9307c4c2004-04-04 12:57:25 +00001160 uint8_t buf[16];
1161 uint64_t v;
1162
1163 if (format == 'i') {
Peter Crosthwaite5bcda5f2015-05-24 14:20:40 -07001164 int flags = 0;
bellard9307c4c2004-04-04 12:57:25 +00001165#ifdef TARGET_I386
Peter Crosthwaite5bcda5f2015-05-24 14:20:40 -07001166 CPUArchState *env = mon_get_cpu_env();
bellard4c27ba22004-04-25 18:05:08 +00001167 if (wsize == 2) {
bellard9307c4c2004-04-04 12:57:25 +00001168 flags = 1;
bellard4c27ba22004-04-25 18:05:08 +00001169 } else if (wsize == 4) {
1170 flags = 0;
1171 } else {
bellard6a15fd12006-04-12 21:07:07 +00001172 /* as default we use the current CS size */
bellard4c27ba22004-04-25 18:05:08 +00001173 flags = 0;
bellard6a15fd12006-04-12 21:07:07 +00001174 if (env) {
1175#ifdef TARGET_X86_64
ths5fafdf22007-09-16 21:08:06 +00001176 if ((env->efer & MSR_EFER_LMA) &&
bellard6a15fd12006-04-12 21:07:07 +00001177 (env->segs[R_CS].flags & DESC_L_MASK))
1178 flags = 2;
1179 else
1180#endif
1181 if (!(env->segs[R_CS].flags & DESC_B_MASK))
1182 flags = 1;
1183 }
bellard4c27ba22004-04-25 18:05:08 +00001184 }
1185#endif
Tom Musta1c38f842014-04-09 14:53:24 -05001186#ifdef TARGET_PPC
Peter Crosthwaite5bcda5f2015-05-24 14:20:40 -07001187 CPUArchState *env = mon_get_cpu_env();
Tom Musta1c38f842014-04-09 14:53:24 -05001188 flags = msr_le << 16;
1189 flags |= env->bfd_mach;
1190#endif
Peter Crosthwaited49190c2015-05-24 14:20:41 -07001191 monitor_disas(mon, mon_get_cpu(), addr, count, is_physical, flags);
bellard9307c4c2004-04-04 12:57:25 +00001192 return;
1193 }
1194
1195 len = wsize * count;
1196 if (wsize == 1)
1197 line_size = 8;
1198 else
1199 line_size = 16;
bellard9307c4c2004-04-04 12:57:25 +00001200 max_digits = 0;
1201
1202 switch(format) {
1203 case 'o':
1204 max_digits = (wsize * 8 + 2) / 3;
1205 break;
1206 default:
1207 case 'x':
1208 max_digits = (wsize * 8) / 4;
1209 break;
1210 case 'u':
1211 case 'd':
1212 max_digits = (wsize * 8 * 10 + 32) / 33;
1213 break;
1214 case 'c':
1215 wsize = 1;
1216 break;
1217 }
1218
1219 while (len > 0) {
blueswir17743e582007-09-24 18:39:04 +00001220 if (is_physical)
aliguori376253e2009-03-05 23:01:23 +00001221 monitor_printf(mon, TARGET_FMT_plx ":", addr);
blueswir17743e582007-09-24 18:39:04 +00001222 else
aliguori376253e2009-03-05 23:01:23 +00001223 monitor_printf(mon, TARGET_FMT_lx ":", (target_ulong)addr);
bellard9307c4c2004-04-04 12:57:25 +00001224 l = len;
1225 if (l > line_size)
1226 l = line_size;
1227 if (is_physical) {
Stefan Weil54f7b4a2011-04-10 18:23:39 +02001228 cpu_physical_memory_read(addr, buf, l);
bellard9307c4c2004-04-04 12:57:25 +00001229 } else {
Peter Crosthwaite5bcda5f2015-05-24 14:20:40 -07001230 if (cpu_memory_rw_debug(mon_get_cpu(), addr, buf, l, 0) < 0) {
aliguori376253e2009-03-05 23:01:23 +00001231 monitor_printf(mon, " Cannot access memory\n");
aliguoric8f79b62008-08-18 14:00:20 +00001232 break;
1233 }
bellard9307c4c2004-04-04 12:57:25 +00001234 }
ths5fafdf22007-09-16 21:08:06 +00001235 i = 0;
bellard9307c4c2004-04-04 12:57:25 +00001236 while (i < l) {
1237 switch(wsize) {
1238 default:
1239 case 1:
Peter Maydell24e60302015-01-20 15:19:32 +00001240 v = ldub_p(buf + i);
bellard9307c4c2004-04-04 12:57:25 +00001241 break;
1242 case 2:
Peter Maydell24e60302015-01-20 15:19:32 +00001243 v = lduw_p(buf + i);
bellard9307c4c2004-04-04 12:57:25 +00001244 break;
1245 case 4:
Peter Maydell24e60302015-01-20 15:19:32 +00001246 v = (uint32_t)ldl_p(buf + i);
bellard9307c4c2004-04-04 12:57:25 +00001247 break;
1248 case 8:
Peter Maydell24e60302015-01-20 15:19:32 +00001249 v = ldq_p(buf + i);
bellard9307c4c2004-04-04 12:57:25 +00001250 break;
1251 }
aliguori376253e2009-03-05 23:01:23 +00001252 monitor_printf(mon, " ");
bellard9307c4c2004-04-04 12:57:25 +00001253 switch(format) {
1254 case 'o':
aliguori376253e2009-03-05 23:01:23 +00001255 monitor_printf(mon, "%#*" PRIo64, max_digits, v);
bellard9307c4c2004-04-04 12:57:25 +00001256 break;
1257 case 'x':
aliguori376253e2009-03-05 23:01:23 +00001258 monitor_printf(mon, "0x%0*" PRIx64, max_digits, v);
bellard9307c4c2004-04-04 12:57:25 +00001259 break;
1260 case 'u':
aliguori376253e2009-03-05 23:01:23 +00001261 monitor_printf(mon, "%*" PRIu64, max_digits, v);
bellard9307c4c2004-04-04 12:57:25 +00001262 break;
1263 case 'd':
aliguori376253e2009-03-05 23:01:23 +00001264 monitor_printf(mon, "%*" PRId64, max_digits, v);
bellard9307c4c2004-04-04 12:57:25 +00001265 break;
1266 case 'c':
aliguori376253e2009-03-05 23:01:23 +00001267 monitor_printc(mon, v);
bellard9307c4c2004-04-04 12:57:25 +00001268 break;
1269 }
1270 i += wsize;
1271 }
aliguori376253e2009-03-05 23:01:23 +00001272 monitor_printf(mon, "\n");
bellard9307c4c2004-04-04 12:57:25 +00001273 addr += l;
1274 len -= l;
1275 }
1276}
1277
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001278static void hmp_memory_dump(Monitor *mon, const QDict *qdict)
bellard9307c4c2004-04-04 12:57:25 +00001279{
Luiz Capitulino1bd14422009-08-28 15:27:17 -03001280 int count = qdict_get_int(qdict, "count");
1281 int format = qdict_get_int(qdict, "format");
1282 int size = qdict_get_int(qdict, "size");
1283 target_long addr = qdict_get_int(qdict, "addr");
1284
aliguori376253e2009-03-05 23:01:23 +00001285 memory_dump(mon, count, format, size, addr, 0);
bellard9307c4c2004-04-04 12:57:25 +00001286}
1287
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001288static void hmp_physical_memory_dump(Monitor *mon, const QDict *qdict)
bellard9307c4c2004-04-04 12:57:25 +00001289{
Luiz Capitulino1bd14422009-08-28 15:27:17 -03001290 int count = qdict_get_int(qdict, "count");
1291 int format = qdict_get_int(qdict, "format");
1292 int size = qdict_get_int(qdict, "size");
Avi Kivitya8170e52012-10-23 12:30:10 +02001293 hwaddr addr = qdict_get_int(qdict, "addr");
Luiz Capitulino1bd14422009-08-28 15:27:17 -03001294
aliguori376253e2009-03-05 23:01:23 +00001295 memory_dump(mon, count, format, size, addr, 1);
bellard9307c4c2004-04-04 12:57:25 +00001296}
1297
Luiz Capitulino1bd14422009-08-28 15:27:17 -03001298static void do_print(Monitor *mon, const QDict *qdict)
bellard9307c4c2004-04-04 12:57:25 +00001299{
Luiz Capitulino1bd14422009-08-28 15:27:17 -03001300 int format = qdict_get_int(qdict, "format");
Avi Kivitya8170e52012-10-23 12:30:10 +02001301 hwaddr val = qdict_get_int(qdict, "val");
Luiz Capitulino1bd14422009-08-28 15:27:17 -03001302
bellard9307c4c2004-04-04 12:57:25 +00001303 switch(format) {
1304 case 'o':
Avi Kivitya8170e52012-10-23 12:30:10 +02001305 monitor_printf(mon, "%#" HWADDR_PRIo, val);
bellard9307c4c2004-04-04 12:57:25 +00001306 break;
1307 case 'x':
Avi Kivitya8170e52012-10-23 12:30:10 +02001308 monitor_printf(mon, "%#" HWADDR_PRIx, val);
bellard9307c4c2004-04-04 12:57:25 +00001309 break;
1310 case 'u':
Avi Kivitya8170e52012-10-23 12:30:10 +02001311 monitor_printf(mon, "%" HWADDR_PRIu, val);
bellard9307c4c2004-04-04 12:57:25 +00001312 break;
1313 default:
1314 case 'd':
Avi Kivitya8170e52012-10-23 12:30:10 +02001315 monitor_printf(mon, "%" HWADDR_PRId, val);
bellard9307c4c2004-04-04 12:57:25 +00001316 break;
1317 case 'c':
aliguori376253e2009-03-05 23:01:23 +00001318 monitor_printc(mon, val);
bellard9307c4c2004-04-04 12:57:25 +00001319 break;
1320 }
aliguori376253e2009-03-05 23:01:23 +00001321 monitor_printf(mon, "\n");
bellard9307c4c2004-04-04 12:57:25 +00001322}
1323
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001324static void hmp_sum(Monitor *mon, const QDict *qdict)
bellarde4cf1ad2005-06-04 20:15:57 +00001325{
1326 uint32_t addr;
bellarde4cf1ad2005-06-04 20:15:57 +00001327 uint16_t sum;
Luiz Capitulinof18c16d2009-08-28 15:27:14 -03001328 uint32_t start = qdict_get_int(qdict, "start");
1329 uint32_t size = qdict_get_int(qdict, "size");
bellarde4cf1ad2005-06-04 20:15:57 +00001330
1331 sum = 0;
1332 for(addr = start; addr < (start + size); addr++) {
Peter Maydell42874d32015-04-26 16:49:24 +01001333 uint8_t val = address_space_ldub(&address_space_memory, addr,
1334 MEMTXATTRS_UNSPECIFIED, NULL);
bellarde4cf1ad2005-06-04 20:15:57 +00001335 /* BSD sum algorithm ('sum' Unix command) */
1336 sum = (sum >> 1) | (sum << 15);
Stefan Weil54f7b4a2011-04-10 18:23:39 +02001337 sum += val;
bellarde4cf1ad2005-06-04 20:15:57 +00001338 }
aliguori376253e2009-03-05 23:01:23 +00001339 monitor_printf(mon, "%05d\n", sum);
bellarde4cf1ad2005-06-04 20:15:57 +00001340}
1341
bellard13224a82006-07-14 22:03:35 +00001342static int mouse_button_state;
1343
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001344static void hmp_mouse_move(Monitor *mon, const QDict *qdict)
bellard13224a82006-07-14 22:03:35 +00001345{
Gerd Hoffmannc751a742013-12-04 15:02:28 +01001346 int dx, dy, dz, button;
Luiz Capitulino1d4daa92009-08-28 15:27:15 -03001347 const char *dx_str = qdict_get_str(qdict, "dx_str");
1348 const char *dy_str = qdict_get_str(qdict, "dy_str");
1349 const char *dz_str = qdict_get_try_str(qdict, "dz_str");
Gerd Hoffmannc751a742013-12-04 15:02:28 +01001350
bellard13224a82006-07-14 22:03:35 +00001351 dx = strtol(dx_str, NULL, 0);
1352 dy = strtol(dy_str, NULL, 0);
Gerd Hoffmannc751a742013-12-04 15:02:28 +01001353 qemu_input_queue_rel(NULL, INPUT_AXIS_X, dx);
1354 qemu_input_queue_rel(NULL, INPUT_AXIS_Y, dy);
1355
1356 if (dz_str) {
bellard13224a82006-07-14 22:03:35 +00001357 dz = strtol(dz_str, NULL, 0);
Gerd Hoffmannc751a742013-12-04 15:02:28 +01001358 if (dz != 0) {
1359 button = (dz > 0) ? INPUT_BUTTON_WHEEL_UP : INPUT_BUTTON_WHEEL_DOWN;
1360 qemu_input_queue_btn(NULL, button, true);
1361 qemu_input_event_sync();
1362 qemu_input_queue_btn(NULL, button, false);
1363 }
1364 }
1365 qemu_input_event_sync();
bellard13224a82006-07-14 22:03:35 +00001366}
1367
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001368static void hmp_mouse_button(Monitor *mon, const QDict *qdict)
bellard13224a82006-07-14 22:03:35 +00001369{
Gerd Hoffmannc751a742013-12-04 15:02:28 +01001370 static uint32_t bmap[INPUT_BUTTON_MAX] = {
1371 [INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON,
1372 [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON,
1373 [INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON,
1374 };
Luiz Capitulinod54908a2009-08-28 15:27:13 -03001375 int button_state = qdict_get_int(qdict, "button_state");
Gerd Hoffmannc751a742013-12-04 15:02:28 +01001376
1377 if (mouse_button_state == button_state) {
1378 return;
1379 }
1380 qemu_input_update_buttons(NULL, bmap, mouse_button_state, button_state);
1381 qemu_input_event_sync();
bellard13224a82006-07-14 22:03:35 +00001382 mouse_button_state = button_state;
bellard13224a82006-07-14 22:03:35 +00001383}
1384
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001385static void hmp_ioport_read(Monitor *mon, const QDict *qdict)
bellard34405572004-06-08 00:55:58 +00001386{
Luiz Capitulinoaa93e392009-08-28 15:27:18 -03001387 int size = qdict_get_int(qdict, "size");
1388 int addr = qdict_get_int(qdict, "addr");
1389 int has_index = qdict_haskey(qdict, "index");
bellard34405572004-06-08 00:55:58 +00001390 uint32_t val;
1391 int suffix;
1392
1393 if (has_index) {
Luiz Capitulinoaa93e392009-08-28 15:27:18 -03001394 int index = qdict_get_int(qdict, "index");
Blue Swirlafcea8c2009-09-20 16:05:47 +00001395 cpu_outb(addr & IOPORTS_MASK, index & 0xff);
bellard34405572004-06-08 00:55:58 +00001396 addr++;
1397 }
1398 addr &= 0xffff;
1399
1400 switch(size) {
1401 default:
1402 case 1:
Blue Swirlafcea8c2009-09-20 16:05:47 +00001403 val = cpu_inb(addr);
bellard34405572004-06-08 00:55:58 +00001404 suffix = 'b';
1405 break;
1406 case 2:
Blue Swirlafcea8c2009-09-20 16:05:47 +00001407 val = cpu_inw(addr);
bellard34405572004-06-08 00:55:58 +00001408 suffix = 'w';
1409 break;
1410 case 4:
Blue Swirlafcea8c2009-09-20 16:05:47 +00001411 val = cpu_inl(addr);
bellard34405572004-06-08 00:55:58 +00001412 suffix = 'l';
1413 break;
1414 }
aliguori376253e2009-03-05 23:01:23 +00001415 monitor_printf(mon, "port%c[0x%04x] = %#0*x\n",
1416 suffix, addr, size * 2, val);
bellard34405572004-06-08 00:55:58 +00001417}
bellarda3a91a32004-06-04 11:06:21 +00001418
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001419static void hmp_ioport_write(Monitor *mon, const QDict *qdict)
Jan Kiszkaf1147842009-07-14 10:20:11 +02001420{
Luiz Capitulino1bd14422009-08-28 15:27:17 -03001421 int size = qdict_get_int(qdict, "size");
1422 int addr = qdict_get_int(qdict, "addr");
1423 int val = qdict_get_int(qdict, "val");
1424
Jan Kiszkaf1147842009-07-14 10:20:11 +02001425 addr &= IOPORTS_MASK;
1426
1427 switch (size) {
1428 default:
1429 case 1:
Blue Swirlafcea8c2009-09-20 16:05:47 +00001430 cpu_outb(addr, val);
Jan Kiszkaf1147842009-07-14 10:20:11 +02001431 break;
1432 case 2:
Blue Swirlafcea8c2009-09-20 16:05:47 +00001433 cpu_outw(addr, val);
Jan Kiszkaf1147842009-07-14 10:20:11 +02001434 break;
1435 case 4:
Blue Swirlafcea8c2009-09-20 16:05:47 +00001436 cpu_outl(addr, val);
Jan Kiszkaf1147842009-07-14 10:20:11 +02001437 break;
1438 }
1439}
1440
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001441static void hmp_boot_set(Monitor *mon, const QDict *qdict)
aurel320ecdffb2008-05-04 20:11:34 +00001442{
Gongleif1839932014-12-03 18:20:58 +00001443 Error *local_err = NULL;
Luiz Capitulinod54908a2009-08-28 15:27:13 -03001444 const char *bootdevice = qdict_get_str(qdict, "bootdevice");
aurel320ecdffb2008-05-04 20:11:34 +00001445
Gongleif1839932014-12-03 18:20:58 +00001446 qemu_boot_set(bootdevice, &local_err);
1447 if (local_err) {
1448 monitor_printf(mon, "%s\n", error_get_pretty(local_err));
1449 error_free(local_err);
aurel320ecdffb2008-05-04 20:11:34 +00001450 } else {
Gongleif1839932014-12-03 18:20:58 +00001451 monitor_printf(mon, "boot device list now set to %s\n", bootdevice);
aurel320ecdffb2008-05-04 20:11:34 +00001452 }
1453}
1454
Markus Armbruster1ce6be22015-02-06 14:18:24 +01001455static void hmp_info_mtree(Monitor *mon, const QDict *qdict)
Blue Swirl314e2982011-09-11 20:22:05 +00001456{
1457 mtree_info((fprintf_function)monitor_printf, mon);
1458}
1459
Markus Armbruster1ce6be22015-02-06 14:18:24 +01001460static void hmp_info_numa(Monitor *mon, const QDict *qdict)
aliguori030ea372009-04-21 22:30:47 +00001461{
aliguorib28b6232009-04-22 20:20:29 +00001462 int i;
Andreas Färber1b1ed8d2012-12-17 04:22:03 +01001463 CPUState *cpu;
zhanghailiang5b009e42014-11-04 19:49:30 +08001464 uint64_t *node_mem;
aliguori030ea372009-04-21 22:30:47 +00001465
zhanghailiang5b009e42014-11-04 19:49:30 +08001466 node_mem = g_new0(uint64_t, nb_numa_nodes);
1467 query_numa_node_mem(node_mem);
aliguori030ea372009-04-21 22:30:47 +00001468 monitor_printf(mon, "%d nodes\n", nb_numa_nodes);
1469 for (i = 0; i < nb_numa_nodes; i++) {
1470 monitor_printf(mon, "node %d cpus:", i);
Andreas Färberbdc44642013-06-24 23:50:24 +02001471 CPU_FOREACH(cpu) {
Andreas Färber1b1ed8d2012-12-17 04:22:03 +01001472 if (cpu->numa_node == i) {
Andreas Färber55e5c282012-12-17 06:18:02 +01001473 monitor_printf(mon, " %d", cpu->cpu_index);
aliguori030ea372009-04-21 22:30:47 +00001474 }
1475 }
1476 monitor_printf(mon, "\n");
1477 monitor_printf(mon, "node %d size: %" PRId64 " MB\n", i,
zhanghailiang5b009e42014-11-04 19:49:30 +08001478 node_mem[i] >> 20);
aliguori030ea372009-04-21 22:30:47 +00001479 }
zhanghailiang5b009e42014-11-04 19:49:30 +08001480 g_free(node_mem);
aliguori030ea372009-04-21 22:30:47 +00001481}
1482
bellard5f1ce942006-02-08 22:40:15 +00001483#ifdef CONFIG_PROFILER
1484
Alexey Kardashevskiy89d5cbd2015-03-16 14:57:38 +11001485int64_t tcg_time;
Aurelien Jarnoe9a66252009-09-30 14:09:52 +02001486int64_t dev_time;
1487
Markus Armbruster1ce6be22015-02-06 14:18:24 +01001488static void hmp_info_profile(Monitor *mon, const QDict *qdict)
bellard5f1ce942006-02-08 22:40:15 +00001489{
aliguori376253e2009-03-05 23:01:23 +00001490 monitor_printf(mon, "async time %" PRId64 " (%0.3f)\n",
Juan Quintela6ee093c2009-09-10 03:04:26 +02001491 dev_time, dev_time / (double)get_ticks_per_sec());
aliguori376253e2009-03-05 23:01:23 +00001492 monitor_printf(mon, "qemu time %" PRId64 " (%0.3f)\n",
Alexey Kardashevskiy89d5cbd2015-03-16 14:57:38 +11001493 tcg_time, tcg_time / (double)get_ticks_per_sec());
1494 tcg_time = 0;
bellard5f1ce942006-02-08 22:40:15 +00001495 dev_time = 0;
bellard5f1ce942006-02-08 22:40:15 +00001496}
1497#else
Markus Armbruster1ce6be22015-02-06 14:18:24 +01001498static void hmp_info_profile(Monitor *mon, const QDict *qdict)
bellard5f1ce942006-02-08 22:40:15 +00001499{
aliguori376253e2009-03-05 23:01:23 +00001500 monitor_printf(mon, "Internal profiler not compiled\n");
bellard5f1ce942006-02-08 22:40:15 +00001501}
1502#endif
1503
bellardec36b692006-07-16 18:57:03 +00001504/* Capture support */
Blue Swirl72cf2d42009-09-12 07:36:22 +00001505static QLIST_HEAD (capture_list_head, CaptureState) capture_head;
bellardec36b692006-07-16 18:57:03 +00001506
Markus Armbruster1ce6be22015-02-06 14:18:24 +01001507static void hmp_info_capture(Monitor *mon, const QDict *qdict)
bellardec36b692006-07-16 18:57:03 +00001508{
1509 int i;
1510 CaptureState *s;
1511
1512 for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) {
aliguori376253e2009-03-05 23:01:23 +00001513 monitor_printf(mon, "[%d]: ", i);
bellardec36b692006-07-16 18:57:03 +00001514 s->ops.info (s->opaque);
1515 }
1516}
1517
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001518static void hmp_stopcapture(Monitor *mon, const QDict *qdict)
bellardec36b692006-07-16 18:57:03 +00001519{
1520 int i;
Luiz Capitulinod54908a2009-08-28 15:27:13 -03001521 int n = qdict_get_int(qdict, "n");
bellardec36b692006-07-16 18:57:03 +00001522 CaptureState *s;
1523
1524 for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) {
1525 if (i == n) {
1526 s->ops.destroy (s->opaque);
Blue Swirl72cf2d42009-09-12 07:36:22 +00001527 QLIST_REMOVE (s, entries);
Anthony Liguori7267c092011-08-20 22:09:37 -05001528 g_free (s);
bellardec36b692006-07-16 18:57:03 +00001529 return;
1530 }
1531 }
1532}
1533
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001534static void hmp_wavcapture(Monitor *mon, const QDict *qdict)
bellardec36b692006-07-16 18:57:03 +00001535{
Luiz Capitulinoc1925482009-08-28 15:27:19 -03001536 const char *path = qdict_get_str(qdict, "path");
1537 int has_freq = qdict_haskey(qdict, "freq");
1538 int freq = qdict_get_try_int(qdict, "freq", -1);
1539 int has_bits = qdict_haskey(qdict, "bits");
1540 int bits = qdict_get_try_int(qdict, "bits", -1);
1541 int has_channels = qdict_haskey(qdict, "nchannels");
1542 int nchannels = qdict_get_try_int(qdict, "nchannels", -1);
bellardec36b692006-07-16 18:57:03 +00001543 CaptureState *s;
1544
Anthony Liguori7267c092011-08-20 22:09:37 -05001545 s = g_malloc0 (sizeof (*s));
bellardec36b692006-07-16 18:57:03 +00001546
1547 freq = has_freq ? freq : 44100;
1548 bits = has_bits ? bits : 16;
1549 nchannels = has_channels ? nchannels : 2;
1550
1551 if (wav_start_capture (s, path, freq, bits, nchannels)) {
Isaku Yamahatad00b2612011-01-21 19:53:55 +09001552 monitor_printf(mon, "Failed to add wave capture\n");
Anthony Liguori7267c092011-08-20 22:09:37 -05001553 g_free (s);
Isaku Yamahatad00b2612011-01-21 19:53:55 +09001554 return;
bellardec36b692006-07-16 18:57:03 +00001555 }
Blue Swirl72cf2d42009-09-12 07:36:22 +00001556 QLIST_INSERT_HEAD (&capture_head, s, entries);
bellardec36b692006-07-16 18:57:03 +00001557}
bellardec36b692006-07-16 18:57:03 +00001558
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001559static qemu_acl *find_acl(Monitor *mon, const char *name)
aliguori76655d62009-03-06 20:27:37 +00001560{
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001561 qemu_acl *acl = qemu_acl_find(name);
aliguori76655d62009-03-06 20:27:37 +00001562
aliguori76655d62009-03-06 20:27:37 +00001563 if (!acl) {
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001564 monitor_printf(mon, "acl: unknown list '%s'\n", name);
aliguori76655d62009-03-06 20:27:37 +00001565 }
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001566 return acl;
1567}
aliguori76655d62009-03-06 20:27:37 +00001568
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001569static void hmp_acl_show(Monitor *mon, const QDict *qdict)
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001570{
Luiz Capitulinod54908a2009-08-28 15:27:13 -03001571 const char *aclname = qdict_get_str(qdict, "aclname");
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001572 qemu_acl *acl = find_acl(mon, aclname);
1573 qemu_acl_entry *entry;
1574 int i = 0;
1575
1576 if (acl) {
aliguori28a76be2009-03-06 20:27:40 +00001577 monitor_printf(mon, "policy: %s\n",
aliguori76655d62009-03-06 20:27:37 +00001578 acl->defaultDeny ? "deny" : "allow");
Blue Swirl72cf2d42009-09-12 07:36:22 +00001579 QTAILQ_FOREACH(entry, &acl->entries, next) {
aliguori28a76be2009-03-06 20:27:40 +00001580 i++;
1581 monitor_printf(mon, "%d: %s %s\n", i,
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001582 entry->deny ? "deny" : "allow", entry->match);
aliguori28a76be2009-03-06 20:27:40 +00001583 }
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001584 }
1585}
1586
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001587static void hmp_acl_reset(Monitor *mon, const QDict *qdict)
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001588{
Luiz Capitulinod54908a2009-08-28 15:27:13 -03001589 const char *aclname = qdict_get_str(qdict, "aclname");
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001590 qemu_acl *acl = find_acl(mon, aclname);
1591
1592 if (acl) {
aliguori28a76be2009-03-06 20:27:40 +00001593 qemu_acl_reset(acl);
1594 monitor_printf(mon, "acl: removed all rules\n");
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001595 }
1596}
aliguori76655d62009-03-06 20:27:37 +00001597
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001598static void hmp_acl_policy(Monitor *mon, const QDict *qdict)
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001599{
Luiz Capitulinof18c16d2009-08-28 15:27:14 -03001600 const char *aclname = qdict_get_str(qdict, "aclname");
1601 const char *policy = qdict_get_str(qdict, "policy");
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001602 qemu_acl *acl = find_acl(mon, aclname);
1603
1604 if (acl) {
1605 if (strcmp(policy, "allow") == 0) {
aliguori28a76be2009-03-06 20:27:40 +00001606 acl->defaultDeny = 0;
1607 monitor_printf(mon, "acl: policy set to 'allow'\n");
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001608 } else if (strcmp(policy, "deny") == 0) {
aliguori28a76be2009-03-06 20:27:40 +00001609 acl->defaultDeny = 1;
1610 monitor_printf(mon, "acl: policy set to 'deny'\n");
1611 } else {
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001612 monitor_printf(mon, "acl: unknown policy '%s', "
1613 "expected 'deny' or 'allow'\n", policy);
aliguori28a76be2009-03-06 20:27:40 +00001614 }
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001615 }
1616}
aliguori76655d62009-03-06 20:27:37 +00001617
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001618static void hmp_acl_add(Monitor *mon, const QDict *qdict)
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001619{
Luiz Capitulino1bd14422009-08-28 15:27:17 -03001620 const char *aclname = qdict_get_str(qdict, "aclname");
1621 const char *match = qdict_get_str(qdict, "match");
1622 const char *policy = qdict_get_str(qdict, "policy");
1623 int has_index = qdict_haskey(qdict, "index");
1624 int index = qdict_get_try_int(qdict, "index", -1);
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001625 qemu_acl *acl = find_acl(mon, aclname);
1626 int deny, ret;
1627
1628 if (acl) {
1629 if (strcmp(policy, "allow") == 0) {
1630 deny = 0;
1631 } else if (strcmp(policy, "deny") == 0) {
1632 deny = 1;
1633 } else {
1634 monitor_printf(mon, "acl: unknown policy '%s', "
1635 "expected 'deny' or 'allow'\n", policy);
aliguori28a76be2009-03-06 20:27:40 +00001636 return;
1637 }
aliguori28a76be2009-03-06 20:27:40 +00001638 if (has_index)
1639 ret = qemu_acl_insert(acl, deny, match, index);
1640 else
1641 ret = qemu_acl_append(acl, deny, match);
1642 if (ret < 0)
1643 monitor_printf(mon, "acl: unable to add acl entry\n");
1644 else
1645 monitor_printf(mon, "acl: added rule at position %d\n", ret);
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001646 }
1647}
aliguori76655d62009-03-06 20:27:37 +00001648
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001649static void hmp_acl_remove(Monitor *mon, const QDict *qdict)
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001650{
Luiz Capitulinof18c16d2009-08-28 15:27:14 -03001651 const char *aclname = qdict_get_str(qdict, "aclname");
1652 const char *match = qdict_get_str(qdict, "match");
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001653 qemu_acl *acl = find_acl(mon, aclname);
1654 int ret;
aliguori76655d62009-03-06 20:27:37 +00001655
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001656 if (acl) {
aliguori28a76be2009-03-06 20:27:40 +00001657 ret = qemu_acl_remove(acl, match);
1658 if (ret < 0)
1659 monitor_printf(mon, "acl: no matching acl entry\n");
1660 else
1661 monitor_printf(mon, "acl: removed rule at position %d\n", ret);
aliguori76655d62009-03-06 20:27:37 +00001662 }
1663}
1664
Corey Bryant208c9d12012-06-22 14:36:09 -04001665void qmp_getfd(const char *fdname, Error **errp)
Mark McLoughlinf07918f2009-07-22 09:11:40 +01001666{
Anthony Liguoric227f092009-10-01 16:12:16 -05001667 mon_fd_t *monfd;
Mark McLoughlinf07918f2009-07-22 09:11:40 +01001668 int fd;
1669
Corey Bryant208c9d12012-06-22 14:36:09 -04001670 fd = qemu_chr_fe_get_msgfd(cur_mon->chr);
Mark McLoughlinf07918f2009-07-22 09:11:40 +01001671 if (fd == -1) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01001672 error_setg(errp, QERR_FD_NOT_SUPPLIED);
Corey Bryant208c9d12012-06-22 14:36:09 -04001673 return;
Mark McLoughlinf07918f2009-07-22 09:11:40 +01001674 }
1675
1676 if (qemu_isdigit(fdname[0])) {
Stefan Hajnoczi0b9f0e22014-04-24 13:58:18 +02001677 close(fd);
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01001678 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "fdname",
1679 "a name not starting with a digit");
Corey Bryant208c9d12012-06-22 14:36:09 -04001680 return;
Mark McLoughlinf07918f2009-07-22 09:11:40 +01001681 }
1682
Corey Bryant208c9d12012-06-22 14:36:09 -04001683 QLIST_FOREACH(monfd, &cur_mon->fds, next) {
Mark McLoughlinf07918f2009-07-22 09:11:40 +01001684 if (strcmp(monfd->name, fdname) != 0) {
1685 continue;
1686 }
1687
1688 close(monfd->fd);
1689 monfd->fd = fd;
Corey Bryant208c9d12012-06-22 14:36:09 -04001690 return;
Mark McLoughlinf07918f2009-07-22 09:11:40 +01001691 }
1692
Anthony Liguori7267c092011-08-20 22:09:37 -05001693 monfd = g_malloc0(sizeof(mon_fd_t));
1694 monfd->name = g_strdup(fdname);
Mark McLoughlinf07918f2009-07-22 09:11:40 +01001695 monfd->fd = fd;
1696
Corey Bryant208c9d12012-06-22 14:36:09 -04001697 QLIST_INSERT_HEAD(&cur_mon->fds, monfd, next);
Mark McLoughlinf07918f2009-07-22 09:11:40 +01001698}
1699
Corey Bryant208c9d12012-06-22 14:36:09 -04001700void qmp_closefd(const char *fdname, Error **errp)
Mark McLoughlinf07918f2009-07-22 09:11:40 +01001701{
Anthony Liguoric227f092009-10-01 16:12:16 -05001702 mon_fd_t *monfd;
Mark McLoughlinf07918f2009-07-22 09:11:40 +01001703
Corey Bryant208c9d12012-06-22 14:36:09 -04001704 QLIST_FOREACH(monfd, &cur_mon->fds, next) {
Mark McLoughlinf07918f2009-07-22 09:11:40 +01001705 if (strcmp(monfd->name, fdname) != 0) {
1706 continue;
1707 }
1708
Blue Swirl72cf2d42009-09-12 07:36:22 +00001709 QLIST_REMOVE(monfd, next);
Mark McLoughlinf07918f2009-07-22 09:11:40 +01001710 close(monfd->fd);
Anthony Liguori7267c092011-08-20 22:09:37 -05001711 g_free(monfd->name);
1712 g_free(monfd);
Corey Bryant208c9d12012-06-22 14:36:09 -04001713 return;
Mark McLoughlinf07918f2009-07-22 09:11:40 +01001714 }
1715
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01001716 error_setg(errp, QERR_FD_NOT_FOUND, fdname);
Mark McLoughlinf07918f2009-07-22 09:11:40 +01001717}
1718
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001719static void hmp_loadvm(Monitor *mon, const QDict *qdict)
Juan Quintelac8d41b22009-08-20 19:42:21 +02001720{
Luiz Capitulino13548692011-07-29 15:36:43 -03001721 int saved_vm_running = runstate_is_running();
Luiz Capitulinod54908a2009-08-28 15:27:13 -03001722 const char *name = qdict_get_str(qdict, "name");
Juan Quintelac8d41b22009-08-20 19:42:21 +02001723
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03001724 vm_stop(RUN_STATE_RESTORE_VM);
Juan Quintelac8d41b22009-08-20 19:42:21 +02001725
Miguel Di Ciurcio Filhof0aa7a82010-07-19 15:25:01 -03001726 if (load_vmstate(name) == 0 && saved_vm_running) {
Juan Quintelac8d41b22009-08-20 19:42:21 +02001727 vm_start();
Miguel Di Ciurcio Filhof0aa7a82010-07-19 15:25:01 -03001728 }
Juan Quintelac8d41b22009-08-20 19:42:21 +02001729}
1730
Paolo Bonzinia9940fc2012-09-20 16:50:32 +02001731int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp)
Mark McLoughlin7768e042009-07-22 09:11:41 +01001732{
Anthony Liguoric227f092009-10-01 16:12:16 -05001733 mon_fd_t *monfd;
Mark McLoughlin7768e042009-07-22 09:11:41 +01001734
Blue Swirl72cf2d42009-09-12 07:36:22 +00001735 QLIST_FOREACH(monfd, &mon->fds, next) {
Mark McLoughlin7768e042009-07-22 09:11:41 +01001736 int fd;
1737
1738 if (strcmp(monfd->name, fdname) != 0) {
1739 continue;
1740 }
1741
1742 fd = monfd->fd;
1743
1744 /* caller takes ownership of fd */
Blue Swirl72cf2d42009-09-12 07:36:22 +00001745 QLIST_REMOVE(monfd, next);
Anthony Liguori7267c092011-08-20 22:09:37 -05001746 g_free(monfd->name);
1747 g_free(monfd);
Mark McLoughlin7768e042009-07-22 09:11:41 +01001748
1749 return fd;
1750 }
1751
Paolo Bonzinia9940fc2012-09-20 16:50:32 +02001752 error_setg(errp, "File descriptor named '%s' has not been found", fdname);
Mark McLoughlin7768e042009-07-22 09:11:41 +01001753 return -1;
1754}
1755
Corey Bryantba1c0482012-08-14 16:43:43 -04001756static void monitor_fdset_cleanup(MonFdset *mon_fdset)
1757{
1758 MonFdsetFd *mon_fdset_fd;
1759 MonFdsetFd *mon_fdset_fd_next;
1760
1761 QLIST_FOREACH_SAFE(mon_fdset_fd, &mon_fdset->fds, next, mon_fdset_fd_next) {
Corey Bryantebe52b52012-10-18 15:19:33 -04001762 if ((mon_fdset_fd->removed ||
1763 (QLIST_EMPTY(&mon_fdset->dup_fds) && mon_refcount == 0)) &&
1764 runstate_is_running()) {
Corey Bryantba1c0482012-08-14 16:43:43 -04001765 close(mon_fdset_fd->fd);
1766 g_free(mon_fdset_fd->opaque);
1767 QLIST_REMOVE(mon_fdset_fd, next);
1768 g_free(mon_fdset_fd);
1769 }
1770 }
1771
Corey Bryantadb696f2012-08-14 16:43:47 -04001772 if (QLIST_EMPTY(&mon_fdset->fds) && QLIST_EMPTY(&mon_fdset->dup_fds)) {
Corey Bryantba1c0482012-08-14 16:43:43 -04001773 QLIST_REMOVE(mon_fdset, next);
1774 g_free(mon_fdset);
1775 }
1776}
1777
Corey Bryantefb87c12012-08-14 16:43:48 -04001778static void monitor_fdsets_cleanup(void)
1779{
1780 MonFdset *mon_fdset;
1781 MonFdset *mon_fdset_next;
1782
1783 QLIST_FOREACH_SAFE(mon_fdset, &mon_fdsets, next, mon_fdset_next) {
1784 monitor_fdset_cleanup(mon_fdset);
1785 }
1786}
1787
Corey Bryantba1c0482012-08-14 16:43:43 -04001788AddfdInfo *qmp_add_fd(bool has_fdset_id, int64_t fdset_id, bool has_opaque,
1789 const char *opaque, Error **errp)
1790{
1791 int fd;
1792 Monitor *mon = cur_mon;
Corey Bryantba1c0482012-08-14 16:43:43 -04001793 AddfdInfo *fdinfo;
1794
1795 fd = qemu_chr_fe_get_msgfd(mon->chr);
1796 if (fd == -1) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01001797 error_setg(errp, QERR_FD_NOT_SUPPLIED);
Corey Bryantba1c0482012-08-14 16:43:43 -04001798 goto error;
1799 }
1800
Corey Bryante446f702012-10-18 15:19:32 -04001801 fdinfo = monitor_fdset_add_fd(fd, has_fdset_id, fdset_id,
1802 has_opaque, opaque, errp);
1803 if (fdinfo) {
1804 return fdinfo;
Corey Bryant9ac54af2012-10-18 15:19:31 -04001805 }
1806
Corey Bryantba1c0482012-08-14 16:43:43 -04001807error:
1808 if (fd != -1) {
1809 close(fd);
1810 }
1811 return NULL;
1812}
1813
1814void qmp_remove_fd(int64_t fdset_id, bool has_fd, int64_t fd, Error **errp)
1815{
1816 MonFdset *mon_fdset;
1817 MonFdsetFd *mon_fdset_fd;
1818 char fd_str[60];
1819
1820 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
1821 if (mon_fdset->id != fdset_id) {
1822 continue;
1823 }
1824 QLIST_FOREACH(mon_fdset_fd, &mon_fdset->fds, next) {
1825 if (has_fd) {
1826 if (mon_fdset_fd->fd != fd) {
1827 continue;
1828 }
1829 mon_fdset_fd->removed = true;
1830 break;
1831 } else {
1832 mon_fdset_fd->removed = true;
1833 }
1834 }
1835 if (has_fd && !mon_fdset_fd) {
1836 goto error;
1837 }
1838 monitor_fdset_cleanup(mon_fdset);
1839 return;
1840 }
1841
1842error:
1843 if (has_fd) {
1844 snprintf(fd_str, sizeof(fd_str), "fdset-id:%" PRId64 ", fd:%" PRId64,
1845 fdset_id, fd);
1846 } else {
1847 snprintf(fd_str, sizeof(fd_str), "fdset-id:%" PRId64, fdset_id);
1848 }
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01001849 error_setg(errp, QERR_FD_NOT_FOUND, fd_str);
Corey Bryantba1c0482012-08-14 16:43:43 -04001850}
1851
1852FdsetInfoList *qmp_query_fdsets(Error **errp)
1853{
1854 MonFdset *mon_fdset;
1855 MonFdsetFd *mon_fdset_fd;
1856 FdsetInfoList *fdset_list = NULL;
1857
1858 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
1859 FdsetInfoList *fdset_info = g_malloc0(sizeof(*fdset_info));
1860 FdsetFdInfoList *fdsetfd_list = NULL;
1861
1862 fdset_info->value = g_malloc0(sizeof(*fdset_info->value));
1863 fdset_info->value->fdset_id = mon_fdset->id;
1864
1865 QLIST_FOREACH(mon_fdset_fd, &mon_fdset->fds, next) {
1866 FdsetFdInfoList *fdsetfd_info;
1867
1868 fdsetfd_info = g_malloc0(sizeof(*fdsetfd_info));
1869 fdsetfd_info->value = g_malloc0(sizeof(*fdsetfd_info->value));
1870 fdsetfd_info->value->fd = mon_fdset_fd->fd;
1871 if (mon_fdset_fd->opaque) {
1872 fdsetfd_info->value->has_opaque = true;
1873 fdsetfd_info->value->opaque = g_strdup(mon_fdset_fd->opaque);
1874 } else {
1875 fdsetfd_info->value->has_opaque = false;
1876 }
1877
1878 fdsetfd_info->next = fdsetfd_list;
1879 fdsetfd_list = fdsetfd_info;
1880 }
1881
1882 fdset_info->value->fds = fdsetfd_list;
1883
1884 fdset_info->next = fdset_list;
1885 fdset_list = fdset_info;
1886 }
1887
1888 return fdset_list;
1889}
1890
Corey Bryante446f702012-10-18 15:19:32 -04001891AddfdInfo *monitor_fdset_add_fd(int fd, bool has_fdset_id, int64_t fdset_id,
1892 bool has_opaque, const char *opaque,
1893 Error **errp)
1894{
1895 MonFdset *mon_fdset = NULL;
1896 MonFdsetFd *mon_fdset_fd;
1897 AddfdInfo *fdinfo;
1898
1899 if (has_fdset_id) {
1900 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
1901 /* Break if match found or match impossible due to ordering by ID */
1902 if (fdset_id <= mon_fdset->id) {
1903 if (fdset_id < mon_fdset->id) {
1904 mon_fdset = NULL;
1905 }
1906 break;
1907 }
1908 }
1909 }
1910
1911 if (mon_fdset == NULL) {
1912 int64_t fdset_id_prev = -1;
1913 MonFdset *mon_fdset_cur = QLIST_FIRST(&mon_fdsets);
1914
1915 if (has_fdset_id) {
1916 if (fdset_id < 0) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01001917 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "fdset-id",
1918 "a non-negative value");
Corey Bryante446f702012-10-18 15:19:32 -04001919 return NULL;
1920 }
1921 /* Use specified fdset ID */
1922 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
1923 mon_fdset_cur = mon_fdset;
1924 if (fdset_id < mon_fdset_cur->id) {
1925 break;
1926 }
1927 }
1928 } else {
1929 /* Use first available fdset ID */
1930 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
1931 mon_fdset_cur = mon_fdset;
1932 if (fdset_id_prev == mon_fdset_cur->id - 1) {
1933 fdset_id_prev = mon_fdset_cur->id;
1934 continue;
1935 }
1936 break;
1937 }
1938 }
1939
1940 mon_fdset = g_malloc0(sizeof(*mon_fdset));
1941 if (has_fdset_id) {
1942 mon_fdset->id = fdset_id;
1943 } else {
1944 mon_fdset->id = fdset_id_prev + 1;
1945 }
1946
1947 /* The fdset list is ordered by fdset ID */
1948 if (!mon_fdset_cur) {
1949 QLIST_INSERT_HEAD(&mon_fdsets, mon_fdset, next);
1950 } else if (mon_fdset->id < mon_fdset_cur->id) {
1951 QLIST_INSERT_BEFORE(mon_fdset_cur, mon_fdset, next);
1952 } else {
1953 QLIST_INSERT_AFTER(mon_fdset_cur, mon_fdset, next);
1954 }
1955 }
1956
1957 mon_fdset_fd = g_malloc0(sizeof(*mon_fdset_fd));
1958 mon_fdset_fd->fd = fd;
1959 mon_fdset_fd->removed = false;
1960 if (has_opaque) {
1961 mon_fdset_fd->opaque = g_strdup(opaque);
1962 }
1963 QLIST_INSERT_HEAD(&mon_fdset->fds, mon_fdset_fd, next);
1964
1965 fdinfo = g_malloc0(sizeof(*fdinfo));
1966 fdinfo->fdset_id = mon_fdset->id;
1967 fdinfo->fd = mon_fdset_fd->fd;
1968
1969 return fdinfo;
1970}
1971
Corey Bryantadb696f2012-08-14 16:43:47 -04001972int monitor_fdset_get_fd(int64_t fdset_id, int flags)
1973{
Blue Swirlb2dc64c2012-08-18 20:14:54 +00001974#ifndef _WIN32
Corey Bryantadb696f2012-08-14 16:43:47 -04001975 MonFdset *mon_fdset;
1976 MonFdsetFd *mon_fdset_fd;
1977 int mon_fd_flags;
1978
Corey Bryantadb696f2012-08-14 16:43:47 -04001979 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
1980 if (mon_fdset->id != fdset_id) {
1981 continue;
1982 }
1983 QLIST_FOREACH(mon_fdset_fd, &mon_fdset->fds, next) {
1984 mon_fd_flags = fcntl(mon_fdset_fd->fd, F_GETFL);
1985 if (mon_fd_flags == -1) {
1986 return -1;
1987 }
1988
1989 if ((flags & O_ACCMODE) == (mon_fd_flags & O_ACCMODE)) {
1990 return mon_fdset_fd->fd;
1991 }
1992 }
1993 errno = EACCES;
1994 return -1;
1995 }
1996#endif
1997
1998 errno = ENOENT;
1999 return -1;
2000}
2001
2002int monitor_fdset_dup_fd_add(int64_t fdset_id, int dup_fd)
2003{
2004 MonFdset *mon_fdset;
2005 MonFdsetFd *mon_fdset_fd_dup;
2006
2007 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
2008 if (mon_fdset->id != fdset_id) {
2009 continue;
2010 }
2011 QLIST_FOREACH(mon_fdset_fd_dup, &mon_fdset->dup_fds, next) {
2012 if (mon_fdset_fd_dup->fd == dup_fd) {
2013 return -1;
2014 }
2015 }
2016 mon_fdset_fd_dup = g_malloc0(sizeof(*mon_fdset_fd_dup));
2017 mon_fdset_fd_dup->fd = dup_fd;
2018 QLIST_INSERT_HEAD(&mon_fdset->dup_fds, mon_fdset_fd_dup, next);
2019 return 0;
2020 }
2021 return -1;
2022}
2023
2024static int monitor_fdset_dup_fd_find_remove(int dup_fd, bool remove)
2025{
2026 MonFdset *mon_fdset;
2027 MonFdsetFd *mon_fdset_fd_dup;
2028
2029 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
2030 QLIST_FOREACH(mon_fdset_fd_dup, &mon_fdset->dup_fds, next) {
2031 if (mon_fdset_fd_dup->fd == dup_fd) {
2032 if (remove) {
2033 QLIST_REMOVE(mon_fdset_fd_dup, next);
2034 if (QLIST_EMPTY(&mon_fdset->dup_fds)) {
2035 monitor_fdset_cleanup(mon_fdset);
2036 }
Michael S. Tsirkinb3dd1b82014-08-17 11:45:17 +02002037 return -1;
2038 } else {
2039 return mon_fdset->id;
Corey Bryantadb696f2012-08-14 16:43:47 -04002040 }
Corey Bryantadb696f2012-08-14 16:43:47 -04002041 }
2042 }
2043 }
2044 return -1;
2045}
2046
2047int monitor_fdset_dup_fd_find(int dup_fd)
2048{
2049 return monitor_fdset_dup_fd_find_remove(dup_fd, false);
2050}
2051
Michael S. Tsirkinb3dd1b82014-08-17 11:45:17 +02002052void monitor_fdset_dup_fd_remove(int dup_fd)
Corey Bryantadb696f2012-08-14 16:43:47 -04002053{
Michael S. Tsirkinb3dd1b82014-08-17 11:45:17 +02002054 monitor_fdset_dup_fd_find_remove(dup_fd, true);
Corey Bryantadb696f2012-08-14 16:43:47 -04002055}
2056
Markus Armbruster1677f4c2015-02-09 14:03:19 +01002057int monitor_fd_param(Monitor *mon, const char *fdname, Error **errp)
Laszlo Ersek59063662014-04-10 10:24:31 +02002058{
2059 int fd;
2060 Error *local_err = NULL;
2061
2062 if (!qemu_isdigit(fdname[0]) && mon) {
Paolo Bonzinia9940fc2012-09-20 16:50:32 +02002063 fd = monitor_get_fd(mon, fdname, &local_err);
Nicholas Bellingera96ed022012-08-21 20:52:07 +00002064 } else {
2065 fd = qemu_parse_fd(fdname);
Laszlo Ersek59063662014-04-10 10:24:31 +02002066 if (fd == -1) {
2067 error_setg(&local_err, "Invalid file descriptor number '%s'",
2068 fdname);
2069 }
2070 }
2071 if (local_err) {
2072 error_propagate(errp, local_err);
2073 assert(fd == -1);
2074 } else {
2075 assert(fd != -1);
Nicholas Bellingera96ed022012-08-21 20:52:07 +00002076 }
2077
2078 return fd;
2079}
2080
Luiz Capitulinoacd0a092010-09-30 16:00:22 -03002081/* Please update hmp-commands.hx when adding or changing commands */
Wayne Xia816f8922011-10-12 11:32:41 +08002082static mon_cmd_t info_cmds[] = {
Pavel Butsykinda76ee72015-09-10 18:38:58 +03002083#include "hmp-commands-info.h"
2084 { NULL, NULL, },
bellard9dc39cb2004-03-14 21:38:27 +00002085};
2086
Wenchao Xiaa13ced52013-01-14 14:06:28 +08002087/* mon_cmds and info_cmds would be sorted at runtime */
2088static mon_cmd_t mon_cmds[] = {
2089#include "hmp-commands.h"
2090 { NULL, NULL, },
2091};
2092
Luiz Capitulinof36b4af2010-09-15 17:17:45 -03002093static const mon_cmd_t qmp_cmds[] = {
Anthony Liguorie3193602011-09-02 12:34:47 -05002094#include "qmp-commands-old.h"
Luiz Capitulinof36b4af2010-09-15 17:17:45 -03002095 { /* NULL */ },
2096};
2097
bellard9307c4c2004-04-04 12:57:25 +00002098/*******************************************************************/
2099
2100static const char *pch;
Peter Maydell6ab7e542013-02-20 15:21:09 +00002101static sigjmp_buf expr_env;
bellard9307c4c2004-04-04 12:57:25 +00002102
bellard9307c4c2004-04-04 12:57:25 +00002103
Stefan Weil9c3175c2013-08-22 21:30:09 +02002104static void GCC_FMT_ATTR(2, 3) QEMU_NORETURN
2105expr_error(Monitor *mon, const char *fmt, ...)
bellard9dc39cb2004-03-14 21:38:27 +00002106{
Fam Zheng277acfe2013-08-20 10:58:21 +08002107 va_list ap;
2108 va_start(ap, fmt);
2109 monitor_vprintf(mon, fmt, ap);
2110 monitor_printf(mon, "\n");
2111 va_end(ap);
Peter Maydell6ab7e542013-02-20 15:21:09 +00002112 siglongjmp(expr_env, 1);
bellard9307c4c2004-04-04 12:57:25 +00002113}
2114
Markus Armbruster09b94182010-01-20 13:07:30 +01002115/* return 0 if OK, -1 if not found */
bellard92a31b12005-02-10 22:00:52 +00002116static int get_monitor_def(target_long *pval, const char *name)
bellard9307c4c2004-04-04 12:57:25 +00002117{
Pavel Butsykinbf957282015-09-10 18:38:59 +03002118 const MonitorDef *md = target_monitor_defs();
bellard92a31b12005-02-10 22:00:52 +00002119 void *ptr;
2120
Pavel Butsykinbf957282015-09-10 18:38:59 +03002121 if (md == NULL) {
2122 return -1;
2123 }
2124
2125 for(; md->name != NULL; md++) {
bellard9307c4c2004-04-04 12:57:25 +00002126 if (compare_cmd(name, md->name)) {
2127 if (md->get_value) {
bellarde95c8d52004-09-30 22:22:08 +00002128 *pval = md->get_value(md, md->offset);
bellard9307c4c2004-04-04 12:57:25 +00002129 } else {
Peter Crosthwaite5bcda5f2015-05-24 14:20:40 -07002130 CPUArchState *env = mon_get_cpu_env();
bellard6a00d602005-11-21 23:25:50 +00002131 ptr = (uint8_t *)env + md->offset;
bellard92a31b12005-02-10 22:00:52 +00002132 switch(md->type) {
2133 case MD_I32:
2134 *pval = *(int32_t *)ptr;
2135 break;
2136 case MD_TLONG:
2137 *pval = *(target_long *)ptr;
2138 break;
2139 default:
2140 *pval = 0;
2141 break;
2142 }
bellard9307c4c2004-04-04 12:57:25 +00002143 }
2144 return 0;
2145 }
2146 }
2147 return -1;
2148}
2149
2150static void next(void)
2151{
Blue Swirl660f11b2009-07-31 21:16:51 +00002152 if (*pch != '\0') {
bellard9307c4c2004-04-04 12:57:25 +00002153 pch++;
blueswir1cd390082008-11-16 13:53:32 +00002154 while (qemu_isspace(*pch))
bellard9307c4c2004-04-04 12:57:25 +00002155 pch++;
2156 }
2157}
2158
aliguori376253e2009-03-05 23:01:23 +00002159static int64_t expr_sum(Monitor *mon);
bellard9307c4c2004-04-04 12:57:25 +00002160
aliguori376253e2009-03-05 23:01:23 +00002161static int64_t expr_unary(Monitor *mon)
bellard9307c4c2004-04-04 12:57:25 +00002162{
blueswir1c2efc952007-09-25 17:28:42 +00002163 int64_t n;
bellard9307c4c2004-04-04 12:57:25 +00002164 char *p;
bellard6a00d602005-11-21 23:25:50 +00002165 int ret;
bellard9307c4c2004-04-04 12:57:25 +00002166
2167 switch(*pch) {
2168 case '+':
2169 next();
aliguori376253e2009-03-05 23:01:23 +00002170 n = expr_unary(mon);
bellard9307c4c2004-04-04 12:57:25 +00002171 break;
2172 case '-':
2173 next();
aliguori376253e2009-03-05 23:01:23 +00002174 n = -expr_unary(mon);
bellard9307c4c2004-04-04 12:57:25 +00002175 break;
2176 case '~':
2177 next();
aliguori376253e2009-03-05 23:01:23 +00002178 n = ~expr_unary(mon);
bellard9307c4c2004-04-04 12:57:25 +00002179 break;
2180 case '(':
2181 next();
aliguori376253e2009-03-05 23:01:23 +00002182 n = expr_sum(mon);
bellard9307c4c2004-04-04 12:57:25 +00002183 if (*pch != ')') {
aliguori376253e2009-03-05 23:01:23 +00002184 expr_error(mon, "')' expected");
bellard9307c4c2004-04-04 12:57:25 +00002185 }
2186 next();
2187 break;
bellard81d09122004-07-14 17:21:37 +00002188 case '\'':
2189 pch++;
2190 if (*pch == '\0')
aliguori376253e2009-03-05 23:01:23 +00002191 expr_error(mon, "character constant expected");
bellard81d09122004-07-14 17:21:37 +00002192 n = *pch;
2193 pch++;
2194 if (*pch != '\'')
aliguori376253e2009-03-05 23:01:23 +00002195 expr_error(mon, "missing terminating \' character");
bellard81d09122004-07-14 17:21:37 +00002196 next();
2197 break;
bellard9307c4c2004-04-04 12:57:25 +00002198 case '$':
2199 {
2200 char buf[128], *q;
ths69b34972007-12-17 03:15:52 +00002201 target_long reg=0;
ths3b46e622007-09-17 08:09:54 +00002202
bellard9307c4c2004-04-04 12:57:25 +00002203 pch++;
2204 q = buf;
2205 while ((*pch >= 'a' && *pch <= 'z') ||
2206 (*pch >= 'A' && *pch <= 'Z') ||
2207 (*pch >= '0' && *pch <= '9') ||
bellard57206fd2004-04-25 18:54:52 +00002208 *pch == '_' || *pch == '.') {
bellard9307c4c2004-04-04 12:57:25 +00002209 if ((q - buf) < sizeof(buf) - 1)
2210 *q++ = *pch;
2211 pch++;
2212 }
blueswir1cd390082008-11-16 13:53:32 +00002213 while (qemu_isspace(*pch))
bellard9307c4c2004-04-04 12:57:25 +00002214 pch++;
2215 *q = 0;
blueswir17743e582007-09-24 18:39:04 +00002216 ret = get_monitor_def(&reg, buf);
Markus Armbruster09b94182010-01-20 13:07:30 +01002217 if (ret < 0)
aliguori376253e2009-03-05 23:01:23 +00002218 expr_error(mon, "unknown register");
blueswir17743e582007-09-24 18:39:04 +00002219 n = reg;
bellard9307c4c2004-04-04 12:57:25 +00002220 }
2221 break;
2222 case '\0':
aliguori376253e2009-03-05 23:01:23 +00002223 expr_error(mon, "unexpected end of expression");
bellard9307c4c2004-04-04 12:57:25 +00002224 n = 0;
2225 break;
2226 default:
Luiz Capitulino6b0e33b2012-04-26 16:48:41 -03002227 errno = 0;
bellard4f4fbf72006-06-25 18:28:12 +00002228 n = strtoull(pch, &p, 0);
Luiz Capitulino6b0e33b2012-04-26 16:48:41 -03002229 if (errno == ERANGE) {
2230 expr_error(mon, "number too large");
2231 }
bellard9307c4c2004-04-04 12:57:25 +00002232 if (pch == p) {
Fam Zheng277acfe2013-08-20 10:58:21 +08002233 expr_error(mon, "invalid char '%c' in expression", *p);
bellard9307c4c2004-04-04 12:57:25 +00002234 }
2235 pch = p;
blueswir1cd390082008-11-16 13:53:32 +00002236 while (qemu_isspace(*pch))
bellard9307c4c2004-04-04 12:57:25 +00002237 pch++;
2238 break;
2239 }
2240 return n;
2241}
2242
2243
aliguori376253e2009-03-05 23:01:23 +00002244static int64_t expr_prod(Monitor *mon)
bellard9307c4c2004-04-04 12:57:25 +00002245{
blueswir1c2efc952007-09-25 17:28:42 +00002246 int64_t val, val2;
bellard92a31b12005-02-10 22:00:52 +00002247 int op;
ths3b46e622007-09-17 08:09:54 +00002248
aliguori376253e2009-03-05 23:01:23 +00002249 val = expr_unary(mon);
bellard9307c4c2004-04-04 12:57:25 +00002250 for(;;) {
2251 op = *pch;
2252 if (op != '*' && op != '/' && op != '%')
2253 break;
2254 next();
aliguori376253e2009-03-05 23:01:23 +00002255 val2 = expr_unary(mon);
bellard9307c4c2004-04-04 12:57:25 +00002256 switch(op) {
2257 default:
2258 case '*':
2259 val *= val2;
2260 break;
2261 case '/':
2262 case '%':
ths5fafdf22007-09-16 21:08:06 +00002263 if (val2 == 0)
aliguori376253e2009-03-05 23:01:23 +00002264 expr_error(mon, "division by zero");
bellard9307c4c2004-04-04 12:57:25 +00002265 if (op == '/')
2266 val /= val2;
2267 else
2268 val %= val2;
2269 break;
2270 }
2271 }
2272 return val;
2273}
2274
aliguori376253e2009-03-05 23:01:23 +00002275static int64_t expr_logic(Monitor *mon)
bellard9307c4c2004-04-04 12:57:25 +00002276{
blueswir1c2efc952007-09-25 17:28:42 +00002277 int64_t val, val2;
bellard92a31b12005-02-10 22:00:52 +00002278 int op;
bellard9307c4c2004-04-04 12:57:25 +00002279
aliguori376253e2009-03-05 23:01:23 +00002280 val = expr_prod(mon);
bellard9307c4c2004-04-04 12:57:25 +00002281 for(;;) {
2282 op = *pch;
2283 if (op != '&' && op != '|' && op != '^')
2284 break;
2285 next();
aliguori376253e2009-03-05 23:01:23 +00002286 val2 = expr_prod(mon);
bellard9307c4c2004-04-04 12:57:25 +00002287 switch(op) {
2288 default:
2289 case '&':
2290 val &= val2;
2291 break;
2292 case '|':
2293 val |= val2;
2294 break;
2295 case '^':
2296 val ^= val2;
2297 break;
2298 }
2299 }
2300 return val;
2301}
2302
aliguori376253e2009-03-05 23:01:23 +00002303static int64_t expr_sum(Monitor *mon)
bellard9307c4c2004-04-04 12:57:25 +00002304{
blueswir1c2efc952007-09-25 17:28:42 +00002305 int64_t val, val2;
bellard92a31b12005-02-10 22:00:52 +00002306 int op;
bellard9307c4c2004-04-04 12:57:25 +00002307
aliguori376253e2009-03-05 23:01:23 +00002308 val = expr_logic(mon);
bellard9307c4c2004-04-04 12:57:25 +00002309 for(;;) {
2310 op = *pch;
2311 if (op != '+' && op != '-')
2312 break;
2313 next();
aliguori376253e2009-03-05 23:01:23 +00002314 val2 = expr_logic(mon);
bellard9307c4c2004-04-04 12:57:25 +00002315 if (op == '+')
2316 val += val2;
2317 else
2318 val -= val2;
2319 }
2320 return val;
2321}
2322
aliguori376253e2009-03-05 23:01:23 +00002323static int get_expr(Monitor *mon, int64_t *pval, const char **pp)
bellard9307c4c2004-04-04 12:57:25 +00002324{
2325 pch = *pp;
Peter Maydell6ab7e542013-02-20 15:21:09 +00002326 if (sigsetjmp(expr_env, 0)) {
bellard9307c4c2004-04-04 12:57:25 +00002327 *pp = pch;
2328 return -1;
2329 }
blueswir1cd390082008-11-16 13:53:32 +00002330 while (qemu_isspace(*pch))
bellard9307c4c2004-04-04 12:57:25 +00002331 pch++;
aliguori376253e2009-03-05 23:01:23 +00002332 *pval = expr_sum(mon);
bellard9307c4c2004-04-04 12:57:25 +00002333 *pp = pch;
2334 return 0;
2335}
2336
Markus Armbruster3350a4d2010-01-25 14:23:03 +01002337static int get_double(Monitor *mon, double *pval, const char **pp)
2338{
2339 const char *p = *pp;
2340 char *tailp;
2341 double d;
2342
2343 d = strtod(p, &tailp);
2344 if (tailp == p) {
2345 monitor_printf(mon, "Number expected\n");
2346 return -1;
2347 }
2348 if (d != d || d - d != 0) {
2349 /* NaN or infinity */
2350 monitor_printf(mon, "Bad number\n");
2351 return -1;
2352 }
2353 *pval = d;
2354 *pp = tailp;
2355 return 0;
2356}
2357
Luiz Capitulino4590fd82009-06-09 18:21:30 -03002358/*
2359 * Store the command-name in cmdname, and return a pointer to
2360 * the remaining of the command string.
2361 */
2362static const char *get_command_name(const char *cmdline,
2363 char *cmdname, size_t nlen)
2364{
2365 size_t len;
2366 const char *p, *pstart;
2367
2368 p = cmdline;
2369 while (qemu_isspace(*p))
2370 p++;
2371 if (*p == '\0')
2372 return NULL;
2373 pstart = p;
2374 while (*p != '\0' && *p != '/' && !qemu_isspace(*p))
2375 p++;
2376 len = p - pstart;
2377 if (len > nlen - 1)
2378 len = nlen - 1;
2379 memcpy(cmdname, pstart, len);
2380 cmdname[len] = '\0';
2381 return p;
2382}
2383
Luiz Capitulino4d76d2b2009-08-28 15:27:09 -03002384/**
2385 * Read key of 'type' into 'key' and return the current
2386 * 'type' pointer.
2387 */
2388static char *key_get_info(const char *type, char **key)
2389{
2390 size_t len;
2391 char *p, *str;
2392
2393 if (*type == ',')
2394 type++;
2395
2396 p = strchr(type, ':');
2397 if (!p) {
2398 *key = NULL;
2399 return NULL;
2400 }
2401 len = p - type;
2402
Anthony Liguori7267c092011-08-20 22:09:37 -05002403 str = g_malloc(len + 1);
Luiz Capitulino4d76d2b2009-08-28 15:27:09 -03002404 memcpy(str, type, len);
2405 str[len] = '\0';
2406
2407 *key = str;
2408 return ++p;
2409}
2410
bellard9307c4c2004-04-04 12:57:25 +00002411static int default_fmt_format = 'x';
2412static int default_fmt_size = 4;
2413
lirans@il.ibm.comfbc3d962009-11-02 15:41:13 +02002414static int is_valid_option(const char *c, const char *typestr)
2415{
2416 char option[3];
2417
2418 option[0] = '-';
2419 option[1] = *c;
2420 option[2] = '\0';
2421
2422 typestr = strstr(typestr, option);
2423 return (typestr != NULL);
2424}
2425
Luiz Capitulino945c5ac2010-09-13 13:17:58 -03002426static const mon_cmd_t *search_dispatch_table(const mon_cmd_t *disp_table,
2427 const char *cmdname)
Luiz Capitulino7fd669a2009-11-26 22:58:54 -02002428{
2429 const mon_cmd_t *cmd;
2430
Luiz Capitulino945c5ac2010-09-13 13:17:58 -03002431 for (cmd = disp_table; cmd->name != NULL; cmd++) {
Luiz Capitulino7fd669a2009-11-26 22:58:54 -02002432 if (compare_cmd(cmdname, cmd->name)) {
2433 return cmd;
2434 }
2435 }
2436
2437 return NULL;
2438}
2439
Luiz Capitulinobead3ce2010-09-15 17:08:39 -03002440static const mon_cmd_t *qmp_find_cmd(const char *cmdname)
2441{
Luiz Capitulinof36b4af2010-09-15 17:17:45 -03002442 return search_dispatch_table(qmp_cmds, cmdname);
Luiz Capitulinobead3ce2010-09-15 17:08:39 -03002443}
2444
Wenchao Xia5f3d3352013-01-14 14:06:27 +08002445/*
Bandan Dasae502122015-06-03 18:38:08 -04002446 * Parse command name from @cmdp according to command table @table.
2447 * If blank, return NULL.
2448 * Else, if no valid command can be found, report to @mon, and return
2449 * NULL.
2450 * Else, change @cmdp to point right behind the name, and return its
2451 * command table entry.
2452 * Do not assume the return value points into @table! It doesn't when
2453 * the command is found in a sub-command table.
Wenchao Xia5f3d3352013-01-14 14:06:27 +08002454 */
Anthony Liguoric227f092009-10-01 16:12:16 -05002455static const mon_cmd_t *monitor_parse_command(Monitor *mon,
Bandan Dasae502122015-06-03 18:38:08 -04002456 const char **cmdp,
2457 mon_cmd_t *table)
bellard9307c4c2004-04-04 12:57:25 +00002458{
Bandan Dasae502122015-06-03 18:38:08 -04002459 const char *p;
Anthony Liguoric227f092009-10-01 16:12:16 -05002460 const mon_cmd_t *cmd;
bellard9307c4c2004-04-04 12:57:25 +00002461 char cmdname[256];
bellard9dc39cb2004-03-14 21:38:27 +00002462
bellard9307c4c2004-04-04 12:57:25 +00002463 /* extract the command name */
Bandan Dasae502122015-06-03 18:38:08 -04002464 p = get_command_name(*cmdp, cmdname, sizeof(cmdname));
Luiz Capitulino4590fd82009-06-09 18:21:30 -03002465 if (!p)
Luiz Capitulino55f81d92009-08-28 15:27:22 -03002466 return NULL;
ths3b46e622007-09-17 08:09:54 +00002467
Wenchao Xia5f3d3352013-01-14 14:06:27 +08002468 cmd = search_dispatch_table(table, cmdname);
Luiz Capitulino7fd669a2009-11-26 22:58:54 -02002469 if (!cmd) {
Wenchao Xia5f3d3352013-01-14 14:06:27 +08002470 monitor_printf(mon, "unknown command: '%.*s'\n",
Bandan Dasae502122015-06-03 18:38:08 -04002471 (int)(p - *cmdp), *cmdp);
Luiz Capitulino55f81d92009-08-28 15:27:22 -03002472 return NULL;
Luiz Capitulinod91d9bf2009-06-09 18:21:54 -03002473 }
bellard9307c4c2004-04-04 12:57:25 +00002474
Wenchao Xia5f3d3352013-01-14 14:06:27 +08002475 /* filter out following useless space */
2476 while (qemu_isspace(*p)) {
2477 p++;
2478 }
Bandan Dasae502122015-06-03 18:38:08 -04002479
2480 *cmdp = p;
Wenchao Xia5f3d3352013-01-14 14:06:27 +08002481 /* search sub command */
Bandan Dasae502122015-06-03 18:38:08 -04002482 if (cmd->sub_table != NULL && *p != '\0') {
2483 return monitor_parse_command(mon, cmdp, cmd->sub_table);
Wenchao Xia5f3d3352013-01-14 14:06:27 +08002484 }
2485
Bandan Dasae502122015-06-03 18:38:08 -04002486 return cmd;
2487}
2488
2489/*
2490 * Parse arguments for @cmd.
2491 * If it can't be parsed, report to @mon, and return NULL.
2492 * Else, insert command arguments into a QDict, and return it.
2493 * Note: On success, caller has to free the QDict structure.
2494 */
2495
2496static QDict *monitor_parse_arguments(Monitor *mon,
2497 const char **endp,
2498 const mon_cmd_t *cmd)
2499{
2500 const char *typestr;
2501 char *key;
2502 int c;
2503 const char *p = *endp;
2504 char buf[1024];
2505 QDict *qdict = qdict_new();
2506
bellard9307c4c2004-04-04 12:57:25 +00002507 /* parse the parameters */
2508 typestr = cmd->args_type;
bellard9307c4c2004-04-04 12:57:25 +00002509 for(;;) {
Luiz Capitulino4d76d2b2009-08-28 15:27:09 -03002510 typestr = key_get_info(typestr, &key);
2511 if (!typestr)
bellard9307c4c2004-04-04 12:57:25 +00002512 break;
Luiz Capitulino4d76d2b2009-08-28 15:27:09 -03002513 c = *typestr;
bellard9307c4c2004-04-04 12:57:25 +00002514 typestr++;
2515 switch(c) {
2516 case 'F':
bellard81d09122004-07-14 17:21:37 +00002517 case 'B':
bellard9307c4c2004-04-04 12:57:25 +00002518 case 's':
2519 {
2520 int ret;
ths3b46e622007-09-17 08:09:54 +00002521
blueswir1cd390082008-11-16 13:53:32 +00002522 while (qemu_isspace(*p))
bellard9307c4c2004-04-04 12:57:25 +00002523 p++;
2524 if (*typestr == '?') {
2525 typestr++;
2526 if (*p == '\0') {
2527 /* no optional string: NULL argument */
Luiz Capitulino53773582009-08-28 15:27:25 -03002528 break;
bellard9307c4c2004-04-04 12:57:25 +00002529 }
2530 }
2531 ret = get_str(buf, sizeof(buf), &p);
2532 if (ret < 0) {
bellard81d09122004-07-14 17:21:37 +00002533 switch(c) {
2534 case 'F':
aliguori376253e2009-03-05 23:01:23 +00002535 monitor_printf(mon, "%s: filename expected\n",
Bandan Dasae502122015-06-03 18:38:08 -04002536 cmd->name);
bellard81d09122004-07-14 17:21:37 +00002537 break;
2538 case 'B':
aliguori376253e2009-03-05 23:01:23 +00002539 monitor_printf(mon, "%s: block device name expected\n",
Bandan Dasae502122015-06-03 18:38:08 -04002540 cmd->name);
bellard81d09122004-07-14 17:21:37 +00002541 break;
2542 default:
Bandan Dasae502122015-06-03 18:38:08 -04002543 monitor_printf(mon, "%s: string expected\n", cmd->name);
bellard81d09122004-07-14 17:21:37 +00002544 break;
2545 }
bellard9307c4c2004-04-04 12:57:25 +00002546 goto fail;
2547 }
Luiz Capitulino53773582009-08-28 15:27:25 -03002548 qdict_put(qdict, key, qstring_from_str(buf));
bellard9307c4c2004-04-04 12:57:25 +00002549 }
2550 break;
Markus Armbruster361127d2010-02-10 20:24:35 +01002551 case 'O':
2552 {
2553 QemuOptsList *opts_list;
2554 QemuOpts *opts;
2555
2556 opts_list = qemu_find_opts(key);
2557 if (!opts_list || opts_list->desc->name) {
2558 goto bad_type;
2559 }
2560 while (qemu_isspace(*p)) {
2561 p++;
2562 }
2563 if (!*p)
2564 break;
2565 if (get_str(buf, sizeof(buf), &p) < 0) {
2566 goto fail;
2567 }
Markus Armbruster70b94332015-02-13 12:50:26 +01002568 opts = qemu_opts_parse_noisily(opts_list, buf, true);
Markus Armbruster361127d2010-02-10 20:24:35 +01002569 if (!opts) {
2570 goto fail;
2571 }
2572 qemu_opts_to_qdict(opts, qdict);
2573 qemu_opts_del(opts);
2574 }
2575 break;
bellard9307c4c2004-04-04 12:57:25 +00002576 case '/':
2577 {
2578 int count, format, size;
ths3b46e622007-09-17 08:09:54 +00002579
blueswir1cd390082008-11-16 13:53:32 +00002580 while (qemu_isspace(*p))
bellard9307c4c2004-04-04 12:57:25 +00002581 p++;
2582 if (*p == '/') {
2583 /* format found */
2584 p++;
2585 count = 1;
blueswir1cd390082008-11-16 13:53:32 +00002586 if (qemu_isdigit(*p)) {
bellard9307c4c2004-04-04 12:57:25 +00002587 count = 0;
blueswir1cd390082008-11-16 13:53:32 +00002588 while (qemu_isdigit(*p)) {
bellard9307c4c2004-04-04 12:57:25 +00002589 count = count * 10 + (*p - '0');
2590 p++;
2591 }
2592 }
2593 size = -1;
2594 format = -1;
2595 for(;;) {
2596 switch(*p) {
2597 case 'o':
2598 case 'd':
2599 case 'u':
2600 case 'x':
2601 case 'i':
2602 case 'c':
2603 format = *p++;
2604 break;
2605 case 'b':
2606 size = 1;
2607 p++;
2608 break;
2609 case 'h':
2610 size = 2;
2611 p++;
2612 break;
2613 case 'w':
2614 size = 4;
2615 p++;
2616 break;
2617 case 'g':
2618 case 'L':
2619 size = 8;
2620 p++;
2621 break;
2622 default:
2623 goto next;
2624 }
2625 }
2626 next:
blueswir1cd390082008-11-16 13:53:32 +00002627 if (*p != '\0' && !qemu_isspace(*p)) {
aliguori376253e2009-03-05 23:01:23 +00002628 monitor_printf(mon, "invalid char in format: '%c'\n",
2629 *p);
bellard9307c4c2004-04-04 12:57:25 +00002630 goto fail;
2631 }
bellard9307c4c2004-04-04 12:57:25 +00002632 if (format < 0)
2633 format = default_fmt_format;
bellard4c27ba22004-04-25 18:05:08 +00002634 if (format != 'i') {
2635 /* for 'i', not specifying a size gives -1 as size */
2636 if (size < 0)
2637 size = default_fmt_size;
aurel32e90f0092008-10-01 21:45:51 +00002638 default_fmt_size = size;
bellard4c27ba22004-04-25 18:05:08 +00002639 }
bellard9307c4c2004-04-04 12:57:25 +00002640 default_fmt_format = format;
2641 } else {
2642 count = 1;
2643 format = default_fmt_format;
bellard4c27ba22004-04-25 18:05:08 +00002644 if (format != 'i') {
2645 size = default_fmt_size;
2646 } else {
2647 size = -1;
2648 }
bellard9307c4c2004-04-04 12:57:25 +00002649 }
Luiz Capitulinof7188bb2009-08-28 15:27:10 -03002650 qdict_put(qdict, "count", qint_from_int(count));
2651 qdict_put(qdict, "format", qint_from_int(format));
2652 qdict_put(qdict, "size", qint_from_int(size));
bellard9307c4c2004-04-04 12:57:25 +00002653 }
2654 break;
2655 case 'i':
bellard92a31b12005-02-10 22:00:52 +00002656 case 'l':
Luiz Capitulinob6e098d2009-12-18 13:25:04 -02002657 case 'M':
bellard9307c4c2004-04-04 12:57:25 +00002658 {
blueswir1c2efc952007-09-25 17:28:42 +00002659 int64_t val;
blueswir17743e582007-09-24 18:39:04 +00002660
blueswir1cd390082008-11-16 13:53:32 +00002661 while (qemu_isspace(*p))
bellard9307c4c2004-04-04 12:57:25 +00002662 p++;
bellard34405572004-06-08 00:55:58 +00002663 if (*typestr == '?' || *typestr == '.') {
bellard34405572004-06-08 00:55:58 +00002664 if (*typestr == '?') {
Luiz Capitulino53773582009-08-28 15:27:25 -03002665 if (*p == '\0') {
2666 typestr++;
2667 break;
2668 }
bellard34405572004-06-08 00:55:58 +00002669 } else {
2670 if (*p == '.') {
2671 p++;
blueswir1cd390082008-11-16 13:53:32 +00002672 while (qemu_isspace(*p))
bellard34405572004-06-08 00:55:58 +00002673 p++;
bellard34405572004-06-08 00:55:58 +00002674 } else {
Luiz Capitulino53773582009-08-28 15:27:25 -03002675 typestr++;
2676 break;
bellard34405572004-06-08 00:55:58 +00002677 }
2678 }
bellard13224a82006-07-14 22:03:35 +00002679 typestr++;
bellard9307c4c2004-04-04 12:57:25 +00002680 }
aliguori376253e2009-03-05 23:01:23 +00002681 if (get_expr(mon, &val, &p))
bellard9307c4c2004-04-04 12:57:25 +00002682 goto fail;
Luiz Capitulino675ebef2009-08-28 15:27:26 -03002683 /* Check if 'i' is greater than 32-bit */
2684 if ((c == 'i') && ((val >> 32) & 0xffffffff)) {
Bandan Dasae502122015-06-03 18:38:08 -04002685 monitor_printf(mon, "\'%s\' has failed: ", cmd->name);
Luiz Capitulino675ebef2009-08-28 15:27:26 -03002686 monitor_printf(mon, "integer is for 32-bit values\n");
2687 goto fail;
Luiz Capitulinob6e098d2009-12-18 13:25:04 -02002688 } else if (c == 'M') {
Luiz Capitulino91162842012-04-26 17:34:30 -03002689 if (val < 0) {
2690 monitor_printf(mon, "enter a positive value\n");
2691 goto fail;
2692 }
Luiz Capitulinob6e098d2009-12-18 13:25:04 -02002693 val <<= 20;
Luiz Capitulino675ebef2009-08-28 15:27:26 -03002694 }
Luiz Capitulino53773582009-08-28 15:27:25 -03002695 qdict_put(qdict, key, qint_from_int(val));
bellard9307c4c2004-04-04 12:57:25 +00002696 }
2697 break;
Jes Sorensendbc0c672010-10-21 17:15:47 +02002698 case 'o':
2699 {
Jes Sorensen70b4f4b2011-01-05 11:41:02 +01002700 int64_t val;
Jes Sorensendbc0c672010-10-21 17:15:47 +02002701 char *end;
2702
2703 while (qemu_isspace(*p)) {
2704 p++;
2705 }
2706 if (*typestr == '?') {
2707 typestr++;
2708 if (*p == '\0') {
2709 break;
2710 }
2711 }
Marc-André Lureau4677bb42015-09-16 18:02:56 +02002712 val = qemu_strtosz(p, &end);
Jes Sorensendbc0c672010-10-21 17:15:47 +02002713 if (val < 0) {
2714 monitor_printf(mon, "invalid size\n");
2715 goto fail;
2716 }
2717 qdict_put(qdict, key, qint_from_int(val));
2718 p = end;
2719 }
2720 break;
Markus Armbrusterfccfb11e2010-01-25 14:23:06 +01002721 case 'T':
Markus Armbruster3350a4d2010-01-25 14:23:03 +01002722 {
2723 double val;
2724
2725 while (qemu_isspace(*p))
2726 p++;
2727 if (*typestr == '?') {
2728 typestr++;
2729 if (*p == '\0') {
2730 break;
2731 }
2732 }
2733 if (get_double(mon, &val, &p) < 0) {
2734 goto fail;
2735 }
Jes Sorensen07de3e62010-10-21 17:15:49 +02002736 if (p[0] && p[1] == 's') {
Markus Armbrusterfccfb11e2010-01-25 14:23:06 +01002737 switch (*p) {
2738 case 'm':
2739 val /= 1e3; p += 2; break;
2740 case 'u':
2741 val /= 1e6; p += 2; break;
2742 case 'n':
2743 val /= 1e9; p += 2; break;
2744 }
2745 }
Markus Armbruster3350a4d2010-01-25 14:23:03 +01002746 if (*p && !qemu_isspace(*p)) {
2747 monitor_printf(mon, "Unknown unit suffix\n");
2748 goto fail;
2749 }
2750 qdict_put(qdict, key, qfloat_from_double(val));
2751 }
2752 break;
Markus Armbruster942cd1f2010-03-26 09:07:09 +01002753 case 'b':
2754 {
2755 const char *beg;
Eric Blakefc48ffc2015-05-15 16:24:59 -06002756 bool val;
Markus Armbruster942cd1f2010-03-26 09:07:09 +01002757
2758 while (qemu_isspace(*p)) {
2759 p++;
2760 }
2761 beg = p;
2762 while (qemu_isgraph(*p)) {
2763 p++;
2764 }
2765 if (p - beg == 2 && !memcmp(beg, "on", p - beg)) {
Eric Blakefc48ffc2015-05-15 16:24:59 -06002766 val = true;
Markus Armbruster942cd1f2010-03-26 09:07:09 +01002767 } else if (p - beg == 3 && !memcmp(beg, "off", p - beg)) {
Eric Blakefc48ffc2015-05-15 16:24:59 -06002768 val = false;
Markus Armbruster942cd1f2010-03-26 09:07:09 +01002769 } else {
2770 monitor_printf(mon, "Expected 'on' or 'off'\n");
2771 goto fail;
2772 }
Eric Blakefc48ffc2015-05-15 16:24:59 -06002773 qdict_put(qdict, key, qbool_from_bool(val));
Markus Armbruster942cd1f2010-03-26 09:07:09 +01002774 }
2775 break;
bellard9307c4c2004-04-04 12:57:25 +00002776 case '-':
2777 {
lirans@il.ibm.comfbc3d962009-11-02 15:41:13 +02002778 const char *tmp = p;
Luiz Capitulinoeb159d12010-05-28 15:25:24 -03002779 int skip_key = 0;
bellard9307c4c2004-04-04 12:57:25 +00002780 /* option */
ths3b46e622007-09-17 08:09:54 +00002781
bellard9307c4c2004-04-04 12:57:25 +00002782 c = *typestr++;
2783 if (c == '\0')
2784 goto bad_type;
blueswir1cd390082008-11-16 13:53:32 +00002785 while (qemu_isspace(*p))
bellard9307c4c2004-04-04 12:57:25 +00002786 p++;
bellard9307c4c2004-04-04 12:57:25 +00002787 if (*p == '-') {
2788 p++;
lirans@il.ibm.comfbc3d962009-11-02 15:41:13 +02002789 if(c != *p) {
2790 if(!is_valid_option(p, typestr)) {
2791
2792 monitor_printf(mon, "%s: unsupported option -%c\n",
Bandan Dasae502122015-06-03 18:38:08 -04002793 cmd->name, *p);
lirans@il.ibm.comfbc3d962009-11-02 15:41:13 +02002794 goto fail;
2795 } else {
2796 skip_key = 1;
2797 }
bellard9307c4c2004-04-04 12:57:25 +00002798 }
lirans@il.ibm.comfbc3d962009-11-02 15:41:13 +02002799 if(skip_key) {
2800 p = tmp;
2801 } else {
Luiz Capitulinoeb159d12010-05-28 15:25:24 -03002802 /* has option */
lirans@il.ibm.comfbc3d962009-11-02 15:41:13 +02002803 p++;
Eric Blakefc48ffc2015-05-15 16:24:59 -06002804 qdict_put(qdict, key, qbool_from_bool(true));
lirans@il.ibm.comfbc3d962009-11-02 15:41:13 +02002805 }
bellard9307c4c2004-04-04 12:57:25 +00002806 }
bellard9307c4c2004-04-04 12:57:25 +00002807 }
2808 break;
Wenchao Xia129be002013-08-27 20:38:26 +08002809 case 'S':
2810 {
2811 /* package all remaining string */
2812 int len;
2813
2814 while (qemu_isspace(*p)) {
2815 p++;
2816 }
2817 if (*typestr == '?') {
2818 typestr++;
2819 if (*p == '\0') {
2820 /* no remaining string: NULL argument */
2821 break;
2822 }
2823 }
2824 len = strlen(p);
2825 if (len <= 0) {
2826 monitor_printf(mon, "%s: string expected\n",
Bandan Dasae502122015-06-03 18:38:08 -04002827 cmd->name);
Bandan Dase549d2a2015-06-03 18:38:10 -04002828 goto fail;
Wenchao Xia129be002013-08-27 20:38:26 +08002829 }
2830 qdict_put(qdict, key, qstring_from_str(p));
2831 p += len;
2832 }
2833 break;
bellard9307c4c2004-04-04 12:57:25 +00002834 default:
2835 bad_type:
Bandan Dasae502122015-06-03 18:38:08 -04002836 monitor_printf(mon, "%s: unknown type '%c'\n", cmd->name, c);
bellard9307c4c2004-04-04 12:57:25 +00002837 goto fail;
2838 }
Anthony Liguori7267c092011-08-20 22:09:37 -05002839 g_free(key);
Luiz Capitulino4d76d2b2009-08-28 15:27:09 -03002840 key = NULL;
bellard9307c4c2004-04-04 12:57:25 +00002841 }
2842 /* check that all arguments were parsed */
blueswir1cd390082008-11-16 13:53:32 +00002843 while (qemu_isspace(*p))
bellard9307c4c2004-04-04 12:57:25 +00002844 p++;
2845 if (*p != '\0') {
aliguori376253e2009-03-05 23:01:23 +00002846 monitor_printf(mon, "%s: extraneous characters at the end of line\n",
Bandan Dasae502122015-06-03 18:38:08 -04002847 cmd->name);
bellard9307c4c2004-04-04 12:57:25 +00002848 goto fail;
2849 }
2850
Bandan Dasae502122015-06-03 18:38:08 -04002851 return qdict;
Gerd Hoffmannac7531e2009-08-14 10:36:06 +02002852
Luiz Capitulino55f81d92009-08-28 15:27:22 -03002853fail:
Bandan Dasae502122015-06-03 18:38:08 -04002854 QDECREF(qdict);
Anthony Liguori7267c092011-08-20 22:09:37 -05002855 g_free(key);
Luiz Capitulino55f81d92009-08-28 15:27:22 -03002856 return NULL;
2857}
2858
Markus Armbruster7ef6cf62015-03-06 19:12:36 +01002859static void handle_hmp_command(Monitor *mon, const char *cmdline)
Luiz Capitulino55f81d92009-08-28 15:27:22 -03002860{
Luiz Capitulino55f81d92009-08-28 15:27:22 -03002861 QDict *qdict;
Anthony Liguoric227f092009-10-01 16:12:16 -05002862 const mon_cmd_t *cmd;
Luiz Capitulino55f81d92009-08-28 15:27:22 -03002863
Bandan Dasae502122015-06-03 18:38:08 -04002864 cmd = monitor_parse_command(mon, &cmdline, mon->cmd_table);
2865 if (!cmd) {
2866 return;
Luiz Capitulino55f81d92009-08-28 15:27:22 -03002867 }
2868
Bandan Dasae502122015-06-03 18:38:08 -04002869 qdict = monitor_parse_arguments(mon, &cmdline, cmd);
2870 if (!qdict) {
Bandan Dasdd41eea2015-06-03 18:38:09 -04002871 monitor_printf(mon, "Try \"help %s\" for more information\n",
2872 cmd->name);
Bandan Dasae502122015-06-03 18:38:08 -04002873 return;
2874 }
2875
2876 cmd->mhandler.cmd(mon, qdict);
Luiz Capitulinof7188bb2009-08-28 15:27:10 -03002877 QDECREF(qdict);
bellard9dc39cb2004-03-14 21:38:27 +00002878}
2879
Wenchao Xiacd5c6bb2013-08-27 20:38:13 +08002880static void cmd_completion(Monitor *mon, const char *name, const char *list)
bellard81d09122004-07-14 17:21:37 +00002881{
2882 const char *p, *pstart;
2883 char cmd[128];
2884 int len;
2885
2886 p = list;
2887 for(;;) {
2888 pstart = p;
2889 p = strchr(p, '|');
2890 if (!p)
2891 p = pstart + strlen(pstart);
2892 len = p - pstart;
2893 if (len > sizeof(cmd) - 2)
2894 len = sizeof(cmd) - 2;
2895 memcpy(cmd, pstart, len);
2896 cmd[len] = '\0';
2897 if (name[0] == '\0' || !strncmp(name, cmd, strlen(name))) {
Wenchao Xiacd5c6bb2013-08-27 20:38:13 +08002898 readline_add_completion(mon->rs, cmd);
bellard81d09122004-07-14 17:21:37 +00002899 }
2900 if (*p == '\0')
2901 break;
2902 p++;
2903 }
2904}
2905
Wenchao Xiacb8f68b2013-08-27 20:38:14 +08002906static void file_completion(Monitor *mon, const char *input)
bellard81d09122004-07-14 17:21:37 +00002907{
2908 DIR *ffs;
2909 struct dirent *d;
2910 char path[1024];
2911 char file[1024], file_prefix[1024];
2912 int input_path_len;
2913 const char *p;
2914
ths5fafdf22007-09-16 21:08:06 +00002915 p = strrchr(input, '/');
bellard81d09122004-07-14 17:21:37 +00002916 if (!p) {
2917 input_path_len = 0;
2918 pstrcpy(file_prefix, sizeof(file_prefix), input);
blueswir1363a37d2008-08-21 17:58:08 +00002919 pstrcpy(path, sizeof(path), ".");
bellard81d09122004-07-14 17:21:37 +00002920 } else {
2921 input_path_len = p - input + 1;
2922 memcpy(path, input, input_path_len);
2923 if (input_path_len > sizeof(path) - 1)
2924 input_path_len = sizeof(path) - 1;
2925 path[input_path_len] = '\0';
2926 pstrcpy(file_prefix, sizeof(file_prefix), p + 1);
2927 }
Bandan Das19f2db52015-06-03 18:38:07 -04002928
bellard81d09122004-07-14 17:21:37 +00002929 ffs = opendir(path);
2930 if (!ffs)
2931 return;
2932 for(;;) {
2933 struct stat sb;
2934 d = readdir(ffs);
2935 if (!d)
2936 break;
Kusanagi Kouichi46c7fc12010-10-20 18:00:01 +09002937
2938 if (strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0) {
2939 continue;
2940 }
2941
bellard81d09122004-07-14 17:21:37 +00002942 if (strstart(d->d_name, file_prefix, NULL)) {
2943 memcpy(file, input, input_path_len);
blueswir1363a37d2008-08-21 17:58:08 +00002944 if (input_path_len < sizeof(file))
2945 pstrcpy(file + input_path_len, sizeof(file) - input_path_len,
2946 d->d_name);
bellard81d09122004-07-14 17:21:37 +00002947 /* stat the file to find out if it's a directory.
2948 * In that case add a slash to speed up typing long paths
2949 */
Markus Armbrusterc951d9a2011-11-16 15:43:47 +01002950 if (stat(file, &sb) == 0 && S_ISDIR(sb.st_mode)) {
blueswir1363a37d2008-08-21 17:58:08 +00002951 pstrcat(file, sizeof(file), "/");
Markus Armbrusterc951d9a2011-11-16 15:43:47 +01002952 }
Wenchao Xiacb8f68b2013-08-27 20:38:14 +08002953 readline_add_completion(mon->rs, file);
bellard81d09122004-07-14 17:21:37 +00002954 }
2955 }
2956 closedir(ffs);
2957}
2958
Luiz Capitulino4d76d2b2009-08-28 15:27:09 -03002959static const char *next_arg_type(const char *typestr)
2960{
2961 const char *p = strchr(typestr, ':');
2962 return (p != NULL ? ++p : typestr);
2963}
2964
Hani Benhabiles40d19392014-05-07 23:41:30 +01002965static void add_completion_option(ReadLineState *rs, const char *str,
2966 const char *option)
2967{
2968 if (!str || !option) {
2969 return;
2970 }
2971 if (!strncmp(option, str, strlen(str))) {
2972 readline_add_completion(rs, option);
2973 }
2974}
2975
Hani Benhabiles13e315d2014-05-07 23:41:29 +01002976void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str)
2977{
2978 size_t len;
2979 ChardevBackendInfoList *list, *start;
2980
2981 if (nb_args != 2) {
2982 return;
2983 }
2984 len = strlen(str);
2985 readline_set_completion_index(rs, len);
2986
2987 start = list = qmp_query_chardev_backends(NULL);
2988 while (list) {
2989 const char *chr_name = list->value->name;
2990
2991 if (!strncmp(chr_name, str, len)) {
2992 readline_add_completion(rs, chr_name);
2993 }
2994 list = list->next;
2995 }
2996 qapi_free_ChardevBackendInfoList(start);
2997}
2998
Hani Benhabilesb162b492014-05-07 23:41:31 +01002999void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str)
3000{
3001 size_t len;
3002 int i;
3003
3004 if (nb_args != 2) {
3005 return;
3006 }
3007 len = strlen(str);
3008 readline_set_completion_index(rs, len);
3009 for (i = 0; NetClientOptionsKind_lookup[i]; i++) {
3010 add_completion_option(rs, str, NetClientOptionsKind_lookup[i]);
3011 }
3012}
3013
Hani Benhabiles2da1b3a2014-04-13 16:25:07 +01003014void device_add_completion(ReadLineState *rs, int nb_args, const char *str)
Hani Benhabiles992d3e62014-02-06 23:30:11 +01003015{
3016 GSList *list, *elt;
3017 size_t len;
3018
Hani Benhabiles2da1b3a2014-04-13 16:25:07 +01003019 if (nb_args != 2) {
3020 return;
3021 }
3022
Hani Benhabiles992d3e62014-02-06 23:30:11 +01003023 len = strlen(str);
3024 readline_set_completion_index(rs, len);
3025 list = elt = object_class_get_list(TYPE_DEVICE, false);
3026 while (elt) {
3027 const char *name;
3028 DeviceClass *dc = OBJECT_CLASS_CHECK(DeviceClass, elt->data,
3029 TYPE_DEVICE);
3030 name = object_class_get_name(OBJECT_CLASS(dc));
Hani Benhabiles2da1b3a2014-04-13 16:25:07 +01003031
3032 if (!dc->cannot_instantiate_with_device_add_yet
3033 && !strncmp(name, str, len)) {
Hani Benhabiles992d3e62014-02-06 23:30:11 +01003034 readline_add_completion(rs, name);
3035 }
3036 elt = elt->next;
3037 }
3038 g_slist_free(list);
3039}
3040
Hani Benhabilesbfa40f72014-04-13 16:25:06 +01003041void object_add_completion(ReadLineState *rs, int nb_args, const char *str)
Hani Benhabiles1094fd32014-02-06 23:30:13 +01003042{
3043 GSList *list, *elt;
3044 size_t len;
3045
Hani Benhabilesbfa40f72014-04-13 16:25:06 +01003046 if (nb_args != 2) {
3047 return;
3048 }
3049
Hani Benhabiles1094fd32014-02-06 23:30:13 +01003050 len = strlen(str);
3051 readline_set_completion_index(rs, len);
3052 list = elt = object_class_get_list(TYPE_USER_CREATABLE, false);
3053 while (elt) {
3054 const char *name;
3055
3056 name = object_class_get_name(OBJECT_CLASS(elt->data));
3057 if (!strncmp(name, str, len) && strcmp(name, TYPE_USER_CREATABLE)) {
3058 readline_add_completion(rs, name);
3059 }
3060 elt = elt->next;
3061 }
3062 g_slist_free(list);
3063}
3064
Zhu Guihua6a1fa9f2014-10-21 19:46:05 +08003065static void peripheral_device_del_completion(ReadLineState *rs,
3066 const char *str, size_t len)
3067{
Marcel Apfelbaum4cae4d52014-11-26 13:50:01 +02003068 Object *peripheral = container_get(qdev_get_machine(), "/peripheral");
3069 GSList *list, *item;
Zhu Guihua6a1fa9f2014-10-21 19:46:05 +08003070
Marcel Apfelbaum4cae4d52014-11-26 13:50:01 +02003071 list = qdev_build_hotpluggable_device_list(peripheral);
3072 if (!list) {
Zhu Guihua6a1fa9f2014-10-21 19:46:05 +08003073 return;
3074 }
3075
Zhu Guihua6a1fa9f2014-10-21 19:46:05 +08003076 for (item = list; item; item = g_slist_next(item)) {
3077 DeviceState *dev = item->data;
3078
3079 if (dev->id && !strncmp(str, dev->id, len)) {
3080 readline_add_completion(rs, dev->id);
3081 }
3082 }
3083
3084 g_slist_free(list);
3085}
3086
Hani Benhabiles6297d9a2014-05-07 23:41:28 +01003087void chardev_remove_completion(ReadLineState *rs, int nb_args, const char *str)
3088{
3089 size_t len;
3090 ChardevInfoList *list, *start;
3091
3092 if (nb_args != 2) {
3093 return;
3094 }
3095 len = strlen(str);
3096 readline_set_completion_index(rs, len);
3097
3098 start = list = qmp_query_chardev(NULL);
3099 while (list) {
3100 ChardevInfo *chr = list->value;
3101
3102 if (!strncmp(chr->label, str, len)) {
3103 readline_add_completion(rs, chr->label);
3104 }
3105 list = list->next;
3106 }
3107 qapi_free_ChardevInfoList(start);
3108}
3109
Hani Benhabiles8e597772014-05-27 23:39:30 +01003110static void ringbuf_completion(ReadLineState *rs, const char *str)
3111{
3112 size_t len;
3113 ChardevInfoList *list, *start;
3114
3115 len = strlen(str);
3116 readline_set_completion_index(rs, len);
3117
3118 start = list = qmp_query_chardev(NULL);
3119 while (list) {
3120 ChardevInfo *chr_info = list->value;
3121
3122 if (!strncmp(chr_info->label, str, len)) {
3123 CharDriverState *chr = qemu_chr_find(chr_info->label);
3124 if (chr && chr_is_ringbuf(chr)) {
3125 readline_add_completion(rs, chr_info->label);
3126 }
3127 }
3128 list = list->next;
3129 }
3130 qapi_free_ChardevInfoList(start);
3131}
3132
Hani Benhabiles8e597772014-05-27 23:39:30 +01003133void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str)
3134{
3135 if (nb_args != 2) {
3136 return;
3137 }
3138 ringbuf_completion(rs, str);
3139}
3140
Hani Benhabiles2da1b3a2014-04-13 16:25:07 +01003141void device_del_completion(ReadLineState *rs, int nb_args, const char *str)
3142{
3143 size_t len;
3144
3145 if (nb_args != 2) {
3146 return;
3147 }
3148
3149 len = strlen(str);
3150 readline_set_completion_index(rs, len);
Zhu Guihua6a1fa9f2014-10-21 19:46:05 +08003151 peripheral_device_del_completion(rs, str, len);
Hani Benhabiles2da1b3a2014-04-13 16:25:07 +01003152}
3153
Hani Benhabilesbfa40f72014-04-13 16:25:06 +01003154void object_del_completion(ReadLineState *rs, int nb_args, const char *str)
Hani Benhabilesb48fa072014-02-06 23:30:12 +01003155{
3156 ObjectPropertyInfoList *list, *start;
3157 size_t len;
3158
Hani Benhabilesbfa40f72014-04-13 16:25:06 +01003159 if (nb_args != 2) {
3160 return;
3161 }
Hani Benhabilesb48fa072014-02-06 23:30:12 +01003162 len = strlen(str);
3163 readline_set_completion_index(rs, len);
3164
3165 start = list = qmp_qom_list("/objects", NULL);
3166 while (list) {
3167 ObjectPropertyInfo *info = list->value;
3168
3169 if (!strncmp(info->type, "child<", 5)
3170 && !strncmp(info->name, str, len)) {
3171 readline_add_completion(rs, info->name);
3172 }
3173 list = list->next;
3174 }
3175 qapi_free_ObjectPropertyInfoList(start);
3176}
3177
Hani Benhabiles29136cd2014-05-07 23:41:27 +01003178void sendkey_completion(ReadLineState *rs, int nb_args, const char *str)
3179{
3180 int i;
3181 char *sep;
3182 size_t len;
3183
3184 if (nb_args != 2) {
3185 return;
3186 }
3187 sep = strrchr(str, '-');
3188 if (sep) {
3189 str = sep + 1;
3190 }
3191 len = strlen(str);
3192 readline_set_completion_index(rs, len);
3193 for (i = 0; i < Q_KEY_CODE_MAX; i++) {
3194 if (!strncmp(str, QKeyCode_lookup[i], len)) {
3195 readline_add_completion(rs, QKeyCode_lookup[i]);
3196 }
3197 }
3198}
3199
Hani Benhabiles40d19392014-05-07 23:41:30 +01003200void set_link_completion(ReadLineState *rs, int nb_args, const char *str)
3201{
3202 size_t len;
3203
3204 len = strlen(str);
3205 readline_set_completion_index(rs, len);
3206 if (nb_args == 2) {
Jason Wangeaed4832015-04-23 14:21:38 +08003207 NetClientState *ncs[MAX_QUEUE_NUM];
Hani Benhabiles40d19392014-05-07 23:41:30 +01003208 int count, i;
3209 count = qemu_find_net_clients_except(NULL, ncs,
Jason Wangeaed4832015-04-23 14:21:38 +08003210 NET_CLIENT_OPTIONS_KIND_NONE,
3211 MAX_QUEUE_NUM);
Jason Wangbcfa4d62015-04-23 14:21:39 +08003212 for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
Hani Benhabiles40d19392014-05-07 23:41:30 +01003213 const char *name = ncs[i]->name;
3214 if (!strncmp(str, name, len)) {
3215 readline_add_completion(rs, name);
3216 }
3217 }
3218 } else if (nb_args == 3) {
3219 add_completion_option(rs, str, "on");
3220 add_completion_option(rs, str, "off");
3221 }
3222}
3223
Hani Benhabiles11b389f2014-05-07 23:41:32 +01003224void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str)
3225{
3226 int len, count, i;
Jason Wangeaed4832015-04-23 14:21:38 +08003227 NetClientState *ncs[MAX_QUEUE_NUM];
Hani Benhabiles11b389f2014-05-07 23:41:32 +01003228
3229 if (nb_args != 2) {
3230 return;
3231 }
3232
3233 len = strlen(str);
3234 readline_set_completion_index(rs, len);
3235 count = qemu_find_net_clients_except(NULL, ncs, NET_CLIENT_OPTIONS_KIND_NIC,
Jason Wangeaed4832015-04-23 14:21:38 +08003236 MAX_QUEUE_NUM);
Jason Wangbcfa4d62015-04-23 14:21:39 +08003237 for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
Hani Benhabiles11b389f2014-05-07 23:41:32 +01003238 QemuOpts *opts;
3239 const char *name = ncs[i]->name;
3240 if (strncmp(str, name, len)) {
3241 continue;
3242 }
3243 opts = qemu_opts_find(qemu_find_opts_err("netdev", NULL), name);
3244 if (opts) {
3245 readline_add_completion(rs, name);
3246 }
3247 }
3248}
3249
Dr. David Alan Gilbert987bd272015-08-14 11:27:43 +01003250void trace_event_completion(ReadLineState *rs, int nb_args, const char *str)
3251{
3252 size_t len;
3253
3254 len = strlen(str);
3255 readline_set_completion_index(rs, len);
3256 if (nb_args == 2) {
3257 TraceEventID id;
3258 for (id = 0; id < trace_event_count(); id++) {
3259 const char *event_name = trace_event_get_name(trace_event_id(id));
3260 if (!strncmp(str, event_name, len)) {
3261 readline_add_completion(rs, event_name);
3262 }
3263 }
3264 } else if (nb_args == 3) {
3265 add_completion_option(rs, str, "on");
3266 add_completion_option(rs, str, "off");
3267 }
3268}
3269
Hani Benhabilesd0ece342014-05-27 23:39:31 +01003270void watchdog_action_completion(ReadLineState *rs, int nb_args, const char *str)
3271{
Hani Benhabiles4bb08af2014-07-29 23:22:40 +01003272 int i;
3273
Hani Benhabilesd0ece342014-05-27 23:39:31 +01003274 if (nb_args != 2) {
3275 return;
3276 }
3277 readline_set_completion_index(rs, strlen(str));
Hani Benhabiles4bb08af2014-07-29 23:22:40 +01003278 for (i = 0; WatchdogExpirationAction_lookup[i]; i++) {
3279 add_completion_option(rs, str, WatchdogExpirationAction_lookup[i]);
3280 }
Hani Benhabilesd0ece342014-05-27 23:39:31 +01003281}
3282
Hani Benhabilesc68a0402014-05-27 23:39:32 +01003283void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
3284 const char *str)
3285{
3286 size_t len;
3287
3288 len = strlen(str);
3289 readline_set_completion_index(rs, len);
3290 if (nb_args == 2) {
3291 int i;
3292 for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
3293 const char *name = MigrationCapability_lookup[i];
3294 if (!strncmp(str, name, len)) {
3295 readline_add_completion(rs, name);
3296 }
3297 }
3298 } else if (nb_args == 3) {
3299 add_completion_option(rs, str, "on");
3300 add_completion_option(rs, str, "off");
3301 }
3302}
3303
Liang Li50e9a622015-03-23 16:32:29 +08003304void migrate_set_parameter_completion(ReadLineState *rs, int nb_args,
3305 const char *str)
3306{
3307 size_t len;
3308
3309 len = strlen(str);
3310 readline_set_completion_index(rs, len);
3311 if (nb_args == 2) {
3312 int i;
3313 for (i = 0; i < MIGRATION_PARAMETER_MAX; i++) {
3314 const char *name = MigrationParameter_lookup[i];
3315 if (!strncmp(str, name, len)) {
3316 readline_add_completion(rs, name);
3317 }
3318 }
3319 }
3320}
3321
Hani Benhabilese3bb5322014-05-27 23:39:34 +01003322void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str)
3323{
3324 int i;
3325 size_t len;
3326 if (nb_args != 2) {
3327 return;
3328 }
3329 len = strlen(str);
3330 readline_set_completion_index(rs, len);
3331 for (i = 0; host_net_devices[i]; i++) {
3332 if (!strncmp(host_net_devices[i], str, len)) {
3333 readline_add_completion(rs, host_net_devices[i]);
3334 }
3335 }
3336}
3337
Hani Benhabilesddd6b452014-05-27 23:39:36 +01003338void host_net_remove_completion(ReadLineState *rs, int nb_args, const char *str)
3339{
Jason Wangeaed4832015-04-23 14:21:38 +08003340 NetClientState *ncs[MAX_QUEUE_NUM];
Hani Benhabilesddd6b452014-05-27 23:39:36 +01003341 int count, i, len;
3342
3343 len = strlen(str);
3344 readline_set_completion_index(rs, len);
3345 if (nb_args == 2) {
3346 count = qemu_find_net_clients_except(NULL, ncs,
Jason Wangeaed4832015-04-23 14:21:38 +08003347 NET_CLIENT_OPTIONS_KIND_NONE,
3348 MAX_QUEUE_NUM);
Jason Wangbcfa4d62015-04-23 14:21:39 +08003349 for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
Hani Benhabilesddd6b452014-05-27 23:39:36 +01003350 int id;
3351 char name[16];
3352
3353 if (net_hub_id_for_client(ncs[i], &id)) {
3354 continue;
3355 }
3356 snprintf(name, sizeof(name), "%d", id);
3357 if (!strncmp(str, name, len)) {
3358 readline_add_completion(rs, name);
3359 }
3360 }
3361 return;
3362 } else if (nb_args == 3) {
3363 count = qemu_find_net_clients_except(NULL, ncs,
Jason Wangeaed4832015-04-23 14:21:38 +08003364 NET_CLIENT_OPTIONS_KIND_NIC,
3365 MAX_QUEUE_NUM);
Jason Wangbcfa4d62015-04-23 14:21:39 +08003366 for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
Jason Wang2c4681f2015-02-02 15:06:38 +08003367 int id;
Hani Benhabilesddd6b452014-05-27 23:39:36 +01003368 const char *name;
3369
Jason Wang2c4681f2015-02-02 15:06:38 +08003370 if (ncs[i]->info->type == NET_CLIENT_OPTIONS_KIND_HUBPORT ||
3371 net_hub_id_for_client(ncs[i], &id)) {
3372 continue;
3373 }
Hani Benhabilesddd6b452014-05-27 23:39:36 +01003374 name = ncs[i]->name;
3375 if (!strncmp(str, name, len)) {
3376 readline_add_completion(rs, name);
3377 }
3378 }
3379 return;
3380 }
3381}
3382
Hani Benhabilesb21631f2014-05-27 23:39:37 +01003383static void vm_completion(ReadLineState *rs, const char *str)
3384{
3385 size_t len;
3386 BlockDriverState *bs = NULL;
3387
3388 len = strlen(str);
3389 readline_set_completion_index(rs, len);
3390 while ((bs = bdrv_next(bs))) {
3391 SnapshotInfoList *snapshots, *snapshot;
3392
3393 if (!bdrv_can_snapshot(bs)) {
3394 continue;
3395 }
3396 if (bdrv_query_snapshot_info_list(bs, &snapshots, NULL)) {
3397 continue;
3398 }
3399 snapshot = snapshots;
3400 while (snapshot) {
3401 char *completion = snapshot->value->name;
3402 if (!strncmp(str, completion, len)) {
3403 readline_add_completion(rs, completion);
3404 }
3405 completion = snapshot->value->id;
3406 if (!strncmp(str, completion, len)) {
3407 readline_add_completion(rs, completion);
3408 }
3409 snapshot = snapshot->next;
3410 }
3411 qapi_free_SnapshotInfoList(snapshots);
3412 }
3413
3414}
3415
3416void delvm_completion(ReadLineState *rs, int nb_args, const char *str)
3417{
3418 if (nb_args == 2) {
3419 vm_completion(rs, str);
3420 }
3421}
3422
3423void loadvm_completion(ReadLineState *rs, int nb_args, const char *str)
3424{
3425 if (nb_args == 2) {
3426 vm_completion(rs, str);
3427 }
3428}
3429
Wenchao Xiac35b6402013-08-27 20:38:24 +08003430static void monitor_find_completion_by_table(Monitor *mon,
3431 const mon_cmd_t *cmd_table,
3432 char **args,
3433 int nb_args)
bellard81d09122004-07-14 17:21:37 +00003434{
3435 const char *cmdname;
Wenchao Xiac35b6402013-08-27 20:38:24 +08003436 int i;
Markus Armbrusterfea68bb2014-10-07 13:59:10 +02003437 const char *ptype, *str, *name;
Anthony Liguoric227f092009-10-01 16:12:16 -05003438 const mon_cmd_t *cmd;
Markus Armbrusterfea68bb2014-10-07 13:59:10 +02003439 BlockDriverState *bs;
bellard81d09122004-07-14 17:21:37 +00003440
bellard81d09122004-07-14 17:21:37 +00003441 if (nb_args <= 1) {
3442 /* command completion */
3443 if (nb_args == 0)
3444 cmdname = "";
3445 else
3446 cmdname = args[0];
Wenchao Xiad2674b22013-08-27 20:38:16 +08003447 readline_set_completion_index(mon->rs, strlen(cmdname));
Wenchao Xiac35b6402013-08-27 20:38:24 +08003448 for (cmd = cmd_table; cmd->name != NULL; cmd++) {
Wenchao Xiacd5c6bb2013-08-27 20:38:13 +08003449 cmd_completion(mon, cmdname, cmd->name);
bellard81d09122004-07-14 17:21:37 +00003450 }
3451 } else {
3452 /* find the command */
Wenchao Xiac35b6402013-08-27 20:38:24 +08003453 for (cmd = cmd_table; cmd->name != NULL; cmd++) {
Jan Kiszka03a63482010-06-16 00:38:33 +02003454 if (compare_cmd(args[0], cmd->name)) {
3455 break;
3456 }
bellard81d09122004-07-14 17:21:37 +00003457 }
Jan Kiszka03a63482010-06-16 00:38:33 +02003458 if (!cmd->name) {
Wenchao Xiac35b6402013-08-27 20:38:24 +08003459 return;
Jan Kiszka03a63482010-06-16 00:38:33 +02003460 }
3461
Wenchao Xiad903a772013-08-27 20:38:25 +08003462 if (cmd->sub_table) {
3463 /* do the job again */
Stefan Weile7ae7712015-03-08 19:30:01 +01003464 monitor_find_completion_by_table(mon, cmd->sub_table,
3465 &args[1], nb_args - 1);
3466 return;
Wenchao Xiad903a772013-08-27 20:38:25 +08003467 }
Hani Benhabilesbfa40f72014-04-13 16:25:06 +01003468 if (cmd->command_completion) {
Stefan Weile7ae7712015-03-08 19:30:01 +01003469 cmd->command_completion(mon->rs, nb_args, args[nb_args - 1]);
3470 return;
Hani Benhabilesbfa40f72014-04-13 16:25:06 +01003471 }
Wenchao Xiad903a772013-08-27 20:38:25 +08003472
Luiz Capitulino4d76d2b2009-08-28 15:27:09 -03003473 ptype = next_arg_type(cmd->args_type);
bellard81d09122004-07-14 17:21:37 +00003474 for(i = 0; i < nb_args - 2; i++) {
3475 if (*ptype != '\0') {
Luiz Capitulino4d76d2b2009-08-28 15:27:09 -03003476 ptype = next_arg_type(ptype);
bellard81d09122004-07-14 17:21:37 +00003477 while (*ptype == '?')
Luiz Capitulino4d76d2b2009-08-28 15:27:09 -03003478 ptype = next_arg_type(ptype);
bellard81d09122004-07-14 17:21:37 +00003479 }
3480 }
3481 str = args[nb_args - 1];
Kevin Wolf48fe86f2014-11-12 16:24:02 +01003482 while (*ptype == '-' && ptype[1] != '\0') {
Jan Kiszka3b6dbf22010-06-16 00:38:34 +02003483 ptype = next_arg_type(ptype);
Blue Swirl2a1704a2009-08-23 20:10:28 +00003484 }
bellard81d09122004-07-14 17:21:37 +00003485 switch(*ptype) {
3486 case 'F':
3487 /* file completion */
Wenchao Xiad2674b22013-08-27 20:38:16 +08003488 readline_set_completion_index(mon->rs, strlen(str));
Wenchao Xiacb8f68b2013-08-27 20:38:14 +08003489 file_completion(mon, str);
bellard81d09122004-07-14 17:21:37 +00003490 break;
3491 case 'B':
3492 /* block device name completion */
Wenchao Xia599a9262013-08-27 20:38:15 +08003493 readline_set_completion_index(mon->rs, strlen(str));
Markus Armbrusterfea68bb2014-10-07 13:59:10 +02003494 for (bs = bdrv_next(NULL); bs; bs = bdrv_next(bs)) {
3495 name = bdrv_get_device_name(bs);
3496 if (str[0] == '\0' ||
3497 !strncmp(name, str, strlen(str))) {
3498 readline_add_completion(mon->rs, name);
3499 }
3500 }
bellard81d09122004-07-14 17:21:37 +00003501 break;
bellard7fe48482004-10-09 18:08:01 +00003502 case 's':
Wenchao Xia129be002013-08-27 20:38:26 +08003503 case 'S':
Hani Benhabiles29136cd2014-05-07 23:41:27 +01003504 if (!strcmp(cmd->name, "help|?")) {
Wenchao Xia7ca0e062013-08-27 20:38:27 +08003505 monitor_find_completion_by_table(mon, cmd_table,
3506 &args[1], nb_args - 1);
bellard7fe48482004-10-09 18:08:01 +00003507 }
3508 break;
bellard81d09122004-07-14 17:21:37 +00003509 default:
3510 break;
3511 }
3512 }
Wenchao Xiac35b6402013-08-27 20:38:24 +08003513}
3514
Stefan Hajnoczic60bf332013-11-14 11:54:14 +01003515static void monitor_find_completion(void *opaque,
Wenchao Xiac35b6402013-08-27 20:38:24 +08003516 const char *cmdline)
3517{
Stefan Hajnoczic60bf332013-11-14 11:54:14 +01003518 Monitor *mon = opaque;
Wenchao Xiac35b6402013-08-27 20:38:24 +08003519 char *args[MAX_ARGS];
3520 int nb_args, len;
3521
3522 /* 1. parse the cmdline */
3523 if (parse_cmdline(cmdline, &nb_args, args) < 0) {
3524 return;
3525 }
Wenchao Xiac35b6402013-08-27 20:38:24 +08003526
3527 /* if the line ends with a space, it means we want to complete the
3528 next arg */
3529 len = strlen(cmdline);
3530 if (len > 0 && qemu_isspace(cmdline[len - 1])) {
3531 if (nb_args >= MAX_ARGS) {
3532 goto cleanup;
3533 }
3534 args[nb_args++] = g_strdup("");
3535 }
3536
3537 /* 2. auto complete according to args */
3538 monitor_find_completion_by_table(mon, mon->cmd_table, args, nb_args);
Jan Kiszka03a63482010-06-16 00:38:33 +02003539
3540cleanup:
Wenchao Xiadcc70cd2013-08-27 20:38:22 +08003541 free_cmdline_args(args, nb_args);
bellard81d09122004-07-14 17:21:37 +00003542}
3543
aliguori731b0362009-03-05 23:01:42 +00003544static int monitor_can_read(void *opaque)
bellard9dc39cb2004-03-14 21:38:27 +00003545{
aliguori731b0362009-03-05 23:01:42 +00003546 Monitor *mon = opaque;
3547
Jan Kiszkac62313b2009-12-04 14:05:29 +01003548 return (mon->suspend_cnt == 0) ? 1 : 0;
bellard9dc39cb2004-03-14 21:38:27 +00003549}
3550
Markus Armbruster40861822015-05-29 10:27:16 +02003551static bool invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd,
3552 Error **errp)
Luiz Capitulino09069b12010-02-04 18:10:06 -02003553{
Markus Armbruster485febc2015-03-13 17:25:50 +01003554 bool is_cap = cmd->mhandler.cmd_new == qmp_capabilities;
Markus Armbrusterf994b252015-03-06 19:51:51 +01003555
3556 if (is_cap && mon->qmp.in_command_mode) {
Markus Armbruster40861822015-05-29 10:27:16 +02003557 error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND,
3558 "Capabilities negotiation is already complete, command "
3559 "'%s' ignored", cmd->name);
Eric Blake2d5a8342015-04-15 09:19:23 -06003560 return true;
3561 }
Markus Armbrusterf994b252015-03-06 19:51:51 +01003562 if (!is_cap && !mon->qmp.in_command_mode) {
Markus Armbruster40861822015-05-29 10:27:16 +02003563 error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND,
3564 "Expecting capabilities negotiation with "
3565 "'qmp_capabilities' before command '%s'", cmd->name);
Eric Blake2d5a8342015-04-15 09:19:23 -06003566 return true;
3567 }
3568 return false;
Luiz Capitulino09069b12010-02-04 18:10:06 -02003569}
3570
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -03003571/*
Luiz Capitulino4af91932010-06-22 11:44:05 -03003572 * Argument validation rules:
3573 *
3574 * 1. The argument must exist in cmd_args qdict
3575 * 2. The argument type must be the expected one
3576 *
3577 * Special case: If the argument doesn't exist in cmd_args and
3578 * the QMP_ACCEPT_UNKNOWNS flag is set, then the
3579 * checking is skipped for it.
3580 */
Markus Armbruster326283a2015-03-02 18:39:09 +01003581static void check_client_args_type(const QDict *client_args,
3582 const QDict *cmd_args, int flags,
3583 Error **errp)
Luiz Capitulino4af91932010-06-22 11:44:05 -03003584{
3585 const QDictEntry *ent;
3586
3587 for (ent = qdict_first(client_args); ent;ent = qdict_next(client_args,ent)){
3588 QObject *obj;
3589 QString *arg_type;
3590 const QObject *client_arg = qdict_entry_value(ent);
3591 const char *client_arg_name = qdict_entry_key(ent);
3592
3593 obj = qdict_get(cmd_args, client_arg_name);
3594 if (!obj) {
3595 if (flags & QMP_ACCEPT_UNKNOWNS) {
3596 /* handler accepts unknowns */
3597 continue;
3598 }
3599 /* client arg doesn't exist */
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01003600 error_setg(errp, QERR_INVALID_PARAMETER, client_arg_name);
Markus Armbruster326283a2015-03-02 18:39:09 +01003601 return;
Luiz Capitulino4af91932010-06-22 11:44:05 -03003602 }
3603
3604 arg_type = qobject_to_qstring(obj);
3605 assert(arg_type != NULL);
3606
3607 /* check if argument's type is correct */
3608 switch (qstring_get_str(arg_type)[0]) {
3609 case 'F':
3610 case 'B':
3611 case 's':
3612 if (qobject_type(client_arg) != QTYPE_QSTRING) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01003613 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
3614 client_arg_name, "string");
Markus Armbruster326283a2015-03-02 18:39:09 +01003615 return;
Luiz Capitulino4af91932010-06-22 11:44:05 -03003616 }
3617 break;
3618 case 'i':
3619 case 'l':
3620 case 'M':
Jes Sorensendbc0c672010-10-21 17:15:47 +02003621 case 'o':
Luiz Capitulino4af91932010-06-22 11:44:05 -03003622 if (qobject_type(client_arg) != QTYPE_QINT) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01003623 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
3624 client_arg_name, "int");
Markus Armbruster326283a2015-03-02 18:39:09 +01003625 return;
Luiz Capitulino4af91932010-06-22 11:44:05 -03003626 }
3627 break;
Luiz Capitulino4af91932010-06-22 11:44:05 -03003628 case 'T':
3629 if (qobject_type(client_arg) != QTYPE_QINT &&
3630 qobject_type(client_arg) != QTYPE_QFLOAT) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01003631 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
3632 client_arg_name, "number");
Markus Armbruster326283a2015-03-02 18:39:09 +01003633 return;
Luiz Capitulino4af91932010-06-22 11:44:05 -03003634 }
3635 break;
3636 case 'b':
3637 case '-':
3638 if (qobject_type(client_arg) != QTYPE_QBOOL) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01003639 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
3640 client_arg_name, "bool");
Markus Armbruster326283a2015-03-02 18:39:09 +01003641 return;
Luiz Capitulino4af91932010-06-22 11:44:05 -03003642 }
3643 break;
3644 case 'O':
3645 assert(flags & QMP_ACCEPT_UNKNOWNS);
3646 break;
Paolo Bonzinib9f89782012-03-22 12:51:11 +01003647 case 'q':
3648 /* Any QObject can be passed. */
3649 break;
Luiz Capitulino4af91932010-06-22 11:44:05 -03003650 case '/':
3651 case '.':
3652 /*
3653 * These types are not supported by QMP and thus are not
3654 * handled here. Fall through.
3655 */
3656 default:
3657 abort();
3658 }
3659 }
Luiz Capitulino4af91932010-06-22 11:44:05 -03003660}
3661
3662/*
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -03003663 * - Check if the client has passed all mandatory args
3664 * - Set special flags for argument validation
3665 */
Markus Armbruster326283a2015-03-02 18:39:09 +01003666static void check_mandatory_args(const QDict *cmd_args,
3667 const QDict *client_args, int *flags,
3668 Error **errp)
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -03003669{
3670 const QDictEntry *ent;
3671
3672 for (ent = qdict_first(cmd_args); ent; ent = qdict_next(cmd_args, ent)) {
3673 const char *cmd_arg_name = qdict_entry_key(ent);
3674 QString *type = qobject_to_qstring(qdict_entry_value(ent));
3675 assert(type != NULL);
3676
3677 if (qstring_get_str(type)[0] == 'O') {
3678 assert((*flags & QMP_ACCEPT_UNKNOWNS) == 0);
3679 *flags |= QMP_ACCEPT_UNKNOWNS;
3680 } else if (qstring_get_str(type)[0] != '-' &&
3681 qstring_get_str(type)[1] != '?' &&
3682 !qdict_haskey(client_args, cmd_arg_name)) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01003683 error_setg(errp, QERR_MISSING_PARAMETER, cmd_arg_name);
Markus Armbruster326283a2015-03-02 18:39:09 +01003684 return;
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -03003685 }
3686 }
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -03003687}
3688
3689static QDict *qdict_from_args_type(const char *args_type)
3690{
3691 int i;
3692 QDict *qdict;
3693 QString *key, *type, *cur_qs;
3694
3695 assert(args_type != NULL);
3696
3697 qdict = qdict_new();
3698
3699 if (args_type == NULL || args_type[0] == '\0') {
3700 /* no args, empty qdict */
3701 goto out;
3702 }
3703
3704 key = qstring_new();
3705 type = qstring_new();
3706
3707 cur_qs = key;
3708
3709 for (i = 0;; i++) {
3710 switch (args_type[i]) {
3711 case ',':
3712 case '\0':
3713 qdict_put(qdict, qstring_get_str(key), type);
3714 QDECREF(key);
3715 if (args_type[i] == '\0') {
3716 goto out;
3717 }
3718 type = qstring_new(); /* qdict has ref */
3719 cur_qs = key = qstring_new();
3720 break;
3721 case ':':
3722 cur_qs = type;
3723 break;
3724 default:
3725 qstring_append_chr(cur_qs, args_type[i]);
3726 break;
3727 }
3728 }
3729
3730out:
3731 return qdict;
3732}
3733
3734/*
3735 * Client argument checking rules:
3736 *
3737 * 1. Client must provide all mandatory arguments
Luiz Capitulino4af91932010-06-22 11:44:05 -03003738 * 2. Each argument provided by the client must be expected
3739 * 3. Each argument provided by the client must have the type expected
3740 * by the command
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -03003741 */
Markus Armbruster326283a2015-03-02 18:39:09 +01003742static void qmp_check_client_args(const mon_cmd_t *cmd, QDict *client_args,
3743 Error **errp)
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -03003744{
Markus Armbruster326283a2015-03-02 18:39:09 +01003745 Error *err = NULL;
3746 int flags;
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -03003747 QDict *cmd_args;
3748
3749 cmd_args = qdict_from_args_type(cmd->args_type);
3750
3751 flags = 0;
Markus Armbruster326283a2015-03-02 18:39:09 +01003752 check_mandatory_args(cmd_args, client_args, &flags, &err);
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -03003753 if (err) {
3754 goto out;
3755 }
3756
Markus Armbruster326283a2015-03-02 18:39:09 +01003757 check_client_args_type(client_args, cmd_args, flags, &err);
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -03003758
3759out:
Markus Armbruster326283a2015-03-02 18:39:09 +01003760 error_propagate(errp, err);
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -03003761 QDECREF(cmd_args);
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -03003762}
3763
Luiz Capitulinoc917c8f2010-05-31 17:28:01 -03003764/*
3765 * Input object checking rules
3766 *
3767 * 1. Input object must be a dict
3768 * 2. The "execute" key must exist
3769 * 3. The "execute" key must be a string
3770 * 4. If the "arguments" key exists, it must be a dict
3771 * 5. If the "id" key exists, it can be anything (ie. json-value)
3772 * 6. Any argument not listed above is considered invalid
3773 */
Markus Armbrusterba0510a2015-03-02 18:41:43 +01003774static QDict *qmp_check_input_obj(QObject *input_obj, Error **errp)
Luiz Capitulinoc917c8f2010-05-31 17:28:01 -03003775{
3776 const QDictEntry *ent;
3777 int has_exec_key = 0;
3778 QDict *input_dict;
3779
3780 if (qobject_type(input_obj) != QTYPE_QDICT) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01003781 error_setg(errp, QERR_QMP_BAD_INPUT_OBJECT, "object");
Luiz Capitulinoc917c8f2010-05-31 17:28:01 -03003782 return NULL;
3783 }
3784
3785 input_dict = qobject_to_qdict(input_obj);
3786
3787 for (ent = qdict_first(input_dict); ent; ent = qdict_next(input_dict, ent)){
3788 const char *arg_name = qdict_entry_key(ent);
3789 const QObject *arg_obj = qdict_entry_value(ent);
3790
3791 if (!strcmp(arg_name, "execute")) {
3792 if (qobject_type(arg_obj) != QTYPE_QSTRING) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01003793 error_setg(errp, QERR_QMP_BAD_INPUT_OBJECT_MEMBER,
3794 "execute", "string");
Luiz Capitulinoc917c8f2010-05-31 17:28:01 -03003795 return NULL;
3796 }
3797 has_exec_key = 1;
3798 } else if (!strcmp(arg_name, "arguments")) {
3799 if (qobject_type(arg_obj) != QTYPE_QDICT) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01003800 error_setg(errp, QERR_QMP_BAD_INPUT_OBJECT_MEMBER,
3801 "arguments", "object");
Luiz Capitulinoc917c8f2010-05-31 17:28:01 -03003802 return NULL;
3803 }
Markus Armbruster779cec42015-06-08 10:44:30 +02003804 } else if (!strcmp(arg_name, "id")) {
3805 /* Any string is acceptable as "id", so nothing to check */
Luiz Capitulinoc917c8f2010-05-31 17:28:01 -03003806 } else {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01003807 error_setg(errp, QERR_QMP_EXTRA_MEMBER, arg_name);
Luiz Capitulinoc917c8f2010-05-31 17:28:01 -03003808 return NULL;
3809 }
3810 }
3811
3812 if (!has_exec_key) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01003813 error_setg(errp, QERR_QMP_BAD_INPUT_OBJECT, "execute");
Luiz Capitulinoc917c8f2010-05-31 17:28:01 -03003814 return NULL;
3815 }
3816
3817 return input_dict;
3818}
3819
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02003820static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
3821{
Markus Armbruster326283a2015-03-02 18:39:09 +01003822 Error *local_err = NULL;
Markus Armbruster84add862015-03-05 16:45:15 +01003823 QObject *obj, *data;
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02003824 QDict *input, *args;
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02003825 const mon_cmd_t *cmd;
Luiz Capitulino40e5a012011-10-21 16:15:31 -02003826 const char *cmd_name;
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02003827 Monitor *mon = cur_mon;
3828
Luiz Capitulinoe4940c62010-06-24 17:58:20 -03003829 args = input = NULL;
Markus Armbruster84add862015-03-05 16:45:15 +01003830 data = NULL;
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02003831
3832 obj = json_parser_parse(tokens, NULL);
3833 if (!obj) {
3834 // FIXME: should be triggered in json_parser_parse()
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01003835 error_setg(&local_err, QERR_JSON_PARSING);
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02003836 goto err_out;
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02003837 }
3838
Markus Armbrusterba0510a2015-03-02 18:41:43 +01003839 input = qmp_check_input_obj(obj, &local_err);
Luiz Capitulinoc917c8f2010-05-31 17:28:01 -03003840 if (!input) {
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02003841 qobject_decref(obj);
3842 goto err_out;
3843 }
3844
Markus Armbruster74358f22015-03-06 19:35:59 +01003845 mon->qmp.id = qdict_get(input, "id");
3846 qobject_incref(mon->qmp.id);
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02003847
Luiz Capitulino0bbab462010-05-31 17:32:50 -03003848 cmd_name = qdict_get_str(input, "execute");
Stefan Hajnoczi89bd8202011-09-23 08:23:06 +01003849 trace_handle_qmp_command(mon, cmd_name);
Anthony Liguorie3193602011-09-02 12:34:47 -05003850 cmd = qmp_find_cmd(cmd_name);
Eric Blake2d5a8342015-04-15 09:19:23 -06003851 if (!cmd) {
Markus Armbruster710aec92015-03-06 11:28:00 +01003852 error_set(&local_err, ERROR_CLASS_COMMAND_NOT_FOUND,
3853 "The command %s has not been found", cmd_name);
Luiz Capitulinoe4940c62010-06-24 17:58:20 -03003854 goto err_out;
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02003855 }
Markus Armbruster40861822015-05-29 10:27:16 +02003856 if (invalid_qmp_mode(mon, cmd, &local_err)) {
Eric Blake2d5a8342015-04-15 09:19:23 -06003857 goto err_out;
3858 }
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02003859
3860 obj = qdict_get(input, "arguments");
3861 if (!obj) {
3862 args = qdict_new();
3863 } else {
3864 args = qobject_to_qdict(obj);
3865 QINCREF(args);
3866 }
3867
Markus Armbruster326283a2015-03-02 18:39:09 +01003868 qmp_check_client_args(cmd, args, &local_err);
3869 if (local_err) {
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02003870 goto err_out;
3871 }
3872
Markus Armbruster485febc2015-03-13 17:25:50 +01003873 cmd->mhandler.cmd_new(args, &data, &local_err);
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02003874
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02003875err_out:
Markus Armbruster710aec92015-03-06 11:28:00 +01003876 monitor_protocol_emitter(mon, data, local_err);
Markus Armbruster84add862015-03-05 16:45:15 +01003877 qobject_decref(data);
Luiz Capitulinoe4940c62010-06-24 17:58:20 -03003878 QDECREF(input);
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02003879 QDECREF(args);
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02003880}
3881
Markus Armbrusterc83fe232015-03-06 19:20:51 +01003882static void monitor_qmp_read(void *opaque, const uint8_t *buf, int size)
Luiz Capitulino9b57c022009-11-26 22:58:58 -02003883{
3884 Monitor *old_mon = cur_mon;
3885
3886 cur_mon = opaque;
3887
Markus Armbruster74358f22015-03-06 19:35:59 +01003888 json_message_parser_feed(&cur_mon->qmp.parser, (const char *) buf, size);
Luiz Capitulino9b57c022009-11-26 22:58:58 -02003889
3890 cur_mon = old_mon;
3891}
3892
aliguori731b0362009-03-05 23:01:42 +00003893static void monitor_read(void *opaque, const uint8_t *buf, int size)
bellard9dc39cb2004-03-14 21:38:27 +00003894{
aliguori731b0362009-03-05 23:01:42 +00003895 Monitor *old_mon = cur_mon;
bellard9dc39cb2004-03-14 21:38:27 +00003896 int i;
aliguori376253e2009-03-05 23:01:23 +00003897
aliguori731b0362009-03-05 23:01:42 +00003898 cur_mon = opaque;
bellard7e2515e2004-08-01 21:52:19 +00003899
aliguoricde76ee2009-03-05 23:01:51 +00003900 if (cur_mon->rs) {
3901 for (i = 0; i < size; i++)
3902 readline_handle_byte(cur_mon->rs, buf[i]);
3903 } else {
3904 if (size == 0 || buf[size - 1] != 0)
3905 monitor_printf(cur_mon, "corrupted command\n");
3906 else
Markus Armbruster7ef6cf62015-03-06 19:12:36 +01003907 handle_hmp_command(cur_mon, (char *)buf);
aliguoricde76ee2009-03-05 23:01:51 +00003908 }
aliguori731b0362009-03-05 23:01:42 +00003909
3910 cur_mon = old_mon;
3911}
aliguorid8f44602008-10-06 13:52:44 +00003912
Stefan Hajnoczic60bf332013-11-14 11:54:14 +01003913static void monitor_command_cb(void *opaque, const char *cmdline,
3914 void *readline_opaque)
bellard7e2515e2004-08-01 21:52:19 +00003915{
Stefan Hajnoczic60bf332013-11-14 11:54:14 +01003916 Monitor *mon = opaque;
3917
aliguori731b0362009-03-05 23:01:42 +00003918 monitor_suspend(mon);
Markus Armbruster7ef6cf62015-03-06 19:12:36 +01003919 handle_hmp_command(mon, cmdline);
aliguori731b0362009-03-05 23:01:42 +00003920 monitor_resume(mon);
aliguorid8f44602008-10-06 13:52:44 +00003921}
3922
aliguoricde76ee2009-03-05 23:01:51 +00003923int monitor_suspend(Monitor *mon)
aliguorid8f44602008-10-06 13:52:44 +00003924{
aliguoricde76ee2009-03-05 23:01:51 +00003925 if (!mon->rs)
3926 return -ENOTTY;
aliguori731b0362009-03-05 23:01:42 +00003927 mon->suspend_cnt++;
aliguoricde76ee2009-03-05 23:01:51 +00003928 return 0;
aliguorid8f44602008-10-06 13:52:44 +00003929}
3930
aliguori376253e2009-03-05 23:01:23 +00003931void monitor_resume(Monitor *mon)
aliguorid8f44602008-10-06 13:52:44 +00003932{
aliguoricde76ee2009-03-05 23:01:51 +00003933 if (!mon->rs)
3934 return;
aliguori731b0362009-03-05 23:01:42 +00003935 if (--mon->suspend_cnt == 0)
3936 readline_show_prompt(mon->rs);
bellard7e2515e2004-08-01 21:52:19 +00003937}
3938
Luiz Capitulinoca9567e2010-02-04 18:10:04 -02003939static QObject *get_qmp_greeting(void)
3940{
Luiz Capitulinob9c15f12011-08-26 17:38:13 -03003941 QObject *ver = NULL;
Luiz Capitulinoca9567e2010-02-04 18:10:04 -02003942
Markus Armbruster7fad30f2015-09-16 13:06:19 +02003943 qmp_marshal_query_version(NULL, &ver, NULL);
Luiz Capitulinoca9567e2010-02-04 18:10:04 -02003944 return qobject_from_jsonf("{'QMP':{'version': %p,'capabilities': []}}",ver);
3945}
3946
Markus Armbrusterc83fe232015-03-06 19:20:51 +01003947static void monitor_qmp_event(void *opaque, int event)
Luiz Capitulino9b57c022009-11-26 22:58:58 -02003948{
Luiz Capitulino47116d12010-02-08 17:01:30 -02003949 QObject *data;
3950 Monitor *mon = opaque;
Luiz Capitulino9b57c022009-11-26 22:58:58 -02003951
Luiz Capitulino47116d12010-02-08 17:01:30 -02003952 switch (event) {
3953 case CHR_EVENT_OPENED:
Markus Armbrusterf994b252015-03-06 19:51:51 +01003954 mon->qmp.in_command_mode = false;
Luiz Capitulinoca9567e2010-02-04 18:10:04 -02003955 data = get_qmp_greeting();
Luiz Capitulino9b57c022009-11-26 22:58:58 -02003956 monitor_json_emitter(mon, data);
3957 qobject_decref(data);
Corey Bryantefb87c12012-08-14 16:43:48 -04003958 mon_refcount++;
Luiz Capitulino47116d12010-02-08 17:01:30 -02003959 break;
3960 case CHR_EVENT_CLOSED:
Markus Armbruster74358f22015-03-06 19:35:59 +01003961 json_message_parser_destroy(&mon->qmp.parser);
3962 json_message_parser_init(&mon->qmp.parser, handle_qmp_command);
Corey Bryantefb87c12012-08-14 16:43:48 -04003963 mon_refcount--;
3964 monitor_fdsets_cleanup();
Luiz Capitulino47116d12010-02-08 17:01:30 -02003965 break;
Luiz Capitulino9b57c022009-11-26 22:58:58 -02003966 }
3967}
3968
aliguori731b0362009-03-05 23:01:42 +00003969static void monitor_event(void *opaque, int event)
ths86e94de2007-01-05 22:01:59 +00003970{
aliguori376253e2009-03-05 23:01:23 +00003971 Monitor *mon = opaque;
3972
aliguori2724b182009-03-05 23:01:47 +00003973 switch (event) {
3974 case CHR_EVENT_MUX_IN:
Paolo Bonzini6cff3e82014-06-18 08:43:59 +02003975 qemu_mutex_lock(&mon->out_lock);
Gerd Hoffmanna7aec5d2009-09-10 10:58:54 +02003976 mon->mux_out = 0;
Paolo Bonzini6cff3e82014-06-18 08:43:59 +02003977 qemu_mutex_unlock(&mon->out_lock);
Gerd Hoffmanna7aec5d2009-09-10 10:58:54 +02003978 if (mon->reset_seen) {
3979 readline_restart(mon->rs);
3980 monitor_resume(mon);
3981 monitor_flush(mon);
3982 } else {
3983 mon->suspend_cnt = 0;
3984 }
aliguori2724b182009-03-05 23:01:47 +00003985 break;
ths86e94de2007-01-05 22:01:59 +00003986
aliguori2724b182009-03-05 23:01:47 +00003987 case CHR_EVENT_MUX_OUT:
Gerd Hoffmanna7aec5d2009-09-10 10:58:54 +02003988 if (mon->reset_seen) {
3989 if (mon->suspend_cnt == 0) {
3990 monitor_printf(mon, "\n");
3991 }
3992 monitor_flush(mon);
3993 monitor_suspend(mon);
3994 } else {
3995 mon->suspend_cnt++;
3996 }
Paolo Bonzini6cff3e82014-06-18 08:43:59 +02003997 qemu_mutex_lock(&mon->out_lock);
Gerd Hoffmanna7aec5d2009-09-10 10:58:54 +02003998 mon->mux_out = 1;
Paolo Bonzini6cff3e82014-06-18 08:43:59 +02003999 qemu_mutex_unlock(&mon->out_lock);
aliguori2724b182009-03-05 23:01:47 +00004000 break;
4001
Amit Shahb6b8df52009-10-07 18:31:16 +05304002 case CHR_EVENT_OPENED:
aliguori2724b182009-03-05 23:01:47 +00004003 monitor_printf(mon, "QEMU %s monitor - type 'help' for more "
4004 "information\n", QEMU_VERSION);
Gerd Hoffmanna7aec5d2009-09-10 10:58:54 +02004005 if (!mon->mux_out) {
Stratos Psomadakise5554e22014-09-15 15:34:57 +03004006 readline_restart(mon->rs);
aliguori2724b182009-03-05 23:01:47 +00004007 readline_show_prompt(mon->rs);
Gerd Hoffmanna7aec5d2009-09-10 10:58:54 +02004008 }
4009 mon->reset_seen = 1;
Corey Bryantefb87c12012-08-14 16:43:48 -04004010 mon_refcount++;
4011 break;
4012
4013 case CHR_EVENT_CLOSED:
4014 mon_refcount--;
4015 monitor_fdsets_cleanup();
aliguori2724b182009-03-05 23:01:47 +00004016 break;
4017 }
ths86e94de2007-01-05 22:01:59 +00004018}
4019
Wayne Xia816f8922011-10-12 11:32:41 +08004020static int
4021compare_mon_cmd(const void *a, const void *b)
4022{
4023 return strcmp(((const mon_cmd_t *)a)->name,
4024 ((const mon_cmd_t *)b)->name);
4025}
4026
4027static void sortcmdlist(void)
4028{
4029 int array_num;
4030 int elem_size = sizeof(mon_cmd_t);
4031
4032 array_num = sizeof(mon_cmds)/elem_size-1;
4033 qsort((void *)mon_cmds, array_num, elem_size, compare_mon_cmd);
4034
4035 array_num = sizeof(info_cmds)/elem_size-1;
4036 qsort((void *)info_cmds, array_num, elem_size, compare_mon_cmd);
4037}
4038
aliguori76655d62009-03-06 20:27:37 +00004039
4040/*
4041 * Local variables:
4042 * c-indent-level: 4
4043 * c-basic-offset: 4
4044 * tab-width: 8
4045 * End:
4046 */
4047
Stefan Hajnoczic60bf332013-11-14 11:54:14 +01004048/* These functions just adapt the readline interface in a typesafe way. We
4049 * could cast function pointers but that discards compiler checks.
4050 */
Stefan Weild5d15072014-01-25 18:18:23 +01004051static void GCC_FMT_ATTR(2, 3) monitor_readline_printf(void *opaque,
4052 const char *fmt, ...)
Stefan Hajnoczic60bf332013-11-14 11:54:14 +01004053{
4054 va_list ap;
4055 va_start(ap, fmt);
4056 monitor_vprintf(opaque, fmt, ap);
4057 va_end(ap);
4058}
4059
4060static void monitor_readline_flush(void *opaque)
4061{
4062 monitor_flush(opaque);
4063}
4064
Paolo Bonzinid622cb52014-06-18 08:44:00 +02004065static void __attribute__((constructor)) monitor_lock_init(void)
4066{
4067 qemu_mutex_init(&monitor_lock);
4068}
4069
aliguori731b0362009-03-05 23:01:42 +00004070void monitor_init(CharDriverState *chr, int flags)
bellard9dc39cb2004-03-14 21:38:27 +00004071{
aliguori731b0362009-03-05 23:01:42 +00004072 static int is_first_init = 1;
aliguori87127162009-03-05 23:01:29 +00004073 Monitor *mon;
ths20d8a3e2007-02-18 17:04:49 +00004074
4075 if (is_first_init) {
Wenchao Xia43a14cf2014-06-18 08:43:31 +02004076 monitor_qapi_event_init();
Wenchao Xiad0383172013-08-27 20:38:18 +08004077 sortcmdlist();
ths20d8a3e2007-02-18 17:04:49 +00004078 is_first_init = 0;
4079 }
aliguori87127162009-03-05 23:01:29 +00004080
Wenchao Xiab01fe892013-08-27 20:38:19 +08004081 mon = g_malloc(sizeof(*mon));
4082 monitor_data_init(mon);
ths20d8a3e2007-02-18 17:04:49 +00004083
aliguori87127162009-03-05 23:01:29 +00004084 mon->chr = chr;
aliguori731b0362009-03-05 23:01:42 +00004085 mon->flags = flags;
aliguoricde76ee2009-03-05 23:01:51 +00004086 if (flags & MONITOR_USE_READLINE) {
Stefan Hajnoczic60bf332013-11-14 11:54:14 +01004087 mon->rs = readline_init(monitor_readline_printf,
4088 monitor_readline_flush,
4089 mon,
4090 monitor_find_completion);
aliguoricde76ee2009-03-05 23:01:51 +00004091 monitor_read_command(mon, 0);
4092 }
aliguori87127162009-03-05 23:01:29 +00004093
Markus Armbruster9f3982f2015-03-06 19:56:38 +01004094 if (monitor_is_qmp(mon)) {
Markus Armbrusterc83fe232015-03-06 19:20:51 +01004095 qemu_chr_add_handlers(chr, monitor_can_read, monitor_qmp_read,
4096 monitor_qmp_event, mon);
Anthony Liguori15f31512011-08-15 11:17:35 -05004097 qemu_chr_fe_set_echo(chr, true);
Markus Armbruster74358f22015-03-06 19:35:59 +01004098 json_message_parser_init(&mon->qmp.parser, handle_qmp_command);
Luiz Capitulino9b57c022009-11-26 22:58:58 -02004099 } else {
4100 qemu_chr_add_handlers(chr, monitor_can_read, monitor_read,
4101 monitor_event, mon);
4102 }
aliguori87127162009-03-05 23:01:29 +00004103
Paolo Bonzinid622cb52014-06-18 08:44:00 +02004104 qemu_mutex_lock(&monitor_lock);
Blue Swirl72cf2d42009-09-12 07:36:22 +00004105 QLIST_INSERT_HEAD(&mon_list, mon, entry);
Paolo Bonzinid622cb52014-06-18 08:44:00 +02004106 qemu_mutex_unlock(&monitor_lock);
bellard7e2515e2004-08-01 21:52:19 +00004107}
4108
Stefan Hajnoczic60bf332013-11-14 11:54:14 +01004109static void bdrv_password_cb(void *opaque, const char *password,
4110 void *readline_opaque)
bellard7e2515e2004-08-01 21:52:19 +00004111{
Stefan Hajnoczic60bf332013-11-14 11:54:14 +01004112 Monitor *mon = opaque;
4113 BlockDriverState *bs = readline_opaque;
aliguoribb5fc202009-03-05 23:01:15 +00004114 int ret = 0;
Markus Armbruster4d2855a2015-01-29 10:37:00 +01004115 Error *local_err = NULL;
bellard7e2515e2004-08-01 21:52:19 +00004116
Markus Armbruster4d2855a2015-01-29 10:37:00 +01004117 bdrv_add_key(bs, password, &local_err);
4118 if (local_err) {
4119 monitor_printf(mon, "%s\n", error_get_pretty(local_err));
4120 error_free(local_err);
aliguoribb5fc202009-03-05 23:01:15 +00004121 ret = -EPERM;
bellard7e2515e2004-08-01 21:52:19 +00004122 }
aliguori731b0362009-03-05 23:01:42 +00004123 if (mon->password_completion_cb)
4124 mon->password_completion_cb(mon->password_opaque, ret);
aliguoribb5fc202009-03-05 23:01:15 +00004125
aliguori731b0362009-03-05 23:01:42 +00004126 monitor_read_command(mon, 1);
bellard9dc39cb2004-03-14 21:38:27 +00004127}
aliguoric0f4ce72009-03-05 23:01:01 +00004128
Luiz Capitulino0bbc47b2010-02-10 23:50:01 -02004129int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
Markus Armbruster097310b2014-10-07 13:59:15 +02004130 BlockCompletionFunc *completion_cb,
Luiz Capitulino0bbc47b2010-02-10 23:50:01 -02004131 void *opaque)
aliguoric0f4ce72009-03-05 23:01:01 +00004132{
aliguoricde76ee2009-03-05 23:01:51 +00004133 int err;
4134
aliguori376253e2009-03-05 23:01:23 +00004135 monitor_printf(mon, "%s (%s) is encrypted.\n", bdrv_get_device_name(bs),
4136 bdrv_get_encrypted_filename(bs));
aliguoribb5fc202009-03-05 23:01:15 +00004137
aliguori731b0362009-03-05 23:01:42 +00004138 mon->password_completion_cb = completion_cb;
4139 mon->password_opaque = opaque;
aliguoribb5fc202009-03-05 23:01:15 +00004140
aliguoricde76ee2009-03-05 23:01:51 +00004141 err = monitor_read_password(mon, bdrv_password_cb, bs);
4142
4143 if (err && completion_cb)
4144 completion_cb(opaque, err);
Luiz Capitulino0bbc47b2010-02-10 23:50:01 -02004145
4146 return err;
aliguoric0f4ce72009-03-05 23:01:01 +00004147}
Luiz Capitulinoe42e8182011-11-22 17:58:31 -02004148
4149int monitor_read_block_device_key(Monitor *mon, const char *device,
Markus Armbruster097310b2014-10-07 13:59:15 +02004150 BlockCompletionFunc *completion_cb,
Luiz Capitulinoe42e8182011-11-22 17:58:31 -02004151 void *opaque)
4152{
Markus Armbruster9b14e0e2015-03-12 17:26:48 +01004153 Error *err = NULL;
Fam Zheng55606252015-03-02 19:36:46 +08004154 BlockBackend *blk;
Luiz Capitulinoe42e8182011-11-22 17:58:31 -02004155
Fam Zheng55606252015-03-02 19:36:46 +08004156 blk = blk_by_name(device);
4157 if (!blk) {
Luiz Capitulinoe42e8182011-11-22 17:58:31 -02004158 monitor_printf(mon, "Device not found %s\n", device);
4159 return -1;
4160 }
Max Reitz5433c242015-10-19 17:53:29 +02004161 if (!blk_bs(blk)) {
4162 monitor_printf(mon, "Device '%s' has no medium\n", device);
4163 return -1;
4164 }
Luiz Capitulinoe42e8182011-11-22 17:58:31 -02004165
Markus Armbruster9b14e0e2015-03-12 17:26:48 +01004166 bdrv_add_key(blk_bs(blk), NULL, &err);
4167 if (err) {
4168 error_free(err);
4169 return monitor_read_bdrv_key_start(mon, blk_bs(blk), completion_cb, opaque);
4170 }
4171
4172 if (completion_cb) {
4173 completion_cb(opaque, 0);
4174 }
4175 return 0;
Luiz Capitulinoe42e8182011-11-22 17:58:31 -02004176}
Paolo Bonzini4d454572012-11-26 16:03:42 +01004177
4178QemuOptsList qemu_mon_opts = {
4179 .name = "mon",
4180 .implied_opt_name = "chardev",
4181 .head = QTAILQ_HEAD_INITIALIZER(qemu_mon_opts.head),
4182 .desc = {
4183 {
4184 .name = "mode",
4185 .type = QEMU_OPT_STRING,
4186 },{
4187 .name = "chardev",
4188 .type = QEMU_OPT_STRING,
4189 },{
4190 .name = "default",
4191 .type = QEMU_OPT_BOOL,
4192 },{
4193 .name = "pretty",
4194 .type = QEMU_OPT_BOOL,
4195 },
4196 { /* end of list */ }
4197 },
4198};
Marcelo Tosattif2ae8ab2014-06-24 18:55:11 -03004199
4200#ifndef TARGET_I386
4201void qmp_rtc_reset_reinjection(Error **errp)
4202{
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01004203 error_setg(errp, QERR_FEATURE_DISABLED, "rtc-reset-reinjection");
Marcelo Tosattif2ae8ab2014-06-24 18:55:11 -03004204}
4205#endif
Jason J. Herne7ee0c3e2015-06-26 14:03:16 -04004206
4207#ifndef TARGET_S390X
4208void qmp_dump_skeys(const char *filename, Error **errp)
4209{
4210 error_setg(errp, QERR_FEATURE_DISABLED, "dump-skeys");
4211}
4212#endif