]> Git Repo - qemu.git/blobdiff - monitor.c
Revert "usb-ccid: fix bus leak"
[qemu.git] / monitor.c
index 32d6114ac3aefc1f8f89ae62da4759d4b0d9e261..6d0cec552e7309be276fed0d1241f8e98f8d476e 100644 (file)
--- a/monitor.c
+++ b/monitor.c
@@ -36,6 +36,7 @@
 #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"
@@ -43,7 +44,6 @@
 #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"
@@ -328,8 +328,8 @@ int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
 
 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);
 }
 
@@ -345,7 +345,7 @@ static void monitor_qmp_cleanup_req_queue_locked(Monitor *mon)
 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));
     }
 }
 
@@ -390,14 +390,14 @@ static void monitor_flush_locked(Monitor *mon)
         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) {
@@ -481,7 +481,7 @@ static void monitor_json_emitter_raw(Monitor *mon,
     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)
@@ -493,9 +493,8 @@ 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 {
@@ -545,7 +544,7 @@ static void monitor_qmp_bh_responder(void *opaque)
             break;
         }
         monitor_json_emitter_raw(response.mon, response.data);
-        qobject_decref(response.data);
+        qobject_unref(response.data);
     }
 }
 
@@ -612,9 +611,8 @@ monitor_qapi_event_queue(QAPIEvent event, QDict *qdict, Error **errp)
              * 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.
@@ -628,8 +626,7 @@ monitor_qapi_event_queue(QAPIEvent event, QDict *qdict, Error **errp)
 
             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,
@@ -659,12 +656,12 @@ static void monitor_qapi_event_handler(void *opaque)
         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);
     }
@@ -746,7 +743,7 @@ static void monitor_data_destroy(Monitor *mon)
         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);
@@ -1181,8 +1178,7 @@ static void monitor_init_qmp_commands(void)
     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,
@@ -1192,7 +1188,7 @@ static void monitor_init_qmp_commands(void)
 
     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)
@@ -3361,7 +3357,7 @@ static QDict *monitor_parse_arguments(Monitor *mon,
     return qdict;
 
 fail:
-    QDECREF(qdict);
+    qobject_unref(qdict);
     g_free(key);
     return NULL;
 }
@@ -3373,6 +3369,12 @@ static void handle_hmp_command(Monitor *mon, const char *cmdline)
 
     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;
@@ -3386,7 +3388,7 @@ static void handle_hmp_command(Monitor *mon, const char *cmdline)
     }
 
     cmd->cmd(mon, qdict);
-    QDECREF(qdict);
+    qobject_unref(qdict);
 }
 
 static void cmd_completion(Monitor *mon, const char *name, const char *list)
@@ -4047,16 +4049,14 @@ static void monitor_qmp_respond(Monitor *mon, QObject *rsp,
 
     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);
 }
 
 /*
@@ -4079,7 +4079,7 @@ static void monitor_qmp_dispatch_one(QMPRequest *req_obj)
     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;
@@ -4097,7 +4097,7 @@ static void monitor_qmp_dispatch_one(QMPRequest *req_obj)
         monitor_resume(mon);
     }
 
-    qobject_decref(req);
+    qobject_unref(req);
 }
 
 /*
@@ -4189,15 +4189,14 @@ static void handle_qmp_command(JSONMessageParser *parser, GQueue *tokens)
         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)
@@ -4244,7 +4243,7 @@ static void handle_qmp_command(JSONMessageParser *parser, GQueue *tokens)
 
 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)
@@ -4363,7 +4362,7 @@ static void monitor_qmp_event(void *opaque, int event)
         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:
@@ -4466,7 +4465,7 @@ static void monitor_iothread_init(void)
      * 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);
 
@@ -4562,12 +4561,26 @@ static void monitor_qmp_setup_handlers_bh(void *opaque)
 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,
@@ -4663,6 +4676,9 @@ QemuOptsList qemu_mon_opts = {
         },{
             .name = "pretty",
             .type = QEMU_OPT_BOOL,
+        },{
+            .name = "x-oob",
+            .type = QEMU_OPT_BOOL,
         },
         { /* end of list */ }
     },
This page took 0.032307 seconds and 4 git commands to generate.