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 int mon_refcount; 751d95db74SKevin Wolf static bool monitor_destroyed; 761d95db74SKevin Wolf 77947e4744SKevin Wolf Monitor *monitor_cur(void) 78947e4744SKevin Wolf { 79e69ee454SKevin Wolf Monitor *mon; 80e69ee454SKevin Wolf 81e69ee454SKevin Wolf qemu_mutex_lock(&monitor_lock); 82e69ee454SKevin Wolf mon = g_hash_table_lookup(coroutine_mon, qemu_coroutine_self()); 83e69ee454SKevin Wolf qemu_mutex_unlock(&monitor_lock); 84e69ee454SKevin Wolf 85e69ee454SKevin Wolf return mon; 86947e4744SKevin Wolf } 87947e4744SKevin Wolf 88947e4744SKevin Wolf /** 89947e4744SKevin Wolf * Sets a new current monitor and returns the old one. 90e69ee454SKevin Wolf * 91e69ee454SKevin Wolf * If a non-NULL monitor is set for a coroutine, another call 92e69ee454SKevin Wolf * resetting it to NULL is required before the coroutine terminates, 93e69ee454SKevin Wolf * otherwise a stale entry would remain in the hash table. 94947e4744SKevin Wolf */ 95e69ee454SKevin Wolf Monitor *monitor_set_cur(Coroutine *co, Monitor *mon) 96947e4744SKevin Wolf { 97e69ee454SKevin Wolf Monitor *old_monitor = monitor_cur(); 98947e4744SKevin Wolf 99e69ee454SKevin Wolf qemu_mutex_lock(&monitor_lock); 100e69ee454SKevin Wolf if (mon) { 101e69ee454SKevin Wolf g_hash_table_replace(coroutine_mon, co, mon); 102e69ee454SKevin Wolf } else { 103e69ee454SKevin Wolf g_hash_table_remove(coroutine_mon, co); 104e69ee454SKevin Wolf } 105e69ee454SKevin Wolf qemu_mutex_unlock(&monitor_lock); 106e69ee454SKevin Wolf 107947e4744SKevin Wolf return old_monitor; 108947e4744SKevin Wolf } 1091d95db74SKevin Wolf 1101d95db74SKevin Wolf /** 1111d95db74SKevin Wolf * Is the current monitor, if any, a QMP monitor? 1121d95db74SKevin Wolf */ 1131d95db74SKevin Wolf bool monitor_cur_is_qmp(void) 1141d95db74SKevin Wolf { 115947e4744SKevin Wolf Monitor *cur_mon = monitor_cur(); 116947e4744SKevin Wolf 1171d95db74SKevin Wolf return cur_mon && monitor_is_qmp(cur_mon); 1181d95db74SKevin Wolf } 1191d95db74SKevin Wolf 1201d95db74SKevin Wolf /** 1211d95db74SKevin Wolf * Is @mon is using readline? 1221d95db74SKevin Wolf * Note: not all HMP monitors use readline, e.g., gdbserver has a 1231d95db74SKevin Wolf * non-interactive HMP monitor, so readline is not used there. 1241d95db74SKevin Wolf */ 12592082416SKevin Wolf static inline bool monitor_uses_readline(const MonitorHMP *mon) 1261d95db74SKevin Wolf { 12792082416SKevin Wolf return mon->use_readline; 1281d95db74SKevin Wolf } 1291d95db74SKevin Wolf 1301d95db74SKevin Wolf static inline bool monitor_is_hmp_non_interactive(const Monitor *mon) 1311d95db74SKevin Wolf { 13292082416SKevin Wolf if (monitor_is_qmp(mon)) { 13392082416SKevin Wolf return false; 13492082416SKevin Wolf } 13592082416SKevin Wolf 13692082416SKevin Wolf return !monitor_uses_readline(container_of(mon, MonitorHMP, common)); 1371d95db74SKevin Wolf } 1381d95db74SKevin Wolf 139bf7b1eabSMarc-André Lureau static gboolean monitor_unblocked(void *do_not_use, GIOCondition cond, 1401d95db74SKevin Wolf void *opaque) 1411d95db74SKevin Wolf { 1421d95db74SKevin Wolf Monitor *mon = opaque; 1431d95db74SKevin Wolf 144e37548efSPaolo Bonzini QEMU_LOCK_GUARD(&mon->mon_lock); 1451d95db74SKevin Wolf mon->out_watch = 0; 1461d95db74SKevin Wolf monitor_flush_locked(mon); 1471d95db74SKevin Wolf return FALSE; 1481d95db74SKevin Wolf } 1491d95db74SKevin Wolf 1501d95db74SKevin Wolf /* Caller must hold mon->mon_lock */ 1514cb96b97SPaolo Bonzini void monitor_flush_locked(Monitor *mon) 1521d95db74SKevin Wolf { 1531d95db74SKevin Wolf int rc; 1541d95db74SKevin Wolf size_t len; 1551d95db74SKevin Wolf const char *buf; 1561d95db74SKevin Wolf 1571d95db74SKevin Wolf if (mon->skip_flush) { 1581d95db74SKevin Wolf return; 1591d95db74SKevin Wolf } 1601d95db74SKevin Wolf 16120076f4aSMarkus Armbruster buf = mon->outbuf->str; 16220076f4aSMarkus Armbruster len = mon->outbuf->len; 1631d95db74SKevin Wolf 1641d95db74SKevin Wolf if (len && !mon->mux_out) { 1651d95db74SKevin Wolf rc = qemu_chr_fe_write(&mon->chr, (const uint8_t *) buf, len); 1661d95db74SKevin Wolf if ((rc < 0 && errno != EAGAIN) || (rc == len)) { 1671d95db74SKevin Wolf /* all flushed or error */ 16820076f4aSMarkus Armbruster g_string_truncate(mon->outbuf, 0); 1691d95db74SKevin Wolf return; 1701d95db74SKevin Wolf } 1711d95db74SKevin Wolf if (rc > 0) { 1721d95db74SKevin Wolf /* partial write */ 17320076f4aSMarkus Armbruster g_string_erase(mon->outbuf, 0, rc); 1741d95db74SKevin Wolf } 1751d95db74SKevin Wolf if (mon->out_watch == 0) { 1761d95db74SKevin Wolf mon->out_watch = 1771d95db74SKevin Wolf qemu_chr_fe_add_watch(&mon->chr, G_IO_OUT | G_IO_HUP, 1781d95db74SKevin Wolf monitor_unblocked, mon); 1791d95db74SKevin Wolf } 1801d95db74SKevin Wolf } 1811d95db74SKevin Wolf } 1821d95db74SKevin Wolf 1831d95db74SKevin Wolf void monitor_flush(Monitor *mon) 1841d95db74SKevin Wolf { 185e37548efSPaolo Bonzini QEMU_LOCK_GUARD(&mon->mon_lock); 1861d95db74SKevin Wolf monitor_flush_locked(mon); 1871d95db74SKevin Wolf } 1881d95db74SKevin Wolf 1891d95db74SKevin Wolf /* flush at every end of line */ 1904cb96b97SPaolo Bonzini int monitor_puts_locked(Monitor *mon, const char *str) 1911d95db74SKevin Wolf { 1921d95db74SKevin Wolf int i; 1931d95db74SKevin Wolf char c; 1941d95db74SKevin Wolf 1951d95db74SKevin Wolf for (i = 0; str[i]; i++) { 1961d95db74SKevin Wolf c = str[i]; 1971d95db74SKevin Wolf if (c == '\n') { 19820076f4aSMarkus Armbruster g_string_append_c(mon->outbuf, '\r'); 1991d95db74SKevin Wolf } 20020076f4aSMarkus Armbruster g_string_append_c(mon->outbuf, c); 2011d95db74SKevin Wolf if (c == '\n') { 2021d95db74SKevin Wolf monitor_flush_locked(mon); 2031d95db74SKevin Wolf } 2041d95db74SKevin Wolf } 2051d95db74SKevin Wolf 2061d95db74SKevin Wolf return i; 2071d95db74SKevin Wolf } 2081d95db74SKevin Wolf 2094cb96b97SPaolo Bonzini int monitor_puts(Monitor *mon, const char *str) 2104cb96b97SPaolo Bonzini { 2114cb96b97SPaolo Bonzini QEMU_LOCK_GUARD(&mon->mon_lock); 2124cb96b97SPaolo Bonzini return monitor_puts_locked(mon, str); 2134cb96b97SPaolo Bonzini } 2144cb96b97SPaolo Bonzini 2151d95db74SKevin Wolf int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) 2161d95db74SKevin Wolf { 2171d95db74SKevin Wolf char *buf; 2181d95db74SKevin Wolf int n; 2191d95db74SKevin Wolf 2201d95db74SKevin Wolf if (!mon) { 2211d95db74SKevin Wolf return -1; 2221d95db74SKevin Wolf } 2231d95db74SKevin Wolf 2241d95db74SKevin Wolf if (monitor_is_qmp(mon)) { 2251d95db74SKevin Wolf return -1; 2261d95db74SKevin Wolf } 2271d95db74SKevin Wolf 2281d95db74SKevin Wolf buf = g_strdup_vprintf(fmt, ap); 2291d95db74SKevin Wolf n = monitor_puts(mon, buf); 2301d95db74SKevin Wolf g_free(buf); 2311d95db74SKevin Wolf return n; 2321d95db74SKevin Wolf } 2331d95db74SKevin Wolf 2341d95db74SKevin Wolf int monitor_printf(Monitor *mon, const char *fmt, ...) 2351d95db74SKevin Wolf { 2361d95db74SKevin Wolf int ret; 2371d95db74SKevin Wolf 2381d95db74SKevin Wolf va_list ap; 2391d95db74SKevin Wolf va_start(ap, fmt); 2401d95db74SKevin Wolf ret = monitor_vprintf(mon, fmt, ap); 2411d95db74SKevin Wolf va_end(ap); 2421d95db74SKevin Wolf return ret; 2431d95db74SKevin Wolf } 2441d95db74SKevin Wolf 245dd00d7faSMarkus Armbruster void monitor_printc(Monitor *mon, int c) 246dd00d7faSMarkus Armbruster { 247dd00d7faSMarkus Armbruster monitor_printf(mon, "'"); 248dd00d7faSMarkus Armbruster switch(c) { 249dd00d7faSMarkus Armbruster case '\'': 250dd00d7faSMarkus Armbruster monitor_printf(mon, "\\'"); 251dd00d7faSMarkus Armbruster break; 252dd00d7faSMarkus Armbruster case '\\': 253dd00d7faSMarkus Armbruster monitor_printf(mon, "\\\\"); 254dd00d7faSMarkus Armbruster break; 255dd00d7faSMarkus Armbruster case '\n': 256dd00d7faSMarkus Armbruster monitor_printf(mon, "\\n"); 257dd00d7faSMarkus Armbruster break; 258dd00d7faSMarkus Armbruster case '\r': 259dd00d7faSMarkus Armbruster monitor_printf(mon, "\\r"); 260dd00d7faSMarkus Armbruster break; 261dd00d7faSMarkus Armbruster default: 262dd00d7faSMarkus Armbruster if (c >= 32 && c <= 126) { 263dd00d7faSMarkus Armbruster monitor_printf(mon, "%c", c); 264dd00d7faSMarkus Armbruster } else { 265dd00d7faSMarkus Armbruster monitor_printf(mon, "\\x%02x", c); 266dd00d7faSMarkus Armbruster } 267dd00d7faSMarkus Armbruster break; 268dd00d7faSMarkus Armbruster } 269dd00d7faSMarkus Armbruster monitor_printf(mon, "'"); 270dd00d7faSMarkus Armbruster } 271dd00d7faSMarkus Armbruster 2721d95db74SKevin Wolf /* 2731d95db74SKevin Wolf * Print to current monitor if we have one, else to stderr. 2741d95db74SKevin Wolf */ 2751d95db74SKevin Wolf int error_vprintf(const char *fmt, va_list ap) 2761d95db74SKevin Wolf { 277947e4744SKevin Wolf Monitor *cur_mon = monitor_cur(); 278947e4744SKevin Wolf 2791d95db74SKevin Wolf if (cur_mon && !monitor_cur_is_qmp()) { 2801d95db74SKevin Wolf return monitor_vprintf(cur_mon, fmt, ap); 2811d95db74SKevin Wolf } 2821d95db74SKevin Wolf return vfprintf(stderr, fmt, ap); 2831d95db74SKevin Wolf } 2841d95db74SKevin Wolf 2851d95db74SKevin Wolf int error_vprintf_unless_qmp(const char *fmt, va_list ap) 2861d95db74SKevin Wolf { 287947e4744SKevin Wolf Monitor *cur_mon = monitor_cur(); 288947e4744SKevin Wolf 2891d95db74SKevin Wolf if (!cur_mon) { 2901d95db74SKevin Wolf return vfprintf(stderr, fmt, ap); 2911d95db74SKevin Wolf } 2921d95db74SKevin Wolf if (!monitor_cur_is_qmp()) { 2931d95db74SKevin Wolf return monitor_vprintf(cur_mon, fmt, ap); 2941d95db74SKevin Wolf } 2951d95db74SKevin Wolf return -1; 2961d95db74SKevin Wolf } 2971d95db74SKevin Wolf 298756a98ddSMarc-André Lureau int error_printf_unless_qmp(const char *fmt, ...) 299756a98ddSMarc-André Lureau { 300756a98ddSMarc-André Lureau va_list ap; 301756a98ddSMarc-André Lureau int ret; 302756a98ddSMarc-André Lureau 303756a98ddSMarc-André Lureau va_start(ap, fmt); 304756a98ddSMarc-André Lureau ret = error_vprintf_unless_qmp(fmt, ap); 305756a98ddSMarc-André Lureau va_end(ap); 306756a98ddSMarc-André Lureau return ret; 307756a98ddSMarc-André Lureau } 3081d95db74SKevin Wolf 3091d95db74SKevin Wolf static MonitorQAPIEventConf monitor_qapi_event_conf[QAPI_EVENT__MAX] = { 3101d95db74SKevin Wolf /* Limit guest-triggerable events to 1 per second */ 3111d95db74SKevin Wolf [QAPI_EVENT_RTC_CHANGE] = { 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 }, 3181d95db74SKevin Wolf }; 3191d95db74SKevin Wolf 3201d95db74SKevin Wolf /* 3211d95db74SKevin Wolf * Return the clock to use for recording an event's time. 3221d95db74SKevin Wolf * It's QEMU_CLOCK_REALTIME, except for qtests it's 3231d95db74SKevin Wolf * QEMU_CLOCK_VIRTUAL, to support testing rate limits. 3241d95db74SKevin Wolf * Beware: result is invalid before configure_accelerator(). 3251d95db74SKevin Wolf */ 3261d95db74SKevin Wolf static inline QEMUClockType monitor_get_event_clock(void) 3271d95db74SKevin Wolf { 3281d95db74SKevin Wolf return qtest_enabled() ? QEMU_CLOCK_VIRTUAL : QEMU_CLOCK_REALTIME; 3291d95db74SKevin Wolf } 3301d95db74SKevin Wolf 3311d95db74SKevin Wolf /* 3321d95db74SKevin Wolf * Broadcast an event to all monitors. 3331d95db74SKevin Wolf * @qdict is the event object. Its member "event" must match @event. 3341d95db74SKevin Wolf * Caller must hold monitor_lock. 3351d95db74SKevin Wolf */ 3361d95db74SKevin Wolf static void monitor_qapi_event_emit(QAPIEvent event, QDict *qdict) 3371d95db74SKevin Wolf { 3381d95db74SKevin Wolf Monitor *mon; 3391d95db74SKevin Wolf MonitorQMP *qmp_mon; 3401d95db74SKevin Wolf 3411d95db74SKevin Wolf trace_monitor_protocol_event_emit(event, qdict); 3421d95db74SKevin Wolf QTAILQ_FOREACH(mon, &mon_list, entry) { 3431d95db74SKevin Wolf if (!monitor_is_qmp(mon)) { 3441d95db74SKevin Wolf continue; 3451d95db74SKevin Wolf } 3461d95db74SKevin Wolf 3471d95db74SKevin Wolf qmp_mon = container_of(mon, MonitorQMP, common); 3481d95db74SKevin Wolf if (qmp_mon->commands != &qmp_cap_negotiation_commands) { 3491d95db74SKevin Wolf qmp_send_response(qmp_mon, qdict); 3501d95db74SKevin Wolf } 3511d95db74SKevin Wolf } 3521d95db74SKevin Wolf } 3531d95db74SKevin Wolf 3541d95db74SKevin Wolf static void monitor_qapi_event_handler(void *opaque); 3551d95db74SKevin Wolf 3561d95db74SKevin Wolf /* 3571d95db74SKevin Wolf * Queue a new event for emission to Monitor instances, 3581d95db74SKevin Wolf * applying any rate limiting if required. 3591d95db74SKevin Wolf */ 3601d95db74SKevin Wolf static void 3611d95db74SKevin Wolf monitor_qapi_event_queue_no_reenter(QAPIEvent event, QDict *qdict) 3621d95db74SKevin Wolf { 3631d95db74SKevin Wolf MonitorQAPIEventConf *evconf; 3641d95db74SKevin Wolf MonitorQAPIEventState *evstate; 3651d95db74SKevin Wolf 3661d95db74SKevin Wolf assert(event < QAPI_EVENT__MAX); 3671d95db74SKevin Wolf evconf = &monitor_qapi_event_conf[event]; 3681d95db74SKevin Wolf trace_monitor_protocol_event_queue(event, qdict, evconf->rate); 3691d95db74SKevin Wolf 370a8e2ab5dSMahmoud Mandour QEMU_LOCK_GUARD(&monitor_lock); 3711d95db74SKevin Wolf 3721d95db74SKevin Wolf if (!evconf->rate) { 3731d95db74SKevin Wolf /* Unthrottled event */ 3741d95db74SKevin Wolf monitor_qapi_event_emit(event, qdict); 3751d95db74SKevin Wolf } else { 3761d95db74SKevin Wolf QDict *data = qobject_to(QDict, qdict_get(qdict, "data")); 3771d95db74SKevin Wolf MonitorQAPIEventState key = { .event = event, .data = data }; 3781d95db74SKevin Wolf 3791d95db74SKevin Wolf evstate = g_hash_table_lookup(monitor_qapi_event_state, &key); 3801d95db74SKevin Wolf assert(!evstate || timer_pending(evstate->timer)); 3811d95db74SKevin Wolf 3821d95db74SKevin Wolf if (evstate) { 3831d95db74SKevin Wolf /* 3841d95db74SKevin Wolf * Timer is pending for (at least) evconf->rate ns after 3851d95db74SKevin Wolf * last send. Store event for sending when timer fires, 3861d95db74SKevin Wolf * replacing a prior stored event if any. 3871d95db74SKevin Wolf */ 3881d95db74SKevin Wolf qobject_unref(evstate->qdict); 3891d95db74SKevin Wolf evstate->qdict = qobject_ref(qdict); 3901d95db74SKevin Wolf } else { 3911d95db74SKevin Wolf /* 3921d95db74SKevin Wolf * Last send was (at least) evconf->rate ns ago. 3931d95db74SKevin Wolf * Send immediately, and arm the timer to call 3941d95db74SKevin Wolf * monitor_qapi_event_handler() in evconf->rate ns. Any 3951d95db74SKevin Wolf * events arriving before then will be delayed until then. 3961d95db74SKevin Wolf */ 3971d95db74SKevin Wolf int64_t now = qemu_clock_get_ns(monitor_get_event_clock()); 3981d95db74SKevin Wolf 3991d95db74SKevin Wolf monitor_qapi_event_emit(event, qdict); 4001d95db74SKevin Wolf 4011d95db74SKevin Wolf evstate = g_new(MonitorQAPIEventState, 1); 4021d95db74SKevin Wolf evstate->event = event; 4031d95db74SKevin Wolf evstate->data = qobject_ref(data); 4041d95db74SKevin Wolf evstate->qdict = NULL; 4051d95db74SKevin Wolf evstate->timer = timer_new_ns(monitor_get_event_clock(), 4061d95db74SKevin Wolf monitor_qapi_event_handler, 4071d95db74SKevin Wolf evstate); 4081d95db74SKevin Wolf g_hash_table_add(monitor_qapi_event_state, evstate); 4091d95db74SKevin Wolf timer_mod_ns(evstate->timer, now + evconf->rate); 4101d95db74SKevin Wolf } 4111d95db74SKevin Wolf } 4121d95db74SKevin Wolf } 4131d95db74SKevin Wolf 4141d95db74SKevin Wolf void qapi_event_emit(QAPIEvent event, QDict *qdict) 4151d95db74SKevin Wolf { 4161d95db74SKevin Wolf /* 4171d95db74SKevin Wolf * monitor_qapi_event_queue_no_reenter() is not reentrant: it 4181d95db74SKevin Wolf * would deadlock on monitor_lock. Work around by queueing 4191d95db74SKevin Wolf * events in thread-local storage. 4201d95db74SKevin Wolf * TODO: remove this, make it re-enter safe. 4211d95db74SKevin Wolf */ 4221d95db74SKevin Wolf typedef struct MonitorQapiEvent { 4231d95db74SKevin Wolf QAPIEvent event; 4241d95db74SKevin Wolf QDict *qdict; 4251d95db74SKevin Wolf QSIMPLEQ_ENTRY(MonitorQapiEvent) entry; 4261d95db74SKevin Wolf } MonitorQapiEvent; 4271d95db74SKevin Wolf static __thread QSIMPLEQ_HEAD(, MonitorQapiEvent) event_queue; 4281d95db74SKevin Wolf static __thread bool reentered; 4291d95db74SKevin Wolf MonitorQapiEvent *ev; 4301d95db74SKevin Wolf 4311d95db74SKevin Wolf if (!reentered) { 4321d95db74SKevin Wolf QSIMPLEQ_INIT(&event_queue); 4331d95db74SKevin Wolf } 4341d95db74SKevin Wolf 4351d95db74SKevin Wolf ev = g_new(MonitorQapiEvent, 1); 4361d95db74SKevin Wolf ev->qdict = qobject_ref(qdict); 4371d95db74SKevin Wolf ev->event = event; 4381d95db74SKevin Wolf QSIMPLEQ_INSERT_TAIL(&event_queue, ev, entry); 4391d95db74SKevin Wolf if (reentered) { 4401d95db74SKevin Wolf return; 4411d95db74SKevin Wolf } 4421d95db74SKevin Wolf 4431d95db74SKevin Wolf reentered = true; 4441d95db74SKevin Wolf 4451d95db74SKevin Wolf while ((ev = QSIMPLEQ_FIRST(&event_queue)) != NULL) { 4461d95db74SKevin Wolf QSIMPLEQ_REMOVE_HEAD(&event_queue, entry); 4471d95db74SKevin Wolf monitor_qapi_event_queue_no_reenter(ev->event, ev->qdict); 4481d95db74SKevin Wolf qobject_unref(ev->qdict); 4491d95db74SKevin Wolf g_free(ev); 4501d95db74SKevin Wolf } 4511d95db74SKevin Wolf 4521d95db74SKevin Wolf reentered = false; 4531d95db74SKevin Wolf } 4541d95db74SKevin Wolf 4551d95db74SKevin Wolf /* 4561d95db74SKevin Wolf * This function runs evconf->rate ns after sending a throttled 4571d95db74SKevin Wolf * event. 4581d95db74SKevin Wolf * If another event has since been stored, send it. 4591d95db74SKevin Wolf */ 4601d95db74SKevin Wolf static void monitor_qapi_event_handler(void *opaque) 4611d95db74SKevin Wolf { 4621d95db74SKevin Wolf MonitorQAPIEventState *evstate = opaque; 4631d95db74SKevin Wolf MonitorQAPIEventConf *evconf = &monitor_qapi_event_conf[evstate->event]; 4641d95db74SKevin Wolf 4651d95db74SKevin Wolf trace_monitor_protocol_event_handler(evstate->event, evstate->qdict); 466a8e2ab5dSMahmoud Mandour QEMU_LOCK_GUARD(&monitor_lock); 4671d95db74SKevin Wolf 4681d95db74SKevin Wolf if (evstate->qdict) { 4691d95db74SKevin Wolf int64_t now = qemu_clock_get_ns(monitor_get_event_clock()); 4701d95db74SKevin Wolf 4711d95db74SKevin Wolf monitor_qapi_event_emit(evstate->event, evstate->qdict); 4721d95db74SKevin Wolf qobject_unref(evstate->qdict); 4731d95db74SKevin Wolf evstate->qdict = NULL; 4741d95db74SKevin Wolf timer_mod_ns(evstate->timer, now + evconf->rate); 4751d95db74SKevin Wolf } else { 4761d95db74SKevin Wolf g_hash_table_remove(monitor_qapi_event_state, evstate); 4771d95db74SKevin Wolf qobject_unref(evstate->data); 4781d95db74SKevin Wolf timer_free(evstate->timer); 4791d95db74SKevin Wolf g_free(evstate); 4801d95db74SKevin Wolf } 4811d95db74SKevin Wolf } 4821d95db74SKevin Wolf 4831d95db74SKevin Wolf static unsigned int qapi_event_throttle_hash(const void *key) 4841d95db74SKevin Wolf { 4851d95db74SKevin Wolf const MonitorQAPIEventState *evstate = key; 4861d95db74SKevin Wolf unsigned int hash = evstate->event * 255; 4871d95db74SKevin Wolf 4881d95db74SKevin Wolf if (evstate->event == QAPI_EVENT_VSERPORT_CHANGE) { 4891d95db74SKevin Wolf hash += g_str_hash(qdict_get_str(evstate->data, "id")); 4901d95db74SKevin Wolf } 4911d95db74SKevin Wolf 4921d95db74SKevin Wolf if (evstate->event == QAPI_EVENT_QUORUM_REPORT_BAD) { 4931d95db74SKevin Wolf hash += g_str_hash(qdict_get_str(evstate->data, "node-name")); 4941d95db74SKevin Wolf } 4951d95db74SKevin Wolf 49677ae2302SDavid Hildenbrand if (evstate->event == QAPI_EVENT_MEMORY_DEVICE_SIZE_CHANGE) { 49777ae2302SDavid Hildenbrand hash += g_str_hash(qdict_get_str(evstate->data, "qom-path")); 49877ae2302SDavid Hildenbrand } 49977ae2302SDavid Hildenbrand 5001d95db74SKevin Wolf return hash; 5011d95db74SKevin Wolf } 5021d95db74SKevin Wolf 5031d95db74SKevin Wolf static gboolean qapi_event_throttle_equal(const void *a, const void *b) 5041d95db74SKevin Wolf { 5051d95db74SKevin Wolf const MonitorQAPIEventState *eva = a; 5061d95db74SKevin Wolf const MonitorQAPIEventState *evb = b; 5071d95db74SKevin Wolf 5081d95db74SKevin Wolf if (eva->event != evb->event) { 5091d95db74SKevin Wolf return FALSE; 5101d95db74SKevin Wolf } 5111d95db74SKevin Wolf 5121d95db74SKevin Wolf if (eva->event == QAPI_EVENT_VSERPORT_CHANGE) { 5131d95db74SKevin Wolf return !strcmp(qdict_get_str(eva->data, "id"), 5141d95db74SKevin Wolf qdict_get_str(evb->data, "id")); 5151d95db74SKevin Wolf } 5161d95db74SKevin Wolf 5171d95db74SKevin Wolf if (eva->event == QAPI_EVENT_QUORUM_REPORT_BAD) { 5181d95db74SKevin Wolf return !strcmp(qdict_get_str(eva->data, "node-name"), 5191d95db74SKevin Wolf qdict_get_str(evb->data, "node-name")); 5201d95db74SKevin Wolf } 5211d95db74SKevin Wolf 52277ae2302SDavid Hildenbrand if (eva->event == QAPI_EVENT_MEMORY_DEVICE_SIZE_CHANGE) { 52377ae2302SDavid Hildenbrand return !strcmp(qdict_get_str(eva->data, "qom-path"), 52477ae2302SDavid Hildenbrand qdict_get_str(evb->data, "qom-path")); 52577ae2302SDavid Hildenbrand } 52677ae2302SDavid Hildenbrand 5271d95db74SKevin Wolf return TRUE; 5281d95db74SKevin Wolf } 5291d95db74SKevin Wolf 5301d95db74SKevin Wolf int monitor_suspend(Monitor *mon) 5311d95db74SKevin Wolf { 5321d95db74SKevin Wolf if (monitor_is_hmp_non_interactive(mon)) { 5331d95db74SKevin Wolf return -ENOTTY; 5341d95db74SKevin Wolf } 5351d95db74SKevin Wolf 536d73415a3SStefan Hajnoczi qatomic_inc(&mon->suspend_cnt); 5371d95db74SKevin Wolf 5381d95db74SKevin Wolf if (mon->use_io_thread) { 5391d95db74SKevin Wolf /* 5401d95db74SKevin Wolf * Kick I/O thread to make sure this takes effect. It'll be 5411d95db74SKevin Wolf * evaluated again in prepare() of the watch object. 5421d95db74SKevin Wolf */ 5431d95db74SKevin Wolf aio_notify(iothread_get_aio_context(mon_iothread)); 5441d95db74SKevin Wolf } 5451d95db74SKevin Wolf 5461d95db74SKevin Wolf trace_monitor_suspend(mon, 1); 5471d95db74SKevin Wolf return 0; 5481d95db74SKevin Wolf } 5491d95db74SKevin Wolf 5501d95db74SKevin Wolf static void monitor_accept_input(void *opaque) 5511d95db74SKevin Wolf { 5521d95db74SKevin Wolf Monitor *mon = opaque; 5531d95db74SKevin Wolf 5546ee7c82dSPaolo Bonzini qemu_mutex_lock(&mon->mon_lock); 5556ee7c82dSPaolo Bonzini if (!monitor_is_qmp(mon) && mon->reset_seen) { 556c5d0c55fSPaolo Bonzini MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common); 557c5d0c55fSPaolo Bonzini assert(hmp_mon->rs); 5586ee7c82dSPaolo Bonzini readline_restart(hmp_mon->rs); 5596ee7c82dSPaolo Bonzini qemu_mutex_unlock(&mon->mon_lock); 560c5d0c55fSPaolo Bonzini readline_show_prompt(hmp_mon->rs); 5616ee7c82dSPaolo Bonzini } else { 5626ee7c82dSPaolo Bonzini qemu_mutex_unlock(&mon->mon_lock); 563c5d0c55fSPaolo Bonzini } 564c5d0c55fSPaolo Bonzini 5651d95db74SKevin Wolf qemu_chr_fe_accept_input(&mon->chr); 5661d95db74SKevin Wolf } 5671d95db74SKevin Wolf 5681d95db74SKevin Wolf void monitor_resume(Monitor *mon) 5691d95db74SKevin Wolf { 5701d95db74SKevin Wolf if (monitor_is_hmp_non_interactive(mon)) { 5711d95db74SKevin Wolf return; 5721d95db74SKevin Wolf } 5731d95db74SKevin Wolf 574d73415a3SStefan Hajnoczi if (qatomic_dec_fetch(&mon->suspend_cnt) == 0) { 5751d95db74SKevin Wolf AioContext *ctx; 5761d95db74SKevin Wolf 5771d95db74SKevin Wolf if (mon->use_io_thread) { 5781d95db74SKevin Wolf ctx = iothread_get_aio_context(mon_iothread); 5791d95db74SKevin Wolf } else { 5801d95db74SKevin Wolf ctx = qemu_get_aio_context(); 5811d95db74SKevin Wolf } 5821d95db74SKevin Wolf 5831d95db74SKevin Wolf aio_bh_schedule_oneshot(ctx, monitor_accept_input, mon); 5841d95db74SKevin Wolf } 5851d95db74SKevin Wolf 5861d95db74SKevin Wolf trace_monitor_suspend(mon, -1); 5871d95db74SKevin Wolf } 5881d95db74SKevin Wolf 5891d95db74SKevin Wolf int monitor_can_read(void *opaque) 5901d95db74SKevin Wolf { 5911d95db74SKevin Wolf Monitor *mon = opaque; 5921d95db74SKevin Wolf 5936ee7c82dSPaolo Bonzini return !qatomic_read(&mon->suspend_cnt); 5941d95db74SKevin Wolf } 5951d95db74SKevin Wolf 5961d95db74SKevin Wolf void monitor_list_append(Monitor *mon) 5971d95db74SKevin Wolf { 5981d95db74SKevin Wolf qemu_mutex_lock(&monitor_lock); 5991d95db74SKevin Wolf /* 6001d95db74SKevin Wolf * This prevents inserting new monitors during monitor_cleanup(). 6011d95db74SKevin Wolf * A cleaner solution would involve the main thread telling other 6021d95db74SKevin Wolf * threads to terminate, waiting for their termination. 6031d95db74SKevin Wolf */ 6041d95db74SKevin Wolf if (!monitor_destroyed) { 6051d95db74SKevin Wolf QTAILQ_INSERT_HEAD(&mon_list, mon, entry); 6061d95db74SKevin Wolf mon = NULL; 6071d95db74SKevin Wolf } 6081d95db74SKevin Wolf qemu_mutex_unlock(&monitor_lock); 6091d95db74SKevin Wolf 6101d95db74SKevin Wolf if (mon) { 6111d95db74SKevin Wolf monitor_data_destroy(mon); 6121d95db74SKevin Wolf g_free(mon); 6131d95db74SKevin Wolf } 6141d95db74SKevin Wolf } 6151d95db74SKevin Wolf 6161d95db74SKevin Wolf static void monitor_iothread_init(void) 6171d95db74SKevin Wolf { 6181d95db74SKevin Wolf mon_iothread = iothread_create("mon_iothread", &error_abort); 6191d95db74SKevin Wolf } 6201d95db74SKevin Wolf 62192082416SKevin Wolf void monitor_data_init(Monitor *mon, bool is_qmp, bool skip_flush, 6221d95db74SKevin Wolf bool use_io_thread) 6231d95db74SKevin Wolf { 6241d95db74SKevin Wolf if (use_io_thread && !mon_iothread) { 6251d95db74SKevin Wolf monitor_iothread_init(); 6261d95db74SKevin Wolf } 6271d95db74SKevin Wolf qemu_mutex_init(&mon->mon_lock); 62892082416SKevin Wolf mon->is_qmp = is_qmp; 62920076f4aSMarkus Armbruster mon->outbuf = g_string_new(NULL); 6301d95db74SKevin Wolf mon->skip_flush = skip_flush; 6311d95db74SKevin Wolf mon->use_io_thread = use_io_thread; 6321d95db74SKevin Wolf } 6331d95db74SKevin Wolf 6341d95db74SKevin Wolf void monitor_data_destroy(Monitor *mon) 6351d95db74SKevin Wolf { 6361d95db74SKevin Wolf g_free(mon->mon_cpu_path); 6371d95db74SKevin Wolf qemu_chr_fe_deinit(&mon->chr, false); 6381d95db74SKevin Wolf if (monitor_is_qmp(mon)) { 6391d95db74SKevin Wolf monitor_data_destroy_qmp(container_of(mon, MonitorQMP, common)); 6401d95db74SKevin Wolf } else { 6411d95db74SKevin Wolf readline_free(container_of(mon, MonitorHMP, common)->rs); 6421d95db74SKevin Wolf } 64320076f4aSMarkus Armbruster g_string_free(mon->outbuf, true); 6441d95db74SKevin Wolf qemu_mutex_destroy(&mon->mon_lock); 6451d95db74SKevin Wolf } 6461d95db74SKevin Wolf 6471d95db74SKevin Wolf void monitor_cleanup(void) 6481d95db74SKevin Wolf { 6491d95db74SKevin Wolf /* 650357bda95SKevin Wolf * The dispatcher needs to stop before destroying the monitor and 651357bda95SKevin Wolf * the I/O thread. 6529ce44e2cSKevin Wolf * 6539ce44e2cSKevin Wolf * We need to poll both qemu_aio_context and iohandler_ctx to make 6549ce44e2cSKevin Wolf * sure that the dispatcher coroutine keeps making progress and 6559ce44e2cSKevin Wolf * eventually terminates. qemu_aio_context is automatically 6569612aa40SStefan Hajnoczi * polled by calling AIO_WAIT_WHILE_UNLOCKED on it, but we must poll 6579ce44e2cSKevin Wolf * iohandler_ctx manually. 658c81219a7SKevin Wolf * 659c81219a7SKevin Wolf * Letting the iothread continue while shutting down the dispatcher 660c81219a7SKevin Wolf * means that new requests may still be coming in. This is okay, 661c81219a7SKevin Wolf * we'll just leave them in the queue without sending a response 662c81219a7SKevin Wolf * and monitor_data_destroy() will free them. 6639ce44e2cSKevin Wolf */ 6640ff25537SPaolo Bonzini WITH_QEMU_LOCK_GUARD(&monitor_lock) { 6659ce44e2cSKevin Wolf qmp_dispatcher_co_shutdown = true; 6660ff25537SPaolo Bonzini } 6679f2d5854SPaolo Bonzini qmp_dispatcher_co_wake(); 6689ce44e2cSKevin Wolf 6699612aa40SStefan Hajnoczi AIO_WAIT_WHILE_UNLOCKED(NULL, 6709ce44e2cSKevin Wolf (aio_poll(iohandler_get_aio_context(), false), 6713e6bed61SPaolo Bonzini qatomic_read(&qmp_dispatcher_co))); 6729ce44e2cSKevin Wolf 673c81219a7SKevin Wolf /* 674c81219a7SKevin Wolf * We need to explicitly stop the I/O thread (but not destroy it), 675c81219a7SKevin Wolf * clean up the monitor resources, then destroy the I/O thread since 676c81219a7SKevin Wolf * we need to unregister from chardev below in 677c81219a7SKevin Wolf * monitor_data_destroy(), and chardev is not thread-safe yet 678c81219a7SKevin Wolf */ 679c81219a7SKevin Wolf if (mon_iothread) { 680c81219a7SKevin Wolf iothread_stop(mon_iothread); 681c81219a7SKevin Wolf } 682c81219a7SKevin Wolf 683357bda95SKevin Wolf /* Flush output buffers and destroy monitors */ 684357bda95SKevin Wolf qemu_mutex_lock(&monitor_lock); 685357bda95SKevin Wolf monitor_destroyed = true; 686357bda95SKevin Wolf while (!QTAILQ_EMPTY(&mon_list)) { 687357bda95SKevin Wolf Monitor *mon = QTAILQ_FIRST(&mon_list); 688357bda95SKevin Wolf QTAILQ_REMOVE(&mon_list, mon, entry); 689357bda95SKevin Wolf /* Permit QAPI event emission from character frontend release */ 690357bda95SKevin Wolf qemu_mutex_unlock(&monitor_lock); 691357bda95SKevin Wolf monitor_flush(mon); 692357bda95SKevin Wolf monitor_data_destroy(mon); 693357bda95SKevin Wolf qemu_mutex_lock(&monitor_lock); 694357bda95SKevin Wolf g_free(mon); 695357bda95SKevin Wolf } 696357bda95SKevin Wolf qemu_mutex_unlock(&monitor_lock); 697357bda95SKevin Wolf 6981d95db74SKevin Wolf if (mon_iothread) { 6991d95db74SKevin Wolf iothread_destroy(mon_iothread); 7001d95db74SKevin Wolf mon_iothread = NULL; 7011d95db74SKevin Wolf } 7021d95db74SKevin Wolf } 7031d95db74SKevin Wolf 7041d95db74SKevin Wolf static void monitor_qapi_event_init(void) 7051d95db74SKevin Wolf { 7061d95db74SKevin Wolf monitor_qapi_event_state = g_hash_table_new(qapi_event_throttle_hash, 7071d95db74SKevin Wolf qapi_event_throttle_equal); 7081d95db74SKevin Wolf } 7091d95db74SKevin Wolf 7109d2b5f2cSMarkus Armbruster void monitor_init_globals(void) 7111d95db74SKevin Wolf { 7121d95db74SKevin Wolf monitor_qapi_event_init(); 7131d95db74SKevin Wolf qemu_mutex_init(&monitor_lock); 714e69ee454SKevin Wolf coroutine_mon = g_hash_table_new(NULL, NULL); 7151d95db74SKevin Wolf 7161d95db74SKevin Wolf /* 7171d95db74SKevin Wolf * The dispatcher BH must run in the main loop thread, since we 7181d95db74SKevin Wolf * have commands assuming that context. It would be nice to get 7191d95db74SKevin Wolf * rid of those assumptions. 7201d95db74SKevin Wolf */ 7219ce44e2cSKevin Wolf qmp_dispatcher_co = qemu_coroutine_create(monitor_qmp_dispatcher_co, NULL); 7229ce44e2cSKevin Wolf aio_co_schedule(iohandler_get_aio_context(), qmp_dispatcher_co); 7231d95db74SKevin Wolf } 7241d95db74SKevin Wolf 725a2f411c4SKevin Wolf int monitor_init(MonitorOptions *opts, bool allow_hmp, Error **errp) 726c3e95551SKevin Wolf { 72750707b39SMarkus Armbruster ERRP_GUARD(); 728c3e95551SKevin Wolf Chardev *chr; 729c3e95551SKevin Wolf 730f2098725SKevin Wolf chr = qemu_chr_find(opts->chardev); 731c3e95551SKevin Wolf if (chr == NULL) { 732f2098725SKevin Wolf error_setg(errp, "chardev \"%s\" not found", opts->chardev); 733c3e95551SKevin Wolf return -1; 734c3e95551SKevin Wolf } 735c3e95551SKevin Wolf 736a2f411c4SKevin Wolf if (!opts->has_mode) { 737a2f411c4SKevin Wolf opts->mode = allow_hmp ? MONITOR_MODE_READLINE : MONITOR_MODE_CONTROL; 738a2f411c4SKevin Wolf } 739a2f411c4SKevin Wolf 740f2098725SKevin Wolf switch (opts->mode) { 741f2098725SKevin Wolf case MONITOR_MODE_CONTROL: 74250707b39SMarkus Armbruster monitor_init_qmp(chr, opts->pretty, errp); 743f2098725SKevin Wolf break; 744f2098725SKevin Wolf case MONITOR_MODE_READLINE: 745a2f411c4SKevin Wolf if (!allow_hmp) { 746a2f411c4SKevin Wolf error_setg(errp, "Only QMP is supported"); 747a2f411c4SKevin Wolf return -1; 748a2f411c4SKevin Wolf } 749f2098725SKevin Wolf if (opts->pretty) { 750283d845cSDaniel P. Berrangé error_setg(errp, "'pretty' is not compatible with HMP monitors"); 751283d845cSDaniel P. Berrangé return -1; 752f2098725SKevin Wolf } 75350707b39SMarkus Armbruster monitor_init_hmp(chr, true, errp); 754f2098725SKevin Wolf break; 755f2098725SKevin Wolf default: 756f2098725SKevin Wolf g_assert_not_reached(); 757f2098725SKevin Wolf } 758f2098725SKevin Wolf 75950707b39SMarkus Armbruster return *errp ? -1 : 0; 760f2098725SKevin Wolf } 761f2098725SKevin Wolf 762f2098725SKevin Wolf int monitor_init_opts(QemuOpts *opts, Error **errp) 763f2098725SKevin Wolf { 764f2098725SKevin Wolf Visitor *v; 765f2098725SKevin Wolf MonitorOptions *options; 766b11a093cSMarkus Armbruster int ret; 767f2098725SKevin Wolf 768f2098725SKevin Wolf v = opts_visitor_new(opts); 769b11a093cSMarkus Armbruster visit_type_MonitorOptions(v, NULL, &options, errp); 770f2098725SKevin Wolf visit_free(v); 771b11a093cSMarkus Armbruster if (!options) { 772f2098725SKevin Wolf return -1; 773c3e95551SKevin Wolf } 774b11a093cSMarkus Armbruster 775b11a093cSMarkus Armbruster ret = monitor_init(options, true, errp); 776b11a093cSMarkus Armbruster qapi_free_MonitorOptions(options); 777b11a093cSMarkus Armbruster return ret; 778c3e95551SKevin Wolf } 779c3e95551SKevin Wolf 7801d95db74SKevin Wolf QemuOptsList qemu_mon_opts = { 7811d95db74SKevin Wolf .name = "mon", 7821d95db74SKevin Wolf .implied_opt_name = "chardev", 7831d95db74SKevin Wolf .head = QTAILQ_HEAD_INITIALIZER(qemu_mon_opts.head), 7841d95db74SKevin Wolf .desc = { 7851d95db74SKevin Wolf { 7861d95db74SKevin Wolf .name = "mode", 7871d95db74SKevin Wolf .type = QEMU_OPT_STRING, 7881d95db74SKevin Wolf },{ 7891d95db74SKevin Wolf .name = "chardev", 7901d95db74SKevin Wolf .type = QEMU_OPT_STRING, 7911d95db74SKevin Wolf },{ 7921d95db74SKevin Wolf .name = "pretty", 7931d95db74SKevin Wolf .type = QEMU_OPT_BOOL, 7941d95db74SKevin Wolf }, 7951d95db74SKevin Wolf { /* end of list */ } 7961d95db74SKevin Wolf }, 7971d95db74SKevin Wolf }; 798