xref: /openbmc/qemu/monitor/monitor.c (revision e67b7aef7c7f67ecd0282e903e0daff806d5d680)
11d95db74SKevin Wolf /*
21d95db74SKevin Wolf  * QEMU monitor
31d95db74SKevin Wolf  *
41d95db74SKevin Wolf  * Copyright (c) 2003-2004 Fabrice Bellard
51d95db74SKevin Wolf  *
61d95db74SKevin Wolf  * Permission is hereby granted, free of charge, to any person obtaining a copy
71d95db74SKevin Wolf  * of this software and associated documentation files (the "Software"), to deal
81d95db74SKevin Wolf  * in the Software without restriction, including without limitation the rights
91d95db74SKevin Wolf  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
101d95db74SKevin Wolf  * copies of the Software, and to permit persons to whom the Software is
111d95db74SKevin Wolf  * furnished to do so, subject to the following conditions:
121d95db74SKevin Wolf  *
131d95db74SKevin Wolf  * The above copyright notice and this permission notice shall be included in
141d95db74SKevin Wolf  * all copies or substantial portions of the Software.
151d95db74SKevin Wolf  *
161d95db74SKevin Wolf  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
171d95db74SKevin Wolf  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
181d95db74SKevin Wolf  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
191d95db74SKevin Wolf  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
201d95db74SKevin Wolf  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
211d95db74SKevin Wolf  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
221d95db74SKevin Wolf  * THE SOFTWARE.
231d95db74SKevin Wolf  */
241d95db74SKevin Wolf 
251d95db74SKevin Wolf #include "qemu/osdep.h"
261d95db74SKevin Wolf #include "monitor-internal.h"
271d95db74SKevin Wolf #include "qapi/error.h"
28f2098725SKevin Wolf #include "qapi/opts-visitor.h"
291d95db74SKevin Wolf #include "qapi/qapi-emit-events.h"
30f2098725SKevin Wolf #include "qapi/qapi-visit-control.h"
311d95db74SKevin Wolf #include "qapi/qmp/qdict.h"
321d95db74SKevin Wolf #include "qemu/error-report.h"
331d95db74SKevin Wolf #include "qemu/option.h"
341d95db74SKevin Wolf #include "sysemu/qtest.h"
351d95db74SKevin Wolf #include "trace.h"
361d95db74SKevin Wolf 
371d95db74SKevin Wolf /*
381d95db74SKevin Wolf  * To prevent flooding clients, events can be throttled. The
391d95db74SKevin Wolf  * throttling is calculated globally, rather than per-Monitor
401d95db74SKevin Wolf  * instance.
411d95db74SKevin Wolf  */
421d95db74SKevin Wolf typedef struct MonitorQAPIEventState {
431d95db74SKevin Wolf     QAPIEvent event;    /* Throttling state for this event type and... */
441d95db74SKevin Wolf     QDict *data;        /* ... data, see qapi_event_throttle_equal() */
451d95db74SKevin Wolf     QEMUTimer *timer;   /* Timer for handling delayed events */
461d95db74SKevin Wolf     QDict *qdict;       /* Delayed event (if any) */
471d95db74SKevin Wolf } MonitorQAPIEventState;
481d95db74SKevin Wolf 
491d95db74SKevin Wolf typedef struct {
501d95db74SKevin Wolf     int64_t rate;       /* Minimum time (in ns) between two events */
511d95db74SKevin Wolf } MonitorQAPIEventConf;
521d95db74SKevin Wolf 
531d95db74SKevin Wolf /* Shared monitor I/O thread */
541d95db74SKevin Wolf IOThread *mon_iothread;
551d95db74SKevin Wolf 
569ce44e2cSKevin Wolf /* Coroutine to dispatch the requests received from I/O thread */
579ce44e2cSKevin Wolf Coroutine *qmp_dispatcher_co;
589ce44e2cSKevin Wolf 
590ff25537SPaolo Bonzini /*
600ff25537SPaolo Bonzini  * Set to true when the dispatcher coroutine should terminate.  Protected
610ff25537SPaolo Bonzini  * by monitor_lock.
620ff25537SPaolo Bonzini  */
639ce44e2cSKevin Wolf bool qmp_dispatcher_co_shutdown;
649ce44e2cSKevin Wolf 
659ce44e2cSKevin Wolf /*
66e69ee454SKevin Wolf  * Protects mon_list, monitor_qapi_event_state, coroutine_mon,
67e69ee454SKevin Wolf  * monitor_destroyed.
68e69ee454SKevin Wolf  */
691d95db74SKevin Wolf QemuMutex monitor_lock;
701d95db74SKevin Wolf static GHashTable *monitor_qapi_event_state;
71e69ee454SKevin Wolf static GHashTable *coroutine_mon; /* Maps Coroutine* to Monitor* */
721d95db74SKevin Wolf 
731d95db74SKevin Wolf MonitorList mon_list;
741d95db74SKevin Wolf static bool monitor_destroyed;
751d95db74SKevin Wolf 
monitor_cur(void)76947e4744SKevin Wolf Monitor *monitor_cur(void)
77947e4744SKevin Wolf {
78e69ee454SKevin Wolf     Monitor *mon;
79e69ee454SKevin Wolf 
80e69ee454SKevin Wolf     qemu_mutex_lock(&monitor_lock);
81e69ee454SKevin Wolf     mon = g_hash_table_lookup(coroutine_mon, qemu_coroutine_self());
82e69ee454SKevin Wolf     qemu_mutex_unlock(&monitor_lock);
83e69ee454SKevin Wolf 
84e69ee454SKevin Wolf     return mon;
85947e4744SKevin Wolf }
86947e4744SKevin Wolf 
87947e4744SKevin Wolf /**
88947e4744SKevin Wolf  * Sets a new current monitor and returns the old one.
89e69ee454SKevin Wolf  *
90e69ee454SKevin Wolf  * If a non-NULL monitor is set for a coroutine, another call
91e69ee454SKevin Wolf  * resetting it to NULL is required before the coroutine terminates,
92e69ee454SKevin Wolf  * otherwise a stale entry would remain in the hash table.
93947e4744SKevin Wolf  */
monitor_set_cur(Coroutine * co,Monitor * mon)94e69ee454SKevin Wolf Monitor *monitor_set_cur(Coroutine *co, Monitor *mon)
95947e4744SKevin Wolf {
96e69ee454SKevin Wolf     Monitor *old_monitor = monitor_cur();
97947e4744SKevin Wolf 
98e69ee454SKevin Wolf     qemu_mutex_lock(&monitor_lock);
99e69ee454SKevin Wolf     if (mon) {
100e69ee454SKevin Wolf         g_hash_table_replace(coroutine_mon, co, mon);
101e69ee454SKevin Wolf     } else {
102e69ee454SKevin Wolf         g_hash_table_remove(coroutine_mon, co);
103e69ee454SKevin Wolf     }
104e69ee454SKevin Wolf     qemu_mutex_unlock(&monitor_lock);
105e69ee454SKevin Wolf 
106947e4744SKevin Wolf     return old_monitor;
107947e4744SKevin Wolf }
1081d95db74SKevin Wolf 
1091d95db74SKevin Wolf /**
1101d95db74SKevin Wolf  * Is the current monitor, if any, a QMP monitor?
1111d95db74SKevin Wolf  */
monitor_cur_is_qmp(void)1121d95db74SKevin Wolf bool monitor_cur_is_qmp(void)
1131d95db74SKevin Wolf {
114947e4744SKevin Wolf     Monitor *cur_mon = monitor_cur();
115947e4744SKevin Wolf 
1161d95db74SKevin Wolf     return cur_mon && monitor_is_qmp(cur_mon);
1171d95db74SKevin Wolf }
1181d95db74SKevin Wolf 
1191d95db74SKevin Wolf /**
1201d95db74SKevin Wolf  * Is @mon is using readline?
1211d95db74SKevin Wolf  * Note: not all HMP monitors use readline, e.g., gdbserver has a
1221d95db74SKevin Wolf  * non-interactive HMP monitor, so readline is not used there.
1231d95db74SKevin Wolf  */
monitor_uses_readline(const MonitorHMP * mon)12492082416SKevin Wolf static inline bool monitor_uses_readline(const MonitorHMP *mon)
1251d95db74SKevin Wolf {
12692082416SKevin Wolf     return mon->use_readline;
1271d95db74SKevin Wolf }
1281d95db74SKevin Wolf 
monitor_is_hmp_non_interactive(const Monitor * mon)1291d95db74SKevin Wolf static inline bool monitor_is_hmp_non_interactive(const Monitor *mon)
1301d95db74SKevin Wolf {
13192082416SKevin Wolf     if (monitor_is_qmp(mon)) {
13292082416SKevin Wolf         return false;
13392082416SKevin Wolf     }
13492082416SKevin Wolf 
13592082416SKevin Wolf     return !monitor_uses_readline(container_of(mon, MonitorHMP, common));
1361d95db74SKevin Wolf }
1371d95db74SKevin Wolf 
monitor_unblocked(void * do_not_use,GIOCondition cond,void * opaque)138bf7b1eabSMarc-André Lureau static gboolean monitor_unblocked(void *do_not_use, GIOCondition cond,
1391d95db74SKevin Wolf                                   void *opaque)
1401d95db74SKevin Wolf {
1411d95db74SKevin Wolf     Monitor *mon = opaque;
1421d95db74SKevin Wolf 
143e37548efSPaolo Bonzini     QEMU_LOCK_GUARD(&mon->mon_lock);
1441d95db74SKevin Wolf     mon->out_watch = 0;
1451d95db74SKevin Wolf     monitor_flush_locked(mon);
14653c7c924SPhilippe Mathieu-Daudé     return G_SOURCE_REMOVE;
1471d95db74SKevin Wolf }
1481d95db74SKevin Wolf 
1491d95db74SKevin Wolf /* Caller must hold mon->mon_lock */
monitor_flush_locked(Monitor * mon)1504cb96b97SPaolo Bonzini void monitor_flush_locked(Monitor *mon)
1511d95db74SKevin Wolf {
1521d95db74SKevin Wolf     int rc;
1531d95db74SKevin Wolf     size_t len;
1541d95db74SKevin Wolf     const char *buf;
1551d95db74SKevin Wolf 
1561d95db74SKevin Wolf     if (mon->skip_flush) {
1571d95db74SKevin Wolf         return;
1581d95db74SKevin Wolf     }
1591d95db74SKevin Wolf 
16020076f4aSMarkus Armbruster     buf = mon->outbuf->str;
16120076f4aSMarkus Armbruster     len = mon->outbuf->len;
1621d95db74SKevin Wolf 
1631d95db74SKevin Wolf     if (len && !mon->mux_out) {
1641d95db74SKevin Wolf         rc = qemu_chr_fe_write(&mon->chr, (const uint8_t *) buf, len);
1651d95db74SKevin Wolf         if ((rc < 0 && errno != EAGAIN) || (rc == len)) {
1661d95db74SKevin Wolf             /* all flushed or error */
16720076f4aSMarkus Armbruster             g_string_truncate(mon->outbuf, 0);
1681d95db74SKevin Wolf             return;
1691d95db74SKevin Wolf         }
1701d95db74SKevin Wolf         if (rc > 0) {
1711d95db74SKevin Wolf             /* partial write */
17220076f4aSMarkus Armbruster             g_string_erase(mon->outbuf, 0, rc);
1731d95db74SKevin Wolf         }
1741d95db74SKevin Wolf         if (mon->out_watch == 0) {
1751d95db74SKevin Wolf             mon->out_watch =
1761d95db74SKevin Wolf                 qemu_chr_fe_add_watch(&mon->chr, G_IO_OUT | G_IO_HUP,
1771d95db74SKevin Wolf                                       monitor_unblocked, mon);
1781d95db74SKevin Wolf         }
1791d95db74SKevin Wolf     }
1801d95db74SKevin Wolf }
1811d95db74SKevin Wolf 
monitor_flush(Monitor * mon)1821d95db74SKevin Wolf void monitor_flush(Monitor *mon)
1831d95db74SKevin Wolf {
184e37548efSPaolo Bonzini     QEMU_LOCK_GUARD(&mon->mon_lock);
1851d95db74SKevin Wolf     monitor_flush_locked(mon);
1861d95db74SKevin Wolf }
1871d95db74SKevin Wolf 
1881d95db74SKevin Wolf /* flush at every end of line */
monitor_puts_locked(Monitor * mon,const char * str)1894cb96b97SPaolo Bonzini int monitor_puts_locked(Monitor *mon, const char *str)
1901d95db74SKevin Wolf {
1911d95db74SKevin Wolf     int i;
1921d95db74SKevin Wolf     char c;
1931d95db74SKevin Wolf 
1941d95db74SKevin Wolf     for (i = 0; str[i]; i++) {
1951d95db74SKevin Wolf         c = str[i];
1961d95db74SKevin Wolf         if (c == '\n') {
19720076f4aSMarkus Armbruster             g_string_append_c(mon->outbuf, '\r');
1981d95db74SKevin Wolf         }
19920076f4aSMarkus Armbruster         g_string_append_c(mon->outbuf, c);
2001d95db74SKevin Wolf         if (c == '\n') {
2011d95db74SKevin Wolf             monitor_flush_locked(mon);
2021d95db74SKevin Wolf         }
2031d95db74SKevin Wolf     }
2041d95db74SKevin Wolf 
2051d95db74SKevin Wolf     return i;
2061d95db74SKevin Wolf }
2071d95db74SKevin Wolf 
monitor_puts(Monitor * mon,const char * str)2084cb96b97SPaolo Bonzini int monitor_puts(Monitor *mon, const char *str)
2094cb96b97SPaolo Bonzini {
2104cb96b97SPaolo Bonzini     QEMU_LOCK_GUARD(&mon->mon_lock);
2114cb96b97SPaolo Bonzini     return monitor_puts_locked(mon, str);
2124cb96b97SPaolo Bonzini }
2134cb96b97SPaolo Bonzini 
monitor_vprintf(Monitor * mon,const char * fmt,va_list ap)2141d95db74SKevin Wolf int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
2151d95db74SKevin Wolf {
2161d95db74SKevin Wolf     char *buf;
2171d95db74SKevin Wolf     int n;
2181d95db74SKevin Wolf 
2191d95db74SKevin Wolf     if (!mon) {
2201d95db74SKevin Wolf         return -1;
2211d95db74SKevin Wolf     }
2221d95db74SKevin Wolf 
2231d95db74SKevin Wolf     if (monitor_is_qmp(mon)) {
2241d95db74SKevin Wolf         return -1;
2251d95db74SKevin Wolf     }
2261d95db74SKevin Wolf 
2271d95db74SKevin Wolf     buf = g_strdup_vprintf(fmt, ap);
2281d95db74SKevin Wolf     n = monitor_puts(mon, buf);
2291d95db74SKevin Wolf     g_free(buf);
2301d95db74SKevin Wolf     return n;
2311d95db74SKevin Wolf }
2321d95db74SKevin Wolf 
monitor_printf(Monitor * mon,const char * fmt,...)2331d95db74SKevin Wolf int monitor_printf(Monitor *mon, const char *fmt, ...)
2341d95db74SKevin Wolf {
2351d95db74SKevin Wolf     int ret;
2361d95db74SKevin Wolf 
2371d95db74SKevin Wolf     va_list ap;
2381d95db74SKevin Wolf     va_start(ap, fmt);
2391d95db74SKevin Wolf     ret = monitor_vprintf(mon, fmt, ap);
2401d95db74SKevin Wolf     va_end(ap);
2411d95db74SKevin Wolf     return ret;
2421d95db74SKevin Wolf }
2431d95db74SKevin Wolf 
monitor_printc(Monitor * mon,int c)244dd00d7faSMarkus Armbruster void monitor_printc(Monitor *mon, int c)
245dd00d7faSMarkus Armbruster {
246dd00d7faSMarkus Armbruster     monitor_printf(mon, "'");
247dd00d7faSMarkus Armbruster     switch(c) {
248dd00d7faSMarkus Armbruster     case '\'':
249dd00d7faSMarkus Armbruster         monitor_printf(mon, "\\'");
250dd00d7faSMarkus Armbruster         break;
251dd00d7faSMarkus Armbruster     case '\\':
252dd00d7faSMarkus Armbruster         monitor_printf(mon, "\\\\");
253dd00d7faSMarkus Armbruster         break;
254dd00d7faSMarkus Armbruster     case '\n':
255dd00d7faSMarkus Armbruster         monitor_printf(mon, "\\n");
256dd00d7faSMarkus Armbruster         break;
257dd00d7faSMarkus Armbruster     case '\r':
258dd00d7faSMarkus Armbruster         monitor_printf(mon, "\\r");
259dd00d7faSMarkus Armbruster         break;
260dd00d7faSMarkus Armbruster     default:
261dd00d7faSMarkus Armbruster         if (c >= 32 && c <= 126) {
262dd00d7faSMarkus Armbruster             monitor_printf(mon, "%c", c);
263dd00d7faSMarkus Armbruster         } else {
264dd00d7faSMarkus Armbruster             monitor_printf(mon, "\\x%02x", c);
265dd00d7faSMarkus Armbruster         }
266dd00d7faSMarkus Armbruster         break;
267dd00d7faSMarkus Armbruster     }
268dd00d7faSMarkus Armbruster     monitor_printf(mon, "'");
269dd00d7faSMarkus Armbruster }
270dd00d7faSMarkus Armbruster 
2711d95db74SKevin Wolf /*
2721d95db74SKevin Wolf  * Print to current monitor if we have one, else to stderr.
2731d95db74SKevin Wolf  */
error_vprintf(const char * fmt,va_list ap)2741d95db74SKevin Wolf int error_vprintf(const char *fmt, va_list ap)
2751d95db74SKevin Wolf {
276947e4744SKevin Wolf     Monitor *cur_mon = monitor_cur();
277947e4744SKevin Wolf 
2781d95db74SKevin Wolf     if (cur_mon && !monitor_cur_is_qmp()) {
2791d95db74SKevin Wolf         return monitor_vprintf(cur_mon, fmt, ap);
2801d95db74SKevin Wolf     }
2811d95db74SKevin Wolf     return vfprintf(stderr, fmt, ap);
2821d95db74SKevin Wolf }
2831d95db74SKevin Wolf 
error_vprintf_unless_qmp(const char * fmt,va_list ap)2841d95db74SKevin Wolf int error_vprintf_unless_qmp(const char *fmt, va_list ap)
2851d95db74SKevin Wolf {
286947e4744SKevin Wolf     Monitor *cur_mon = monitor_cur();
287947e4744SKevin Wolf 
2881d95db74SKevin Wolf     if (!cur_mon) {
2891d95db74SKevin Wolf         return vfprintf(stderr, fmt, ap);
2901d95db74SKevin Wolf     }
2911d95db74SKevin Wolf     if (!monitor_cur_is_qmp()) {
2921d95db74SKevin Wolf         return monitor_vprintf(cur_mon, fmt, ap);
2931d95db74SKevin Wolf     }
2941d95db74SKevin Wolf     return -1;
2951d95db74SKevin Wolf }
2961d95db74SKevin Wolf 
error_printf_unless_qmp(const char * fmt,...)297756a98ddSMarc-André Lureau int error_printf_unless_qmp(const char *fmt, ...)
298756a98ddSMarc-André Lureau {
299756a98ddSMarc-André Lureau     va_list ap;
300756a98ddSMarc-André Lureau     int ret;
301756a98ddSMarc-André Lureau 
302756a98ddSMarc-André Lureau     va_start(ap, fmt);
303756a98ddSMarc-André Lureau     ret = error_vprintf_unless_qmp(fmt, ap);
304756a98ddSMarc-André Lureau     va_end(ap);
305756a98ddSMarc-André Lureau     return ret;
306756a98ddSMarc-André Lureau }
3071d95db74SKevin Wolf 
3081d95db74SKevin Wolf static MonitorQAPIEventConf monitor_qapi_event_conf[QAPI_EVENT__MAX] = {
3091d95db74SKevin Wolf     /* Limit guest-triggerable events to 1 per second */
3101d95db74SKevin Wolf     [QAPI_EVENT_RTC_CHANGE]        = { 1000 * SCALE_MS },
311*2155d2ddSLeonid Kaplan     [QAPI_EVENT_BLOCK_IO_ERROR]    = { 1000 * SCALE_MS },
3121d95db74SKevin Wolf     [QAPI_EVENT_WATCHDOG]          = { 1000 * SCALE_MS },
3131d95db74SKevin Wolf     [QAPI_EVENT_BALLOON_CHANGE]    = { 1000 * SCALE_MS },
3141d95db74SKevin Wolf     [QAPI_EVENT_QUORUM_REPORT_BAD] = { 1000 * SCALE_MS },
3151d95db74SKevin Wolf     [QAPI_EVENT_QUORUM_FAILURE]    = { 1000 * SCALE_MS },
3161d95db74SKevin Wolf     [QAPI_EVENT_VSERPORT_CHANGE]   = { 1000 * SCALE_MS },
317722a3c78SDavid Hildenbrand     [QAPI_EVENT_MEMORY_DEVICE_SIZE_CHANGE] = { 1000 * SCALE_MS },
318259ebed4SMaciej S. Szmigiero     [QAPI_EVENT_HV_BALLOON_STATUS_REPORT] = { 1000 * SCALE_MS },
3191d95db74SKevin Wolf };
3201d95db74SKevin Wolf 
3211d95db74SKevin Wolf /*
3221d95db74SKevin Wolf  * Return the clock to use for recording an event's time.
3231d95db74SKevin Wolf  * It's QEMU_CLOCK_REALTIME, except for qtests it's
3241d95db74SKevin Wolf  * QEMU_CLOCK_VIRTUAL, to support testing rate limits.
3251d95db74SKevin Wolf  * Beware: result is invalid before configure_accelerator().
3261d95db74SKevin Wolf  */
monitor_get_event_clock(void)3271d95db74SKevin Wolf static inline QEMUClockType monitor_get_event_clock(void)
3281d95db74SKevin Wolf {
3291d95db74SKevin Wolf     return qtest_enabled() ? QEMU_CLOCK_VIRTUAL : QEMU_CLOCK_REALTIME;
3301d95db74SKevin Wolf }
3311d95db74SKevin Wolf 
3321d95db74SKevin Wolf /*
3331d95db74SKevin Wolf  * Broadcast an event to all monitors.
3341d95db74SKevin Wolf  * @qdict is the event object.  Its member "event" must match @event.
3351d95db74SKevin Wolf  * Caller must hold monitor_lock.
3361d95db74SKevin Wolf  */
monitor_qapi_event_emit(QAPIEvent event,QDict * qdict)3371d95db74SKevin Wolf static void monitor_qapi_event_emit(QAPIEvent event, QDict *qdict)
3381d95db74SKevin Wolf {
3391d95db74SKevin Wolf     Monitor *mon;
3401d95db74SKevin Wolf     MonitorQMP *qmp_mon;
3411d95db74SKevin Wolf 
3421d95db74SKevin Wolf     trace_monitor_protocol_event_emit(event, qdict);
3431d95db74SKevin Wolf     QTAILQ_FOREACH(mon, &mon_list, entry) {
3441d95db74SKevin Wolf         if (!monitor_is_qmp(mon)) {
3451d95db74SKevin Wolf             continue;
3461d95db74SKevin Wolf         }
3471d95db74SKevin Wolf 
3481d95db74SKevin Wolf         qmp_mon = container_of(mon, MonitorQMP, common);
3491d95db74SKevin Wolf         if (qmp_mon->commands != &qmp_cap_negotiation_commands) {
3501d95db74SKevin Wolf             qmp_send_response(qmp_mon, qdict);
3511d95db74SKevin Wolf         }
3521d95db74SKevin Wolf     }
3531d95db74SKevin Wolf }
3541d95db74SKevin Wolf 
3551d95db74SKevin Wolf static void monitor_qapi_event_handler(void *opaque);
3561d95db74SKevin Wolf 
3571d95db74SKevin Wolf /*
3581d95db74SKevin Wolf  * Queue a new event for emission to Monitor instances,
3591d95db74SKevin Wolf  * applying any rate limiting if required.
3601d95db74SKevin Wolf  */
3611d95db74SKevin Wolf static void
monitor_qapi_event_queue_no_reenter(QAPIEvent event,QDict * qdict)3621d95db74SKevin Wolf monitor_qapi_event_queue_no_reenter(QAPIEvent event, QDict *qdict)
3631d95db74SKevin Wolf {
3641d95db74SKevin Wolf     MonitorQAPIEventConf *evconf;
3651d95db74SKevin Wolf     MonitorQAPIEventState *evstate;
3661d95db74SKevin Wolf 
3671d95db74SKevin Wolf     assert(event < QAPI_EVENT__MAX);
3681d95db74SKevin Wolf     evconf = &monitor_qapi_event_conf[event];
3691d95db74SKevin Wolf     trace_monitor_protocol_event_queue(event, qdict, evconf->rate);
3701d95db74SKevin Wolf 
371a8e2ab5dSMahmoud Mandour     QEMU_LOCK_GUARD(&monitor_lock);
3721d95db74SKevin Wolf 
3731d95db74SKevin Wolf     if (!evconf->rate) {
3741d95db74SKevin Wolf         /* Unthrottled event */
3751d95db74SKevin Wolf         monitor_qapi_event_emit(event, qdict);
3761d95db74SKevin Wolf     } else {
3771d95db74SKevin Wolf         QDict *data = qobject_to(QDict, qdict_get(qdict, "data"));
3781d95db74SKevin Wolf         MonitorQAPIEventState key = { .event = event, .data = data };
3791d95db74SKevin Wolf 
3801d95db74SKevin Wolf         evstate = g_hash_table_lookup(monitor_qapi_event_state, &key);
3811d95db74SKevin Wolf         assert(!evstate || timer_pending(evstate->timer));
3821d95db74SKevin Wolf 
3831d95db74SKevin Wolf         if (evstate) {
3841d95db74SKevin Wolf             /*
3851d95db74SKevin Wolf              * Timer is pending for (at least) evconf->rate ns after
3861d95db74SKevin Wolf              * last send.  Store event for sending when timer fires,
3871d95db74SKevin Wolf              * replacing a prior stored event if any.
3881d95db74SKevin Wolf              */
3891d95db74SKevin Wolf             qobject_unref(evstate->qdict);
3901d95db74SKevin Wolf             evstate->qdict = qobject_ref(qdict);
3911d95db74SKevin Wolf         } else {
3921d95db74SKevin Wolf             /*
3931d95db74SKevin Wolf              * Last send was (at least) evconf->rate ns ago.
3941d95db74SKevin Wolf              * Send immediately, and arm the timer to call
3951d95db74SKevin Wolf              * monitor_qapi_event_handler() in evconf->rate ns.  Any
3961d95db74SKevin Wolf              * events arriving before then will be delayed until then.
3971d95db74SKevin Wolf              */
3981d95db74SKevin Wolf             int64_t now = qemu_clock_get_ns(monitor_get_event_clock());
3991d95db74SKevin Wolf 
4001d95db74SKevin Wolf             monitor_qapi_event_emit(event, qdict);
4011d95db74SKevin Wolf 
4021d95db74SKevin Wolf             evstate = g_new(MonitorQAPIEventState, 1);
4031d95db74SKevin Wolf             evstate->event = event;
4041d95db74SKevin Wolf             evstate->data = qobject_ref(data);
4051d95db74SKevin Wolf             evstate->qdict = NULL;
4061d95db74SKevin Wolf             evstate->timer = timer_new_ns(monitor_get_event_clock(),
4071d95db74SKevin Wolf                                           monitor_qapi_event_handler,
4081d95db74SKevin Wolf                                           evstate);
4091d95db74SKevin Wolf             g_hash_table_add(monitor_qapi_event_state, evstate);
4101d95db74SKevin Wolf             timer_mod_ns(evstate->timer, now + evconf->rate);
4111d95db74SKevin Wolf         }
4121d95db74SKevin Wolf     }
4131d95db74SKevin Wolf }
4141d95db74SKevin Wolf 
qapi_event_emit(QAPIEvent event,QDict * qdict)4151d95db74SKevin Wolf void qapi_event_emit(QAPIEvent event, QDict *qdict)
4161d95db74SKevin Wolf {
4171d95db74SKevin Wolf     /*
4181d95db74SKevin Wolf      * monitor_qapi_event_queue_no_reenter() is not reentrant: it
4191d95db74SKevin Wolf      * would deadlock on monitor_lock.  Work around by queueing
4201d95db74SKevin Wolf      * events in thread-local storage.
4211d95db74SKevin Wolf      * TODO: remove this, make it re-enter safe.
4221d95db74SKevin Wolf      */
4231d95db74SKevin Wolf     typedef struct MonitorQapiEvent {
4241d95db74SKevin Wolf         QAPIEvent event;
4251d95db74SKevin Wolf         QDict *qdict;
4261d95db74SKevin Wolf         QSIMPLEQ_ENTRY(MonitorQapiEvent) entry;
4271d95db74SKevin Wolf     } MonitorQapiEvent;
4281d95db74SKevin Wolf     static __thread QSIMPLEQ_HEAD(, MonitorQapiEvent) event_queue;
4291d95db74SKevin Wolf     static __thread bool reentered;
4301d95db74SKevin Wolf     MonitorQapiEvent *ev;
4311d95db74SKevin Wolf 
4321d95db74SKevin Wolf     if (!reentered) {
4331d95db74SKevin Wolf         QSIMPLEQ_INIT(&event_queue);
4341d95db74SKevin Wolf     }
4351d95db74SKevin Wolf 
4361d95db74SKevin Wolf     ev = g_new(MonitorQapiEvent, 1);
4371d95db74SKevin Wolf     ev->qdict = qobject_ref(qdict);
4381d95db74SKevin Wolf     ev->event = event;
4391d95db74SKevin Wolf     QSIMPLEQ_INSERT_TAIL(&event_queue, ev, entry);
4401d95db74SKevin Wolf     if (reentered) {
4411d95db74SKevin Wolf         return;
4421d95db74SKevin Wolf     }
4431d95db74SKevin Wolf 
4441d95db74SKevin Wolf     reentered = true;
4451d95db74SKevin Wolf 
4461d95db74SKevin Wolf     while ((ev = QSIMPLEQ_FIRST(&event_queue)) != NULL) {
4471d95db74SKevin Wolf         QSIMPLEQ_REMOVE_HEAD(&event_queue, entry);
4481d95db74SKevin Wolf         monitor_qapi_event_queue_no_reenter(ev->event, ev->qdict);
4491d95db74SKevin Wolf         qobject_unref(ev->qdict);
4501d95db74SKevin Wolf         g_free(ev);
4511d95db74SKevin Wolf     }
4521d95db74SKevin Wolf 
4531d95db74SKevin Wolf     reentered = false;
4541d95db74SKevin Wolf }
4551d95db74SKevin Wolf 
4561d95db74SKevin Wolf /*
4571d95db74SKevin Wolf  * This function runs evconf->rate ns after sending a throttled
4581d95db74SKevin Wolf  * event.
4591d95db74SKevin Wolf  * If another event has since been stored, send it.
4601d95db74SKevin Wolf  */
monitor_qapi_event_handler(void * opaque)4611d95db74SKevin Wolf static void monitor_qapi_event_handler(void *opaque)
4621d95db74SKevin Wolf {
4631d95db74SKevin Wolf     MonitorQAPIEventState *evstate = opaque;
4641d95db74SKevin Wolf     MonitorQAPIEventConf *evconf = &monitor_qapi_event_conf[evstate->event];
4651d95db74SKevin Wolf 
4661d95db74SKevin Wolf     trace_monitor_protocol_event_handler(evstate->event, evstate->qdict);
467a8e2ab5dSMahmoud Mandour     QEMU_LOCK_GUARD(&monitor_lock);
4681d95db74SKevin Wolf 
4691d95db74SKevin Wolf     if (evstate->qdict) {
4701d95db74SKevin Wolf         int64_t now = qemu_clock_get_ns(monitor_get_event_clock());
4711d95db74SKevin Wolf 
4721d95db74SKevin Wolf         monitor_qapi_event_emit(evstate->event, evstate->qdict);
4731d95db74SKevin Wolf         qobject_unref(evstate->qdict);
4741d95db74SKevin Wolf         evstate->qdict = NULL;
4751d95db74SKevin Wolf         timer_mod_ns(evstate->timer, now + evconf->rate);
4761d95db74SKevin Wolf     } else {
4771d95db74SKevin Wolf         g_hash_table_remove(monitor_qapi_event_state, evstate);
4781d95db74SKevin Wolf         qobject_unref(evstate->data);
4791d95db74SKevin Wolf         timer_free(evstate->timer);
4801d95db74SKevin Wolf         g_free(evstate);
4811d95db74SKevin Wolf     }
4821d95db74SKevin Wolf }
4831d95db74SKevin Wolf 
qapi_event_throttle_hash(const void * key)4841d95db74SKevin Wolf static unsigned int qapi_event_throttle_hash(const void *key)
4851d95db74SKevin Wolf {
4861d95db74SKevin Wolf     const MonitorQAPIEventState *evstate = key;
4871d95db74SKevin Wolf     unsigned int hash = evstate->event * 255;
4881d95db74SKevin Wolf 
4891d95db74SKevin Wolf     if (evstate->event == QAPI_EVENT_VSERPORT_CHANGE) {
4901d95db74SKevin Wolf         hash += g_str_hash(qdict_get_str(evstate->data, "id"));
4911d95db74SKevin Wolf     }
4921d95db74SKevin Wolf 
4931d95db74SKevin Wolf     if (evstate->event == QAPI_EVENT_QUORUM_REPORT_BAD) {
4941d95db74SKevin Wolf         hash += g_str_hash(qdict_get_str(evstate->data, "node-name"));
4951d95db74SKevin Wolf     }
4961d95db74SKevin Wolf 
497*2155d2ddSLeonid Kaplan     if (evstate->event == QAPI_EVENT_MEMORY_DEVICE_SIZE_CHANGE ||
498*2155d2ddSLeonid Kaplan         evstate->event == QAPI_EVENT_BLOCK_IO_ERROR) {
49977ae2302SDavid Hildenbrand         hash += g_str_hash(qdict_get_str(evstate->data, "qom-path"));
50077ae2302SDavid Hildenbrand     }
50177ae2302SDavid Hildenbrand 
5021d95db74SKevin Wolf     return hash;
5031d95db74SKevin Wolf }
5041d95db74SKevin Wolf 
qapi_event_throttle_equal(const void * a,const void * b)5051d95db74SKevin Wolf static gboolean qapi_event_throttle_equal(const void *a, const void *b)
5061d95db74SKevin Wolf {
5071d95db74SKevin Wolf     const MonitorQAPIEventState *eva = a;
5081d95db74SKevin Wolf     const MonitorQAPIEventState *evb = b;
5091d95db74SKevin Wolf 
5101d95db74SKevin Wolf     if (eva->event != evb->event) {
5111d95db74SKevin Wolf         return FALSE;
5121d95db74SKevin Wolf     }
5131d95db74SKevin Wolf 
5141d95db74SKevin Wolf     if (eva->event == QAPI_EVENT_VSERPORT_CHANGE) {
5151d95db74SKevin Wolf         return !strcmp(qdict_get_str(eva->data, "id"),
5161d95db74SKevin Wolf                        qdict_get_str(evb->data, "id"));
5171d95db74SKevin Wolf     }
5181d95db74SKevin Wolf 
5191d95db74SKevin Wolf     if (eva->event == QAPI_EVENT_QUORUM_REPORT_BAD) {
5201d95db74SKevin Wolf         return !strcmp(qdict_get_str(eva->data, "node-name"),
5211d95db74SKevin Wolf                        qdict_get_str(evb->data, "node-name"));
5221d95db74SKevin Wolf     }
5231d95db74SKevin Wolf 
524*2155d2ddSLeonid Kaplan     if (eva->event == QAPI_EVENT_MEMORY_DEVICE_SIZE_CHANGE ||
525*2155d2ddSLeonid Kaplan         eva->event == QAPI_EVENT_BLOCK_IO_ERROR) {
52677ae2302SDavid Hildenbrand         return !strcmp(qdict_get_str(eva->data, "qom-path"),
52777ae2302SDavid Hildenbrand                        qdict_get_str(evb->data, "qom-path"));
52877ae2302SDavid Hildenbrand     }
52977ae2302SDavid Hildenbrand 
5301d95db74SKevin Wolf     return TRUE;
5311d95db74SKevin Wolf }
5321d95db74SKevin Wolf 
monitor_suspend(Monitor * mon)5331d95db74SKevin Wolf int monitor_suspend(Monitor *mon)
5341d95db74SKevin Wolf {
5351d95db74SKevin Wolf     if (monitor_is_hmp_non_interactive(mon)) {
5361d95db74SKevin Wolf         return -ENOTTY;
5371d95db74SKevin Wolf     }
5381d95db74SKevin Wolf 
539d73415a3SStefan Hajnoczi     qatomic_inc(&mon->suspend_cnt);
5401d95db74SKevin Wolf 
5411d95db74SKevin Wolf     if (mon->use_io_thread) {
5421d95db74SKevin Wolf         /*
5431d95db74SKevin Wolf          * Kick I/O thread to make sure this takes effect.  It'll be
5441d95db74SKevin Wolf          * evaluated again in prepare() of the watch object.
5451d95db74SKevin Wolf          */
5461d95db74SKevin Wolf         aio_notify(iothread_get_aio_context(mon_iothread));
5471d95db74SKevin Wolf     }
5481d95db74SKevin Wolf 
5491d95db74SKevin Wolf     trace_monitor_suspend(mon, 1);
5501d95db74SKevin Wolf     return 0;
5511d95db74SKevin Wolf }
5521d95db74SKevin Wolf 
monitor_accept_input(void * opaque)5531d95db74SKevin Wolf static void monitor_accept_input(void *opaque)
5541d95db74SKevin Wolf {
5551d95db74SKevin Wolf     Monitor *mon = opaque;
5561d95db74SKevin Wolf 
5576ee7c82dSPaolo Bonzini     qemu_mutex_lock(&mon->mon_lock);
5586ee7c82dSPaolo Bonzini     if (!monitor_is_qmp(mon) && mon->reset_seen) {
559c5d0c55fSPaolo Bonzini         MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common);
560c5d0c55fSPaolo Bonzini         assert(hmp_mon->rs);
5616ee7c82dSPaolo Bonzini         readline_restart(hmp_mon->rs);
5626ee7c82dSPaolo Bonzini         qemu_mutex_unlock(&mon->mon_lock);
563c5d0c55fSPaolo Bonzini         readline_show_prompt(hmp_mon->rs);
5646ee7c82dSPaolo Bonzini     } else {
5656ee7c82dSPaolo Bonzini         qemu_mutex_unlock(&mon->mon_lock);
566c5d0c55fSPaolo Bonzini     }
567c5d0c55fSPaolo Bonzini 
5681d95db74SKevin Wolf     qemu_chr_fe_accept_input(&mon->chr);
5691d95db74SKevin Wolf }
5701d95db74SKevin Wolf 
monitor_resume(Monitor * mon)5711d95db74SKevin Wolf void monitor_resume(Monitor *mon)
5721d95db74SKevin Wolf {
5731d95db74SKevin Wolf     if (monitor_is_hmp_non_interactive(mon)) {
5741d95db74SKevin Wolf         return;
5751d95db74SKevin Wolf     }
5761d95db74SKevin Wolf 
577d73415a3SStefan Hajnoczi     if (qatomic_dec_fetch(&mon->suspend_cnt) == 0) {
5781d95db74SKevin Wolf         AioContext *ctx;
5791d95db74SKevin Wolf 
5801d95db74SKevin Wolf         if (mon->use_io_thread) {
5811d95db74SKevin Wolf             ctx = iothread_get_aio_context(mon_iothread);
5821d95db74SKevin Wolf         } else {
5831d95db74SKevin Wolf             ctx = qemu_get_aio_context();
5841d95db74SKevin Wolf         }
5851d95db74SKevin Wolf 
5861d95db74SKevin Wolf         aio_bh_schedule_oneshot(ctx, monitor_accept_input, mon);
5871d95db74SKevin Wolf     }
5881d95db74SKevin Wolf 
5891d95db74SKevin Wolf     trace_monitor_suspend(mon, -1);
5901d95db74SKevin Wolf }
5911d95db74SKevin Wolf 
monitor_can_read(void * opaque)5921d95db74SKevin Wolf int monitor_can_read(void *opaque)
5931d95db74SKevin Wolf {
5941d95db74SKevin Wolf     Monitor *mon = opaque;
5951d95db74SKevin Wolf 
5966ee7c82dSPaolo Bonzini     return !qatomic_read(&mon->suspend_cnt);
5971d95db74SKevin Wolf }
5981d95db74SKevin Wolf 
monitor_list_append(Monitor * mon)5991d95db74SKevin Wolf void monitor_list_append(Monitor *mon)
6001d95db74SKevin Wolf {
6011d95db74SKevin Wolf     qemu_mutex_lock(&monitor_lock);
6021d95db74SKevin Wolf     /*
6031d95db74SKevin Wolf      * This prevents inserting new monitors during monitor_cleanup().
6041d95db74SKevin Wolf      * A cleaner solution would involve the main thread telling other
6051d95db74SKevin Wolf      * threads to terminate, waiting for their termination.
6061d95db74SKevin Wolf      */
6071d95db74SKevin Wolf     if (!monitor_destroyed) {
6081d95db74SKevin Wolf         QTAILQ_INSERT_HEAD(&mon_list, mon, entry);
6091d95db74SKevin Wolf         mon = NULL;
6101d95db74SKevin Wolf     }
6111d95db74SKevin Wolf     qemu_mutex_unlock(&monitor_lock);
6121d95db74SKevin Wolf 
6131d95db74SKevin Wolf     if (mon) {
6141d95db74SKevin Wolf         monitor_data_destroy(mon);
6151d95db74SKevin Wolf         g_free(mon);
6161d95db74SKevin Wolf     }
6171d95db74SKevin Wolf }
6181d95db74SKevin Wolf 
monitor_iothread_init(void)6191d95db74SKevin Wolf static void monitor_iothread_init(void)
6201d95db74SKevin Wolf {
6211d95db74SKevin Wolf     mon_iothread = iothread_create("mon_iothread", &error_abort);
6221d95db74SKevin Wolf }
6231d95db74SKevin Wolf 
monitor_data_init(Monitor * mon,bool is_qmp,bool skip_flush,bool use_io_thread)62492082416SKevin Wolf void monitor_data_init(Monitor *mon, bool is_qmp, bool skip_flush,
6251d95db74SKevin Wolf                        bool use_io_thread)
6261d95db74SKevin Wolf {
6271d95db74SKevin Wolf     if (use_io_thread && !mon_iothread) {
6281d95db74SKevin Wolf         monitor_iothread_init();
6291d95db74SKevin Wolf     }
6301d95db74SKevin Wolf     qemu_mutex_init(&mon->mon_lock);
63192082416SKevin Wolf     mon->is_qmp = is_qmp;
63220076f4aSMarkus Armbruster     mon->outbuf = g_string_new(NULL);
6331d95db74SKevin Wolf     mon->skip_flush = skip_flush;
6341d95db74SKevin Wolf     mon->use_io_thread = use_io_thread;
6351d95db74SKevin Wolf }
6361d95db74SKevin Wolf 
monitor_data_destroy(Monitor * mon)6371d95db74SKevin Wolf void monitor_data_destroy(Monitor *mon)
6381d95db74SKevin Wolf {
6391d95db74SKevin Wolf     g_free(mon->mon_cpu_path);
6401d95db74SKevin Wolf     qemu_chr_fe_deinit(&mon->chr, false);
6411d95db74SKevin Wolf     if (monitor_is_qmp(mon)) {
6421d95db74SKevin Wolf         monitor_data_destroy_qmp(container_of(mon, MonitorQMP, common));
6431d95db74SKevin Wolf     } else {
6441d95db74SKevin Wolf         readline_free(container_of(mon, MonitorHMP, common)->rs);
6451d95db74SKevin Wolf     }
64620076f4aSMarkus Armbruster     g_string_free(mon->outbuf, true);
6471d95db74SKevin Wolf     qemu_mutex_destroy(&mon->mon_lock);
6481d95db74SKevin Wolf }
6491d95db74SKevin Wolf 
monitor_cleanup(void)6501d95db74SKevin Wolf void monitor_cleanup(void)
6511d95db74SKevin Wolf {
6521d95db74SKevin Wolf     /*
653357bda95SKevin Wolf      * The dispatcher needs to stop before destroying the monitor and
654357bda95SKevin Wolf      * the I/O thread.
6559ce44e2cSKevin Wolf      *
6569ce44e2cSKevin Wolf      * We need to poll both qemu_aio_context and iohandler_ctx to make
6579ce44e2cSKevin Wolf      * sure that the dispatcher coroutine keeps making progress and
6589ce44e2cSKevin Wolf      * eventually terminates.  qemu_aio_context is automatically
6599612aa40SStefan Hajnoczi      * polled by calling AIO_WAIT_WHILE_UNLOCKED on it, but we must poll
6609ce44e2cSKevin Wolf      * iohandler_ctx manually.
661c81219a7SKevin Wolf      *
662c81219a7SKevin Wolf      * Letting the iothread continue while shutting down the dispatcher
663c81219a7SKevin Wolf      * means that new requests may still be coming in. This is okay,
664c81219a7SKevin Wolf      * we'll just leave them in the queue without sending a response
665c81219a7SKevin Wolf      * and monitor_data_destroy() will free them.
6669ce44e2cSKevin Wolf      */
6670ff25537SPaolo Bonzini     WITH_QEMU_LOCK_GUARD(&monitor_lock) {
6689ce44e2cSKevin Wolf         qmp_dispatcher_co_shutdown = true;
6690ff25537SPaolo Bonzini     }
6709f2d5854SPaolo Bonzini     qmp_dispatcher_co_wake();
6719ce44e2cSKevin Wolf 
6729612aa40SStefan Hajnoczi     AIO_WAIT_WHILE_UNLOCKED(NULL,
6739ce44e2cSKevin Wolf                    (aio_poll(iohandler_get_aio_context(), false),
6743e6bed61SPaolo Bonzini                     qatomic_read(&qmp_dispatcher_co)));
6759ce44e2cSKevin Wolf 
676c81219a7SKevin Wolf     /*
677c81219a7SKevin Wolf      * We need to explicitly stop the I/O thread (but not destroy it),
678c81219a7SKevin Wolf      * clean up the monitor resources, then destroy the I/O thread since
679c81219a7SKevin Wolf      * we need to unregister from chardev below in
680c81219a7SKevin Wolf      * monitor_data_destroy(), and chardev is not thread-safe yet
681c81219a7SKevin Wolf      */
682c81219a7SKevin Wolf     if (mon_iothread) {
683c81219a7SKevin Wolf         iothread_stop(mon_iothread);
684c81219a7SKevin Wolf     }
685c81219a7SKevin Wolf 
686357bda95SKevin Wolf     /* Flush output buffers and destroy monitors */
687357bda95SKevin Wolf     qemu_mutex_lock(&monitor_lock);
688357bda95SKevin Wolf     monitor_destroyed = true;
689357bda95SKevin Wolf     while (!QTAILQ_EMPTY(&mon_list)) {
690357bda95SKevin Wolf         Monitor *mon = QTAILQ_FIRST(&mon_list);
691357bda95SKevin Wolf         QTAILQ_REMOVE(&mon_list, mon, entry);
692357bda95SKevin Wolf         /* Permit QAPI event emission from character frontend release */
693357bda95SKevin Wolf         qemu_mutex_unlock(&monitor_lock);
694357bda95SKevin Wolf         monitor_flush(mon);
695357bda95SKevin Wolf         monitor_data_destroy(mon);
696357bda95SKevin Wolf         qemu_mutex_lock(&monitor_lock);
697357bda95SKevin Wolf         g_free(mon);
698357bda95SKevin Wolf     }
699357bda95SKevin Wolf     qemu_mutex_unlock(&monitor_lock);
700357bda95SKevin Wolf 
7011d95db74SKevin Wolf     if (mon_iothread) {
7021d95db74SKevin Wolf         iothread_destroy(mon_iothread);
7031d95db74SKevin Wolf         mon_iothread = NULL;
7041d95db74SKevin Wolf     }
7051d95db74SKevin Wolf }
7061d95db74SKevin Wolf 
monitor_qapi_event_init(void)7071d95db74SKevin Wolf static void monitor_qapi_event_init(void)
7081d95db74SKevin Wolf {
7091d95db74SKevin Wolf     monitor_qapi_event_state = g_hash_table_new(qapi_event_throttle_hash,
7101d95db74SKevin Wolf                                                 qapi_event_throttle_equal);
7111d95db74SKevin Wolf }
7121d95db74SKevin Wolf 
monitor_init_globals(void)7139d2b5f2cSMarkus Armbruster void monitor_init_globals(void)
7141d95db74SKevin Wolf {
7151d95db74SKevin Wolf     monitor_qapi_event_init();
7161d95db74SKevin Wolf     qemu_mutex_init(&monitor_lock);
717e69ee454SKevin Wolf     coroutine_mon = g_hash_table_new(NULL, NULL);
7181d95db74SKevin Wolf 
7191d95db74SKevin Wolf     /*
7201d95db74SKevin Wolf      * The dispatcher BH must run in the main loop thread, since we
7211d95db74SKevin Wolf      * have commands assuming that context.  It would be nice to get
7221d95db74SKevin Wolf      * rid of those assumptions.
7231d95db74SKevin Wolf      */
7249ce44e2cSKevin Wolf     qmp_dispatcher_co = qemu_coroutine_create(monitor_qmp_dispatcher_co, NULL);
7259ce44e2cSKevin Wolf     aio_co_schedule(iohandler_get_aio_context(), qmp_dispatcher_co);
7261d95db74SKevin Wolf }
7271d95db74SKevin Wolf 
monitor_init(MonitorOptions * opts,bool allow_hmp,Error ** errp)728a2f411c4SKevin Wolf int monitor_init(MonitorOptions *opts, bool allow_hmp, Error **errp)
729c3e95551SKevin Wolf {
73050707b39SMarkus Armbruster     ERRP_GUARD();
731c3e95551SKevin Wolf     Chardev *chr;
732c3e95551SKevin Wolf 
733f2098725SKevin Wolf     chr = qemu_chr_find(opts->chardev);
734c3e95551SKevin Wolf     if (chr == NULL) {
735f2098725SKevin Wolf         error_setg(errp, "chardev \"%s\" not found", opts->chardev);
736c3e95551SKevin Wolf         return -1;
737c3e95551SKevin Wolf     }
738c3e95551SKevin Wolf 
739a2f411c4SKevin Wolf     if (!opts->has_mode) {
740a2f411c4SKevin Wolf         opts->mode = allow_hmp ? MONITOR_MODE_READLINE : MONITOR_MODE_CONTROL;
741a2f411c4SKevin Wolf     }
742a2f411c4SKevin Wolf 
743f2098725SKevin Wolf     switch (opts->mode) {
744f2098725SKevin Wolf     case MONITOR_MODE_CONTROL:
74550707b39SMarkus Armbruster         monitor_init_qmp(chr, opts->pretty, errp);
746f2098725SKevin Wolf         break;
747f2098725SKevin Wolf     case MONITOR_MODE_READLINE:
748a2f411c4SKevin Wolf         if (!allow_hmp) {
749a2f411c4SKevin Wolf             error_setg(errp, "Only QMP is supported");
750a2f411c4SKevin Wolf             return -1;
751a2f411c4SKevin Wolf         }
752f2098725SKevin Wolf         if (opts->pretty) {
753283d845cSDaniel P. Berrangé             error_setg(errp, "'pretty' is not compatible with HMP monitors");
754283d845cSDaniel P. Berrangé             return -1;
755f2098725SKevin Wolf         }
75650707b39SMarkus Armbruster         monitor_init_hmp(chr, true, errp);
757f2098725SKevin Wolf         break;
758f2098725SKevin Wolf     default:
759f2098725SKevin Wolf         g_assert_not_reached();
760f2098725SKevin Wolf     }
761f2098725SKevin Wolf 
76250707b39SMarkus Armbruster     return *errp ? -1 : 0;
763f2098725SKevin Wolf }
764f2098725SKevin Wolf 
monitor_init_opts(QemuOpts * opts,Error ** errp)765f2098725SKevin Wolf int monitor_init_opts(QemuOpts *opts, Error **errp)
766f2098725SKevin Wolf {
767f2098725SKevin Wolf     Visitor *v;
768f2098725SKevin Wolf     MonitorOptions *options;
769b11a093cSMarkus Armbruster     int ret;
770f2098725SKevin Wolf 
771f2098725SKevin Wolf     v = opts_visitor_new(opts);
772b11a093cSMarkus Armbruster     visit_type_MonitorOptions(v, NULL, &options, errp);
773f2098725SKevin Wolf     visit_free(v);
774b11a093cSMarkus Armbruster     if (!options) {
775f2098725SKevin Wolf         return -1;
776c3e95551SKevin Wolf     }
777b11a093cSMarkus Armbruster 
778b11a093cSMarkus Armbruster     ret = monitor_init(options, true, errp);
779b11a093cSMarkus Armbruster     qapi_free_MonitorOptions(options);
780b11a093cSMarkus Armbruster     return ret;
781c3e95551SKevin Wolf }
782c3e95551SKevin Wolf 
7831d95db74SKevin Wolf QemuOptsList qemu_mon_opts = {
7841d95db74SKevin Wolf     .name = "mon",
7851d95db74SKevin Wolf     .implied_opt_name = "chardev",
7861d95db74SKevin Wolf     .head = QTAILQ_HEAD_INITIALIZER(qemu_mon_opts.head),
7871d95db74SKevin Wolf     .desc = {
7881d95db74SKevin Wolf         {
7891d95db74SKevin Wolf             .name = "mode",
7901d95db74SKevin Wolf             .type = QEMU_OPT_STRING,
7911d95db74SKevin Wolf         },{
7921d95db74SKevin Wolf             .name = "chardev",
7931d95db74SKevin Wolf             .type = QEMU_OPT_STRING,
7941d95db74SKevin Wolf         },{
7951d95db74SKevin Wolf             .name = "pretty",
7961d95db74SKevin Wolf             .type = QEMU_OPT_BOOL,
7971d95db74SKevin Wolf         },
7981d95db74SKevin Wolf         { /* end of list */ }
7991d95db74SKevin Wolf     },
8001d95db74SKevin Wolf };
801