pve-qemu/debian/patches/pve/0041-savevm-async-updates.p...

216 lines
6.9 KiB
Diff

From d7b0ad8cf8ef0aad35b0549128003dbb49b8386d Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Fri, 9 Sep 2016 15:21:19 +0200
Subject: [PATCH 41/48] savevm-async updates
---
savevm-async.c | 79 +++++++++++++++++++++++++++++-----------------------------
1 file changed, 39 insertions(+), 40 deletions(-)
diff --git a/savevm-async.c b/savevm-async.c
index 46c1be7..2f4766c 100644
--- a/savevm-async.c
+++ b/savevm-async.c
@@ -20,6 +20,8 @@
/* #define DEBUG_SAVEVM_STATE */
+#define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
+
#ifdef DEBUG_SAVEVM_STATE
#define DPRINTF(fmt, ...) \
do { printf("savevm-async: " fmt, ## __VA_ARGS__); } while (0)
@@ -38,7 +40,7 @@ enum {
static struct SnapshotState {
- BlockDriverState *bs;
+ BlockBackend *target;
size_t bs_pos;
int state;
Error *error;
@@ -99,17 +101,17 @@ static int save_snapshot_cleanup(void)
ret = qemu_fclose(snap_state.file);
}
- if (snap_state.bs) {
+ if (snap_state.target) {
/* try to truncate, but ignore errors (will fail on block devices).
* note: bdrv_read() need whole blocks, so we round up
*/
size_t size = (snap_state.bs_pos + BDRV_SECTOR_SIZE) & BDRV_SECTOR_MASK;
- bdrv_truncate(snap_state.bs, size);
- bdrv_op_unblock_all(snap_state.bs, snap_state.blocker);
+ blk_truncate(snap_state.target, size);
+ blk_op_unblock_all(snap_state.target, snap_state.blocker);
error_free(snap_state.blocker);
snap_state.blocker = NULL;
- bdrv_unref(snap_state.bs);
- snap_state.bs = NULL;
+ blk_unref(snap_state.target);
+ snap_state.target = NULL;
}
return ret;
@@ -151,21 +153,22 @@ static void save_snapshot_completed(void)
static int block_state_close(void *opaque)
{
snap_state.file = NULL;
- return bdrv_flush(snap_state.bs);
+ return blk_flush(snap_state.target);
}
-static ssize_t block_state_put_buffer(void *opaque, const uint8_t *buf,
- int64_t pos, size_t size)
+static ssize_t block_state_writev_buffer(void *opaque, struct iovec *iov,
+ int iovcnt, int64_t pos)
{
- ssize_t ret;
-
- assert(pos == snap_state.bs_pos);
+ int ret;
+ QEMUIOVector qiov;
- if ((ret = bdrv_pwrite(snap_state.bs, snap_state.bs_pos, buf, size)) > 0) {
- snap_state.bs_pos += ret;
+ qemu_iovec_init_external(&qiov, iov, iovcnt);
+ ret = blk_co_pwritev(snap_state.target, pos, qiov.size, &qiov, 0);
+ if (ret < 0) {
+ return ret;
}
-
- return ret;
+ snap_state.bs_pos += qiov.size;
+ return qiov.size;
}
static int store_and_stop(void) {
@@ -227,7 +230,7 @@ static void process_savevm_co(void *opaque)
/* stop the VM if we get to the end of available space,
* or if pending_size is just a few MB
*/
- maxlen = bdrv_getlength(snap_state.bs) - 30*1024*1024;
+ maxlen = blk_getlength(snap_state.target) - 30*1024*1024;
if ((pending_size < 100000) ||
((snap_state.bs_pos + pending_size) >= maxlen)) {
if (store_and_stop())
@@ -244,7 +247,7 @@ static void process_savevm_co(void *opaque)
}
static const QEMUFileOps block_file_ops = {
- .put_buffer = block_state_put_buffer,
+ .writev_buffer = block_state_writev_buffer,
.close = block_state_close,
};
@@ -254,7 +257,6 @@ void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp)
Error *local_err = NULL;
int bdrv_oflags = BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_NO_FLUSH;
- int ret;
if (snap_state.state != SAVE_STATE_DONE) {
error_set(errp, ERROR_CLASS_GENERIC_ERROR,
@@ -284,13 +286,11 @@ void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp)
}
/* Open the image */
- snap_state.bs = bdrv_new();
-
QDict *options = NULL;
options = qdict_new();
qdict_put(options, "driver", qstring_from_str("raw"));
- ret = bdrv_open(&snap_state.bs, statefile, NULL, options, bdrv_oflags, &local_err);
- if (ret < 0) {
+ snap_state.target = blk_new_open(statefile, NULL, options, bdrv_oflags, &local_err);
+ if (!snap_state.target) {
error_set(errp, ERROR_CLASS_GENERIC_ERROR, "failed to open '%s'", statefile);
goto restart;
}
@@ -304,9 +304,9 @@ void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp)
error_setg(&snap_state.blocker, "block device is in use by savevm");
- bdrv_op_block_all(snap_state.bs, snap_state.blocker);
+ blk_op_block_all(snap_state.target, snap_state.blocker);
- Coroutine *co = qemu_coroutine_create(process_savevm_co);
+ Coroutine *co = qemu_coroutine_create(process_savevm_co, NULL);
qemu_coroutine_enter(co);
return;
@@ -457,8 +457,8 @@ void qmp_delete_drive_snapshot(const char *device, const char *name,
static ssize_t loadstate_get_buffer(void *opaque, uint8_t *buf, int64_t pos,
size_t size)
{
- BlockDriverState *bs = (BlockDriverState *)opaque;
- int64_t maxlen = bdrv_getlength(bs);
+ BlockBackend *be = opaque;
+ int64_t maxlen = blk_getlength(be);
if (pos > maxlen) {
return -EIO;
}
@@ -468,7 +468,7 @@ static ssize_t loadstate_get_buffer(void *opaque, uint8_t *buf, int64_t pos,
if (size == 0) {
return 0;
}
- return bdrv_pread(bs, pos, buf, size);
+ return blk_pread(be, pos, buf, size);
}
static const QEMUFileOps loadstate_file_ops = {
@@ -477,28 +477,27 @@ static const QEMUFileOps loadstate_file_ops = {
int load_state_from_blockdev(const char *filename)
{
- BlockDriverState *bs = NULL;
+ BlockBackend *be;
Error *local_err = NULL;
Error *blocker = NULL;
QEMUFile *f;
- int ret;
+ int ret = -EINVAL;
- bs = bdrv_new();
- ret = bdrv_open(&bs, filename, NULL, NULL, 0, &local_err);
- error_setg(&blocker, "block device is in use by load state");
- bdrv_op_block_all(bs, blocker);
+ be = blk_new_open(filename, NULL, NULL, 0, &local_err);
- if (ret < 0) {
+ if (!be) {
error_report("Could not open VM state file");
goto the_end;
}
+ error_setg(&blocker, "block device is in use by load state");
+ blk_op_block_all(be, blocker);
+
/* restore the VM state */
- f = qemu_fopen_ops(bs, &loadstate_file_ops);
+ f = qemu_fopen_ops(be, &loadstate_file_ops);
if (!f) {
error_report("Could not open VM state file");
- ret = -EINVAL;
goto the_end;
}
@@ -515,10 +514,10 @@ int load_state_from_blockdev(const char *filename)
ret = 0;
the_end:
- if (bs) {
- bdrv_op_unblock_all(bs, blocker);
+ if (be) {
+ blk_op_unblock_all(be, blocker);
error_free(blocker);
- bdrv_unref(bs);
+ blk_unref(be);
}
return ret;
}
--
2.1.4