@@ -52,14 +52,15 @@ static AioHandler *find_aio_handler(int fd)
return NULL;
}
-int qemu_aio_set_fd_handler(int fd,
+static int qemu_aio_assign_fd_handler(int fd,
IOHandler *io_read,
IOHandler *io_write,
AioFlushHandler *io_flush,
AioProcessQueue *io_process_queue,
- void *opaque)
+ void *opaque, bool system)
{
AioHandler *node;
+ int r;
node = find_aio_handler(fd);
@@ -93,11 +94,34 @@ int qemu_aio_set_fd_handler(int fd,
node->opaque = opaque;
}
- qemu_set_fd_handler2(fd, NULL, io_read, io_write, opaque);
-
+ r = system ? qemu_set_fd_handler2(fd, NULL, io_read, io_write, opaque) :
+ qemu_set_system_fd_handler(fd, NULL, io_read, io_write, opaque);
+ assert(!r);
return 0;
}
+int qemu_aio_set_fd_handler(int fd,
+ IOHandler *io_read,
+ IOHandler *io_write,
+ AioFlushHandler *io_flush,
+ AioProcessQueue *io_process_queue,
+ void *opaque)
+{
+ return qemu_aio_assign_fd_handler(fd, io_read, io_write, io_flush,
+ io_process_queue, opaque, false);
+}
+
+int qemu_aio_set_system_fd_handler(int fd,
+ IOHandler *io_read,
+ IOHandler *io_write,
+ AioFlushHandler *io_flush,
+ AioProcessQueue *io_process_queue,
+ void *opaque)
+{
+ return qemu_aio_assign_fd_handler(fd, io_read, io_write, io_flush,
+ io_process_queue, opaque, true);
+}
+
void qemu_aio_flush(void)
{
AioHandler *node;
@@ -154,7 +154,7 @@ static void prep_fetchline(void *opaque)
{
int *fetchable = opaque;
- qemu_aio_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL, NULL, NULL);
+ qemu_aio_set_system_fd_handler(STDIN_FILENO, NULL, NULL, NULL, NULL, NULL);
*fetchable= 1;
}
@@ -202,8 +202,8 @@ command_loop(void)
if (!prompted) {
printf("%s", get_prompt());
fflush(stdout);
- qemu_aio_set_fd_handler(STDIN_FILENO, prep_fetchline, NULL, NULL,
- NULL, &fetchable);
+ qemu_aio_set_system_fd_handler(STDIN_FILENO, prep_fetchline,
+ NULL, NULL, NULL, &fetchable);
prompted = 1;
}
@@ -228,7 +228,7 @@ command_loop(void)
prompted = 0;
fetchable = 0;
}
- qemu_aio_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL, NULL, NULL);
+ qemu_aio_set_system_fd_handler(STDIN_FILENO, NULL, NULL, NULL, NULL, NULL);
}
/* from libxcmd/input.c */
@@ -2653,7 +2653,7 @@ int gdbserver_start(const char *device)
sigaction(SIGINT, &act, NULL);
}
#endif
- chr = qemu_chr_open("gdb", device, NULL);
+ chr = qemu_chr_open_system("gdb", device, NULL);
if (!chr)
return -1;
@@ -123,7 +123,7 @@ static void exec_accept_incoming_migration(void *opaque)
QEMUFile *f = opaque;
process_incoming_migration(f);
- qemu_set_fd_handler2(qemu_stdio_fd(f), NULL, NULL, NULL, NULL);
+ qemu_set_system_fd_handler(qemu_stdio_fd(f), NULL, NULL, NULL, NULL);
qemu_fclose(f);
}
@@ -138,7 +138,7 @@ int exec_start_incoming_migration(const char *command)
return -errno;
}
- qemu_set_fd_handler2(qemu_stdio_fd(f), NULL,
+ qemu_set_system_fd_handler(qemu_stdio_fd(f), NULL,
exec_accept_incoming_migration, NULL, f);
return 0;
@@ -106,7 +106,7 @@ static void fd_accept_incoming_migration(void *opaque)
QEMUFile *f = opaque;
process_incoming_migration(f);
- qemu_set_fd_handler2(qemu_stdio_fd(f), NULL, NULL, NULL, NULL);
+ qemu_set_system_fd_handler(qemu_stdio_fd(f), NULL, NULL, NULL, NULL);
qemu_fclose(f);
}
@@ -124,7 +124,7 @@ int fd_start_incoming_migration(const char *infd)
return -errno;
}
- qemu_set_fd_handler2(fd, NULL, fd_accept_incoming_migration, NULL, f);
+ qemu_set_system_fd_handler(fd, NULL, fd_accept_incoming_migration, NULL, f);
return 0;
}
@@ -66,7 +66,7 @@ static void tcp_wait_for_connect(void *opaque)
return;
}
- qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
+ qemu_set_system_fd_handler(s->fd, NULL, NULL, NULL, NULL);
if (val == 0)
migrate_fd_connect(s);
@@ -123,7 +123,7 @@ MigrationState *tcp_start_outgoing_migration(Monitor *mon,
ret = -(s->get_error(s));
if (ret == -EINPROGRESS || ret == -EWOULDBLOCK)
- qemu_set_fd_handler2(s->fd, NULL, NULL, tcp_wait_for_connect, s);
+ qemu_set_system_fd_handler(s->fd, NULL, NULL, tcp_wait_for_connect, s);
} while (ret == -EINTR);
if (ret < 0 && ret != -EINPROGRESS && ret != -EWOULDBLOCK) {
@@ -165,7 +165,7 @@ static void tcp_accept_incoming_migration(void *opaque)
out:
close(c);
out2:
- qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL);
+ qemu_set_system_fd_handler(s, NULL, NULL, NULL, NULL);
close(s);
}
@@ -193,7 +193,7 @@ int tcp_start_incoming_migration(const char *host_port)
if (listen(s, 1) == -1)
goto err;
- qemu_set_fd_handler2(s, NULL, tcp_accept_incoming_migration, NULL,
+ qemu_set_system_fd_handler(s, NULL, tcp_accept_incoming_migration, NULL,
(void *)(unsigned long)s);
return 0;
@@ -65,7 +65,7 @@ static void unix_wait_for_connect(void *opaque)
return;
}
- qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
+ qemu_set_system_fd_handler(s->fd, NULL, NULL, NULL, NULL);
if (val == 0)
migrate_fd_connect(s);
@@ -118,7 +118,7 @@ MigrationState *unix_start_outgoing_migration(Monitor *mon,
ret = -(s->get_error(s));
if (ret == -EINPROGRESS || ret == -EWOULDBLOCK)
- qemu_set_fd_handler2(s->fd, NULL, NULL, unix_wait_for_connect, s);
+ qemu_set_system_fd_handler(s->fd, NULL, NULL, unix_wait_for_connect, s);
} while (ret == -EINTR);
if (ret < 0 && ret != -EINPROGRESS && ret != -EWOULDBLOCK) {
@@ -171,7 +171,7 @@ static void unix_accept_incoming_migration(void *opaque)
process_incoming_migration(f);
qemu_fclose(f);
out:
- qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL);
+ qemu_set_system_fd_handler(s, NULL, NULL, NULL, NULL);
close(s);
close(c);
}
@@ -203,7 +203,7 @@ int unix_start_incoming_migration(const char *path)
goto err;
}
- qemu_set_fd_handler2(sock, NULL, unix_accept_incoming_migration, NULL,
+ qemu_set_system_fd_handler(sock, NULL, unix_accept_incoming_migration, NULL,
(void *)(unsigned long)sock);
return 0;
@@ -273,7 +273,7 @@ int migrate_fd_cleanup(FdMigrationState *s)
{
int ret = 0;
- qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
+ qemu_set_system_fd_handler(s->fd, NULL, NULL, NULL, NULL);
if (s->file) {
DPRINTF("closing file\n");
@@ -300,7 +300,7 @@ void migrate_fd_put_notify(void *opaque)
{
FdMigrationState *s = opaque;
- qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
+ qemu_set_system_fd_handler(s->fd, NULL, NULL, NULL, NULL);
qemu_file_put_notify(s->file);
}
@@ -317,7 +317,7 @@ ssize_t migrate_fd_put_buffer(void *opaque, const void *data, size_t size)
ret = -(s->get_error(s));
if (ret == -EAGAIN) {
- qemu_set_fd_handler2(s->fd, NULL, NULL, migrate_fd_put_notify, s);
+ qemu_set_system_fd_handler(s->fd, NULL, NULL, migrate_fd_put_notify, s);
} else if (ret < 0) {
if (s->mon) {
monitor_resume(s->mon);
@@ -445,6 +445,6 @@ int migrate_fd_close(void *opaque)
{
FdMigrationState *s = opaque;
- qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
+ qemu_set_system_fd_handler(s->fd, NULL, NULL, NULL, NULL);
return s->close(s);
}
@@ -56,4 +56,11 @@ int qemu_aio_set_fd_handler(int fd,
AioProcessQueue *io_process_queue,
void *opaque);
+/* Same but for system handlers, which run when VM is stopped. */
+int qemu_aio_set_system_fd_handler(int fd,
+ IOHandler *io_read,
+ IOHandler *io_write,
+ AioFlushHandler *io_flush,
+ AioProcessQueue *io_process_queue,
+ void *opaque);
#endif
@@ -2500,6 +2500,16 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i
return chr;
}
+CharDriverState *qemu_chr_system_open(const char *label,
+ const char *filename, void (*init)(struct CharDriverState *s))
+{
+ CharDriverState *chr = qemu_chr_open(label, filename, init);
+ if (chr) {
+ chr->system = 1;
+ }
+ return chr;
+}
+
void qemu_chr_close(CharDriverState *chr)
{
QTAILQ_REMOVE(&chardevs, chr, next);
@@ -68,6 +68,7 @@ struct CharDriverState {
char *label;
char *filename;
int opened;
+ int system;
QTAILQ_ENTRY(CharDriverState) next;
};
@@ -75,6 +76,8 @@ QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
void (*init)(struct CharDriverState *s));
CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*init)(struct CharDriverState *s));
+CharDriverState *qemu_chr_system_open(const char *label, const char *filename,
+ void (*init)(struct CharDriverState *s));
void qemu_chr_close(CharDriverState *chr);
void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
GCC_FMT_ATTR(2, 3);
@@ -111,4 +114,9 @@ int qemu_set_fd_handler(int fd,
IOHandler *fd_read,
IOHandler *fd_write,
void *opaque);
+int qemu_set_system_fd_handler(int fd,
+ IOCanReadHandler *fd_read_poll,
+ IOHandler *fd_read,
+ IOHandler *fd_write,
+ void *opaque);
#endif
@@ -1577,7 +1577,7 @@ int kvm_main_loop(void)
fcntl(sigfd, F_SETFL, O_NONBLOCK);
- qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL,
+ qemu_set_system_fd_handler(sigfd, NULL, sigfd_handler, NULL,
(void *)(unsigned long) sigfd);
pthread_cond_broadcast(&qemu_system_cond);
@@ -111,3 +111,12 @@ int qemu_set_fd_handler2(int fd,
{
return 0;
}
+
+int qemu_set_system_fd_handler(int fd,
+ IOCanReadHandler *fd_read_poll,
+ IOHandler *fd_read,
+ IOHandler *fd_write,
+ void *opaque)
+{
+ return 0;
+}
@@ -97,7 +97,7 @@ static void watch_update_mask(SpiceWatch *watch, int event_mask)
if (watch->event_mask & SPICE_WATCH_EVENT_WRITE) {
on_read = watch_write;
}
- qemu_set_fd_handler(watch->fd, on_read, on_write, watch);
+ qemu_set_system_fd_handler(watch->fd, NULL, on_read, on_write, watch);
}
static SpiceWatch *watch_add(int fd, int event_mask, SpiceWatchFunc func, void *opaque)
@@ -84,7 +84,7 @@ long vnc_client_write_sasl(VncState *vs)
* SASL encoded output
*/
if (vs->output.offset == 0) {
- qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
+ qemu_set_systemk_fd_handler(vs->csock, NULL, vnc_client_read, NULL, vs);
}
return ret;
@@ -71,9 +71,9 @@ static int vnc_start_vencrypt_handshake(struct VncState *vs) {
if (!gnutls_error_is_fatal(ret)) {
VNC_DEBUG("Handshake interrupted (blocking)\n");
if (!gnutls_record_get_direction(vs->tls.session))
- qemu_set_fd_handler(vs->csock, vnc_tls_handshake_io, NULL, vs);
+ qemu_set_system_fd_handler(vs->csock, NULL, vnc_tls_handshake_io, NULL, vs);
else
- qemu_set_fd_handler(vs->csock, NULL, vnc_tls_handshake_io, vs);
+ qemu_set_system_fd_handler(vs->csock, NULL, NULL, vnc_tls_handshake_io, vs);
return 0;
}
VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));
@@ -93,7 +93,7 @@ static int vnc_start_vencrypt_handshake(struct VncState *vs) {
VNC_DEBUG("Handshake done, switching to TLS data mode\n");
vs->tls.wiremode = VNC_WIREMODE_TLS;
- qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
+ qemu_set_system_fd_handler(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
start_auth_vencrypt_subauth(vs);
@@ -1005,7 +1005,7 @@ static void vnc_disconnect_start(VncState *vs)
{
if (vs->csock == -1)
return;
- qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
+ qemu_set_system_fd_handler(vs->csock, NULL, NULL, NULL, NULL);
closesocket(vs->csock);
vs->csock = -1;
}
@@ -1155,7 +1155,7 @@ static long vnc_client_write_plain(VncState *vs)
vs->output.offset -= ret;
if (vs->output.offset == 0) {
- qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
+ qemu_set_system_fd_handler(vs->csock, NULL, vnc_client_read, NULL, vs);
}
return ret;
@@ -1189,7 +1189,7 @@ void vnc_client_write(void *opaque)
if (vs->output.offset) {
vnc_client_write_locked(opaque);
} else if (vs->csock != -1) {
- qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
+ qemu_set_system_fd_handler(vs->csock, NULL, vnc_client_read, NULL, vs);
}
vnc_unlock_output(vs);
}
@@ -1305,7 +1305,7 @@ void vnc_write(VncState *vs, const void *data, size_t len)
buffer_reserve(&vs->output, len);
if (vs->csock != -1 && buffer_empty(&vs->output)) {
- qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
+ qemu_set_system_fd_handler(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
}
buffer_append(&vs->output, data, len);
@@ -2369,7 +2369,7 @@ static void vnc_connect(VncDisplay *vd, int csock)
VNC_DEBUG("New client on socket %d\n", csock);
dcl->idle = 0;
socket_set_nonblock(vs->csock);
- qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
+ qemu_set_system_fd_handler(vs->csock, NULL, vnc_client_read, NULL, vs);
vnc_client_cache_addr(vs);
vnc_qmp_event(vs, QEVENT_VNC_CONNECTED);
@@ -2471,7 +2471,7 @@ void vnc_display_close(DisplayState *ds)
vs->display = NULL;
}
if (vs->lsock != -1) {
- qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
+ qemu_set_system_fd_handler(vs->lsock, NULL, NULL, NULL, NULL);
close(vs->lsock);
vs->lsock = -1;
}
@@ -2736,5 +2736,5 @@ int vnc_display_open(DisplayState *ds, const char *display)
vs->display = dpy;
}
}
- return qemu_set_fd_handler2(vs->lsock, NULL, vnc_listen_read, NULL, vs);
+ return qemu_set_system_fd_handler(vs->lsock, NULL, vnc_listen_read, NULL, vs);
}
@@ -929,34 +929,36 @@ typedef struct IOHandlerRecord {
QLIST_ENTRY(IOHandlerRecord) next;
} IOHandlerRecord;
-static QLIST_HEAD(, IOHandlerRecord) io_handlers =
- QLIST_HEAD_INITIALIZER(io_handlers);
+typedef QLIST_HEAD(, IOHandlerRecord) IOHandlerRecordList;
+static IOHandlerRecordList device_io_handlers =
+ QLIST_HEAD_INITIALIZER(device_io_handlers);
+static IOHandlerRecordList system_io_handlers =
+ QLIST_HEAD_INITIALIZER(system_io_handlers);
-/* XXX: fd_read_poll should be suppressed, but an API change is
- necessary in the character devices to suppress fd_can_read(). */
-int qemu_set_fd_handler2(int fd,
- IOCanReadHandler *fd_read_poll,
- IOHandler *fd_read,
- IOHandler *fd_write,
- void *opaque)
+static int qemu_assign_fd_handler(int fd,
+ IOCanReadHandler *fd_read_poll,
+ IOHandler *fd_read,
+ IOHandler *fd_write,
+ void *opaque,
+ IOHandlerRecordList *list)
{
IOHandlerRecord *ioh;
if (!fd_read && !fd_write) {
- QLIST_FOREACH(ioh, &io_handlers, next) {
+ QLIST_FOREACH(ioh, list, next) {
if (ioh->fd == fd) {
ioh->deleted = 1;
break;
}
}
} else {
- QLIST_FOREACH(ioh, &io_handlers, next) {
+ QLIST_FOREACH(ioh, list, next) {
if (ioh->fd == fd)
goto found;
}
ioh = qemu_mallocz(sizeof(IOHandlerRecord));
- QLIST_INSERT_HEAD(&io_handlers, ioh, next);
+ QLIST_INSERT_HEAD(list, ioh, next);
found:
ioh->fd = fd;
ioh->fd_read_poll = fd_read_poll;
@@ -969,6 +971,19 @@ int qemu_set_fd_handler2(int fd,
return 0;
}
+
+/* XXX: fd_read_poll should be suppressed, but an API change is
+ necessary in the character devices to suppress fd_can_read(). */
+int qemu_set_fd_handler2(int fd,
+ IOCanReadHandler *fd_read_poll,
+ IOHandler *fd_read,
+ IOHandler *fd_write,
+ void *opaque)
+{
+ return qemu_assign_fd_handler(fd, fd_read_poll, fd_read, fd_write, opaque,
+ &device_io_handlers);
+}
+
int qemu_set_fd_handler(int fd,
IOHandler *fd_read,
IOHandler *fd_write,
@@ -977,6 +992,18 @@ int qemu_set_fd_handler(int fd,
return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
}
+int qemu_set_system_fd_handler(int fd,
+ IOCanReadHandler *fd_read_poll,
+ IOHandler *fd_read,
+ IOHandler *fd_write,
+ void *opaque)
+{
+ qemu_assign_fd_handler(fd, fd_read_poll, fd_read, fd_write, opaque,
+ &device_io_handlers);
+ return qemu_assign_fd_handler(fd, fd_read_poll, fd_read, fd_write, opaque,
+ &system_io_handlers);
+}
+
/***********************************************************/
/* machine registration */
@@ -1213,13 +1240,57 @@ void qemu_system_powerdown_request(void)
qemu_notify_event();
}
-void main_loop_wait(int nonblocking)
+static inline int get_ioh_fds(IOHandlerRecordList *list,
+ int nfds, fd_set *rfds, fd_set *wfds)
{
IOHandlerRecord *ioh;
+ QLIST_FOREACH(ioh, list, next) {
+ if (ioh->deleted)
+ continue;
+ if (ioh->fd_read &&
+ (!ioh->fd_read_poll ||
+ ioh->fd_read_poll(ioh->opaque) != 0)) {
+ FD_SET(ioh->fd, rfds);
+ if (ioh->fd > nfds)
+ nfds = ioh->fd;
+ }
+ if (ioh->fd_write) {
+ FD_SET(ioh->fd, wfds);
+ if (ioh->fd > nfds)
+ nfds = ioh->fd;
+ }
+ }
+ return nfds;
+}
+
+static inline void call_ioh_fds(IOHandlerRecordList *list,
+ fd_set *rfds, fd_set *wfds)
+{
+ IOHandlerRecord *ioh, *pioh;
+
+ QLIST_FOREACH_SAFE(ioh, list, next, pioh) {
+ if (ioh->deleted) {
+ QLIST_REMOVE(ioh, next);
+ qemu_free(ioh);
+ continue;
+ }
+ if (ioh->fd_read && FD_ISSET(ioh->fd, rfds)) {
+ ioh->fd_read(ioh->opaque);
+ if (!(ioh->fd_read_poll && ioh->fd_read_poll(ioh->opaque)))
+ FD_CLR(ioh->fd, rfds);
+ }
+ if (ioh->fd_write && FD_ISSET(ioh->fd, wfds)) {
+ ioh->fd_write(ioh->opaque);
+ }
+ }
+}
+void main_loop_wait(int nonblocking)
+{
fd_set rfds, wfds, xfds;
int ret, nfds;
struct timeval tv;
int timeout;
+ IOHandlerRecordList *handlers;
if (nonblocking)
timeout = 0;
@@ -1231,64 +1302,47 @@ void main_loop_wait(int nonblocking)
os_host_main_loop_wait(&timeout);
/* poll any events */
- /* XXX: separate device handlers from system ones */
nfds = -1;
FD_ZERO(&rfds);
FD_ZERO(&wfds);
FD_ZERO(&xfds);
- QLIST_FOREACH(ioh, &io_handlers, next) {
- if (ioh->deleted)
- continue;
- if (ioh->fd_read &&
- (!ioh->fd_read_poll ||
- ioh->fd_read_poll(ioh->opaque) != 0)) {
- FD_SET(ioh->fd, &rfds);
- if (ioh->fd > nfds)
- nfds = ioh->fd;
- }
- if (ioh->fd_write) {
- FD_SET(ioh->fd, &wfds);
- if (ioh->fd > nfds)
- nfds = ioh->fd;
- }
- }
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = (timeout % 1000) * 1000;
+ if (vm_running) {
- slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
+ nfds = get_ioh_fds(&device_io_handlers, nfds, &rfds, &wfds);
- qemu_mutex_unlock_iothread();
- ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
- qemu_mutex_lock_iothread();
- if (ret > 0) {
- IOHandlerRecord *pioh;
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
- QLIST_FOREACH_SAFE(ioh, &io_handlers, next, pioh) {
- if (ioh->deleted) {
- QLIST_REMOVE(ioh, next);
- qemu_free(ioh);
- continue;
- }
- if (ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
- ioh->fd_read(ioh->opaque);
- if (!(ioh->fd_read_poll && ioh->fd_read_poll(ioh->opaque)))
- FD_CLR(ioh->fd, &rfds);
- }
- if (ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
- ioh->fd_write(ioh->opaque);
- }
+ slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
+
+ qemu_mutex_unlock_iothread();
+ ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
+ qemu_mutex_lock_iothread();
+ if (ret > 0) {
+ call_ioh_fds(&device_io_handlers, &rfds, &wfds);
}
- }
- slirp_select_poll(&rfds, &wfds, &xfds, (ret < 0));
+ slirp_select_poll(&rfds, &wfds, &xfds, (ret < 0));
- qemu_run_all_timers();
+ qemu_run_all_timers();
- /* Check bottom-halves last in case any of the earlier events triggered
- them. */
- qemu_bh_poll();
+ /* Check bottom-halves last in case any of the earlier events triggered
+ them. */
+ qemu_bh_poll();
+ } else {
+ nfds = get_ioh_fds(&system_io_handlers, nfds, &rfds, &wfds);
+
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+ qemu_mutex_unlock_iothread();
+ ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
+ qemu_mutex_lock_iothread();
+ if (ret > 0) {
+ call_ioh_fds(&system_io_handlers, &rfds, &wfds);
+ }
+ }
}
static int vm_can_run(void)
Stop running devices on vmstop, so that VM does not interact with outside world at that time. Whitelist system handlers which run even when VM is stopped. These are specific handlers like monitor, gdbstub, migration. I'm not really sure about ui: spice and vnc: do they need to run? Untested. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> --- Change from previous versions: reversed the approach, block all handlers except very specific ones. aio.c | 32 ++++++++- cmd.c | 8 +- gdbstub.c | 2 +- migration-exec.c | 4 +- migration-fd.c | 4 +- migration-tcp.c | 8 +- migration-unix.c | 8 +- migration.c | 8 +- qemu-aio.h | 7 ++ qemu-char.c | 10 +++ qemu-char.h | 8 ++ qemu-kvm.c | 2 +- qemu-tool.c | 9 +++ ui/spice-core.c | 2 +- ui/vnc-auth-sasl.c | 2 +- ui/vnc-auth-vencrypt.c | 6 +- ui/vnc.c | 14 ++-- vl.c | 174 +++++++++++++++++++++++++++++++----------------- 18 files changed, 210 insertions(+), 98 deletions(-)