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;
|
||||
}
|
||||
|
||||
typedef struct BDRVSSHRestart {
|
||||
BlockDriverState *bs;
|
||||
Coroutine *co;
|
||||
} BDRVSSHRestart;
|
||||
|
||||
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
|
||||
@ -905,7 +914,10 @@ static coroutine_fn void co_yield(BDRVSSHState *s, BlockDriverState *bs)
|
||||
{
|
||||
int r;
|
||||
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);
|
||||
|
||||
@ -920,11 +932,9 @@ static coroutine_fn void co_yield(BDRVSSHState *s, BlockDriverState *bs)
|
||||
rd_handler, wr_handler);
|
||||
|
||||
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();
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user