mirror of https://github.com/xemu-project/xemu.git
ssh: support I/O from any AioContext
The coroutine may run in a different AioContext, causing the fd handler to busy wait. Fix this by resetting the handler in restart_coroutine, before the coroutine is restarted. Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Fam Zheng <famz@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Message-Id: <20170629132749.997-12-pbonzini@redhat.com> Signed-off-by: Fam Zheng <famz@redhat.com>
This commit is contained in:
parent
f1af3251f8
commit
5aca18a4ff
24
block/ssh.c
24
block/ssh.c
|
@ -888,13 +888,22 @@ static int ssh_has_zero_init(BlockDriverState *bs)
|
||||||
return has_zero_init;
|
return has_zero_init;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct BDRVSSHRestart {
|
||||||
|
BlockDriverState *bs;
|
||||||
|
Coroutine *co;
|
||||||
|
} BDRVSSHRestart;
|
||||||
|
|
||||||
static void restart_coroutine(void *opaque)
|
static void restart_coroutine(void *opaque)
|
||||||
{
|
{
|
||||||
Coroutine *co = opaque;
|
BDRVSSHRestart *restart = opaque;
|
||||||
|
BlockDriverState *bs = restart->bs;
|
||||||
|
BDRVSSHState *s = bs->opaque;
|
||||||
|
AioContext *ctx = bdrv_get_aio_context(bs);
|
||||||
|
|
||||||
DPRINTF("co=%p", co);
|
DPRINTF("co=%p", restart->co);
|
||||||
|
aio_set_fd_handler(ctx, s->sock, false, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
aio_co_wake(co);
|
aio_co_wake(restart->co);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A non-blocking call returned EAGAIN, so yield, ensuring the
|
/* A non-blocking call returned EAGAIN, so yield, ensuring the
|
||||||
|
@ -905,7 +914,10 @@ static coroutine_fn void co_yield(BDRVSSHState *s, BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
IOHandler *rd_handler = NULL, *wr_handler = NULL;
|
IOHandler *rd_handler = NULL, *wr_handler = NULL;
|
||||||
Coroutine *co = qemu_coroutine_self();
|
BDRVSSHRestart restart = {
|
||||||
|
.bs = bs,
|
||||||
|
.co = qemu_coroutine_self()
|
||||||
|
};
|
||||||
|
|
||||||
r = libssh2_session_block_directions(s->session);
|
r = libssh2_session_block_directions(s->session);
|
||||||
|
|
||||||
|
@ -920,11 +932,9 @@ static coroutine_fn void co_yield(BDRVSSHState *s, BlockDriverState *bs)
|
||||||
rd_handler, wr_handler);
|
rd_handler, wr_handler);
|
||||||
|
|
||||||
aio_set_fd_handler(bdrv_get_aio_context(bs), s->sock,
|
aio_set_fd_handler(bdrv_get_aio_context(bs), s->sock,
|
||||||
false, rd_handler, wr_handler, NULL, co);
|
false, rd_handler, wr_handler, NULL, &restart);
|
||||||
qemu_coroutine_yield();
|
qemu_coroutine_yield();
|
||||||
DPRINTF("s->sock=%d - back", s->sock);
|
DPRINTF("s->sock=%d - back", s->sock);
|
||||||
aio_set_fd_handler(bdrv_get_aio_context(bs), s->sock, false,
|
|
||||||
NULL, NULL, NULL, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SFTP has a function `libssh2_sftp_seek64' which seeks to a position
|
/* SFTP has a function `libssh2_sftp_seek64' which seeks to a position
|
||||||
|
|
Loading…
Reference in New Issue