]> git.proxmox.com Git - pve-qemu-kvm.git/blob - debian/patches/pve/0041-savevm-async-updates.patch
839724d7f8ba00967e577f6b2d1fcd1c25b72920
[pve-qemu-kvm.git] / debian / patches / pve / 0041-savevm-async-updates.patch
1 From aa7a8a709827e37bd49c65018627799c6eced431 Mon Sep 17 00:00:00 2001
2 From: Wolfgang Bumiller <w.bumiller@proxmox.com>
3 Date: Fri, 9 Sep 2016 15:21:19 +0200
4 Subject: [PATCH 41/47] savevm-async updates
5
6 ---
7 savevm-async.c | 79 +++++++++++++++++++++++++++++-----------------------------
8 1 file changed, 39 insertions(+), 40 deletions(-)
9
10 diff --git a/savevm-async.c b/savevm-async.c
11 index 46c1be7..2f4766c 100644
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;
55 @@ -151,21 +153,22 @@ static void save_snapshot_completed(void)
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)
65 +static ssize_t block_state_writev_buffer(void *opaque, struct iovec *iov,
66 + int iovcnt, int64_t pos)
67 {
68 - ssize_t ret;
69 -
70 - assert(pos == snap_state.bs_pos);
71 + int ret;
72 + QEMUIOVector qiov;
73
74 - if ((ret = bdrv_pwrite(snap_state.bs, snap_state.bs_pos, buf, size)) > 0) {
75 - snap_state.bs_pos += ret;
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;
80 }
81 -
82 - return ret;
83 + snap_state.bs_pos += qiov.size;
84 + return qiov.size;
85 }
86
87 static int store_and_stop(void) {
88 @@ -227,7 +230,7 @@ static void process_savevm_co(void *opaque)
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())
97 @@ -244,7 +247,7 @@ static void process_savevm_co(void *opaque)
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
106 @@ -254,7 +257,6 @@ void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp)
107 Error *local_err = NULL;
108
109 int bdrv_oflags = BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_NO_FLUSH;
110 - int ret;
111
112 if (snap_state.state != SAVE_STATE_DONE) {
113 error_set(errp, ERROR_CLASS_GENERIC_ERROR,
114 @@ -284,13 +286,11 @@ void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp)
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 }
130 @@ -304,9 +304,9 @@ void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp)
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;
142 @@ -457,8 +457,8 @@ void qmp_delete_drive_snapshot(const char *device, const char *name,
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 }
153 @@ -468,7 +468,7 @@ static ssize_t loadstate_get_buffer(void *opaque, uint8_t *buf, int64_t pos,
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 = {
162 @@ -477,28 +477,27 @@ static const QEMUFileOps loadstate_file_ops = {
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 + int ret = -EINVAL;
174
175 - bs = bdrv_new();
176 - ret = bdrv_open(&bs, filename, NULL, NULL, 0, &local_err);
177 - error_setg(&blocker, "block device is in use by load state");
178 - bdrv_op_block_all(bs, blocker);
179 + be = blk_new_open(filename, NULL, NULL, 0, &local_err);
180
181 - if (ret < 0) {
182 + if (!be) {
183 error_report("Could not open VM state file");
184 goto the_end;
185 }
186
187 + error_setg(&blocker, "block device is in use by load state");
188 + blk_op_block_all(be, blocker);
189 +
190 /* restore the VM state */
191 - f = qemu_fopen_ops(bs, &loadstate_file_ops);
192 + f = qemu_fopen_ops(be, &loadstate_file_ops);
193 if (!f) {
194 error_report("Could not open VM state file");
195 - ret = -EINVAL;
196 goto the_end;
197 }
198
199 @@ -515,10 +514,10 @@ int load_state_from_blockdev(const char *filename)
200 ret = 0;
201
202 the_end:
203 - if (bs) {
204 - bdrv_op_unblock_all(bs, blocker);
205 + if (be) {
206 + blk_op_unblock_all(be, blocker);
207 error_free(blocker);
208 - bdrv_unref(bs);
209 + blk_unref(be);
210 }
211 return ret;
212 }
213 --
214 2.1.4
215