return (mon->flags & MONITOR_USE_CONTROL);
}
+/* Return non-zero iff we have a current monitor, and it is in QMP mode. */
+int monitor_cur_is_qmp(void)
+{
+ return cur_mon && monitor_ctrl_mode(cur_mon);
+}
+
static void monitor_read_command(Monitor *mon, int show_prompt)
{
if (!mon->rs)
void *opaque)
{
if (monitor_ctrl_mode(mon)) {
- qemu_error_new(QERR_MISSING_PARAMETER, "password");
+ qerror_report(QERR_MISSING_PARAMETER, "password");
return -EINVAL;
} else if (mon->rs) {
readline_start(mon->rs, "Password: ", 1, readline_func, opaque);
if (cmd->name == NULL) {
if (monitor_ctrl_mode(mon)) {
- qemu_error_new(QERR_COMMAND_NOT_FOUND, item);
+ qerror_report(QERR_COMMAND_NOT_FOUND, item);
return -1;
}
goto help;
} else {
if (monitor_ctrl_mode(mon)) {
/* handler not converted yet */
- qemu_error_new(QERR_COMMAND_NOT_FOUND, item);
+ qerror_report(QERR_COMMAND_NOT_FOUND, item);
return -1;
} else {
cmd->mhandler.info(mon);
{
int index = qdict_get_int(qdict, "index");
if (mon_set_cpu(index) < 0) {
- qemu_error_new(QERR_INVALID_PARAMETER, "index");
+ qerror_report(QERR_INVALID_PARAMETER, "index");
return -1;
}
return 0;
if (bdrv_is_inserted(bs)) {
if (!force) {
if (!bdrv_is_removable(bs)) {
- qemu_error_new(QERR_DEVICE_NOT_REMOVABLE,
+ qerror_report(QERR_DEVICE_NOT_REMOVABLE,
bdrv_get_device_name(bs));
return -1;
}
if (bdrv_is_locked(bs)) {
- qemu_error_new(QERR_DEVICE_LOCKED, bdrv_get_device_name(bs));
+ qerror_report(QERR_DEVICE_LOCKED, bdrv_get_device_name(bs));
return -1;
}
}
bs = bdrv_find(filename);
if (!bs) {
- qemu_error_new(QERR_DEVICE_NOT_FOUND, filename);
+ qerror_report(QERR_DEVICE_NOT_FOUND, filename);
return -1;
}
return eject_device(mon, bs, force);
bs = bdrv_find(qdict_get_str(qdict, "device"));
if (!bs) {
- qemu_error_new(QERR_DEVICE_NOT_FOUND, qdict_get_str(qdict, "device"));
+ qerror_report(QERR_DEVICE_NOT_FOUND, qdict_get_str(qdict, "device"));
return -1;
}
if (bdrv_set_key(bs, qdict_get_str(qdict, "password")) < 0) {
- qemu_error_new(QERR_INVALID_PASSWORD);
+ qerror_report(QERR_INVALID_PASSWORD);
return -1;
}
bs = bdrv_find(device);
if (!bs) {
- qemu_error_new(QERR_DEVICE_NOT_FOUND, device);
+ qerror_report(QERR_DEVICE_NOT_FOUND, device);
return -1;
}
if (fmt) {
drv = bdrv_find_whitelisted_format(fmt);
if (!drv) {
- qemu_error_new(QERR_INVALID_BLOCK_FORMAT, fmt);
+ qerror_report(QERR_INVALID_BLOCK_FORMAT, fmt);
return -1;
}
}
static int change_vnc_password(const char *password)
{
if (vnc_display_password(NULL, password) < 0) {
- qemu_error_new(QERR_SET_PASSWD_FAILED);
+ qerror_report(QERR_SET_PASSWD_FAILED);
return -1;
}
}
} else {
if (vnc_display_open(NULL, target) < 0) {
- qemu_error_new(QERR_VNC_SERVER_FAILED, target);
+ qerror_report(QERR_VNC_SERVER_FAILED, target);
return -1;
}
}
f = fopen(filename, "wb");
if (!f) {
- qemu_error_new(QERR_OPEN_FILE_FAILED, filename);
+ qerror_report(QERR_OPEN_FILE_FAILED, filename);
return -1;
}
while (size != 0) {
f = fopen(filename, "wb");
if (!f) {
- qemu_error_new(QERR_OPEN_FILE_FAILED, filename);
+ qerror_report(QERR_OPEN_FILE_FAILED, filename);
return -1;
}
while (size != 0) {
int ret;
if (kvm_enabled() && !kvm_has_sync_mmu()) {
- qemu_error_new(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
+ qerror_report(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
return -1;
}
ret = qemu_balloon_status(cb, opaque);
if (!ret) {
- qemu_error_new(QERR_DEVICE_NOT_ACTIVE, "balloon");
+ qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon");
return -1;
}
int ret;
if (kvm_enabled() && !kvm_has_sync_mmu()) {
- qemu_error_new(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
+ qerror_report(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
return -1;
}
ret = qemu_balloon(qdict_get_int(params, "value"), cb, opaque);
if (ret == 0) {
- qemu_error_new(QERR_DEVICE_NOT_ACTIVE, "balloon");
+ qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon");
return -1;
}
fd = qemu_chr_get_msgfd(mon->chr);
if (fd == -1) {
- qemu_error_new(QERR_FD_NOT_SUPPLIED);
+ qerror_report(QERR_FD_NOT_SUPPLIED);
return -1;
}
if (qemu_isdigit(fdname[0])) {
- qemu_error_new(QERR_INVALID_PARAMETER, "fdname");
+ qerror_report(QERR_INVALID_PARAMETER, "fdname");
return -1;
}
fd = dup(fd);
if (fd == -1) {
if (errno == EMFILE)
- qemu_error_new(QERR_TOO_MANY_FILES);
+ qerror_report(QERR_TOO_MANY_FILES);
else
- qemu_error_new(QERR_UNDEFINED_ERROR);
+ qerror_report(QERR_UNDEFINED_ERROR);
return -1;
}
return 0;
}
- qemu_error_new(QERR_FD_NOT_FOUND, fdname);
+ qerror_report(QERR_FD_NOT_FOUND, fdname);
return -1;
}
}
}
-static void monitor_print_error(Monitor *mon)
-{
- qerror_print(mon->error);
- QDECREF(mon->error);
- mon->error = NULL;
-}
-
static int is_async_return(const QObject *data)
{
if (data && qobject_type(data) == QTYPE_QDICT) {
static void handler_audit(Monitor *mon, const mon_cmd_t *cmd, int ret)
{
- if (ret && !monitor_has_error(mon)) {
- /*
- * If it returns failure, it must have passed on error.
- *
- * Action: Report an internal error to the client if in QMP.
- */
- if (monitor_ctrl_mode(mon)) {
- qemu_error_new(QERR_UNDEFINED_ERROR);
+ if (monitor_ctrl_mode(mon)) {
+ if (ret && !monitor_has_error(mon)) {
+ /*
+ * If it returns failure, it must have passed on error.
+ *
+ * Action: Report an internal error to the client if in QMP.
+ */
+ qerror_report(QERR_UNDEFINED_ERROR);
+ MON_DEBUG("command '%s' returned failure but did not pass an error\n",
+ cmd->name);
}
- MON_DEBUG("command '%s' returned failure but did not pass an error\n",
- cmd->name);
- }
#ifdef CONFIG_DEBUG_MONITOR
- if (!ret && monitor_has_error(mon)) {
- /*
- * If it returns success, it must not have passed an error.
- *
- * Action: Report the passed error to the client.
- */
- MON_DEBUG("command '%s' returned success but passed an error\n",
- cmd->name);
- }
+ if (!ret && monitor_has_error(mon)) {
+ /*
+ * If it returns success, it must not have passed an error.
+ *
+ * Action: Report the passed error to the client.
+ */
+ MON_DEBUG("command '%s' returned success but passed an error\n",
+ cmd->name);
+ }
- if (mon_print_count_get(mon) > 0 && strcmp(cmd->name, "info") != 0) {
- /*
- * Handlers should not call Monitor print functions.
- *
- * Action: Ignore them in QMP.
- *
- * (XXX: we don't check any 'info' or 'query' command here
- * because the user print function _is_ called by do_info(), hence
- * we will trigger this check. This problem will go away when we
- * make 'query' commands real and kill do_info())
- */
- MON_DEBUG("command '%s' called print functions %d time(s)\n",
- cmd->name, mon_print_count_get(mon));
- }
+ if (mon_print_count_get(mon) > 0 && strcmp(cmd->name, "info") != 0) {
+ /*
+ * Handlers should not call Monitor print functions.
+ *
+ * Action: Ignore them in QMP.
+ *
+ * (XXX: we don't check any 'info' or 'query' command here
+ * because the user print function _is_ called by do_info(), hence
+ * we will trigger this check. This problem will go away when we
+ * make 'query' commands real and kill do_info())
+ */
+ MON_DEBUG("command '%s' called print functions %d time(s)\n",
+ cmd->name, mon_print_count_get(mon));
+ }
#endif
+ } else {
+ assert(!monitor_has_error(mon));
+ QDECREF(mon->error);
+ mon->error = NULL;
+ }
}
static void monitor_call_handler(Monitor *mon, const mon_cmd_t *cmd,
if (!cmd)
goto out;
- qemu_errors_to_mon(mon);
-
if (monitor_handler_is_async(cmd)) {
user_async_cmd_handler(mon, cmd, qdict);
} else if (monitor_handler_ported(cmd)) {
cmd->mhandler.cmd(mon, qdict);
}
- if (monitor_has_error(mon))
- monitor_print_error(mon);
-
- qemu_errors_to_previous();
-
out:
QDECREF(qdict);
}
static int check_opt(const CmdArgs *cmd_args, const char *name, QDict *args)
{
if (!cmd_args->optional) {
- qemu_error_new(QERR_MISSING_PARAMETER, name);
+ qerror_report(QERR_MISSING_PARAMETER, name);
return -1;
}
case 'B':
case 's':
if (qobject_type(value) != QTYPE_QSTRING) {
- qemu_error_new(QERR_INVALID_PARAMETER_TYPE, name, "string");
+ qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "string");
return -1;
}
break;
for (i = 0; keys[i]; i++) {
QObject *obj = qdict_get(args, keys[i]);
if (!obj) {
- qemu_error_new(QERR_MISSING_PARAMETER, name);
+ qerror_report(QERR_MISSING_PARAMETER, name);
return -1;
}
if (qobject_type(obj) != QTYPE_QINT) {
- qemu_error_new(QERR_INVALID_PARAMETER_TYPE, name, "int");
+ qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "int");
return -1;
}
}
case 'l':
case 'M':
if (qobject_type(value) != QTYPE_QINT) {
- qemu_error_new(QERR_INVALID_PARAMETER_TYPE, name, "int");
+ qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "int");
return -1;
}
break;
case 'b':
case 'T':
if (qobject_type(value) != QTYPE_QINT && qobject_type(value) != QTYPE_QFLOAT) {
- qemu_error_new(QERR_INVALID_PARAMETER_TYPE, name, "number");
+ qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "number");
return -1;
}
break;
case '-':
if (qobject_type(value) != QTYPE_QINT &&
qobject_type(value) != QTYPE_QBOOL) {
- qemu_error_new(QERR_INVALID_PARAMETER_TYPE, name, "bool");
+ qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "bool");
return -1;
}
if (qobject_type(value) == QTYPE_QBOOL) {
const char *cmd_name, *info_item;
args = NULL;
- qemu_errors_to_mon(mon);
obj = json_parser_parse(tokens, NULL);
if (!obj) {
// FIXME: should be triggered in json_parser_parse()
- qemu_error_new(QERR_JSON_PARSING);
+ qerror_report(QERR_JSON_PARSING);
goto err_out;
} else if (qobject_type(obj) != QTYPE_QDICT) {
- qemu_error_new(QERR_QMP_BAD_INPUT_OBJECT, "object");
+ qerror_report(QERR_QMP_BAD_INPUT_OBJECT, "object");
qobject_decref(obj);
goto err_out;
}
obj = qdict_get(input, "execute");
if (!obj) {
- qemu_error_new(QERR_QMP_BAD_INPUT_OBJECT, "execute");
+ qerror_report(QERR_QMP_BAD_INPUT_OBJECT, "execute");
goto err_input;
} else if (qobject_type(obj) != QTYPE_QSTRING) {
- qemu_error_new(QERR_QMP_BAD_INPUT_OBJECT, "string");
+ qerror_report(QERR_QMP_BAD_INPUT_OBJECT, "string");
goto err_input;
}
cmd_name = qstring_get_str(qobject_to_qstring(obj));
if (invalid_qmp_mode(mon, cmd_name)) {
- qemu_error_new(QERR_COMMAND_NOT_FOUND, cmd_name);
+ qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name);
goto err_input;
}
* converted into 'query-' commands
*/
if (compare_cmd(cmd_name, "info")) {
- qemu_error_new(QERR_COMMAND_NOT_FOUND, cmd_name);
+ qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name);
goto err_input;
} else if (strstart(cmd_name, "query-", &info_item)) {
cmd = monitor_find_command("info");
} else {
cmd = monitor_find_command(cmd_name);
if (!cmd || !monitor_handler_ported(cmd)) {
- qemu_error_new(QERR_COMMAND_NOT_FOUND, cmd_name);
+ qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name);
goto err_input;
}
}
monitor_protocol_emitter(mon, NULL);
out:
QDECREF(args);
- qemu_errors_to_previous();
}
/**
}
if (monitor_ctrl_mode(mon)) {
- qemu_error_new(QERR_DEVICE_ENCRYPTED, bdrv_get_device_name(bs));
+ qerror_report(QERR_DEVICE_ENCRYPTED, bdrv_get_device_name(bs));
return -1;
}
return err;
}
-
-typedef struct QemuErrorSink QemuErrorSink;
-struct QemuErrorSink {
- enum {
- ERR_SINK_FILE,
- ERR_SINK_MONITOR,
- } dest;
- union {
- FILE *fp;
- Monitor *mon;
- };
- QemuErrorSink *previous;
-};
-
-static QemuErrorSink *qemu_error_sink;
-
-void qemu_errors_to_file(FILE *fp)
-{
- QemuErrorSink *sink;
-
- sink = qemu_mallocz(sizeof(*sink));
- sink->dest = ERR_SINK_FILE;
- sink->fp = fp;
- sink->previous = qemu_error_sink;
- qemu_error_sink = sink;
-}
-
-void qemu_errors_to_mon(Monitor *mon)
-{
- QemuErrorSink *sink;
-
- sink = qemu_mallocz(sizeof(*sink));
- sink->dest = ERR_SINK_MONITOR;
- sink->mon = mon;
- sink->previous = qemu_error_sink;
- qemu_error_sink = sink;
-}
-
-void qemu_errors_to_previous(void)
-{
- QemuErrorSink *sink;
-
- assert(qemu_error_sink != NULL);
- sink = qemu_error_sink;
- qemu_error_sink = sink->previous;
- qemu_free(sink);
-}
-
-void qemu_error(const char *fmt, ...)
-{
- va_list args;
-
- assert(qemu_error_sink != NULL);
- switch (qemu_error_sink->dest) {
- case ERR_SINK_FILE:
- va_start(args, fmt);
- vfprintf(qemu_error_sink->fp, fmt, args);
- va_end(args);
- break;
- case ERR_SINK_MONITOR:
- va_start(args, fmt);
- monitor_vprintf(qemu_error_sink->mon, fmt, args);
- va_end(args);
- break;
- }
-}
-
-void qemu_error_internal(const char *file, int linenr, const char *func,
- const char *fmt, ...)
-{
- va_list va;
- QError *qerror;
-
- assert(qemu_error_sink != NULL);
-
- va_start(va, fmt);
- qerror = qerror_from_info(file, linenr, func, fmt, &va);
- va_end(va);
-
- switch (qemu_error_sink->dest) {
- case ERR_SINK_FILE:
- qerror_print(qerror);
- QDECREF(qerror);
- break;
- case ERR_SINK_MONITOR:
- monitor_set_error(qemu_error_sink->mon, qerror);
- break;
- }
-}