char: avoid chardevice direct access
frontends should avoid accessing CharDriver struct where possible Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <1499342940-56739-6-git-send-email-anton.nefedov@virtuozzo.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
7c44a2a9d1
commit
3065070153
@ -189,6 +189,11 @@ bool qemu_chr_fe_backend_connected(CharBackend *be)
|
|||||||
return !!be->chr;
|
return !!be->chr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool qemu_chr_fe_backend_open(CharBackend *be)
|
||||||
|
{
|
||||||
|
return be->chr && be->chr->be_open;
|
||||||
|
}
|
||||||
|
|
||||||
bool qemu_chr_fe_init(CharBackend *b, Chardev *s, Error **errp)
|
bool qemu_chr_fe_init(CharBackend *b, Chardev *s, Error **errp)
|
||||||
{
|
{
|
||||||
int tag = 0;
|
int tag = 0;
|
||||||
|
@ -1106,7 +1106,7 @@ static void strongarm_uart_tx(void *opaque)
|
|||||||
|
|
||||||
if (s->utcr3 & UTCR3_LBM) /* loopback */ {
|
if (s->utcr3 & UTCR3_LBM) /* loopback */ {
|
||||||
strongarm_uart_receive(s, &s->tx_fifo[s->tx_start], 1);
|
strongarm_uart_receive(s, &s->tx_fifo[s->tx_start], 1);
|
||||||
} else if (qemu_chr_fe_get_driver(&s->chr)) {
|
} else if (qemu_chr_fe_backend_connected(&s->chr)) {
|
||||||
/* XXX this blocks entire thread. Rewrite to use
|
/* XXX this blocks entire thread. Rewrite to use
|
||||||
* qemu_chr_fe_write and background I/O callbacks */
|
* qemu_chr_fe_write and background I/O callbacks */
|
||||||
qemu_chr_fe_write_all(&s->chr, &s->tx_fifo[s->tx_start], 1);
|
qemu_chr_fe_write_all(&s->chr, &s->tx_fifo[s->tx_start], 1);
|
||||||
|
@ -279,7 +279,7 @@ static gboolean cadence_uart_xmit(GIOChannel *chan, GIOCondition cond,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* instant drain the fifo when there's no back-end */
|
/* instant drain the fifo when there's no back-end */
|
||||||
if (!qemu_chr_fe_get_driver(&s->chr)) {
|
if (!qemu_chr_fe_backend_connected(&s->chr)) {
|
||||||
s->tx_count = 0;
|
s->tx_count = 0;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ static const MemoryRegionOps debugcon_ops = {
|
|||||||
|
|
||||||
static void debugcon_realize_core(DebugconState *s, Error **errp)
|
static void debugcon_realize_core(DebugconState *s, Error **errp)
|
||||||
{
|
{
|
||||||
if (!qemu_chr_fe_get_driver(&s->chr)) {
|
if (!qemu_chr_fe_backend_connected(&s->chr)) {
|
||||||
error_setg(errp, "Can't create debugcon device, empty char device");
|
error_setg(errp, "Can't create debugcon device, empty char device");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -417,7 +417,7 @@ static void escc_update_parameters(ChannelState *s)
|
|||||||
int speed, parity, data_bits, stop_bits;
|
int speed, parity, data_bits, stop_bits;
|
||||||
QEMUSerialSetParams ssp;
|
QEMUSerialSetParams ssp;
|
||||||
|
|
||||||
if (!qemu_chr_fe_get_driver(&s->chr) || s->type != ser)
|
if (!qemu_chr_fe_backend_connected(&s->chr) || s->type != ser)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREN) {
|
if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREN) {
|
||||||
@ -557,7 +557,7 @@ static void escc_mem_write(void *opaque, hwaddr addr,
|
|||||||
trace_escc_mem_writeb_data(CHN_C(s), val);
|
trace_escc_mem_writeb_data(CHN_C(s), val);
|
||||||
s->tx = val;
|
s->tx = val;
|
||||||
if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled
|
if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled
|
||||||
if (qemu_chr_fe_get_driver(&s->chr)) {
|
if (qemu_chr_fe_backend_connected(&s->chr)) {
|
||||||
/* XXX this blocks entire thread. Rewrite to use
|
/* XXX this blocks entire thread. Rewrite to use
|
||||||
* qemu_chr_fe_write and background I/O callbacks */
|
* qemu_chr_fe_write and background I/O callbacks */
|
||||||
qemu_chr_fe_write_all(&s->chr, &s->tx, 1);
|
qemu_chr_fe_write_all(&s->chr, &s->tx, 1);
|
||||||
@ -1013,7 +1013,7 @@ static void escc_realize(DeviceState *dev, Error **errp)
|
|||||||
ESCC_SIZE << s->it_shift);
|
ESCC_SIZE << s->it_shift);
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
if (qemu_chr_fe_get_driver(&s->chn[i].chr)) {
|
if (qemu_chr_fe_backend_connected(&s->chn[i].chr)) {
|
||||||
s->chn[i].clock = s->frequency / 2;
|
s->chn[i].clock = s->frequency / 2;
|
||||||
qemu_chr_fe_set_handlers(&s->chn[i].chr, serial_can_receive,
|
qemu_chr_fe_set_handlers(&s->chn[i].chr, serial_can_receive,
|
||||||
serial_receive1, serial_event, NULL,
|
serial_receive1, serial_event, NULL,
|
||||||
|
@ -380,7 +380,7 @@ static void exynos4210_uart_write(void *opaque, hwaddr offset,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case UTXH:
|
case UTXH:
|
||||||
if (qemu_chr_fe_get_driver(&s->chr)) {
|
if (qemu_chr_fe_backend_connected(&s->chr)) {
|
||||||
s->reg[I_(UTRSTAT)] &= ~(UTRSTAT_TRANSMITTER_EMPTY |
|
s->reg[I_(UTRSTAT)] &= ~(UTRSTAT_TRANSMITTER_EMPTY |
|
||||||
UTRSTAT_Tx_BUFFER_EMPTY);
|
UTRSTAT_Tx_BUFFER_EMPTY);
|
||||||
ch = (uint8_t)val;
|
ch = (uint8_t)val;
|
||||||
|
@ -201,7 +201,7 @@ static void grlib_apbuart_write(void *opaque, hwaddr addr,
|
|||||||
case DATA_OFFSET:
|
case DATA_OFFSET:
|
||||||
case DATA_OFFSET + 3: /* When only one byte write */
|
case DATA_OFFSET + 3: /* When only one byte write */
|
||||||
/* Transmit when character device available and transmitter enabled */
|
/* Transmit when character device available and transmitter enabled */
|
||||||
if (qemu_chr_fe_get_driver(&uart->chr) &&
|
if (qemu_chr_fe_backend_connected(&uart->chr) &&
|
||||||
(uart->control & UART_TRANSMIT_ENABLE)) {
|
(uart->control & UART_TRANSMIT_ENABLE)) {
|
||||||
c = value & 0xFF;
|
c = value & 0xFF;
|
||||||
/* XXX this blocks entire thread. Rewrite to use
|
/* XXX this blocks entire thread. Rewrite to use
|
||||||
|
@ -542,7 +542,7 @@ static void ipoctal_realize(DeviceState *dev, Error **errp)
|
|||||||
ch->ipoctal = s;
|
ch->ipoctal = s;
|
||||||
|
|
||||||
/* Redirect IP-Octal channels to host character devices */
|
/* Redirect IP-Octal channels to host character devices */
|
||||||
if (qemu_chr_fe_get_driver(&ch->dev)) {
|
if (qemu_chr_fe_backend_connected(&ch->dev)) {
|
||||||
qemu_chr_fe_set_handlers(&ch->dev, hostdev_can_receive,
|
qemu_chr_fe_set_handlers(&ch->dev, hostdev_can_receive,
|
||||||
hostdev_receive, hostdev_event,
|
hostdev_receive, hostdev_event,
|
||||||
NULL, ch, NULL, true);
|
NULL, ch, NULL, true);
|
||||||
|
@ -513,7 +513,7 @@ static void parallel_isa_realizefn(DeviceState *dev, Error **errp)
|
|||||||
int base;
|
int base;
|
||||||
uint8_t dummy;
|
uint8_t dummy;
|
||||||
|
|
||||||
if (!qemu_chr_fe_get_driver(&s->chr)) {
|
if (!qemu_chr_fe_backend_connected(&s->chr)) {
|
||||||
error_setg(errp, "Can't create parallel device, empty char device");
|
error_setg(errp, "Can't create parallel device, empty char device");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -195,7 +195,7 @@ static int write_console_data(SCLPEvent *event, const uint8_t *buf, int len)
|
|||||||
{
|
{
|
||||||
SCLPConsoleLM *scon = SCLPLM_CONSOLE(event);
|
SCLPConsoleLM *scon = SCLPLM_CONSOLE(event);
|
||||||
|
|
||||||
if (!qemu_chr_fe_get_driver(&scon->chr)) {
|
if (!qemu_chr_fe_backend_connected(&scon->chr)) {
|
||||||
/* If there's no backend, we can just say we consumed all data. */
|
/* If there's no backend, we can just say we consumed all data. */
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,7 @@ static ssize_t write_console_data(SCLPEvent *event, const uint8_t *buf,
|
|||||||
{
|
{
|
||||||
SCLPConsole *scon = SCLP_CONSOLE(event);
|
SCLPConsole *scon = SCLP_CONSOLE(event);
|
||||||
|
|
||||||
if (!qemu_chr_fe_get_driver(&scon->chr)) {
|
if (!qemu_chr_fe_backend_connected(&scon->chr)) {
|
||||||
/* If there's no backend, we can just say we consumed all data. */
|
/* If there's no backend, we can just say we consumed all data. */
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
@ -886,7 +886,7 @@ static void serial_reset(void *opaque)
|
|||||||
|
|
||||||
void serial_realize_core(SerialState *s, Error **errp)
|
void serial_realize_core(SerialState *s, Error **errp)
|
||||||
{
|
{
|
||||||
if (!qemu_chr_fe_get_driver(&s->chr)) {
|
if (!qemu_chr_fe_backend_connected(&s->chr)) {
|
||||||
error_setg(errp, "Can't create serial device, empty char device");
|
error_setg(errp, "Can't create serial device, empty char device");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,7 @@ static void sh_serial_write(void *opaque, hwaddr offs,
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case 0x0c: /* FTDR / TDR */
|
case 0x0c: /* FTDR / TDR */
|
||||||
if (qemu_chr_fe_get_driver(&s->chr)) {
|
if (qemu_chr_fe_backend_connected(&s->chr)) {
|
||||||
ch = val;
|
ch = val;
|
||||||
/* XXX this blocks entire thread. Rewrite to use
|
/* XXX this blocks entire thread. Rewrite to use
|
||||||
* qemu_chr_fe_write and background I/O callbacks */
|
* qemu_chr_fe_write and background I/O callbacks */
|
||||||
|
@ -78,7 +78,7 @@ static void spapr_vty_realize(VIOsPAPRDevice *sdev, Error **errp)
|
|||||||
{
|
{
|
||||||
VIOsPAPRVTYDevice *dev = VIO_SPAPR_VTY_DEVICE(sdev);
|
VIOsPAPRVTYDevice *dev = VIO_SPAPR_VTY_DEVICE(sdev);
|
||||||
|
|
||||||
if (!qemu_chr_fe_get_driver(&dev->chardev)) {
|
if (!qemu_chr_fe_backend_connected(&dev->chardev)) {
|
||||||
error_setg(errp, "chardev property not set");
|
error_setg(errp, "chardev property not set");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -239,7 +239,7 @@ static int write_payload_3270(EmulatedCcw3270Device *dev, uint8_t cmd,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!qemu_chr_fe_get_driver(&t->chr)) {
|
if (!qemu_chr_fe_backend_connected(&t->chr)) {
|
||||||
/* We just say we consumed all data if there's no backend. */
|
/* We just say we consumed all data if there's no backend. */
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ static ssize_t flush_buf(VirtIOSerialPort *port,
|
|||||||
VirtConsole *vcon = VIRTIO_CONSOLE(port);
|
VirtConsole *vcon = VIRTIO_CONSOLE(port);
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
if (!qemu_chr_fe_get_driver(&vcon->chr)) {
|
if (!qemu_chr_fe_backend_connected(&vcon->chr)) {
|
||||||
/* If there's no backend, we can just say we consumed all data. */
|
/* If there's no backend, we can just say we consumed all data. */
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
@ -168,7 +168,6 @@ static void virtconsole_realize(DeviceState *dev, Error **errp)
|
|||||||
VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
|
VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
|
||||||
VirtConsole *vcon = VIRTIO_CONSOLE(dev);
|
VirtConsole *vcon = VIRTIO_CONSOLE(dev);
|
||||||
VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(dev);
|
VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(dev);
|
||||||
Chardev *chr = qemu_chr_fe_get_driver(&vcon->chr);
|
|
||||||
|
|
||||||
if (port->id == 0 && !k->is_console) {
|
if (port->id == 0 && !k->is_console) {
|
||||||
error_setg(errp, "Port number 0 on virtio-serial devices reserved "
|
error_setg(errp, "Port number 0 on virtio-serial devices reserved "
|
||||||
@ -176,7 +175,7 @@ static void virtconsole_realize(DeviceState *dev, Error **errp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chr) {
|
if (qemu_chr_fe_backend_connected(&vcon->chr)) {
|
||||||
/*
|
/*
|
||||||
* For consoles we don't block guest data transfer just
|
* For consoles we don't block guest data transfer just
|
||||||
* because nothing is connected - we'll just let it go
|
* because nothing is connected - we'll just let it go
|
||||||
|
@ -150,7 +150,7 @@ static void xencons_send(struct XenConsole *con)
|
|||||||
ssize_t len, size;
|
ssize_t len, size;
|
||||||
|
|
||||||
size = con->buffer.size - con->buffer.consumed;
|
size = con->buffer.size - con->buffer.consumed;
|
||||||
if (qemu_chr_fe_get_driver(&con->chr)) {
|
if (qemu_chr_fe_backend_connected(&con->chr)) {
|
||||||
len = qemu_chr_fe_write(&con->chr,
|
len = qemu_chr_fe_write(&con->chr,
|
||||||
con->buffer.data + con->buffer.consumed,
|
con->buffer.data + con->buffer.consumed,
|
||||||
size);
|
size);
|
||||||
|
@ -447,7 +447,7 @@ static void ipmi_bmc_extern_realize(DeviceState *dev, Error **errp)
|
|||||||
{
|
{
|
||||||
IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(dev);
|
IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(dev);
|
||||||
|
|
||||||
if (!qemu_chr_fe_get_driver(&ibe->chr)) {
|
if (!qemu_chr_fe_backend_connected(&ibe->chr)) {
|
||||||
error_setg(errp, "IPMI external bmc requires chardev attribute");
|
error_setg(errp, "IPMI external bmc requires chardev attribute");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1128,7 +1128,7 @@ static void ivshmem_doorbell_realize(PCIDevice *dev, Error **errp)
|
|||||||
{
|
{
|
||||||
IVShmemState *s = IVSHMEM_COMMON(dev);
|
IVShmemState *s = IVSHMEM_COMMON(dev);
|
||||||
|
|
||||||
if (!qemu_chr_fe_get_driver(&s->server_chr)) {
|
if (!qemu_chr_fe_backend_connected(&s->server_chr)) {
|
||||||
error_setg(errp, "You must specify a 'chardev'");
|
error_setg(errp, "You must specify a 'chardev'");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1257,7 +1257,7 @@ static void ivshmem_realize(PCIDevice *dev, Error **errp)
|
|||||||
" or ivshmem-doorbell instead");
|
" or ivshmem-doorbell instead");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!!qemu_chr_fe_get_driver(&s->server_chr) + !!s->shmobj != 1) {
|
if (qemu_chr_fe_backend_connected(&s->server_chr) + !!s->shmobj != 1) {
|
||||||
error_setg(errp, "You must specify either 'shm' or 'chardev'");
|
error_setg(errp, "You must specify either 'shm' or 'chardev'");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -322,7 +322,7 @@ static void passthru_apdu_from_guest(
|
|||||||
{
|
{
|
||||||
PassthruState *card = PASSTHRU_CCID_CARD(base);
|
PassthruState *card = PASSTHRU_CCID_CARD(base);
|
||||||
|
|
||||||
if (!qemu_chr_fe_get_driver(&card->cs)) {
|
if (!qemu_chr_fe_backend_connected(&card->cs)) {
|
||||||
printf("ccid-passthru: no chardev, discarding apdu length %d\n", len);
|
printf("ccid-passthru: no chardev, discarding apdu length %d\n", len);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -343,7 +343,7 @@ static int passthru_initfn(CCIDCardState *base)
|
|||||||
|
|
||||||
card->vscard_in_pos = 0;
|
card->vscard_in_pos = 0;
|
||||||
card->vscard_in_hdr = 0;
|
card->vscard_in_hdr = 0;
|
||||||
if (qemu_chr_fe_get_driver(&card->cs)) {
|
if (qemu_chr_fe_backend_connected(&card->cs)) {
|
||||||
DPRINTF(card, D_INFO, "initing chardev\n");
|
DPRINTF(card, D_INFO, "initing chardev\n");
|
||||||
qemu_chr_fe_set_handlers(&card->cs,
|
qemu_chr_fe_set_handlers(&card->cs,
|
||||||
ccid_card_vscard_can_read,
|
ccid_card_vscard_can_read,
|
||||||
|
@ -484,13 +484,12 @@ static void usb_serial_realize(USBDevice *dev, Error **errp)
|
|||||||
{
|
{
|
||||||
USBSerialState *s = USB_SERIAL_DEV(dev);
|
USBSerialState *s = USB_SERIAL_DEV(dev);
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
Chardev *chr = qemu_chr_fe_get_driver(&s->cs);
|
|
||||||
|
|
||||||
usb_desc_create_serial(dev);
|
usb_desc_create_serial(dev);
|
||||||
usb_desc_init(dev);
|
usb_desc_init(dev);
|
||||||
dev->auto_attach = 0;
|
dev->auto_attach = 0;
|
||||||
|
|
||||||
if (!chr) {
|
if (!qemu_chr_fe_backend_connected(&s->cs)) {
|
||||||
error_setg(errp, "Property chardev is required");
|
error_setg(errp, "Property chardev is required");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -505,7 +504,7 @@ static void usb_serial_realize(USBDevice *dev, Error **errp)
|
|||||||
usb_serial_event, NULL, s, NULL, true);
|
usb_serial_event, NULL, s, NULL, true);
|
||||||
usb_serial_handle_reset(dev);
|
usb_serial_handle_reset(dev);
|
||||||
|
|
||||||
if (chr->be_open && !dev->attached) {
|
if (qemu_chr_fe_backend_open(&s->cs) && !dev->attached) {
|
||||||
usb_device_attach(dev, &error_abort);
|
usb_device_attach(dev, &error_abort);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,10 +273,9 @@ static gboolean usbredir_write_unblocked(GIOChannel *chan, GIOCondition cond,
|
|||||||
static int usbredir_write(void *priv, uint8_t *data, int count)
|
static int usbredir_write(void *priv, uint8_t *data, int count)
|
||||||
{
|
{
|
||||||
USBRedirDevice *dev = priv;
|
USBRedirDevice *dev = priv;
|
||||||
Chardev *chr = qemu_chr_fe_get_driver(&dev->cs);
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (!chr->be_open) {
|
if (!qemu_chr_fe_backend_open(&dev->cs)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1366,7 +1365,7 @@ static void usbredir_realize(USBDevice *udev, Error **errp)
|
|||||||
USBRedirDevice *dev = USB_REDIRECT(udev);
|
USBRedirDevice *dev = USB_REDIRECT(udev);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!qemu_chr_fe_get_driver(&dev->cs)) {
|
if (!qemu_chr_fe_backend_connected(&dev->cs)) {
|
||||||
error_setg(errp, QERR_MISSING_PARAMETER, "chardev");
|
error_setg(errp, QERR_MISSING_PARAMETER, "chardev");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,13 @@ Chardev *qemu_chr_fe_get_driver(CharBackend *be);
|
|||||||
*/
|
*/
|
||||||
bool qemu_chr_fe_backend_connected(CharBackend *be);
|
bool qemu_chr_fe_backend_connected(CharBackend *be);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @qemu_chr_fe_backend_open:
|
||||||
|
*
|
||||||
|
* Returns true if chardevice associated with @be is open.
|
||||||
|
*/
|
||||||
|
bool qemu_chr_fe_backend_open(CharBackend *be);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @qemu_chr_fe_set_handlers:
|
* @qemu_chr_fe_set_handlers:
|
||||||
* @b: a CharBackend
|
* @b: a CharBackend
|
||||||
|
@ -163,7 +163,7 @@ static ssize_t filter_redirector_receive_iov(NetFilterState *nf,
|
|||||||
MirrorState *s = FILTER_REDIRECTOR(nf);
|
MirrorState *s = FILTER_REDIRECTOR(nf);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (qemu_chr_fe_get_driver(&s->chr_out)) {
|
if (qemu_chr_fe_backend_connected(&s->chr_out)) {
|
||||||
ret = filter_send(&s->chr_out, iov, iovcnt);
|
ret = filter_send(&s->chr_out, iov, iovcnt);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
error_report("filter redirector send failed(%s)", strerror(-ret));
|
error_report("filter redirector send failed(%s)", strerror(-ret));
|
||||||
|
Loading…
Reference in New Issue
Block a user