libvduse: Add support for reconnecting

To support reconnecting after restart or crash, VDUSE backend
might need to resubmit inflight I/Os. This stores the metadata
such as the index of inflight I/O's descriptors to a shm file so
that VDUSE backend can restore them during reconnecting.

Signed-off-by: Xie Yongji <xieyongji@bytedance.com>
Message-Id: <20220523084611.91-9-xieyongji@bytedance.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Xie Yongji 2022-05-23 16:46:11 +08:00 committed by Kevin Wolf
parent 9e4dea6727
commit d043e2db87
3 changed files with 260 additions and 6 deletions

View file

@ -30,6 +30,7 @@ typedef struct VduseBlkExport {
VirtioBlkHandler handler;
VduseDev *dev;
uint16_t num_queues;
char *recon_file;
unsigned int inflight;
} VduseBlkExport;
@ -125,6 +126,8 @@ static void vduse_blk_enable_queue(VduseDev *dev, VduseVirtq *vq)
aio_set_fd_handler(vblk_exp->export.ctx, vduse_queue_get_fd(vq),
true, on_vduse_vq_kick, NULL, NULL, NULL, vq);
/* Make sure we don't miss any kick afer reconnecting */
eventfd_write(vduse_queue_get_fd(vq), 1);
}
static void vduse_blk_disable_queue(VduseDev *dev, VduseVirtq *vq)
@ -306,6 +309,15 @@ static int vduse_blk_exp_create(BlockExport *exp, BlockExportOptions *opts,
return -ENOMEM;
}
vblk_exp->recon_file = g_strdup_printf("%s/vduse-blk-%s",
g_get_tmp_dir(), exp->id);
if (vduse_set_reconnect_log_file(vblk_exp->dev, vblk_exp->recon_file)) {
error_setg(errp, "failed to set reconnect log file");
vduse_dev_destroy(vblk_exp->dev);
g_free(vblk_exp->recon_file);
return -EINVAL;
}
for (i = 0; i < num_queues; i++) {
vduse_dev_setup_queue(vblk_exp->dev, i, queue_size);
}
@ -324,11 +336,16 @@ static int vduse_blk_exp_create(BlockExport *exp, BlockExportOptions *opts,
static void vduse_blk_exp_delete(BlockExport *exp)
{
VduseBlkExport *vblk_exp = container_of(exp, VduseBlkExport, export);
int ret;
blk_remove_aio_context_notifier(exp->blk, blk_aio_attached, blk_aio_detach,
vblk_exp);
blk_set_dev_ops(exp->blk, NULL, NULL);
vduse_dev_destroy(vblk_exp->dev);
ret = vduse_dev_destroy(vblk_exp->dev);
if (ret != -EBUSY) {
unlink(vblk_exp->recon_file);
}
g_free(vblk_exp->recon_file);
}
static void vduse_blk_exp_request_shutdown(BlockExport *exp)