diff options
Diffstat (limited to 'migration/channel-block.c')
| -rw-r--r-- | migration/channel-block.c | 48 |
1 files changed, 46 insertions, 2 deletions
diff --git a/migration/channel-block.c b/migration/channel-block.c index fff8d87..9cf383d 100644 --- a/migration/channel-block.c +++ b/migration/channel-block.c @@ -30,6 +30,7 @@ qio_channel_block_new(BlockDriverState *bs) QIOChannelBlock *ioc; ioc = QIO_CHANNEL_BLOCK(object_new(TYPE_QIO_CHANNEL_BLOCK)); + qio_channel_set_feature(QIO_CHANNEL(ioc), QIO_CHANNEL_FEATURE_SEEKABLE); bdrv_ref(bs); ioc->bs = bs; @@ -96,6 +97,47 @@ qio_channel_block_writev(QIOChannel *ioc, return qiov.size; } +static ssize_t +qio_channel_block_preadv(QIOChannel *ioc, + const struct iovec *iov, + size_t niov, + off_t offset, + Error **errp) +{ + QIOChannelBlock *bioc = QIO_CHANNEL_BLOCK(ioc); + QEMUIOVector qiov; + int ret; + + qemu_iovec_init_external(&qiov, (struct iovec *)iov, niov); + ret = bdrv_readv_vmstate(bioc->bs, &qiov, offset); + if (ret < 0) { + error_setg_errno(errp, -ret, "bdrv_readv_vmstate failed"); + return -1; + } + + return qiov.size; +} + +static ssize_t +qio_channel_block_pwritev(QIOChannel *ioc, + const struct iovec *iov, + size_t niov, + off_t offset, + Error **errp) +{ + QIOChannelBlock *bioc = QIO_CHANNEL_BLOCK(ioc); + QEMUIOVector qiov; + int ret; + + qemu_iovec_init_external(&qiov, (struct iovec *)iov, niov); + ret = bdrv_writev_vmstate(bioc->bs, &qiov, offset); + if (ret < 0) { + error_setg_errno(errp, -ret, "bdrv_writev_vmstate failed"); + return -1; + } + + return qiov.size; +} static int qio_channel_block_set_blocking(QIOChannel *ioc, @@ -123,7 +165,7 @@ qio_channel_block_seek(QIOChannel *ioc, bioc->offset = offset; break; case SEEK_CUR: - bioc->offset += whence; + bioc->offset += offset; break; case SEEK_END: error_setg(errp, "Size of VMstate region is unknown"); @@ -170,13 +212,15 @@ qio_channel_block_set_aio_fd_handler(QIOChannel *ioc, static void qio_channel_block_class_init(ObjectClass *klass, - void *class_data G_GNUC_UNUSED) + const void *class_data G_GNUC_UNUSED) { QIOChannelClass *ioc_klass = QIO_CHANNEL_CLASS(klass); ioc_klass->io_writev = qio_channel_block_writev; ioc_klass->io_readv = qio_channel_block_readv; ioc_klass->io_set_blocking = qio_channel_block_set_blocking; + ioc_klass->io_preadv = qio_channel_block_preadv; + ioc_klass->io_pwritev = qio_channel_block_pwritev; ioc_klass->io_seek = qio_channel_block_seek; ioc_klass->io_close = qio_channel_block_close; ioc_klass->io_set_aio_fd_handler = qio_channel_block_set_aio_fd_handler; |
