Merge remote branch 'qmp/for-anthony' into staging

This commit is contained in:
Anthony Liguori 2010-10-05 13:54:49 -05:00
commit 48f57044e6
12 changed files with 1527 additions and 1192 deletions

View File

@ -255,10 +255,10 @@ TEXIFLAG=$(if $(V),,--quiet)
qemu-options.texi: $(SRC_PATH)/qemu-options.hx
$(call quiet-command,sh $(SRC_PATH)/hxtool -t < $< > $@," GEN $@")
qemu-monitor.texi: $(SRC_PATH)/qemu-monitor.hx
qemu-monitor.texi: $(SRC_PATH)/hmp-commands.hx
$(call quiet-command,sh $(SRC_PATH)/hxtool -t < $< > $@," GEN $@")
QMP/qmp-commands.txt: $(SRC_PATH)/qemu-monitor.hx
QMP/qmp-commands.txt: $(SRC_PATH)/qmp-commands.hx
$(call quiet-command,sh $(SRC_PATH)/hxtool -q < $< > $@," GEN $@")
qemu-img-cmds.texi: $(SRC_PATH)/qemu-img-cmds.hx

View File

@ -309,7 +309,7 @@ obj-alpha-y = alpha_palcode.o
main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
monitor.o: qemu-monitor.h
monitor.o: hmp-commands.h qmp-commands.h
$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS)
@ -330,13 +330,16 @@ $(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)
gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/feature_to_c.sh
$(call quiet-command,rm -f $@ && $(SHELL) $(SRC_PATH)/feature_to_c.sh $@ $(TARGET_XML_FILES)," GEN $(TARGET_DIR)$@")
qemu-monitor.h: $(SRC_PATH)/qemu-monitor.hx
hmp-commands.h: $(SRC_PATH)/hmp-commands.hx
$(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@")
qmp-commands.h: $(SRC_PATH)/qmp-commands.hx
$(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@")
clean:
rm -f *.o *.a *~ $(PROGS) nwfpe/*.o fpu/*.o
rm -f *.d */*.d tcg/*.o ide/*.o
rm -f qemu-monitor.h gdbstub-xml.c
rm -f hmp-commands.h qmp-commands.h gdbstub-xml.c
install: all
ifneq ($(PROGS),)

View File

@ -82,10 +82,10 @@ doing any code change. This is so because:
2. Review can improve your interface. Letting that happen before
you implement it can save you work.
* The qmp-commands.txt file is generated from the qemu-monitor.hx one, which
* The qmp-commands.txt file is generated from the qmp-commands.hx one, which
is the file that should be edited.
Homepage
--------
http://www.linux-kvm.org/page/MonitorProtocol
http://wiki.qemu.org/QMP

1216
hmp-commands.hx Normal file

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,10 @@
#include <sys/mman.h>
#endif
/* Disable guest-provided stats by now (https://bugzilla.redhat.com/show_bug.cgi?id=623903) */
#define ENABLE_GUEST_STATS 0
typedef struct VirtIOBalloon
{
VirtIODevice vdev;
@ -83,12 +87,14 @@ static QObject *get_stats_qobject(VirtIOBalloon *dev)
VIRTIO_BALLOON_PFN_SHIFT);
stat_put(dict, "actual", actual);
#if ENABLE_GUEST_STATS
stat_put(dict, "mem_swapped_in", dev->stats[VIRTIO_BALLOON_S_SWAP_IN]);
stat_put(dict, "mem_swapped_out", dev->stats[VIRTIO_BALLOON_S_SWAP_OUT]);
stat_put(dict, "major_page_faults", dev->stats[VIRTIO_BALLOON_S_MAJFLT]);
stat_put(dict, "minor_page_faults", dev->stats[VIRTIO_BALLOON_S_MINFLT]);
stat_put(dict, "free_mem", dev->stats[VIRTIO_BALLOON_S_MEMFREE]);
stat_put(dict, "total_mem", dev->stats[VIRTIO_BALLOON_S_MEMTOT]);
#endif
return QOBJECT(dict);
}
@ -214,7 +220,7 @@ static void virtio_balloon_to_target(void *opaque, ram_addr_t target,
}
dev->stats_callback = cb;
dev->stats_opaque_callback_data = cb_data;
if (dev->vdev.guest_features & (1 << VIRTIO_BALLOON_F_STATS_VQ)) {
if (ENABLE_GUEST_STATS && (dev->vdev.guest_features & (1 << VIRTIO_BALLOON_F_STATS_VQ))) {
virtqueue_push(dev->svq, &dev->stats_vq_elem, dev->stats_vq_offset);
virtio_notify(&dev->vdev, dev->svq);
} else {

366
monitor.c
View File

@ -189,6 +189,9 @@ static QLIST_HEAD(mon_list, Monitor) mon_list;
static const mon_cmd_t mon_cmds[];
static const mon_cmd_t info_cmds[];
static const mon_cmd_t qmp_cmds[];
static const mon_cmd_t qmp_query_cmds[];
Monitor *cur_mon;
Monitor *default_mon;
@ -328,21 +331,16 @@ static int GCC_FMT_ATTR(2, 3) monitor_fprintf(FILE *stream,
static void monitor_user_noop(Monitor *mon, const QObject *data) { }
static inline int monitor_handler_ported(const mon_cmd_t *cmd)
static inline int handler_is_qobject(const mon_cmd_t *cmd)
{
return cmd->user_print != NULL;
}
static inline bool monitor_handler_is_async(const mon_cmd_t *cmd)
static inline bool handler_is_async(const mon_cmd_t *cmd)
{
return cmd->flags & MONITOR_CMD_ASYNC;
}
static inline bool monitor_cmd_user_only(const mon_cmd_t *cmd)
{
return (cmd->flags & MONITOR_CMD_USER_ONLY);
}
static inline int monitor_has_error(const Monitor *mon)
{
return mon->error != NULL;
@ -352,7 +350,10 @@ static void monitor_json_emitter(Monitor *mon, const QObject *data)
{
QString *json;
json = qobject_to_json(data);
if (mon->flags & MONITOR_USE_PRETTY)
json = qobject_to_json_pretty(data);
else
json = qobject_to_json(data);
assert(json != NULL);
qstring_append_chr(json, '\n');
@ -634,13 +635,12 @@ static void user_async_info_handler(Monitor *mon, const mon_cmd_t *cmd)
}
}
static int do_info(Monitor *mon, const QDict *qdict, QObject **ret_data)
static void do_info(Monitor *mon, const QDict *qdict)
{
const mon_cmd_t *cmd;
const char *item = qdict_get_try_str(qdict, "item");
if (!item) {
assert(monitor_ctrl_mode(mon) == 0);
goto help;
}
@ -650,56 +650,27 @@ static int do_info(Monitor *mon, const QDict *qdict, QObject **ret_data)
}
if (cmd->name == NULL) {
if (monitor_ctrl_mode(mon)) {
qerror_report(QERR_COMMAND_NOT_FOUND, item);
return -1;
}
goto help;
}
if (monitor_ctrl_mode(mon) && monitor_cmd_user_only(cmd)) {
qerror_report(QERR_COMMAND_NOT_FOUND, item);
return -1;
}
if (handler_is_async(cmd)) {
user_async_info_handler(mon, cmd);
} else if (handler_is_qobject(cmd)) {
QObject *info_data = NULL;
if (monitor_handler_is_async(cmd)) {
if (monitor_ctrl_mode(mon)) {
qmp_async_info_handler(mon, cmd);
} else {
user_async_info_handler(mon, cmd);
}
/*
* Indicate that this command is asynchronous and will not return any
* data (not even empty). Instead, the data will be returned via a
* completion callback.
*/
*ret_data = qobject_from_jsonf("{ '__mon_async': 'return' }");
} else if (monitor_handler_ported(cmd)) {
cmd->mhandler.info_new(mon, ret_data);
if (!monitor_ctrl_mode(mon)) {
/*
* User Protocol function is called here, Monitor Protocol is
* handled by monitor_call_handler()
*/
if (*ret_data)
cmd->user_print(mon, *ret_data);
cmd->mhandler.info_new(mon, &info_data);
if (info_data) {
cmd->user_print(mon, info_data);
qobject_decref(info_data);
}
} else {
if (monitor_ctrl_mode(mon)) {
/* handler not converted yet */
qerror_report(QERR_COMMAND_NOT_FOUND, item);
return -1;
} else {
cmd->mhandler.info(mon);
}
cmd->mhandler.info(mon);
}
return 0;
return;
help:
help_cmd(mon, "info");
return 0;
}
static void do_info_version_print(Monitor *mon, const QObject *data)
@ -773,19 +744,14 @@ static void do_info_commands(Monitor *mon, QObject **ret_data)
cmd_list = qlist_new();
for (cmd = mon_cmds; cmd->name != NULL; cmd++) {
if (monitor_handler_ported(cmd) && !monitor_cmd_user_only(cmd) &&
!compare_cmd(cmd->name, "info")) {
qlist_append_obj(cmd_list, get_cmd_dict(cmd->name));
}
for (cmd = qmp_cmds; cmd->name != NULL; cmd++) {
qlist_append_obj(cmd_list, get_cmd_dict(cmd->name));
}
for (cmd = info_cmds; cmd->name != NULL; cmd++) {
if (monitor_handler_ported(cmd) && !monitor_cmd_user_only(cmd)) {
char buf[128];
snprintf(buf, sizeof(buf), "query-%s", cmd->name);
qlist_append_obj(cmd_list, get_cmd_dict(buf));
}
for (cmd = qmp_query_cmds; cmd->name != NULL; cmd++) {
char buf[128];
snprintf(buf, sizeof(buf), "query-%s", cmd->name);
qlist_append_obj(cmd_list, get_cmd_dict(buf));
}
*ret_data = QOBJECT(cmd_list);
@ -2367,11 +2333,11 @@ int monitor_get_fd(Monitor *mon, const char *fdname)
}
static const mon_cmd_t mon_cmds[] = {
#include "qemu-monitor.h"
#include "hmp-commands.h"
{ NULL, NULL, },
};
/* Please update qemu-monitor.hx when adding or changing commands */
/* Please update hmp-commands.hx when adding or changing commands */
static const mon_cmd_t info_cmds[] = {
{
.name = "version",
@ -2381,14 +2347,6 @@ static const mon_cmd_t info_cmds[] = {
.user_print = do_info_version_print,
.mhandler.info_new = do_info_version,
},
{
.name = "commands",
.args_type = "",
.params = "",
.help = "list QMP available commands",
.user_print = monitor_user_noop,
.mhandler.info_new = do_info_commands,
},
{
.name = "network",
.args_type = "",
@ -2663,6 +2621,136 @@ static const mon_cmd_t info_cmds[] = {
},
};
static const mon_cmd_t qmp_cmds[] = {
#include "qmp-commands.h"
{ /* NULL */ },
};
static const mon_cmd_t qmp_query_cmds[] = {
{
.name = "version",
.args_type = "",
.params = "",
.help = "show the version of QEMU",
.user_print = do_info_version_print,
.mhandler.info_new = do_info_version,
},
{
.name = "commands",
.args_type = "",
.params = "",
.help = "list QMP available commands",
.user_print = monitor_user_noop,
.mhandler.info_new = do_info_commands,
},
{
.name = "chardev",
.args_type = "",
.params = "",
.help = "show the character devices",
.user_print = qemu_chr_info_print,
.mhandler.info_new = qemu_chr_info,
},
{
.name = "block",
.args_type = "",
.params = "",
.help = "show the block devices",
.user_print = bdrv_info_print,
.mhandler.info_new = bdrv_info,
},
{
.name = "blockstats",
.args_type = "",
.params = "",
.help = "show block device statistics",
.user_print = bdrv_stats_print,
.mhandler.info_new = bdrv_info_stats,
},
{
.name = "cpus",
.args_type = "",
.params = "",
.help = "show infos for each CPU",
.user_print = monitor_print_cpus,
.mhandler.info_new = do_info_cpus,
},
{
.name = "pci",
.args_type = "",
.params = "",
.help = "show PCI info",
.user_print = do_pci_info_print,
.mhandler.info_new = do_pci_info,
},
{
.name = "kvm",
.args_type = "",
.params = "",
.help = "show KVM information",
.user_print = do_info_kvm_print,
.mhandler.info_new = do_info_kvm,
},
{
.name = "status",
.args_type = "",
.params = "",
.help = "show the current VM status (running|paused)",
.user_print = do_info_status_print,
.mhandler.info_new = do_info_status,
},
{
.name = "mice",
.args_type = "",
.params = "",
.help = "show which guest mouse is receiving events",
.user_print = do_info_mice_print,
.mhandler.info_new = do_info_mice,
},
{
.name = "vnc",
.args_type = "",
.params = "",
.help = "show the vnc server status",
.user_print = do_info_vnc_print,
.mhandler.info_new = do_info_vnc,
},
{
.name = "name",
.args_type = "",
.params = "",
.help = "show the current VM name",
.user_print = do_info_name_print,
.mhandler.info_new = do_info_name,
},
{
.name = "uuid",
.args_type = "",
.params = "",
.help = "show the current VM UUID",
.user_print = do_info_uuid_print,
.mhandler.info_new = do_info_uuid,
},
{
.name = "migrate",
.args_type = "",
.params = "",
.help = "show migration status",
.user_print = do_info_migrate_print,
.mhandler.info_new = do_info_migrate,
},
{
.name = "balloon",
.args_type = "",
.params = "",
.help = "show balloon information",
.user_print = monitor_print_balloon,
.mhandler.info_async = do_info_balloon,
.flags = MONITOR_CMD_ASYNC,
},
{ /* NULL */ },
};
/*******************************************************************/
static const char *pch;
@ -3369,11 +3457,12 @@ static int is_valid_option(const char *c, const char *typestr)
return (typestr != NULL);
}
static const mon_cmd_t *monitor_find_command(const char *cmdname)
static const mon_cmd_t *search_dispatch_table(const mon_cmd_t *disp_table,
const char *cmdname)
{
const mon_cmd_t *cmd;
for (cmd = mon_cmds; cmd->name != NULL; cmd++) {
for (cmd = disp_table; cmd->name != NULL; cmd++) {
if (compare_cmd(cmdname, cmd->name)) {
return cmd;
}
@ -3382,6 +3471,21 @@ static const mon_cmd_t *monitor_find_command(const char *cmdname)
return NULL;
}
static const mon_cmd_t *monitor_find_command(const char *cmdname)
{
return search_dispatch_table(mon_cmds, cmdname);
}
static const mon_cmd_t *qmp_find_query_cmd(const char *info_item)
{
return search_dispatch_table(qmp_query_cmds, info_item);
}
static const mon_cmd_t *qmp_find_cmd(const char *cmdname)
{
return search_dispatch_table(qmp_cmds, cmdname);
}
static const mon_cmd_t *monitor_parse_command(Monitor *mon,
const char *cmdline,
QDict *qdict)
@ -3730,15 +3834,6 @@ void monitor_set_error(Monitor *mon, QError *qerror)
}
}
static int is_async_return(const QObject *data)
{
if (data && qobject_type(data) == QTYPE_QDICT) {
return qdict_haskey(qobject_to_qdict(data), "__mon_async");
}
return 0;
}
static void handler_audit(Monitor *mon, const mon_cmd_t *cmd, int ret)
{
if (monitor_ctrl_mode(mon)) {
@ -3786,37 +3881,6 @@ static void handler_audit(Monitor *mon, const mon_cmd_t *cmd, int ret)
}
}
static void monitor_call_handler(Monitor *mon, const mon_cmd_t *cmd,
const QDict *params)
{
int ret;
QObject *data = NULL;
mon_print_count_init(mon);
ret = cmd->mhandler.cmd_new(mon, params, &data);
handler_audit(mon, cmd, ret);
if (is_async_return(data)) {
/*
* Asynchronous commands have no initial return data but they can
* generate errors. Data is returned via the async completion handler.
*/
if (monitor_ctrl_mode(mon) && monitor_has_error(mon)) {
monitor_protocol_emitter(mon, NULL);
}
} else if (monitor_ctrl_mode(mon)) {
/* Monitor Protocol */
monitor_protocol_emitter(mon, data);
} else {
/* User Protocol */
if (data)
cmd->user_print(mon, data);
}
qobject_decref(data);
}
static void handle_user_command(Monitor *mon, const char *cmdline)
{
QDict *qdict;
@ -3828,10 +3892,18 @@ static void handle_user_command(Monitor *mon, const char *cmdline)
if (!cmd)
goto out;
if (monitor_handler_is_async(cmd)) {
if (handler_is_async(cmd)) {
user_async_cmd_handler(mon, cmd, qdict);
} else if (monitor_handler_ported(cmd)) {
monitor_call_handler(mon, cmd, qdict);
} else if (handler_is_qobject(cmd)) {
QObject *data = NULL;
/* XXX: ignores the error code */
cmd->mhandler.cmd_new(mon, qdict, &data);
assert(!monitor_has_error(mon));
if (data) {
cmd->user_print(mon, data);
qobject_decref(data);
}
} else {
cmd->mhandler.cmd(mon, qdict);
}
@ -4321,6 +4393,38 @@ static QDict *qmp_check_input_obj(QObject *input_obj)
return input_dict;
}
static void qmp_call_query_cmd(Monitor *mon, const mon_cmd_t *cmd)
{
QObject *ret_data = NULL;
if (handler_is_async(cmd)) {
qmp_async_info_handler(mon, cmd);
if (monitor_has_error(mon)) {
monitor_protocol_emitter(mon, NULL);
}
} else {
cmd->mhandler.info_new(mon, &ret_data);
if (ret_data) {
monitor_protocol_emitter(mon, ret_data);
qobject_decref(ret_data);
}
}
}
static void qmp_call_cmd(Monitor *mon, const mon_cmd_t *cmd,
const QDict *params)
{
int ret;
QObject *data = NULL;
mon_print_count_init(mon);
ret = cmd->mhandler.cmd_new(mon, params, &data);
handler_audit(mon, cmd, ret);
monitor_protocol_emitter(mon, data);
qobject_decref(data);
}
static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
{
int err;
@ -4328,8 +4432,9 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
QDict *input, *args;
const mon_cmd_t *cmd;
Monitor *mon = cur_mon;
const char *cmd_name, *info_item;
const char *cmd_name, *query_cmd;
query_cmd = NULL;
args = input = NULL;
obj = json_parser_parse(tokens, NULL);
@ -4354,24 +4459,15 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
goto err_out;
}
/*
* XXX: We need this special case until we get info handlers
* converted into 'query-' commands
*/
if (compare_cmd(cmd_name, "info")) {
if (strstart(cmd_name, "query-", &query_cmd)) {
cmd = qmp_find_query_cmd(query_cmd);
} else {
cmd = qmp_find_cmd(cmd_name);
}
if (!cmd) {
qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name);
goto err_out;
} else if (strstart(cmd_name, "query-", &info_item)) {
cmd = monitor_find_command("info");
qdict_put_obj(input, "arguments",
qobject_from_jsonf("{ 'item': %s }", info_item));
} else {
cmd = monitor_find_command(cmd_name);
if (!cmd || !monitor_handler_ported(cmd)
|| monitor_cmd_user_only(cmd)) {
qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name);
goto err_out;
}
}
obj = qdict_get(input, "arguments");
@ -4387,14 +4483,16 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
goto err_out;
}
if (monitor_handler_is_async(cmd)) {
if (query_cmd) {
qmp_call_query_cmd(mon, cmd);
} else if (handler_is_async(cmd)) {
err = qmp_async_cmd_handler(mon, cmd, args);
if (err) {
/* emit the error response */
goto err_out;
}
} else {
monitor_call_handler(mon, cmd, args);
qmp_call_cmd(mon, cmd, args);
}
goto out;

View File

@ -14,10 +14,10 @@ extern Monitor *default_mon;
#define MONITOR_IS_DEFAULT 0x01
#define MONITOR_USE_READLINE 0x02
#define MONITOR_USE_CONTROL 0x04
#define MONITOR_USE_PRETTY 0x08
/* flags for monitor commands */
#define MONITOR_CMD_ASYNC 0x0001
#define MONITOR_CMD_USER_ONLY 0x0002
/* QMP events */
typedef enum MonitorEvent {

View File

@ -283,6 +283,9 @@ static QemuOptsList qemu_mon_opts = {
},{
.name = "default",
.type = QEMU_OPT_BOOL,
},{
.name = "pretty",
.type = QEMU_OPT_BOOL,
},
{ /* end of list */ }
},

55
qjson.c
View File

@ -72,43 +72,57 @@ QObject *qobject_from_jsonf(const char *string, ...)
typedef struct ToJsonIterState
{
int indent;
int pretty;
int count;
QString *str;
} ToJsonIterState;
static void to_json(const QObject *obj, QString *str);
static void to_json(const QObject *obj, QString *str, int pretty, int indent);
static void to_json_dict_iter(const char *key, QObject *obj, void *opaque)
{
ToJsonIterState *s = opaque;
QString *qkey;
int j;
if (s->count) {
if (s->count)
qstring_append(s->str, ", ");
if (s->pretty) {
qstring_append(s->str, "\n");
for (j = 0 ; j < s->indent ; j++)
qstring_append(s->str, " ");
}
qkey = qstring_from_str(key);
to_json(QOBJECT(qkey), s->str);
to_json(QOBJECT(qkey), s->str, s->pretty, s->indent);
QDECREF(qkey);
qstring_append(s->str, ": ");
to_json(obj, s->str);
to_json(obj, s->str, s->pretty, s->indent);
s->count++;
}
static void to_json_list_iter(QObject *obj, void *opaque)
{
ToJsonIterState *s = opaque;
int j;
if (s->count) {
if (s->count)
qstring_append(s->str, ", ");
if (s->pretty) {
qstring_append(s->str, "\n");
for (j = 0 ; j < s->indent ; j++)
qstring_append(s->str, " ");
}
to_json(obj, s->str);
to_json(obj, s->str, s->pretty, s->indent);
s->count++;
}
static void to_json(const QObject *obj, QString *str)
static void to_json(const QObject *obj, QString *str, int pretty, int indent)
{
switch (qobject_type(obj)) {
case QTYPE_QINT: {
@ -193,8 +207,16 @@ static void to_json(const QObject *obj, QString *str)
s.count = 0;
s.str = str;
s.indent = indent + 1;
s.pretty = pretty;
qstring_append(str, "{");
qdict_iter(val, to_json_dict_iter, &s);
if (pretty) {
int j;
qstring_append(str, "\n");
for (j = 0 ; j < indent ; j++)
qstring_append(str, " ");
}
qstring_append(str, "}");
break;
}
@ -204,8 +226,16 @@ static void to_json(const QObject *obj, QString *str)
s.count = 0;
s.str = str;
s.indent = indent + 1;
s.pretty = pretty;
qstring_append(str, "[");
qlist_iter(val, (void *)to_json_list_iter, &s);
if (pretty) {
int j;
qstring_append(str, "\n");
for (j = 0 ; j < indent ; j++)
qstring_append(str, " ");
}
qstring_append(str, "]");
break;
}
@ -249,7 +279,16 @@ QString *qobject_to_json(const QObject *obj)
{
QString *str = qstring_new();
to_json(obj, str);
to_json(obj, str, 0, 0);
return str;
}
QString *qobject_to_json_pretty(const QObject *obj)
{
QString *str = qstring_new();
to_json(obj, str, 1, 0);
return str;
}

View File

@ -23,5 +23,6 @@ QObject *qobject_from_jsonf(const char *string, ...) GCC_FMT_ATTR(1, 2);
QObject *qobject_from_jsonv(const char *string, va_list *ap) GCC_FMT_ATTR(1, 0);
QString *qobject_to_json(const QObject *obj);
QString *qobject_to_json_pretty(const QObject *obj);
#endif /* QJSON_H */

File diff suppressed because it is too large Load Diff

3
vl.c
View File

@ -1562,6 +1562,9 @@ static int mon_init_func(QemuOpts *opts, void *opaque)
exit(1);
}
if (qemu_opt_get_bool(opts, "pretty", 0))
flags |= MONITOR_USE_PRETTY;
if (qemu_opt_get_bool(opts, "default", 0))
flags |= MONITOR_IS_DEFAULT;