aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--blockdev-nbd.c3
-rw-r--r--chardev/char-fe.c13
-rw-r--r--chardev/char-io.c48
-rw-r--r--chardev/char-socket.c8
-rw-r--r--chardev/char.c37
-rw-r--r--gdbstub.c6
-rw-r--r--hw/char/xen_console.c6
-rw-r--r--include/block/nbd.h7
-rw-r--r--include/chardev/char-fe.h81
-rw-r--r--include/chardev/char.h81
-rw-r--r--nbd/client.c44
-rw-r--r--nbd/server.c80
-rw-r--r--net/slirp.c6
-rw-r--r--qemu-nbd.c26
-rwxr-xr-xscripts/device-crash-test6
-rwxr-xr-xtests/docker/docker.py4
-rw-r--r--tests/migration/guestperf/shell.py8
-rw-r--r--vl.c10
18 files changed, 216 insertions, 258 deletions
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index 1ef11041a7..1d170c80b8 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -36,8 +36,7 @@ static void nbd_accept(QIONetListener *listener, QIOChannelSocket *cioc,
gpointer opaque)
{
qio_channel_set_name(QIO_CHANNEL(cioc), "nbd-server");
- nbd_client_new(NULL, cioc,
- nbd_server->tlscreds, NULL,
+ nbd_client_new(cioc, nbd_server->tlscreds, NULL,
nbd_blockdev_client_closed);
}
diff --git a/chardev/char-fe.c b/chardev/char-fe.c
index b1f228e8b5..a8931f7afd 100644
--- a/chardev/char-fe.c
+++ b/chardev/char-fe.c
@@ -56,7 +56,7 @@ int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len)
int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len)
{
Chardev *s = be->chr;
- int offset = 0, counter = 10;
+ int offset = 0;
int res;
if (!s || !CHARDEV_GET_CLASS(s)->chr_sync_read) {
@@ -88,10 +88,6 @@ int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len)
}
offset += res;
-
- if (!counter--) {
- break;
- }
}
if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_RECORD) {
@@ -239,7 +235,12 @@ void qemu_chr_fe_deinit(CharBackend *b, bool del)
d->backends[b->tag] = NULL;
}
if (del) {
- object_unparent(OBJECT(b->chr));
+ Object *obj = OBJECT(b->chr);
+ if (obj->parent) {
+ object_unparent(obj);
+ } else {
+ object_unref(obj);
+ }
}
b->chr = NULL;
}
diff --git a/chardev/char-io.c b/chardev/char-io.c
index f81052481a..8ced184160 100644
--- a/chardev/char-io.c
+++ b/chardev/char-io.c
@@ -33,7 +33,6 @@ typedef struct IOWatchPoll {
IOCanReadHandler *fd_can_read;
GSourceFunc fd_read;
void *opaque;
- GMainContext *context;
} IOWatchPoll;
static IOWatchPoll *io_watch_poll_from_source(GSource *source)
@@ -55,47 +54,24 @@ static gboolean io_watch_poll_prepare(GSource *source,
iwp->src = qio_channel_create_watch(
iwp->ioc, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL);
g_source_set_callback(iwp->src, iwp->fd_read, iwp->opaque, NULL);
- g_source_attach(iwp->src, iwp->context);
- } else {
- g_source_destroy(iwp->src);
+ g_source_add_child_source(source, iwp->src);
g_source_unref(iwp->src);
+ } else {
+ g_source_remove_child_source(source, iwp->src);
iwp->src = NULL;
}
return FALSE;
}
-static gboolean io_watch_poll_check(GSource *source)
-{
- return FALSE;
-}
-
static gboolean io_watch_poll_dispatch(GSource *source, GSourceFunc callback,
gpointer user_data)
{
- abort();
-}
-
-static void io_watch_poll_finalize(GSource *source)
-{
- /* Due to a glib bug, removing the last reference to a source
- * inside a finalize callback causes recursive locking (and a
- * deadlock). This is not a problem inside other callbacks,
- * including dispatch callbacks, so we call io_remove_watch_poll
- * to remove this source. At this point, iwp->src must
- * be NULL, or we would leak it.
- *
- * This would be solved much more elegantly by child sources,
- * but we support older glib versions that do not have them.
- */
- IOWatchPoll *iwp = io_watch_poll_from_source(source);
- assert(iwp->src == NULL);
+ return G_SOURCE_CONTINUE;
}
static GSourceFuncs io_watch_poll_funcs = {
.prepare = io_watch_poll_prepare,
- .check = io_watch_poll_check,
.dispatch = io_watch_poll_dispatch,
- .finalize = io_watch_poll_finalize,
};
GSource *io_add_watch_poll(Chardev *chr,
@@ -115,7 +91,6 @@ GSource *io_add_watch_poll(Chardev *chr,
iwp->ioc = ioc;
iwp->fd_read = (GSourceFunc) fd_read;
iwp->src = NULL;
- iwp->context = context;
name = g_strdup_printf("chardev-iowatch-%s", chr->label);
g_source_set_name((GSource *)iwp, name);
@@ -126,23 +101,10 @@ GSource *io_add_watch_poll(Chardev *chr,
return (GSource *)iwp;
}
-static void io_remove_watch_poll(GSource *source)
-{
- IOWatchPoll *iwp;
-
- iwp = io_watch_poll_from_source(source);
- if (iwp->src) {
- g_source_destroy(iwp->src);
- g_source_unref(iwp->src);
- iwp->src = NULL;
- }
- g_source_destroy(&iwp->parent);
-}
-
void remove_fd_in_watch(Chardev *chr)
{
if (chr->gsource) {
- io_remove_watch_poll(chr->gsource);
+ g_source_destroy(chr->gsource);
chr->gsource = NULL;
}
}
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 7cd0ae2824..a75b46d9fe 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -423,8 +423,12 @@ static void update_disconnected_filename(SocketChardev *s)
Chardev *chr = CHARDEV(s);
g_free(chr->filename);
- chr->filename = SocketAddress_to_str("disconnected:", s->addr,
- s->is_listen, s->is_telnet);
+ if (s->addr) {
+ chr->filename = SocketAddress_to_str("disconnected:", s->addr,
+ s->is_listen, s->is_telnet);
+ } else {
+ chr->filename = g_strdup("disconnected:socket");
+ }
}
/* NB may be called even if tcp_chr_connect has not been
diff --git a/chardev/char.c b/chardev/char.c
index 76d866e6fe..e115166995 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -329,7 +329,8 @@ int qemu_chr_wait_connected(Chardev *chr, Error **errp)
return 0;
}
-QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
+QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename,
+ bool permit_mux_mon)
{
char host[65], port[33], width[8], height[8];
int pos;
@@ -344,6 +345,10 @@ QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
}
if (strstart(filename, "mon:", &p)) {
+ if (!permit_mux_mon) {
+ error_report("mon: isn't supported in this context");
+ return NULL;
+ }
filename = p;
qemu_opt_set(opts, "mux", "on", &error_abort);
if (strcmp(filename, "stdio") == 0) {
@@ -683,7 +688,8 @@ out:
return chr;
}
-Chardev *qemu_chr_new_noreplay(const char *label, const char *filename)
+Chardev *qemu_chr_new_noreplay(const char *label, const char *filename,
+ bool permit_mux_mon)
{
const char *p;
Chardev *chr;
@@ -694,25 +700,32 @@ Chardev *qemu_chr_new_noreplay(const char *label, const char *filename)
return qemu_chr_find(p);
}
- opts = qemu_chr_parse_compat(label, filename);
+ opts = qemu_chr_parse_compat(label, filename, permit_mux_mon);
if (!opts)
return NULL;
chr = qemu_chr_new_from_opts(opts, &err);
- if (err) {
+ if (!chr) {
error_report_err(err);
+ goto out;
}
- if (chr && qemu_opt_get_bool(opts, "mux", 0)) {
+
+ if (qemu_opt_get_bool(opts, "mux", 0)) {
+ assert(permit_mux_mon);
monitor_init(chr, MONITOR_USE_READLINE);
}
+
+out:
qemu_opts_del(opts);
return chr;
}
-Chardev *qemu_chr_new(const char *label, const char *filename)
+static Chardev *qemu_chr_new_permit_mux_mon(const char *label,
+ const char *filename,
+ bool permit_mux_mon)
{
Chardev *chr;
- chr = qemu_chr_new_noreplay(label, filename);
+ chr = qemu_chr_new_noreplay(label, filename, permit_mux_mon);
if (chr) {
if (replay_mode != REPLAY_MODE_NONE) {
qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_REPLAY);
@@ -726,6 +739,16 @@ Chardev *qemu_chr_new(const char *label, const char *filename)
return chr;
}
+Chardev *qemu_chr_new(const char *label, const char *filename)
+{
+ return qemu_chr_new_permit_mux_mon(label, filename, false);
+}
+
+Chardev *qemu_chr_new_mux_mon(const char *label, const char *filename)
+{
+ return qemu_chr_new_permit_mux_mon(label, filename, true);
+}
+
static int qmp_query_chardev_foreach(Object *obj, void *data)
{
Chardev *chr = CHARDEV(obj);
diff --git a/gdbstub.c b/gdbstub.c
index d6ab95006c..c8478de8f5 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2038,7 +2038,11 @@ int gdbserver_start(const char *device)
sigaction(SIGINT, &act, NULL);
}
#endif
- chr = qemu_chr_new_noreplay("gdb", device);
+ /*
+ * FIXME: it's a bit weird to allow using a mux chardev here
+ * and implicitly setup a monitor. We may want to break this.
+ */
+ chr = qemu_chr_new_noreplay("gdb", device, true);
if (!chr)
return -1;
}
diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c
index 8b4b4bf523..44f7236382 100644
--- a/hw/char/xen_console.c
+++ b/hw/char/xen_console.c
@@ -207,7 +207,11 @@ static int con_init(struct XenDevice *xendev)
} else {
snprintf(label, sizeof(label), "xencons%d", con->xendev.dev);
qemu_chr_fe_init(&con->chr,
- qemu_chr_new(label, output), &error_abort);
+ /*
+ * FIXME: sure we want to support implicit
+ * muxed monitors here?
+ */
+ qemu_chr_new_mux_mon(label, output), &error_abort);
}
xenstore_store_pv_console_info(con->xendev.dev,
diff --git a/include/block/nbd.h b/include/block/nbd.h
index 4638c839f5..6a5bfe5d55 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -135,7 +135,9 @@ typedef struct NBDExtent {
#define NBD_FLAG_SEND_TRIM (1 << 5) /* Send TRIM (discard) */
#define NBD_FLAG_SEND_WRITE_ZEROES (1 << 6) /* Send WRITE_ZEROES */
#define NBD_FLAG_SEND_DF (1 << 7) /* Send DF (Do not Fragment) */
-#define NBD_FLAG_SEND_CACHE (1 << 8) /* Send CACHE (prefetch) */
+#define NBD_FLAG_CAN_MULTI_CONN (1 << 8) /* Multi-client cache consistent */
+#define NBD_FLAG_SEND_RESIZE (1 << 9) /* Send resize */
+#define NBD_FLAG_SEND_CACHE (1 << 10) /* Send CACHE (prefetch) */
/* New-style handshake (global) flags, sent from server to client, and
control what will happen during handshake phase. */
@@ -308,8 +310,7 @@ void nbd_export_set_name(NBDExport *exp, const char *name);
void nbd_export_set_description(NBDExport *exp, const char *description);
void nbd_export_close_all(void);
-void nbd_client_new(NBDExport *exp,
- QIOChannelSocket *sioc,
+void nbd_client_new(QIOChannelSocket *sioc,
QCryptoTLSCreds *tlscreds,
const char *tlsaclname,
void (*close_fn)(NBDClient *, bool));
diff --git a/include/chardev/char-fe.h b/include/chardev/char-fe.h
index c67271f1ba..46c997d352 100644
--- a/include/chardev/char-fe.h
+++ b/include/chardev/char-fe.h
@@ -20,7 +20,7 @@ struct CharBackend {
};
/**
- * @qemu_chr_fe_init:
+ * qemu_chr_fe_init:
*
* Initializes a front end for the given CharBackend and
* Chardev. Call qemu_chr_fe_deinit() to remove the association and
@@ -31,7 +31,7 @@ struct CharBackend {
bool qemu_chr_fe_init(CharBackend *b, Chardev *s, Error **errp);
/**
- * @qemu_chr_fe_deinit:
+ * qemu_chr_fe_deinit:
* @b: a CharBackend
* @del: if true, delete the chardev backend
*
@@ -42,9 +42,9 @@ bool qemu_chr_fe_init(CharBackend *b, Chardev *s, Error **errp);
void qemu_chr_fe_deinit(CharBackend *b, bool del);
/**
- * @qemu_chr_fe_get_driver:
+ * qemu_chr_fe_get_driver:
*
- * Returns the driver associated with a CharBackend or NULL if no
+ * Returns: the driver associated with a CharBackend or NULL if no
* associated Chardev.
* Note: avoid this function as the driver should never be accessed directly,
* especially by the frontends that support chardevice hotswap.
@@ -53,21 +53,21 @@ void qemu_chr_fe_deinit(CharBackend *b, bool del);
Chardev *qemu_chr_fe_get_driver(CharBackend *be);
/**
- * @qemu_chr_fe_backend_connected:
+ * qemu_chr_fe_backend_connected:
*
- * Returns true if there is a chardevice associated with @be.
+ * Returns: true if there is a chardevice associated with @be.
*/
bool qemu_chr_fe_backend_connected(CharBackend *be);
/**
- * @qemu_chr_fe_backend_open:
+ * qemu_chr_fe_backend_open:
*
- * Returns true if chardevice associated with @be is 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
* @fd_can_read: callback to get the amount of data the frontend may
* receive
@@ -95,7 +95,7 @@ void qemu_chr_fe_set_handlers(CharBackend *b,
bool set_open);
/**
- * @qemu_chr_fe_take_focus:
+ * qemu_chr_fe_take_focus:
*
* Take the focus (if the front end is muxed).
*
@@ -104,14 +104,14 @@ void qemu_chr_fe_set_handlers(CharBackend *b,
void qemu_chr_fe_take_focus(CharBackend *b);
/**
- * @qemu_chr_fe_accept_input:
+ * qemu_chr_fe_accept_input:
*
* Notify that the frontend is ready to receive data
*/
void qemu_chr_fe_accept_input(CharBackend *be);
/**
- * @qemu_chr_fe_disconnect:
+ * qemu_chr_fe_disconnect:
*
* Close a fd accepted by character backend.
* Without associated Chardev, do nothing.
@@ -119,7 +119,7 @@ void qemu_chr_fe_accept_input(CharBackend *be);
void qemu_chr_fe_disconnect(CharBackend *be);
/**
- * @qemu_chr_fe_wait_connected:
+ * qemu_chr_fe_wait_connected:
*
* Wait for characted backend to be connected, return < 0 on error or
* if no associated Chardev.
@@ -127,19 +127,18 @@ void qemu_chr_fe_disconnect(CharBackend *be);
int qemu_chr_fe_wait_connected(CharBackend *be, Error **errp);
/**
- * @qemu_chr_fe_set_echo:
+ * qemu_chr_fe_set_echo:
+ * @echo: true to enable echo, false to disable echo
*
* Ask the backend to override its normal echo setting. This only really
* applies to the stdio backend and is used by the QMP server such that you
* can see what you type if you try to type QMP commands.
* Without associated Chardev, do nothing.
- *
- * @echo true to enable echo, false to disable echo
*/
void qemu_chr_fe_set_echo(CharBackend *be, bool echo);
/**
- * @qemu_chr_fe_set_open:
+ * qemu_chr_fe_set_open:
*
* Set character frontend open status. This is an indication that the
* front end is ready (or not) to begin doing I/O.
@@ -148,83 +147,77 @@ void qemu_chr_fe_set_echo(CharBackend *be, bool echo);
void qemu_chr_fe_set_open(CharBackend *be, int fe_open);
/**
- * @qemu_chr_fe_printf:
+ * qemu_chr_fe_printf:
+ * @fmt: see #printf
*
* Write to a character backend using a printf style interface. This
* function is thread-safe. It does nothing without associated
* Chardev.
- *
- * @fmt see #printf
*/
void qemu_chr_fe_printf(CharBackend *be, const char *fmt, ...)
GCC_FMT_ATTR(2, 3);
/**
- * @qemu_chr_fe_add_watch:
+ * qemu_chr_fe_add_watch:
+ * @cond: the condition to poll for
+ * @func: the function to call when the condition happens
+ * @user_data: the opaque pointer to pass to @func
*
* If the backend is connected, create and add a #GSource that fires
* when the given condition (typically G_IO_OUT|G_IO_HUP or G_IO_HUP)
* is active; return the #GSource's tag. If it is disconnected,
* or without associated Chardev, return 0.
*
- * @cond the condition to poll for
- * @func the function to call when the condition happens
- * @user_data the opaque pointer to pass to @func
- *
* Returns: the source tag
*/
guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond,
GIOFunc func, void *user_data);
/**
- * @qemu_chr_fe_write:
+ * qemu_chr_fe_write:
+ * @buf: the data
+ * @len: the number of bytes to send
*
* Write data to a character backend from the front end. This function
* will send data from the front end to the back end. This function
* is thread-safe.
*
- * @buf the data
- * @len the number of bytes to send
- *
* Returns: the number of bytes consumed (0 if no associated Chardev)
*/
int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len);
/**
- * @qemu_chr_fe_write_all:
+ * qemu_chr_fe_write_all:
+ * @buf: the data
+ * @len: the number of bytes to send
*
* Write data to a character backend from the front end. This function will
* send data from the front end to the back end. Unlike @qemu_chr_fe_write,
* this function will block if the back end cannot consume all of the data
* attempted to be written. This function is thread-safe.
*
- * @buf the data
- * @len the number of bytes to send
- *
* Returns: the number of bytes consumed (0 if no associated Chardev)
*/
int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len);
/**
- * @qemu_chr_fe_read_all:
+ * qemu_chr_fe_read_all:
+ * @buf: the data buffer
+ * @len: the number of bytes to read
*
* Read data to a buffer from the back end.
*
- * @buf the data buffer
- * @len the number of bytes to read
- *
* Returns: the number of bytes read (0 if no associated Chardev)
*/
int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len);
/**
- * @qemu_chr_fe_ioctl:
+ * qemu_chr_fe_ioctl:
+ * @cmd: see CHR_IOCTL_*
+ * @arg: the data associated with @cmd
*
* Issue a device specific ioctl to a backend. This function is thread-safe.
*
- * @cmd see CHR_IOCTL_*
- * @arg the data associated with @cmd
- *
* Returns: if @cmd is not supported by the backend or there is no
* associated Chardev, -ENOTSUP, otherwise the return
* value depends on the semantics of @cmd
@@ -232,7 +225,7 @@ int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len);
int qemu_chr_fe_ioctl(CharBackend *be, int cmd, void *arg);
/**
- * @qemu_chr_fe_get_msgfd:
+ * qemu_chr_fe_get_msgfd:
*
* For backends capable of fd passing, return the latest file descriptor passed
* by a client.
@@ -245,7 +238,7 @@ int qemu_chr_fe_ioctl(CharBackend *be, int cmd, void *arg);
int qemu_chr_fe_get_msgfd(CharBackend *be);
/**
- * @qemu_chr_fe_get_msgfds:
+ * qemu_chr_fe_get_msgfds:
*
* For backends capable of fd passing, return the number of file received
* descriptors and fills the fds array up to num elements
@@ -258,7 +251,7 @@ int qemu_chr_fe_get_msgfd(CharBackend *be);
int qemu_chr_fe_get_msgfds(CharBackend *be, int *fds, int num);
/**
- * @qemu_chr_fe_set_msgfds:
+ * qemu_chr_fe_set_msgfds:
*
* For backends capable of fd passing, set an array of fds to be passed with
* the next send operation.
diff --git a/include/chardev/char.h b/include/chardev/char.h
index 6f0576e214..7becd8c80c 100644
--- a/include/chardev/char.h
+++ b/include/chardev/char.h
@@ -68,12 +68,11 @@ struct Chardev {
};
/**
- * @qemu_chr_new_from_opts:
+ * qemu_chr_new_from_opts:
+ * @opts: see qemu-config.c for a list of valid options
*
* Create a new character backend from a QemuOpts list.
*
- * @opts see qemu-config.c for a list of valid options
- *
* Returns: on success: a new character backend
* otherwise: NULL; @errp specifies the error
* or left untouched in case of help option
@@ -82,17 +81,16 @@ Chardev *qemu_chr_new_from_opts(QemuOpts *opts,
Error **errp);
/**
- * @qemu_chr_parse_common:
+ * qemu_chr_parse_common:
+ * @opts: the options that still need parsing
+ * @backend: a new backend
*
* Parse the common options available to all character backends.
- *
- * @opts the options that still need parsing
- * @backend a new backend
*/
void qemu_chr_parse_common(QemuOpts *opts, ChardevCommon *backend);
/**
- * @qemu_chr_parse_opts:
+ * qemu_chr_parse_opts:
*
* Parse the options to the ChardevBackend struct.
*
@@ -102,49 +100,61 @@ ChardevBackend *qemu_chr_parse_opts(QemuOpts *opts,
Error **errp);
/**
- * @qemu_chr_new:
+ * qemu_chr_new:
+ * @label: the name of the backend
+ * @filename: the URI
*
* Create a new character backend from a URI.
- *
- * @label the name of the backend
- * @filename the URI
+ * Do not implicitly initialize a monitor if the chardev is muxed.
*
* Returns: a new character backend
*/
Chardev *qemu_chr_new(const char *label, const char *filename);
/**
- * @qemu_chr_change:
+ * qemu_chr_new_mux_mon:
+ * @label: the name of the backend
+ * @filename: the URI
*
- * Change an existing character backend
+ * Create a new character backend from a URI.
+ * Implicitly initialize a monitor if the chardev is muxed.
+ *
+ * Returns: a new character backend
+ */
+Chardev *qemu_chr_new_mux_mon(const char *label, const char *filename);
+
+/**
+* qemu_chr_change:
+* @opts: the new backend options
*
- * @opts the new backend options
+ * Change an existing character backend
*/
void qemu_chr_change(QemuOpts *opts, Error **errp);
/**
- * @qemu_chr_cleanup:
+ * qemu_chr_cleanup:
*
* Delete all chardevs (when leaving qemu)
*/
void qemu_chr_cleanup(void);
/**
- * @qemu_chr_new_noreplay:
+ * qemu_chr_new_noreplay:
+ * @label: the name of the backend
+ * @filename: the URI
+ * @permit_mux_mon: if chardev is muxed, initialize a monitor
*
* Create a new character backend from a URI.
* Character device communications are not written
* into the replay log.
*
- * @label the name of the backend
- * @filename the URI
- *
* Returns: a new character backend
*/
-Chardev *qemu_chr_new_noreplay(const char *label, const char *filename);
+Chardev *qemu_chr_new_noreplay(const char *label, const char *filename,
+ bool permit_mux_mon);
/**
- * @qemu_chr_be_can_write:
+ * qemu_chr_be_can_write:
*
* Determine how much data the front end can currently accept. This function
* returns the number of bytes the front end can accept. If it returns 0, the
@@ -156,43 +166,39 @@ Chardev *qemu_chr_new_noreplay(const char *label, const char *filename);
int qemu_chr_be_can_write(Chardev *s);
/**
- * @qemu_chr_be_write:
+ * qemu_chr_be_write:
+ * @buf: a buffer to receive data from the front end
+ * @len: the number of bytes to receive from the front end
*
* Write data from the back end to the front end. Before issuing this call,
* the caller should call @qemu_chr_be_can_write to determine how much data
* the front end can currently accept.
- *
- * @buf a buffer to receive data from the front end
- * @len the number of bytes to receive from the front end
*/
void qemu_chr_be_write(Chardev *s, uint8_t *buf, int len);
/**
- * @qemu_chr_be_write_impl:
+ * qemu_chr_be_write_impl:
+ * @buf: a buffer to receive data from the front end
+ * @len: the number of bytes to receive from the front end
*
* Implementation of back end writing. Used by replay module.
- *
- * @buf a buffer to receive data from the front end
- * @len the number of bytes to receive from the front end
*/
void qemu_chr_be_write_impl(Chardev *s, uint8_t *buf, int len);
/**
- * @qemu_chr_be_update_read_handlers:
+ * qemu_chr_be_update_read_handlers:
+ * @context: the gcontext that will be used to attach the watch sources
*
* Invoked when frontend read handlers are setup
- *
- * @context the gcontext that will be used to attach the watch sources
*/
void qemu_chr_be_update_read_handlers(Chardev *s,
GMainContext *context);
/**
- * @qemu_chr_be_event:
+ * qemu_chr_be_event:
+ * @event: the event to send
*
* Send an event from the back end to the front end.
- *
- * @event the event to send
*/
void qemu_chr_be_event(Chardev *s, int event);
@@ -203,7 +209,8 @@ bool qemu_chr_has_feature(Chardev *chr,
ChardevFeature feature);
void qemu_chr_set_feature(Chardev *chr,
ChardevFeature feature);
-QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
+QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename,
+ bool permit_mux_mon);
int qemu_chr_write(Chardev *s, const uint8_t *buf, int len, bool write_all);
#define qemu_chr_write_all(s, buf, len) qemu_chr_write(s, buf, len, true)
int qemu_chr_wait_connected(Chardev *chr, Error **errp);
diff --git a/nbd/client.c b/nbd/client.c
index 40b74d9761..b4d457a19a 100644
--- a/nbd/client.c
+++ b/nbd/client.c
@@ -117,10 +117,10 @@ static int nbd_receive_option_reply(QIOChannel *ioc, uint32_t opt,
nbd_send_opt_abort(ioc);
return -1;
}
- be64_to_cpus(&reply->magic);
- be32_to_cpus(&reply->option);
- be32_to_cpus(&reply->type);
- be32_to_cpus(&reply->length);
+ reply->magic = be64_to_cpu(reply->magic);
+ reply->option = be32_to_cpu(reply->option);
+ reply->type = be32_to_cpu(reply->type);
+ reply->length = be32_to_cpu(reply->length);
trace_nbd_receive_option_reply(reply->option, nbd_opt_lookup(reply->option),
reply->type, nbd_rep_lookup(reply->type),
@@ -396,7 +396,7 @@ static int nbd_opt_go(QIOChannel *ioc, const char *wantname,
return -1;
}
len -= sizeof(type);
- be16_to_cpus(&type);
+ type = be16_to_cpu(type);
switch (type) {
case NBD_INFO_EXPORT:
if (len != sizeof(info->size) + sizeof(info->flags)) {
@@ -410,13 +410,13 @@ static int nbd_opt_go(QIOChannel *ioc, const char *wantname,
nbd_send_opt_abort(ioc);
return -1;
}
- be64_to_cpus(&info->size);
+ info->size = be64_to_cpu(info->size);
if (nbd_read(ioc, &info->flags, sizeof(info->flags), errp) < 0) {
error_prepend(errp, "failed to read info flags: ");
nbd_send_opt_abort(ioc);
return -1;
}
- be16_to_cpus(&info->flags);
+ info->flags = be16_to_cpu(info->flags);
trace_nbd_receive_negotiate_size_flags(info->size, info->flags);
break;
@@ -433,7 +433,7 @@ static int nbd_opt_go(QIOChannel *ioc, const char *wantname,
nbd_send_opt_abort(ioc);
return -1;
}
- be32_to_cpus(&info->min_block);
+ info->min_block = be32_to_cpu(info->min_block);
if (!is_power_of_2(info->min_block)) {
error_setg(errp, "server minimum block size %" PRIu32
" is not a power of two", info->min_block);
@@ -447,7 +447,7 @@ static int nbd_opt_go(QIOChannel *ioc, const char *wantname,
nbd_send_opt_abort(ioc);
return -1;
}
- be32_to_cpus(&info->opt_block);
+ info->opt_block = be32_to_cpu(info->opt_block);
if (!is_power_of_2(info->opt_block) ||
info->opt_block < info->min_block) {
error_setg(errp, "server preferred block size %" PRIu32
@@ -461,7 +461,7 @@ static int nbd_opt_go(QIOChannel *ioc, const char *wantname,
nbd_send_opt_abort(ioc);
return -1;
}
- be32_to_cpus(&info->max_block);
+ info->max_block = be32_to_cpu(info->max_block);
if (info->max_block < info->min_block) {
error_setg(errp, "server maximum block size %" PRIu32
" is not valid", info->max_block);
@@ -668,7 +668,7 @@ static int nbd_negotiate_simple_meta_context(QIOChannel *ioc,
if (nbd_read(ioc, &received_id, sizeof(received_id), errp) < 0) {
return -1;
}
- be32_to_cpus(&received_id);
+ received_id = be32_to_cpu(received_id);
reply.length -= sizeof(received_id);
name = g_malloc(reply.length + 1);
@@ -872,13 +872,13 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name,
error_prepend(errp, "Failed to read export length: ");
goto fail;
}
- be64_to_cpus(&info->size);
+ info->size = be64_to_cpu(info->size);
if (nbd_read(ioc, &info->flags, sizeof(info->flags), errp) < 0) {
error_prepend(errp, "Failed to read export flags: ");
goto fail;
}
- be16_to_cpus(&info->flags);
+ info->flags = be16_to_cpu(info->flags);
} else if (magic == NBD_CLIENT_MAGIC) {
uint32_t oldflags;
@@ -895,13 +895,13 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name,
error_prepend(errp, "Failed to read export length: ");
goto fail;
}
- be64_to_cpus(&info->size);
+ info->size = be64_to_cpu(info->size);
if (nbd_read(ioc, &oldflags, sizeof(oldflags), errp) < 0) {
error_prepend(errp, "Failed to read export flags: ");
goto fail;
}
- be32_to_cpus(&oldflags);
+ oldflags = be32_to_cpu(oldflags);
if (oldflags & ~0xffff) {
error_setg(errp, "Unexpected export flags %0x" PRIx32, oldflags);
goto fail;
@@ -1080,8 +1080,8 @@ static int nbd_receive_simple_reply(QIOChannel *ioc, NBDSimpleReply *reply,
return ret;
}
- be32_to_cpus(&reply->error);
- be64_to_cpus(&reply->handle);
+ reply->error = be32_to_cpu(reply->error);
+ reply->handle = be64_to_cpu(reply->handle);
return 0;
}
@@ -1105,10 +1105,10 @@ static int nbd_receive_structured_reply_chunk(QIOChannel *ioc,
return ret;
}
- be16_to_cpus(&chunk->flags);
- be16_to_cpus(&chunk->type);
- be64_to_cpus(&chunk->handle);
- be32_to_cpus(&chunk->length);
+ chunk->flags = be16_to_cpu(chunk->flags);
+ chunk->type = be16_to_cpu(chunk->type);
+ chunk->handle = be64_to_cpu(chunk->handle);
+ chunk->length = be32_to_cpu(chunk->length);
return 0;
}
@@ -1128,7 +1128,7 @@ int nbd_receive_reply(QIOChannel *ioc, NBDReply *reply, Error **errp)
return ret;
}
- be32_to_cpus(&reply->magic);
+ reply->magic = be32_to_cpu(reply->magic);
switch (reply->magic) {
case NBD_SIMPLE_REPLY_MAGIC:
diff --git a/nbd/server.c b/nbd/server.c
index c3dd402b45..a1eda0114f 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -333,7 +333,7 @@ static int nbd_opt_read_name(NBDClient *client, char *name, uint32_t *length,
if (ret <= 0) {
return ret;
}
- cpu_to_be32s(&len);
+ len = cpu_to_be32(len);
if (len > NBD_MAX_NAME_SIZE) {
return nbd_opt_invalid(client, errp,
@@ -486,7 +486,7 @@ static int nbd_negotiate_send_info(NBDClient *client,
if (rc < 0) {
return rc;
}
- cpu_to_be16s(&info);
+ info = cpu_to_be16(info);
if (nbd_write(client->ioc, &info, sizeof(info), errp) < 0) {
return -EIO;
}
@@ -551,14 +551,14 @@ static int nbd_negotiate_handle_info(NBDClient *client, uint16_t myflags,
if (rc <= 0) {
return rc;
}
- be16_to_cpus(&requests);
+ requests = be16_to_cpu(requests);
trace_nbd_negotiate_handle_info_requests(requests);
while (requests--) {
rc = nbd_opt_read(client, &request, sizeof(request), errp);
if (rc <= 0) {
return rc;
}
- be16_to_cpus(&request);
+ request = be16_to_cpu(request);
trace_nbd_negotiate_handle_info_request(request,
nbd_info_lookup(request));
/* We care about NBD_INFO_NAME and NBD_INFO_BLOCK_SIZE;
@@ -618,9 +618,9 @@ static int nbd_negotiate_handle_info(NBDClient *client, uint16_t myflags,
/* maximum - At most 32M, but smaller as appropriate. */
sizes[2] = MIN(blk_get_max_transfer(exp->blk), NBD_MAX_BUFFER_SIZE);
trace_nbd_negotiate_handle_info_block_size(sizes[0], sizes[1], sizes[2]);
- cpu_to_be32s(&sizes[0]);
- cpu_to_be32s(&sizes[1]);
- cpu_to_be32s(&sizes[2]);
+ sizes[0] = cpu_to_be32(sizes[0]);
+ sizes[1] = cpu_to_be32(sizes[1]);
+ sizes[2] = cpu_to_be32(sizes[2]);
rc = nbd_negotiate_send_info(client, NBD_INFO_BLOCK_SIZE,
sizeof(sizes), sizes, errp);
if (rc < 0) {
@@ -904,7 +904,7 @@ static int nbd_negotiate_meta_query(NBDClient *client,
if (ret <= 0) {
return ret;
}
- cpu_to_be32s(&len);
+ len = cpu_to_be32(len);
if (len < ns_len) {
trace_nbd_negotiate_meta_query_skip("length too short");
@@ -971,7 +971,7 @@ static int nbd_negotiate_meta_queries(NBDClient *client,
if (ret <= 0) {
return ret;
}
- cpu_to_be32s(&nb_queries);
+ nb_queries = cpu_to_be32(nb_queries);
trace_nbd_negotiate_meta_context(nbd_opt_lookup(client->opt),
export_name, nb_queries);
@@ -1049,7 +1049,7 @@ static int nbd_negotiate_options(NBDClient *client, uint16_t myflags,
error_prepend(errp, "read failed: ");
return -EIO;
}
- be32_to_cpus(&flags);
+ flags = be32_to_cpu(flags);
trace_nbd_negotiate_options_flags(flags);
if (flags & NBD_FLAG_C_FIXED_NEWSTYLE) {
fixedNewstyle = true;
@@ -1253,7 +1253,6 @@ static coroutine_fn int nbd_negotiate(NBDClient *client, Error **errp)
const uint16_t myflags = (NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_TRIM |
NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA |
NBD_FLAG_SEND_WRITE_ZEROES | NBD_FLAG_SEND_CACHE);
- bool oldStyle;
/* Old style negotiation header, no room for options
[ 0 .. 7] passwd ("NBDMAGIC")
@@ -1274,33 +1273,19 @@ static coroutine_fn int nbd_negotiate(NBDClient *client, Error **errp)
trace_nbd_negotiate_begin();
memcpy(buf, "NBDMAGIC", 8);
- oldStyle = client->exp != NULL && !client->tlscreds;
- if (oldStyle) {
- trace_nbd_negotiate_old_style(client->exp->size,
- client->exp->nbdflags | myflags);
- stq_be_p(buf + 8, NBD_CLIENT_MAGIC);
- stq_be_p(buf + 16, client->exp->size);
- stl_be_p(buf + 24, client->exp->nbdflags | myflags);
+ stq_be_p(buf + 8, NBD_OPTS_MAGIC);
+ stw_be_p(buf + 16, NBD_FLAG_FIXED_NEWSTYLE | NBD_FLAG_NO_ZEROES);
- if (nbd_write(client->ioc, buf, sizeof(buf), errp) < 0) {
- error_prepend(errp, "write failed: ");
- return -EINVAL;
- }
- } else {
- stq_be_p(buf + 8, NBD_OPTS_MAGIC);
- stw_be_p(buf + 16, NBD_FLAG_FIXED_NEWSTYLE | NBD_FLAG_NO_ZEROES);
-
- if (nbd_write(client->ioc, buf, 18, errp) < 0) {
- error_prepend(errp, "write failed: ");
- return -EINVAL;
- }
- ret = nbd_negotiate_options(client, myflags, errp);
- if (ret != 0) {
- if (ret < 0) {
- error_prepend(errp, "option negotiation failed: ");
- }
- return ret;
+ if (nbd_write(client->ioc, buf, 18, errp) < 0) {
+ error_prepend(errp, "write failed: ");
+ return -EINVAL;
+ }
+ ret = nbd_negotiate_options(client, myflags, errp);
+ if (ret != 0) {
+ if (ret < 0) {
+ error_prepend(errp, "option negotiation failed: ");
}
+ return ret;
}
assert(!client->optlen);
@@ -1900,8 +1885,8 @@ static int blockstatus_to_extents(BlockDriverState *bs, uint64_t offset,
extents_end = extent + 1;
for (extent = extents; extent < extents_end; extent++) {
- cpu_to_be32s(&extent->flags);
- cpu_to_be32s(&extent->length);
+ extent->flags = cpu_to_be32(extent->flags);
+ extent->length = cpu_to_be32(extent->length);
}
*bytes -= remaining_bytes;
@@ -2177,7 +2162,8 @@ static coroutine_fn int nbd_do_cmd_read(NBDClient *client, NBDRequest *request,
}
if (client->structured_reply && !(request->flags & NBD_CMD_FLAG_DF) &&
- request->len) {
+ request->len && request->type != NBD_CMD_CACHE)
+ {
return nbd_co_send_sparse_read(client, request->handle, request->from,
data, request->len, errp);
}
@@ -2395,13 +2381,8 @@ static void nbd_client_receive_next_request(NBDClient *client)
static coroutine_fn void nbd_co_client_start(void *opaque)
{
NBDClient *client = opaque;
- NBDExport *exp = client->exp;
Error *local_err = NULL;
- if (exp) {
- nbd_export_get(exp);
- QTAILQ_INSERT_TAIL(&exp->clients, client, next);
- }
qemu_co_mutex_init(&client->send_lock);
if (nbd_negotiate(client, &local_err)) {
@@ -2416,13 +2397,11 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
}
/*
- * Create a new client listener on the given export @exp, using the
- * given channel @sioc. Begin servicing it in a coroutine. When the
- * connection closes, call @close_fn with an indication of whether the
- * client completed negotiation.
+ * Create a new client listener using the given channel @sioc.
+ * Begin servicing it in a coroutine. When the connection closes, call
+ * @close_fn with an indication of whether the client completed negotiation.
*/
-void nbd_client_new(NBDExport *exp,
- QIOChannelSocket *sioc,
+void nbd_client_new(QIOChannelSocket *sioc,
QCryptoTLSCreds *tlscreds,
const char *tlsaclname,
void (*close_fn)(NBDClient *, bool))
@@ -2432,7 +2411,6 @@ void nbd_client_new(NBDExport *exp,
client = g_new0(NBDClient, 1);
client->refcount = 1;
- client->exp = exp;
client->tlscreds = tlscreds;
if (tlscreds) {
object_ref(OBJECT(client->tlscreds));
diff --git a/net/slirp.c b/net/slirp.c
index c93b64dd91..99884de204 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -764,7 +764,11 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp)
}
} else {
Error *err = NULL;
- Chardev *chr = qemu_chr_new(buf, p);
+ /*
+ * FIXME: sure we want to support implicit
+ * muxed monitors here?
+ */
+ Chardev *chr = qemu_chr_new_mux_mon(buf, p);
if (!chr) {
error_setg(errp, "Could not open guest forwarding device '%s'",
diff --git a/qemu-nbd.c b/qemu-nbd.c
index 51b9d38c72..e76fe3082a 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -56,7 +56,6 @@
#define MBR_SIZE 512
static NBDExport *exp;
-static bool newproto;
static int verbose;
static char *srcpath;
static SocketAddress *saddr;
@@ -84,8 +83,8 @@ static void usage(const char *name)
" -e, --shared=NUM device can be shared by NUM clients (default '1')\n"
" -t, --persistent don't exit on the last connection\n"
" -v, --verbose display extra debugging information\n"
-" -x, --export-name=NAME expose export by name\n"
-" -D, --description=TEXT with -x, also export a human-readable description\n"
+" -x, --export-name=NAME expose export by name (default is empty string)\n"
+" -D, --description=TEXT export a human-readable description\n"
"\n"
"Exposing part of the image:\n"
" -o, --offset=OFFSET offset into the image\n"
@@ -94,6 +93,7 @@ static void usage(const char *name)
"General purpose options:\n"
" --object type,id=ID,... define an object such as 'secret' for providing\n"
" passwords and/or encryption keys\n"
+" --tls-creds=ID use id of an earlier --object to provide TLS\n"
" -T, --trace [[enable=]<pattern>][,events=<file>][,file=<file>]\n"
" specify tracing options\n"
" --fork fork off the server process and exit the parent\n"
@@ -354,8 +354,7 @@ static void nbd_accept(QIONetListener *listener, QIOChannelSocket *cioc,
nb_fds++;
nbd_update_server_watch();
- nbd_client_new(newproto ? NULL : exp, cioc,
- tlscreds, NULL, nbd_client_closed);
+ nbd_client_new(cioc, tlscreds, NULL, nbd_client_closed);
}
static void nbd_update_server_watch(void)
@@ -549,7 +548,7 @@ int main(int argc, char **argv)
Error *local_err = NULL;
BlockdevDetectZeroesOptions detect_zeroes = BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF;
QDict *options = NULL;
- const char *export_name = NULL;
+ const char *export_name = ""; /* Default export name */
const char *export_description = NULL;
const char *tlscredsid = NULL;
bool imageOpts = false;
@@ -808,11 +807,6 @@ int main(int argc, char **argv)
error_report("TLS is not supported with a host device");
exit(EXIT_FAILURE);
}
- if (!export_name) {
- /* Set the default NBD protocol export name, since
- * we *must* use new style protocol for TLS */
- export_name = "";
- }
tlscreds = nbd_get_tls_creds(tlscredsid, &local_err);
if (local_err) {
error_report("Failed to get TLS creds %s",
@@ -1013,14 +1007,8 @@ int main(int argc, char **argv)
error_report_err(local_err);
exit(EXIT_FAILURE);
}
- if (export_name) {
- nbd_export_set_name(exp, export_name);
- nbd_export_set_description(exp, export_description);
- newproto = true;
- } else if (export_description) {
- error_report("Export description requires an export name");
- exit(EXIT_FAILURE);
- }
+ nbd_export_set_name(exp, export_name);
+ nbd_export_set_description(exp, export_description);
if (device) {
int ret;
diff --git a/scripts/device-crash-test b/scripts/device-crash-test
index 7045594bd4..930200b034 100755
--- a/scripts/device-crash-test
+++ b/scripts/device-crash-test
@@ -35,7 +35,6 @@ import random
import argparse
from itertools import chain
-sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'scripts'))
from qemu import QEMUMachine
logger = logging.getLogger('device-crash-test')
@@ -99,7 +98,6 @@ ERROR_WHITELIST = [
{'device':'isa-ipmi-bt', 'expected':True}, # IPMI device requires a bmc attribute to be set
{'device':'isa-ipmi-kcs', 'expected':True}, # IPMI device requires a bmc attribute to be set
{'device':'isa-parallel', 'expected':True}, # Can't create serial device, empty char device
- {'device':'isa-serial', 'expected':True}, # Can't create serial device, empty char device
{'device':'ivshmem', 'expected':True}, # You must specify either 'shm' or 'chardev'
{'device':'ivshmem-doorbell', 'expected':True}, # You must specify a 'chardev'
{'device':'ivshmem-plain', 'expected':True}, # You must specify a 'memdev'
@@ -110,9 +108,6 @@ ERROR_WHITELIST = [
{'device':'pc-dimm', 'expected':True}, # 'memdev' property is not set
{'device':'pci-bridge', 'expected':True}, # Bridge chassis not specified. Each bridge is required to be assigned a unique chassis id > 0.
{'device':'pci-bridge-seat', 'expected':True}, # Bridge chassis not specified. Each bridge is required to be assigned a unique chassis id > 0.
- {'device':'pci-serial', 'expected':True}, # Can't create serial device, empty char device
- {'device':'pci-serial-2x', 'expected':True}, # Can't create serial device, empty char device
- {'device':'pci-serial-4x', 'expected':True}, # Can't create serial device, empty char device
{'device':'pxa2xx-dma', 'expected':True}, # channels value invalid
{'device':'pxb', 'expected':True}, # Bridge chassis not specified. Each bridge is required to be assigned a unique chassis id > 0.
{'device':'scsi-block', 'expected':True}, # drive property not set
@@ -218,7 +213,6 @@ ERROR_WHITELIST = [
{'exitcode':-6, 'log':r"Object .* is not an instance of type generic-pc-machine", 'loglevel':logging.ERROR},
{'exitcode':-6, 'log':r"Object .* is not an instance of type e500-ccsr", 'loglevel':logging.ERROR},
{'exitcode':-6, 'log':r"vmstate_register_with_alias_id: Assertion `!se->compat \|\| se->instance_id == 0' failed", 'loglevel':logging.ERROR},
- {'exitcode':-11, 'device':'isa-serial', 'loglevel':logging.ERROR, 'expected':True},
# everything else (including SIGABRT and SIGSEGV) will be a fatal error:
{'exitcode':None, 'fatal':True, 'loglevel':logging.FATAL},
diff --git a/tests/docker/docker.py b/tests/docker/docker.py
index d3006d4dae..44d5f7493b 100755
--- a/tests/docker/docker.py
+++ b/tests/docker/docker.py
@@ -14,14 +14,12 @@
from __future__ import print_function
import os
import sys
-sys.path.append(os.path.join(os.path.dirname(__file__),
- '..', '..', 'scripts'))
-import argparse
import subprocess
import json
import hashlib
import atexit
import uuid
+import argparse
import tempfile
import re
import signal
diff --git a/tests/migration/guestperf/shell.py b/tests/migration/guestperf/shell.py
index a6b8cec1e0..61d2abbaad 100644
--- a/tests/migration/guestperf/shell.py
+++ b/tests/migration/guestperf/shell.py
@@ -19,14 +19,12 @@ from __future__ import print_function
#
-import os
-import os.path
-import sys
-sys.path.append(os.path.join(os.path.dirname(__file__),
- '..', '..', '..', 'scripts'))
import argparse
import fnmatch
+import os
+import os.path
import platform
+import sys
import logging
from guestperf.hardware import Hardware
diff --git a/vl.c b/vl.c
index 0388852deb..a867c9c4d9 100644
--- a/vl.c
+++ b/vl.c
@@ -2310,7 +2310,7 @@ static void monitor_parse(const char *optarg, const char *mode, bool pretty)
} else {
snprintf(label, sizeof(label), "compat_monitor%d",
monitor_device_index);
- opts = qemu_chr_parse_compat(label, optarg);
+ opts = qemu_chr_parse_compat(label, optarg, true);
if (!opts) {
error_report("parse error: %s", optarg);
exit(1);
@@ -2382,7 +2382,7 @@ static int serial_parse(const char *devname)
snprintf(label, sizeof(label), "serial%d", index);
serial_hds = g_renew(Chardev *, serial_hds, index + 1);
- serial_hds[index] = qemu_chr_new(label, devname);
+ serial_hds[index] = qemu_chr_new_mux_mon(label, devname);
if (!serial_hds[index]) {
error_report("could not connect serial device"
" to character backend '%s'", devname);
@@ -2418,7 +2418,7 @@ static int parallel_parse(const char *devname)
exit(1);
}
snprintf(label, sizeof(label), "parallel%d", index);
- parallel_hds[index] = qemu_chr_new(label, devname);
+ parallel_hds[index] = qemu_chr_new_mux_mon(label, devname);
if (!parallel_hds[index]) {
error_report("could not connect parallel device"
" to character backend '%s'", devname);
@@ -2449,7 +2449,7 @@ static int virtcon_parse(const char *devname)
qemu_opt_set(dev_opts, "driver", "virtconsole", &error_abort);
snprintf(label, sizeof(label), "virtcon%d", index);
- virtcon_hds[index] = qemu_chr_new(label, devname);
+ virtcon_hds[index] = qemu_chr_new_mux_mon(label, devname);
if (!virtcon_hds[index]) {
error_report("could not connect virtio console"
" to character backend '%s'", devname);
@@ -2465,7 +2465,7 @@ static int debugcon_parse(const char *devname)
{
QemuOpts *opts;
- if (!qemu_chr_new("debugcon", devname)) {
+ if (!qemu_chr_new_mux_mon("debugcon", devname)) {
exit(1);
}
opts = qemu_opts_create(qemu_find_opts("device"), "debugcon", 1, NULL);