]> git.proxmox.com Git - pve-qemu-kvm.git/blame - new/savevm-async.c
activate savevm-live.patch patch
[pve-qemu-kvm.git] / new / savevm-async.c
CommitLineData
e128dc27
DM
1#include "qemu-common.h"
2#include "qerror.h"
3#include "sysemu.h"
4#include "qmp-commands.h"
5#include "blockdev.h"
6#include "qemu/qom-qobject.h"
7#include "buffered_file.h"
8#include "migration.h"
9
10//#define DEBUG_SAVEVM_STATE
11
12#ifdef DEBUG_SAVEVM_STATE
13#define DPRINTF(fmt, ...) \
14 do { printf("savevm-async: " fmt, ## __VA_ARGS__); } while (0)
15#else
16#define DPRINTF(fmt, ...) \
17 do { } while (0)
18#endif
19
20enum {
21 SAVE_STATE_DONE,
22 SAVE_STATE_ERROR,
23 SAVE_STATE_ACTIVE,
24 SAVE_STATE_COMPLETED,
25};
26
27static struct SnapshotState {
28 BlockDriverState *bs;
29 size_t bs_pos;
30 int state;
31 Error *error;
32 int saved_vm_running;
33 QEMUFile *file;
34 int64_t total_time;
35} snap_state;
36
37SaveVMInfo *qmp_query_savevm(Error **errp)
38{
39 SaveVMInfo *info = g_malloc0(sizeof(*info));
40 struct SnapshotState *s = &snap_state;
41
42 if (s->state != SAVE_STATE_DONE) {
43 info->has_bytes = true;
44 info->bytes = s->bs_pos;
45 switch (s->state) {
46 case SAVE_STATE_ERROR:
47 info->has_status = true;
48 info->status = g_strdup("failed");
49 info->has_total_time = true;
50 info->total_time = s->total_time;
51 if (s->error) {
52 info->has_error = true;
53 info->error = g_strdup(error_get_pretty(s->error));
54 }
55 break;
56 case SAVE_STATE_ACTIVE:
57 info->has_status = true;
58 info->status = g_strdup("active");
59 info->has_total_time = true;
60 info->total_time = qemu_get_clock_ms(rt_clock)
61 - s->total_time;
62 break;
63 case SAVE_STATE_COMPLETED:
64 info->has_status = true;
65 info->status = g_strdup("completed");
66 info->has_total_time = true;
67 info->total_time = s->total_time;
68 break;
69 }
70 }
71
72 return info;
73}
74
75static int save_snapshot_cleanup(void)
76{
77 int ret = 0;
78
79 DPRINTF("save_snapshot_cleanup\n");
80
81 snap_state.total_time = qemu_get_clock_ms(rt_clock) -
82 snap_state.total_time;
83
84 if (snap_state.file) {
85 ret = qemu_fclose(snap_state.file);
86 }
87
88 if (snap_state.bs) {
89 // try to truncate, but ignore errors (will fail on block devices).
90 // note: bdrv_read() need whole blocks, so we round up
91 size_t size = (snap_state.bs_pos + BDRV_SECTOR_SIZE) & BDRV_SECTOR_MASK;
92 bdrv_truncate(snap_state.bs, size);
93
94 bdrv_delete(snap_state.bs);
95 snap_state.bs = NULL;
96 }
97
98 return ret;
99}
100
101static void save_snapshot_error(const char *fmt, ...)
102{
103 va_list ap;
104 char *msg;
105
106 va_start(ap, fmt);
107 msg = g_strdup_vprintf(fmt, ap);
108 va_end(ap);
109
110 DPRINTF("save_snapshot_error: %s\n", msg);
111
112 if (!snap_state.error) {
113 error_set(&snap_state.error, ERROR_CLASS_GENERIC_ERROR, "%s", msg);
114 }
115
116 g_free (msg);
117
118 snap_state.state = SAVE_STATE_ERROR;
119
120 save_snapshot_cleanup();
121}
122
123static void save_snapshot_completed(void)
124{
125 DPRINTF("save_snapshot_completed\n");
126
127 if (save_snapshot_cleanup() < 0) {
128 snap_state.state = SAVE_STATE_ERROR;
129 } else {
130 snap_state.state = SAVE_STATE_COMPLETED;
131 }
132}
133
134static int block_state_close(void *opaque)
135{
136 snap_state.file = NULL;
137 return bdrv_flush(snap_state.bs);
138}
139
140static ssize_t block_state_put_buffer(void *opaque, const void *buf,
141 size_t size)
142{
143 int ret;
144
145 if ((ret = bdrv_pwrite(snap_state.bs, snap_state.bs_pos, buf, size)) > 0) {
146 snap_state.bs_pos += ret;
147 }
148
149 return ret;
150}
151
152static void block_state_put_ready(void *opaque)
153{
2d58a6b0
DM
154 uint64_t remaining;
155 int64_t maxlen;
e128dc27
DM
156 int ret;
157
158 if (snap_state.state != SAVE_STATE_ACTIVE) {
159 save_snapshot_error("put_ready returning because of non-active state");
160 return;
161 }
162
2d58a6b0
DM
163 ret = qemu_savevm_state_iterate(snap_state.file);
164 remaining = ram_bytes_remaining();
165
166 // stop if we get to the end of available space,
167 // or if remaining is just a few MB
168 maxlen = bdrv_getlength(snap_state.bs) - 30*1024*1024;
169 if ((remaining < 100000) || ((snap_state.bs_pos + remaining) >= maxlen)) {
170 if (runstate_is_running()) {
171 vm_stop(RUN_STATE_SAVE_VM);
172 }
e128dc27
DM
173 }
174
e128dc27
DM
175 if (ret < 0) {
176 save_snapshot_error("qemu_savevm_state_iterate error %d", ret);
177 return;
178 } else if (ret == 1) {
2d58a6b0
DM
179 if (runstate_is_running()) {
180 vm_stop(RUN_STATE_SAVE_VM);
181 }
e128dc27
DM
182 DPRINTF("savevm inerate finished\n");
183 if ((ret = qemu_savevm_state_complete(snap_state.file)) < 0) {
184 save_snapshot_error("qemu_savevm_state_complete error %d", ret);
185 return;
186 } else {
187 DPRINTF("save complete\n");
188 save_snapshot_completed();
189 return;
190 }
191 }
192}
193
194static void block_state_wait_for_unfreeze(void *opaque)
195{
196 /* do nothing here - should not be called */
197}
198
199void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp)
200{
201 BlockDriver *drv = NULL;
202 int bdrv_oflags = BDRV_O_CACHE_WB | BDRV_O_RDWR;
203 MigrationParams params = {
204 .blk = 0,
205 .shared = 0
206 };
207 int ret;
208
209 if (snap_state.state != SAVE_STATE_DONE) {
210 error_set(errp, ERROR_CLASS_GENERIC_ERROR,
211 "VM snapshot already started\n");
212 return;
213 }
214
215 /* initialize snapshot info */
216 snap_state.saved_vm_running = runstate_is_running();
217 snap_state.bs_pos = 0;
218 snap_state.total_time = qemu_get_clock_ms(rt_clock);
219
220 if (snap_state.error) {
221 error_free(snap_state.error);
222 snap_state.error = NULL;
223 }
224
e128dc27 225 if (!has_statefile) {
2d58a6b0 226 vm_stop(RUN_STATE_SAVE_VM);
e128dc27
DM
227 snap_state.state = SAVE_STATE_COMPLETED;
228 return;
229 }
230
231 if (qemu_savevm_state_blocked(errp)) {
232 return;
233 }
234
235 /* Open the image */
236 snap_state.bs = bdrv_new("vmstate");
237 ret = bdrv_open(snap_state.bs, statefile, bdrv_oflags, drv);
238 if (ret < 0) {
239 error_set(errp, QERR_OPEN_FILE_FAILED, statefile);
240 goto restart;
241 }
242
243 snap_state.file = qemu_fopen_ops_buffered(&snap_state, 1000000000,
244 block_state_put_buffer,
245 block_state_put_ready,
246 block_state_wait_for_unfreeze,
247 block_state_close);
248
249 if (!snap_state.file) {
250 error_set(errp, QERR_OPEN_FILE_FAILED, statefile);
251 goto restart;
252 }
253
254 snap_state.state = SAVE_STATE_ACTIVE;
255
256 ret = qemu_savevm_state_begin(snap_state.file, &params);
257 if (ret < 0) {
258 error_set(errp, ERROR_CLASS_GENERIC_ERROR,
259 "qemu_savevm_state_begin failed\n");
260 goto restart;
261 }
262
263 block_state_put_ready(&snap_state);
264
265 return;
266
267restart:
268
269 save_snapshot_error("setup failed");
270
271 if (snap_state.saved_vm_running) {
272 vm_start();
273 }
274}
275
276void qmp_savevm_end(Error **errp)
277{
278 if (snap_state.state == SAVE_STATE_DONE) {
279 error_set(errp, ERROR_CLASS_GENERIC_ERROR,
280 "VM snapshot not started\n");
281 return;
282 }
283
284 if (snap_state.saved_vm_running) {
285 vm_start();
286 }
287
288 snap_state.state = SAVE_STATE_DONE;
289}
290
291void qmp_snapshot_drive(const char *device, const char *name, Error **errp)
292{
293 BlockDriverState *bs;
294 QEMUSnapshotInfo sn1, *sn = &sn1;
295 int ret;
296#ifdef _WIN32
297 struct _timeb tb;
298#else
299 struct timeval tv;
300#endif
301
302 if (snap_state.state != SAVE_STATE_COMPLETED) {
303 error_set(errp, ERROR_CLASS_GENERIC_ERROR,
304 "VM snapshot not ready/started\n");
305 return;
306 }
307
308 bs = bdrv_find(device);
309 if (!bs) {
310 error_set(errp, QERR_DEVICE_NOT_FOUND, device);
311 return;
312 }
313
314 if (!bdrv_is_inserted(bs)) {
315 error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
316 return;
317 }
318
319 if (bdrv_is_read_only(bs)) {
320 error_set(errp, QERR_DEVICE_IS_READ_ONLY, device);
321 return;
322 }
323
324 if (!bdrv_can_snapshot(bs)) {
325 error_set(errp, QERR_NOT_SUPPORTED);
326 return;
327 }
328
329 if (bdrv_snapshot_find(bs, sn, name) >= 0) {
330 error_set(errp, ERROR_CLASS_GENERIC_ERROR,
331 "snapshot '%s' already exists", name);
332 return;
333 }
334
335 sn = &sn1;
336 memset(sn, 0, sizeof(*sn));
337
338#ifdef _WIN32
339 _ftime(&tb);
340 sn->date_sec = tb.time;
341 sn->date_nsec = tb.millitm * 1000000;
342#else
343 gettimeofday(&tv, NULL);
344 sn->date_sec = tv.tv_sec;
345 sn->date_nsec = tv.tv_usec * 1000;
346#endif
347 sn->vm_clock_nsec = qemu_get_clock_ns(vm_clock);
348
349 pstrcpy(sn->name, sizeof(sn->name), name);
350
351 sn->vm_state_size = 0; /* do not save state */
352
353 ret = bdrv_snapshot_create(bs, sn);
354 if (ret < 0) {
355 error_set(errp, ERROR_CLASS_GENERIC_ERROR,
356 "Error while creating snapshot on '%s'\n", device);
357 return;
358 }
359}
360
361void qmp_delete_drive_snapshot(const char *device, const char *name,
362 Error **errp)
363{
364 BlockDriverState *bs;
365 QEMUSnapshotInfo sn1, *sn = &sn1;
366 int ret;
367
368 bs = bdrv_find(device);
369 if (!bs) {
370 error_set(errp, QERR_DEVICE_NOT_FOUND, device);
371 return;
372 }
373 if (bdrv_is_read_only(bs)) {
374 error_set(errp, QERR_DEVICE_IS_READ_ONLY, device);
375 return;
376 }
377
378 if (!bdrv_can_snapshot(bs)) {
379 error_set(errp, QERR_NOT_SUPPORTED);
380 return;
381 }
382
383 if (bdrv_snapshot_find(bs, sn, name) < 0) {
384 /* return success if snapshot does not exists */
385 return;
386 }
387
388 ret = bdrv_snapshot_delete(bs, name);
389 if (ret < 0) {
390 error_set(errp, ERROR_CLASS_GENERIC_ERROR,
391 "Error while deleting snapshot on '%s'\n", device);
392 return;
393 }
394}
395
396static int loadstate_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
397{
398 BlockDriverState *bs = (BlockDriverState *)opaque;
399 int64_t maxlen = bdrv_getlength(bs);
400 if (pos > maxlen) {
401 return -EIO;
402 }
403 if ((pos + size) > maxlen) {
404 size = maxlen - pos - 1;
405 }
406 if (size == 0) {
407 return 0;
408 }
409 return bdrv_pread(bs, pos, buf, size);
410}
411
412int load_state_from_blockdev(const char *filename)
413{
414 BlockDriverState *bs = NULL;
415 BlockDriver *drv = NULL;
416 QEMUFile *f;
417 int ret = -1;
418
419 bs = bdrv_new("vmstate");
420 ret = bdrv_open(bs, filename, BDRV_O_CACHE_WB, drv);
421 if (ret < 0) {
422 error_report("Could not open VM state file");
423 goto the_end;
424 }
425
426 /* restore the VM state */
427 f = qemu_fopen_ops(bs, NULL, loadstate_get_buffer, NULL, NULL, NULL, NULL);
428 if (!f) {
429 error_report("Could not open VM state file");
430 ret = -EINVAL;
431 goto the_end;
432 }
433
434 qemu_system_reset(VMRESET_SILENT);
435 ret = qemu_loadvm_state(f);
436
437 qemu_fclose(f);
438 if (ret < 0) {
439 error_report("Error %d while loading VM state", ret);
440 goto the_end;
441 }
442
443 ret = 0;
444
445 the_end:
446 if (bs) {
447 bdrv_delete(bs);
448 }
449 return ret;
450}