#include "net/slirp.h"
#include "chardev/char-fe.h"
#include "chardev/char-io.h"
+#include "chardev/char-mux.h"
#include "ui/qemu-spice.h"
#include "sysemu/numa.h"
#include "monitor/monitor.h"
#include "qemu/readline.h"
#include "ui/console.h"
#include "ui/input.h"
-#include "sysemu/blockdev.h"
#include "sysemu/block-backend.h"
#include "audio/audio.h"
#include "disas/disas.h"
static void qmp_request_free(QMPRequest *req)
{
- qobject_decref(req->id);
- qobject_decref(req->req);
+ qobject_unref(req->id);
+ qobject_unref(req->req);
g_free(req);
}
static void monitor_qmp_cleanup_resp_queue_locked(Monitor *mon)
{
while (!g_queue_is_empty(mon->qmp.qmp_responses)) {
- qobject_decref(g_queue_pop_head(mon->qmp.qmp_responses));
+ qobject_unref((QObject *)g_queue_pop_head(mon->qmp.qmp_responses));
}
}
rc = qemu_chr_fe_write(&mon->chr, (const uint8_t *) buf, len);
if ((rc < 0 && errno != EAGAIN) || (rc == len)) {
/* all flushed or error */
- QDECREF(mon->outbuf);
+ qobject_unref(mon->outbuf);
mon->outbuf = qstring_new();
return;
}
if (rc > 0) {
/* partial write */
QString *tmp = qstring_from_str(buf + rc);
- QDECREF(mon->outbuf);
+ qobject_unref(mon->outbuf);
mon->outbuf = tmp;
}
if (mon->out_watch == 0) {
qstring_append_chr(json, '\n');
monitor_puts(mon, qstring_get_str(json));
- QDECREF(json);
+ qobject_unref(json);
}
static void monitor_json_emitter(Monitor *mon, QObject *data)
* caller won't free the data (which will be finally freed in
* responder thread).
*/
- qobject_incref(data);
qemu_mutex_lock(&mon->qmp.qmp_queue_lock);
- g_queue_push_tail(mon->qmp.qmp_responses, (void *)data);
+ g_queue_push_tail(mon->qmp.qmp_responses, qobject_ref(data));
qemu_mutex_unlock(&mon->qmp.qmp_queue_lock);
qemu_bh_schedule(mon_global.qmp_respond_bh);
} else {
break;
}
monitor_json_emitter_raw(response.mon, response.data);
- qobject_decref(response.data);
+ qobject_unref(response.data);
}
}
* last send. Store event for sending when timer fires,
* replacing a prior stored event if any.
*/
- QDECREF(evstate->qdict);
- evstate->qdict = qdict;
- QINCREF(evstate->qdict);
+ qobject_unref(evstate->qdict);
+ evstate->qdict = qobject_ref(qdict);
} else {
/*
* Last send was (at least) evconf->rate ns ago.
evstate = g_new(MonitorQAPIEventState, 1);
evstate->event = event;
- evstate->data = data;
- QINCREF(evstate->data);
+ evstate->data = qobject_ref(data);
evstate->qdict = NULL;
evstate->timer = timer_new_ns(event_clock_type,
monitor_qapi_event_handler,
int64_t now = qemu_clock_get_ns(event_clock_type);
monitor_qapi_event_emit(evstate->event, evstate->qdict);
- QDECREF(evstate->qdict);
+ qobject_unref(evstate->qdict);
evstate->qdict = NULL;
timer_mod_ns(evstate->timer, now + evconf->rate);
} else {
g_hash_table_remove(monitor_qapi_event_state, evstate);
- QDECREF(evstate->data);
+ qobject_unref(evstate->data);
timer_free(evstate->timer);
g_free(evstate);
}
json_message_parser_destroy(&mon->qmp.parser);
}
readline_free(mon->rs);
- QDECREF(mon->outbuf);
+ qobject_unref(mon->outbuf);
qemu_mutex_destroy(&mon->out_lock);
qemu_mutex_destroy(&mon->qmp.qmp_queue_lock);
monitor_qmp_cleanup_req_queue_locked(mon);
qmp_init_marshal(&qmp_commands);
qmp_register_command(&qmp_commands, "query-qmp-schema",
- qmp_query_qmp_schema,
- QCO_NO_OPTIONS);
+ qmp_query_qmp_schema, QCO_ALLOW_PRECONFIG);
qmp_register_command(&qmp_commands, "device_add", qmp_device_add,
QCO_NO_OPTIONS);
qmp_register_command(&qmp_commands, "netdev_add", qmp_netdev_add,
QTAILQ_INIT(&qmp_cap_negotiation_commands);
qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities",
- qmp_marshal_qmp_capabilities, QCO_NO_OPTIONS);
+ qmp_marshal_qmp_capabilities, QCO_ALLOW_PRECONFIG);
}
static bool qmp_cap_enabled(Monitor *mon, QMPCapability cap)
return qdict;
fail:
- QDECREF(qdict);
+ qobject_unref(qdict);
g_free(key);
return NULL;
}
trace_handle_hmp_command(mon, cmdline);
+ if (runstate_check(RUN_STATE_PRECONFIG)) {
+ monitor_printf(mon, "HMP not available in preconfig state, "
+ "use QMP instead\n");
+ return;
+ }
+
cmd = monitor_parse_command(mon, cmdline, &cmdline, mon->cmd_table);
if (!cmd) {
return;
}
cmd->cmd(mon, qdict);
- QDECREF(qdict);
+ qobject_unref(qdict);
}
static void cmd_completion(Monitor *mon, const char *name, const char *list)
if (rsp) {
if (id) {
- /* This is for the qdict below. */
- qobject_incref(id);
- qdict_put_obj(qobject_to(QDict, rsp), "id", id);
+ qdict_put_obj(qobject_to(QDict, rsp), "id", qobject_ref(id));
}
monitor_json_emitter(mon, rsp);
}
- qobject_decref(id);
- qobject_decref(rsp);
+ qobject_unref(id);
+ qobject_unref(rsp);
}
/*
if (trace_event_get_state_backends(TRACE_HANDLE_QMP_COMMAND)) {
QString *req_json = qobject_to_json(req);
trace_handle_qmp_command(mon, qstring_get_str(req_json));
- QDECREF(req_json);
+ qobject_unref(req_json);
}
old_mon = cur_mon;
monitor_resume(mon);
}
- qobject_decref(req);
+ qobject_unref(req);
}
/*
goto err;
}
- qobject_incref(id);
- qdict_del(qdict, "id");
-
req_obj = g_new0(QMPRequest, 1);
req_obj->mon = mon;
- req_obj->id = id;
+ req_obj->id = qobject_ref(id);
req_obj->req = req;
req_obj->need_resume = false;
+ qdict_del(qdict, "id");
+
if (qmp_is_oob(qdict)) {
/* Out-Of-Band (OOB) requests are executed directly in parser. */
trace_monitor_qmp_cmd_out_of_band(qobject_get_try_str(req_obj->id)
err:
monitor_qmp_respond(mon, NULL, err, NULL);
- qobject_decref(req);
+ qobject_unref(req);
}
static void monitor_qmp_read(void *opaque, const uint8_t *buf, int size)
monitor_qmp_caps_reset(mon);
data = get_qmp_greeting(mon);
monitor_json_emitter(mon, data);
- qobject_decref(data);
+ qobject_unref(data);
mon_refcount++;
break;
case CHR_EVENT_CLOSED:
* have assumption to be run on main loop thread. It would be
* nice that one day we can remove this assumption in the future.
*/
- mon_global.qmp_dispatcher_bh = aio_bh_new(qemu_get_aio_context(),
+ mon_global.qmp_dispatcher_bh = aio_bh_new(iohandler_get_aio_context(),
monitor_qmp_bh_dispatcher,
NULL);
void monitor_init(Chardev *chr, int flags)
{
Monitor *mon = g_malloc(sizeof(*mon));
+ bool use_readline = flags & MONITOR_USE_READLINE;
+ bool use_oob = flags & MONITOR_USE_OOB;
+
+ if (use_oob) {
+ if (CHARDEV_IS_MUX(chr)) {
+ error_report("Monitor Out-Of-Band is not supported with "
+ "MUX typed chardev backend");
+ exit(1);
+ }
+ if (use_readline) {
+ error_report("Monitor Out-Of-band is only supported by QMP");
+ exit(1);
+ }
+ }
- monitor_data_init(mon, false, false);
+ monitor_data_init(mon, false, use_oob);
qemu_chr_fe_init(&mon->chr, chr, &error_abort);
mon->flags = flags;
- if (flags & MONITOR_USE_READLINE) {
+ if (use_readline) {
mon->rs = readline_init(monitor_readline_printf,
monitor_readline_flush,
mon,
},{
.name = "pretty",
.type = QEMU_OPT_BOOL,
+ },{
+ .name = "x-oob",
+ .type = QEMU_OPT_BOOL,
},
{ /* end of list */ }
},