]> git.proxmox.com Git - pve-qemu-kvm.git/blame - debian/patches/pve/0041-savevm-async-updates.patch
Fix #1193: live snapshot state got truncated
[pve-qemu-kvm.git] / debian / patches / pve / 0041-savevm-async-updates.patch
CommitLineData
b3c63c38 1From b7bac74dd970eba47961cdaac3b219a2de7668b5 Mon Sep 17 00:00:00 2001
68a30562
WB
2From: Wolfgang Bumiller <w.bumiller@proxmox.com>
3Date: Fri, 9 Sep 2016 15:21:19 +0200
b3c63c38 4Subject: [PATCH 41/44] savevm-async updates
68a30562
WB
5
6---
b3c63c38
WB
7 savevm-async.c | 76 +++++++++++++++++++++++++++++-----------------------------
8 1 file changed, 38 insertions(+), 38 deletions(-)
68a30562
WB
9
10diff --git a/savevm-async.c b/savevm-async.c
b3c63c38 11index 76cd8fa..af86cbd 100644
68a30562
WB
12--- a/savevm-async.c
13+++ b/savevm-async.c
14@@ -20,6 +20,8 @@
15
16 /* #define DEBUG_SAVEVM_STATE */
17
18+#define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
19+
20 #ifdef DEBUG_SAVEVM_STATE
21 #define DPRINTF(fmt, ...) \
22 do { printf("savevm-async: " fmt, ## __VA_ARGS__); } while (0)
23@@ -38,7 +40,7 @@ enum {
24
25
26 static struct SnapshotState {
27- BlockDriverState *bs;
28+ BlockBackend *target;
29 size_t bs_pos;
30 int state;
31 Error *error;
32@@ -99,17 +101,17 @@ static int save_snapshot_cleanup(void)
33 ret = qemu_fclose(snap_state.file);
34 }
35
36- if (snap_state.bs) {
37+ if (snap_state.target) {
38 /* try to truncate, but ignore errors (will fail on block devices).
39 * note: bdrv_read() need whole blocks, so we round up
40 */
41 size_t size = (snap_state.bs_pos + BDRV_SECTOR_SIZE) & BDRV_SECTOR_MASK;
42- bdrv_truncate(snap_state.bs, size);
43- bdrv_op_unblock_all(snap_state.bs, snap_state.blocker);
44+ blk_truncate(snap_state.target, size);
45+ blk_op_unblock_all(snap_state.target, snap_state.blocker);
46 error_free(snap_state.blocker);
47 snap_state.blocker = NULL;
48- bdrv_unref(snap_state.bs);
49- snap_state.bs = NULL;
50+ blk_unref(snap_state.target);
51+ snap_state.target = NULL;
52 }
53
54 return ret;
b3c63c38 55@@ -151,21 +153,22 @@ static void save_snapshot_completed(void)
68a30562
WB
56 static int block_state_close(void *opaque)
57 {
58 snap_state.file = NULL;
59- return bdrv_flush(snap_state.bs);
60+ return blk_flush(snap_state.target);
61 }
62
63-static ssize_t block_state_put_buffer(void *opaque, const uint8_t *buf,
64- int64_t pos, size_t size)
68a30562
WB
65+static ssize_t block_state_writev_buffer(void *opaque, struct iovec *iov,
66+ int iovcnt, int64_t pos)
67 {
68- ssize_t ret;
b3c63c38 69-
68a30562 70- assert(pos == snap_state.bs_pos);
b3c63c38
WB
71+ int ret;
72+ QEMUIOVector qiov;
68a30562
WB
73
74- if ((ret = bdrv_pwrite(snap_state.bs, snap_state.bs_pos, buf, size)) > 0) {
75- snap_state.bs_pos += ret;
b3c63c38
WB
76+ qemu_iovec_init_external(&qiov, iov, iovcnt);
77+ ret = blk_co_pwritev(snap_state.target, pos, qiov.size, &qiov, 0);
78+ if (ret < 0) {
79+ return ret;
68a30562 80 }
b3c63c38 81-
68a30562 82- return ret;
b3c63c38 83+ snap_state.bs_pos += qiov.size;
68a30562
WB
84+ return qiov.size;
85 }
86
87 static int store_and_stop(void) {
b3c63c38 88@@ -227,7 +230,7 @@ static void process_savevm_co(void *opaque)
68a30562
WB
89 /* stop the VM if we get to the end of available space,
90 * or if pending_size is just a few MB
91 */
92- maxlen = bdrv_getlength(snap_state.bs) - 30*1024*1024;
93+ maxlen = blk_getlength(snap_state.target) - 30*1024*1024;
94 if ((pending_size < 100000) ||
95 ((snap_state.bs_pos + pending_size) >= maxlen)) {
96 if (store_and_stop())
b3c63c38 97@@ -244,7 +247,7 @@ static void process_savevm_co(void *opaque)
68a30562
WB
98 }
99
100 static const QEMUFileOps block_file_ops = {
101- .put_buffer = block_state_put_buffer,
102+ .writev_buffer = block_state_writev_buffer,
103 .close = block_state_close,
104 };
105
b3c63c38 106@@ -254,7 +257,6 @@ void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp)
68a30562
WB
107 Error *local_err = NULL;
108
109 int bdrv_oflags = BDRV_O_RDWR | BDRV_O_NO_FLUSH;
110- int ret;
111
112 if (snap_state.state != SAVE_STATE_DONE) {
113 error_set(errp, ERROR_CLASS_GENERIC_ERROR,
b3c63c38 114@@ -284,13 +286,11 @@ void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp)
68a30562
WB
115 }
116
117 /* Open the image */
118- snap_state.bs = bdrv_new();
119-
120 QDict *options = NULL;
121 options = qdict_new();
122 qdict_put(options, "driver", qstring_from_str("raw"));
123- ret = bdrv_open(&snap_state.bs, statefile, NULL, options, bdrv_oflags, &local_err);
124- if (ret < 0) {
125+ snap_state.target = blk_new_open(statefile, NULL, options, bdrv_oflags, &local_err);
126+ if (!snap_state.target) {
127 error_set(errp, ERROR_CLASS_GENERIC_ERROR, "failed to open '%s'", statefile);
128 goto restart;
129 }
b3c63c38 130@@ -304,9 +304,9 @@ void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp)
68a30562
WB
131
132
133 error_setg(&snap_state.blocker, "block device is in use by savevm");
134- bdrv_op_block_all(snap_state.bs, snap_state.blocker);
135+ blk_op_block_all(snap_state.target, snap_state.blocker);
136
137- Coroutine *co = qemu_coroutine_create(process_savevm_co);
138+ Coroutine *co = qemu_coroutine_create(process_savevm_co, NULL);
139 qemu_coroutine_enter(co);
140
141 return;
b3c63c38 142@@ -457,8 +457,8 @@ void qmp_delete_drive_snapshot(const char *device, const char *name,
68a30562
WB
143 static ssize_t loadstate_get_buffer(void *opaque, uint8_t *buf, int64_t pos,
144 size_t size)
145 {
146- BlockDriverState *bs = (BlockDriverState *)opaque;
147- int64_t maxlen = bdrv_getlength(bs);
148+ BlockBackend *be = opaque;
149+ int64_t maxlen = blk_getlength(be);
150 if (pos > maxlen) {
151 return -EIO;
152 }
b3c63c38 153@@ -468,7 +468,7 @@ static ssize_t loadstate_get_buffer(void *opaque, uint8_t *buf, int64_t pos,
68a30562
WB
154 if (size == 0) {
155 return 0;
156 }
157- return bdrv_pread(bs, pos, buf, size);
158+ return blk_pread(be, pos, buf, size);
159 }
160
161 static const QEMUFileOps loadstate_file_ops = {
b3c63c38 162@@ -477,25 +477,25 @@ static const QEMUFileOps loadstate_file_ops = {
68a30562
WB
163
164 int load_state_from_blockdev(const char *filename)
165 {
166- BlockDriverState *bs = NULL;
167+ BlockBackend *be;
168 Error *local_err = NULL;
169 Error *blocker = NULL;
170
171 QEMUFile *f;
172 int ret;
173
174- bs = bdrv_new();
175- ret = bdrv_open(&bs, filename, NULL, NULL, 0, &local_err);
176- error_setg(&blocker, "block device is in use by load state");
177- bdrv_op_block_all(bs, blocker);
178+ be = blk_new_open(filename, NULL, NULL, 0, &local_err);
179
180- if (ret < 0) {
181+ if (!be) {
182 error_report("Could not open VM state file");
183 goto the_end;
184 }
185
186+ error_setg(&blocker, "block device is in use by load state");
187+ blk_op_block_all(be, blocker);
188+
189 /* restore the VM state */
190- f = qemu_fopen_ops(bs, &loadstate_file_ops);
191+ f = qemu_fopen_ops(be, &loadstate_file_ops);
192 if (!f) {
193 error_report("Could not open VM state file");
194 ret = -EINVAL;
b3c63c38 195@@ -516,10 +516,10 @@ int load_state_from_blockdev(const char *filename)
68a30562
WB
196 ret = 0;
197
198 the_end:
199- if (bs) {
200- bdrv_op_unblock_all(bs, blocker);
201+ if (be) {
202+ blk_op_unblock_all(be, blocker);
203 error_free(blocker);
204- bdrv_unref(bs);
205+ blk_unref(be);
206 }
207 return ret;
208 }
209--
2102.1.4
211