Libvirt wants to know about the guest-side connection state of some virtio-serial ports (in particular the one(s) assigned to guest agent(s)). Report such states with a new monitor event.
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1080376 Signed-off-by: Laszlo Ersek <ler...@redhat.com> --- Notes: v2: - emit event unconditionally; drop per-port "report_connstate" property [Eric] - rate-limit the new event [Eric] -- unify it with other guest-triggerable events in monitor_qapi_event_init() - rebased to Wenchao's qapi-event series - introduce one event only, VSERPORT_CHANGE, and make the port status a parameter [Eric] qapi-event.json | 16 ++++++++++++++++ qapi-schema.json | 16 ++++++++++++++++ hw/char/virtio-console.c | 15 ++++++++++++--- monitor.c | 1 + 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/qapi-event.json b/qapi-event.json index e7a47f9..0ec20c4 100644 --- a/qapi-event.json +++ b/qapi-event.json @@ -315,4 +315,20 @@ ## { 'event': 'QUORUM_REPORT_BAD', 'data': { '*error': 'str', 'node-name': 'str', 'sector-num': 'int', 'sector-count': 'int' } } + +## +# @VSERPORT_CHANGE +# +# Emitted when the guest takes an action that changes the status of a +# virtio-serial port (eg. opens or closes it). +# +# @id: device identifier of the virtio-serial port +# +# @status: new status of the virtio-serial port +# +# Since: 2.1 +## +{ 'event': 'VSERPORT_CHANGE', + 'data': { 'id': 'str', + 'status': 'VirtioSerialPortStatus' } } diff --git a/qapi-schema.json b/qapi-schema.json index e7727a1..d1dc8be 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3398,5 +3398,21 @@ ## { 'enum': 'GuestPanicAction', 'data': [ 'pause' ] } +## +# @VirtioSerialPortStatus +# +# An enumeration of the possible / recognized states of virtio-serial ports. +# +# @connected: the virtio-serial port has been opened (connected to) in the +# guest. +# +# @disconnected: the virtio-serial port has been closed (disconnected from) in +# the guest. +# +# Since: 2.1 +## +{ 'enum': 'VirtioSerialPortStatus', + 'data': [ 'connected', 'disconnected' ] } + { 'include': 'qapi-event.json' } diff --git a/hw/char/virtio-console.c b/hw/char/virtio-console.c index 6c8be0f..729faac 100644 --- a/hw/char/virtio-console.c +++ b/hw/char/virtio-console.c @@ -13,8 +13,9 @@ #include "sysemu/char.h" #include "qemu/error-report.h" #include "trace.h" #include "hw/virtio/virtio-serial.h" +#include "qapi-event.h" #define TYPE_VIRTIO_CONSOLE_SERIAL_PORT "virtserialport" #define VIRTIO_CONSOLE(obj) \ OBJECT_CHECK(VirtConsole, (obj), TYPE_VIRTIO_CONSOLE_SERIAL_PORT) @@ -80,13 +81,21 @@ static ssize_t flush_buf(VirtIOSerialPort *port, /* Callback function that's called when the guest opens/closes the port */ static void set_guest_connected(VirtIOSerialPort *port, int guest_connected) { VirtConsole *vcon = VIRTIO_CONSOLE(port); + DeviceState *dev = DEVICE(port); - if (!vcon->chr) { - return; + if (vcon->chr) { + qemu_chr_fe_set_open(vcon->chr, guest_connected); + } + + if (dev->id) { + VirtioSerialPortStatus status = guest_connected ? + VIRTIO_SERIAL_PORT_STATUS_CONNECTED : + VIRTIO_SERIAL_PORT_STATUS_DISCONNECTED; + + qapi_event_send_vserport_change(dev->id, status, &error_abort); } - qemu_chr_fe_set_open(vcon->chr, guest_connected); } /* Readiness of the guest to accept data on a port */ static int chr_can_read(void *opaque) diff --git a/monitor.c b/monitor.c index a8ab600..5fbf987 100644 --- a/monitor.c +++ b/monitor.c @@ -584,8 +584,9 @@ static void monitor_qapi_event_init(void) /* Limit guest-triggerable events to 1 per second */ monitor_qapi_event_throttle(QAPI_EVENT_RTC_CHANGE, 1000); monitor_qapi_event_throttle(QAPI_EVENT_WATCHDOG, 1000); monitor_qapi_event_throttle(QAPI_EVENT_BALLOON_CHANGE, 1000); + monitor_qapi_event_throttle(QAPI_EVENT_VSERPORT_CHANGE, 1000); /* limit the rate of quorum events to avoid hammering the management */ monitor_qapi_event_throttle(QAPI_EVENT_QUORUM_REPORT_BAD, 1000); monitor_qapi_event_throttle(QAPI_EVENT_QUORUM_FAILURE, 1000); -- 1.8.3.1