blob: e9d16de5698239b80d9c3aea79937f151c28481d [file] [log] [blame]
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001/*
2 * QEMU System Emulator
3 *
4 * Copyright (c) 2003-2008 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24#include <unistd.h>
25#include <fcntl.h>
26#include <signal.h>
27#include <time.h>
28#include <errno.h>
29#include <sys/time.h>
30#include <zlib.h>
31
David 'Digit' Turner2c538c82010-05-10 16:48:20 -070032/* Needed early for CONFIG_BSD etc. */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070033#include "config-host.h"
34
35#ifndef _WIN32
36#include <sys/times.h>
37#include <sys/wait.h>
38#include <termios.h>
39#include <sys/mman.h>
40#include <sys/ioctl.h>
41#include <sys/resource.h>
42#include <sys/socket.h>
43#include <netinet/in.h>
44#include <net/if.h>
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070045#include <arpa/inet.h>
46#include <dirent.h>
47#include <netdb.h>
48#include <sys/select.h>
David 'Digit' Turner2c538c82010-05-10 16:48:20 -070049#ifdef CONFIG_BSD
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070050#include <sys/stat.h>
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +010051#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070052#include <libutil.h>
53#else
54#include <util.h>
55#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070056#ifdef __linux__
57#include <pty.h>
58#include <malloc.h>
59#include <linux/rtc.h>
60#endif
61#endif
62#endif
63
64#ifdef _WIN32
65#include <windows.h>
66#include <malloc.h>
67#include <sys/timeb.h>
68#include <mmsystem.h>
69#define getopt_long_only getopt_long
70#define memalign(align, size) malloc(size)
71#endif
72
73#include "qemu-common.h"
74#include "hw/hw.h"
75#include "net.h"
76#include "monitor.h"
77#include "sysemu.h"
78#include "qemu-timer.h"
79#include "qemu-char.h"
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +010080#include "blockdev.h"
Ot ten Thije2ff39a32010-10-06 17:48:15 +010081#include "outputchannel.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070082#include "block.h"
83#include "audio/audio.h"
84#include "migration.h"
85#include "qemu_socket.h"
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +010086#include "qemu-queue.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070087#include "qemu_file.h"
Tim Baverstock622b8f42010-12-07 11:36:59 +000088#include "android/snapshot.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070089
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070090
91#define SELF_ANNOUNCE_ROUNDS 5
David 'Digit' Turner986acc92011-05-10 16:50:01 +020092
93#ifndef ETH_P_RARP
94#define ETH_P_RARP 0x8035
95#endif
96#define ARP_HTYPE_ETH 0x0001
97#define ARP_PTYPE_IP 0x0800
98#define ARP_OP_REQUEST_REV 0x3
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070099
David 'Digit' Turner5973c772011-05-10 07:06:00 +0200100static int announce_self_create(uint8_t *buf,
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700101 uint8_t *mac_addr)
102{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200103 /* Ethernet header. */
104 memset(buf, 0xff, 6); /* destination MAC addr */
105 memcpy(buf + 6, mac_addr, 6); /* source MAC addr */
106 *(uint16_t *)(buf + 12) = htons(ETH_P_RARP); /* ethertype */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700107
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200108 /* RARP header. */
109 *(uint16_t *)(buf + 14) = htons(ARP_HTYPE_ETH); /* hardware addr space */
110 *(uint16_t *)(buf + 16) = htons(ARP_PTYPE_IP); /* protocol addr space */
111 *(buf + 18) = 6; /* hardware addr length (ethernet) */
112 *(buf + 19) = 4; /* protocol addr length (IPv4) */
113 *(uint16_t *)(buf + 20) = htons(ARP_OP_REQUEST_REV); /* opcode */
114 memcpy(buf + 22, mac_addr, 6); /* source hw addr */
115 memset(buf + 28, 0x00, 4); /* source protocol addr */
116 memcpy(buf + 32, mac_addr, 6); /* target hw addr */
117 memset(buf + 38, 0x00, 4); /* target protocol addr */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700118
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200119 /* Padding to get up to 60 bytes (ethernet min packet size, minus FCS). */
120 memset(buf + 42, 0x00, 18);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700121
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200122 return 60; /* len (FCS will be added by hardware) */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700123}
124
125static void qemu_announce_self_once(void *opaque)
126{
127 int i, len;
128 VLANState *vlan;
129 VLANClientState *vc;
130 uint8_t buf[256];
131 static int count = SELF_ANNOUNCE_ROUNDS;
132 QEMUTimer *timer = *(QEMUTimer **)opaque;
133
134 for (i = 0; i < MAX_NICS; i++) {
135 if (!nd_table[i].used)
136 continue;
137 len = announce_self_create(buf, nd_table[i].macaddr);
138 vlan = nd_table[i].vlan;
139 for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
140 vc->receive(vc, buf, len);
141 }
142 }
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200143 if (--count) {
144 /* delay 50ms, 150ms, 250ms, ... */
145 qemu_mod_timer(timer, qemu_get_clock_ms(rt_clock) +
146 50 + (SELF_ANNOUNCE_ROUNDS - count - 1) * 100);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700147 } else {
148 qemu_del_timer(timer);
149 qemu_free_timer(timer);
150 }
151}
152
153void qemu_announce_self(void)
154{
155 static QEMUTimer *timer;
David 'Digit' Turner5973c772011-05-10 07:06:00 +0200156 timer = qemu_new_timer_ms(rt_clock, qemu_announce_self_once, &timer);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700157 qemu_announce_self_once(&timer);
158}
159
160/***********************************************************/
161/* savevm/loadvm support */
162
163#define IO_BUF_SIZE 32768
164
165struct QEMUFile {
166 QEMUFilePutBufferFunc *put_buffer;
167 QEMUFileGetBufferFunc *get_buffer;
168 QEMUFileCloseFunc *close;
169 QEMUFileRateLimit *rate_limit;
170 QEMUFileSetRateLimit *set_rate_limit;
David Turnera12820e2010-09-09 21:16:39 +0200171 QEMUFileGetRateLimit *get_rate_limit;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700172 void *opaque;
173 int is_write;
174
175 int64_t buf_offset; /* start of buffer when writing, end of buffer
176 when reading */
177 int buf_index;
178 int buf_size; /* 0 when writing */
179 uint8_t buf[IO_BUF_SIZE];
180
181 int has_error;
182};
183
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200184typedef struct QEMUFileStdio
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700185{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200186 FILE *stdio_file;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700187 QEMUFile *file;
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200188} QEMUFileStdio;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700189
190typedef struct QEMUFileSocket
191{
192 int fd;
193 QEMUFile *file;
194} QEMUFileSocket;
195
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200196static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700197{
198 QEMUFileSocket *s = opaque;
199 ssize_t len;
200
201 do {
202 len = recv(s->fd, (void *)buf, size, 0);
203 } while (len == -1 && socket_error() == EINTR);
204
205 if (len == -1)
206 len = -socket_error();
207
208 return len;
209}
210
211static int file_socket_close(void *opaque)
212{
213 QEMUFileSocket *s = opaque;
214 qemu_free(s);
215 return 0;
216}
217
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200218static int stdio_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, int size)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700219{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200220 QEMUFileStdio *s = opaque;
221 return fwrite(buf, 1, size, s->stdio_file);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700222}
223
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200224static int stdio_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700225{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200226 QEMUFileStdio *s = opaque;
227 FILE *fp = s->stdio_file;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700228 int bytes;
229
230 do {
231 clearerr(fp);
232 bytes = fread(buf, 1, size, fp);
233 } while ((bytes == 0) && ferror(fp) && (errno == EINTR));
234 return bytes;
235}
236
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200237static int stdio_pclose(void *opaque)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700238{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200239 QEMUFileStdio *s = opaque;
240 int ret;
241 ret = pclose(s->stdio_file);
242 qemu_free(s);
243 return ret;
244}
245
246static int stdio_fclose(void *opaque)
247{
248 QEMUFileStdio *s = opaque;
249 fclose(s->stdio_file);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700250 qemu_free(s);
251 return 0;
252}
253
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200254QEMUFile *qemu_popen(FILE *stdio_file, const char *mode)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700255{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200256 QEMUFileStdio *s;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700257
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200258 if (stdio_file == NULL || mode == NULL || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != 0) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700259 fprintf(stderr, "qemu_popen: Argument validity check failed\n");
260 return NULL;
261 }
262
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200263 s = qemu_mallocz(sizeof(QEMUFileStdio));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700264
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200265 s->stdio_file = stdio_file;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700266
267 if(mode[0] == 'r') {
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200268 s->file = qemu_fopen_ops(s, NULL, stdio_get_buffer, stdio_pclose,
269 NULL, NULL, NULL);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700270 } else {
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200271 s->file = qemu_fopen_ops(s, stdio_put_buffer, NULL, stdio_pclose,
272 NULL, NULL, NULL);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700273 }
274 return s->file;
275}
276
277QEMUFile *qemu_popen_cmd(const char *command, const char *mode)
278{
279 FILE *popen_file;
280
281 popen_file = popen(command, mode);
282 if(popen_file == NULL) {
283 return NULL;
284 }
285
286 return qemu_popen(popen_file, mode);
287}
288
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200289int qemu_stdio_fd(QEMUFile *f)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700290{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200291 QEMUFileStdio *p;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700292 int fd;
293
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200294 p = (QEMUFileStdio *)f->opaque;
295 fd = fileno(p->stdio_file);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700296
297 return fd;
298}
299
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200300QEMUFile *qemu_fdopen(int fd, const char *mode)
301{
302 QEMUFileStdio *s;
303
304 if (mode == NULL ||
305 (mode[0] != 'r' && mode[0] != 'w') ||
306 mode[1] != 'b' || mode[2] != 0) {
307 fprintf(stderr, "qemu_fdopen: Argument validity check failed\n");
308 return NULL;
309 }
310
311 s = qemu_mallocz(sizeof(QEMUFileStdio));
312 s->stdio_file = fdopen(fd, mode);
313 if (!s->stdio_file)
314 goto fail;
315
316 if(mode[0] == 'r') {
317 s->file = qemu_fopen_ops(s, NULL, stdio_get_buffer, stdio_fclose,
318 NULL, NULL, NULL);
319 } else {
320 s->file = qemu_fopen_ops(s, stdio_put_buffer, NULL, stdio_fclose,
321 NULL, NULL, NULL);
322 }
323 return s->file;
324
325fail:
326 qemu_free(s);
327 return NULL;
328}
329
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700330QEMUFile *qemu_fopen_socket(int fd)
331{
332 QEMUFileSocket *s = qemu_mallocz(sizeof(QEMUFileSocket));
333
334 s->fd = fd;
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200335 s->file = qemu_fopen_ops(s, NULL, socket_get_buffer, file_socket_close,
336 NULL, NULL, NULL);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700337 return s->file;
338}
339
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700340static int file_put_buffer(void *opaque, const uint8_t *buf,
341 int64_t pos, int size)
342{
343 QEMUFileStdio *s = opaque;
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200344 fseek(s->stdio_file, pos, SEEK_SET);
345 return fwrite(buf, 1, size, s->stdio_file);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700346}
347
348static int file_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
349{
350 QEMUFileStdio *s = opaque;
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200351 fseek(s->stdio_file, pos, SEEK_SET);
352 return fread(buf, 1, size, s->stdio_file);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700353}
354
355QEMUFile *qemu_fopen(const char *filename, const char *mode)
356{
357 QEMUFileStdio *s;
358
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200359 if (mode == NULL ||
360 (mode[0] != 'r' && mode[0] != 'w') ||
361 mode[1] != 'b' || mode[2] != 0) {
362 fprintf(stderr, "qemu_fopen: Argument validity check failed\n");
363 return NULL;
364 }
365
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700366 s = qemu_mallocz(sizeof(QEMUFileStdio));
367
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200368 s->stdio_file = fopen(filename, mode);
369 if (!s->stdio_file)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700370 goto fail;
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200371
372 if(mode[0] == 'w') {
373 s->file = qemu_fopen_ops(s, file_put_buffer, NULL, stdio_fclose,
374 NULL, NULL, NULL);
375 } else {
376 s->file = qemu_fopen_ops(s, NULL, file_get_buffer, stdio_fclose,
377 NULL, NULL, NULL);
378 }
379 return s->file;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700380fail:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700381 qemu_free(s);
382 return NULL;
383}
384
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700385static int block_put_buffer(void *opaque, const uint8_t *buf,
386 int64_t pos, int size)
387{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200388 bdrv_save_vmstate(opaque, buf, pos, size);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700389 return size;
390}
391
392static int block_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
393{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200394 return bdrv_load_vmstate(opaque, buf, pos, size);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700395}
396
397static int bdrv_fclose(void *opaque)
398{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700399 return 0;
400}
401
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200402static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int is_writable)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700403{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700404 if (is_writable)
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200405 return qemu_fopen_ops(bs, block_put_buffer, NULL, bdrv_fclose,
406 NULL, NULL, NULL);
407 return qemu_fopen_ops(bs, NULL, block_get_buffer, bdrv_fclose, NULL, NULL, NULL);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700408}
409
410QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer,
411 QEMUFileGetBufferFunc *get_buffer,
412 QEMUFileCloseFunc *close,
413 QEMUFileRateLimit *rate_limit,
David Turnera12820e2010-09-09 21:16:39 +0200414 QEMUFileSetRateLimit *set_rate_limit,
415 QEMUFileGetRateLimit *get_rate_limit)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700416{
417 QEMUFile *f;
418
419 f = qemu_mallocz(sizeof(QEMUFile));
420
421 f->opaque = opaque;
422 f->put_buffer = put_buffer;
423 f->get_buffer = get_buffer;
424 f->close = close;
425 f->rate_limit = rate_limit;
426 f->set_rate_limit = set_rate_limit;
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200427 f->get_rate_limit = get_rate_limit;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700428 f->is_write = 0;
429
430 return f;
431}
432
433int qemu_file_has_error(QEMUFile *f)
434{
435 return f->has_error;
436}
437
438void qemu_file_set_error(QEMUFile *f)
439{
440 f->has_error = 1;
441}
442
443void qemu_fflush(QEMUFile *f)
444{
445 if (!f->put_buffer)
446 return;
447
448 if (f->is_write && f->buf_index > 0) {
449 int len;
450
451 len = f->put_buffer(f->opaque, f->buf, f->buf_offset, f->buf_index);
452 if (len > 0)
453 f->buf_offset += f->buf_index;
454 else
455 f->has_error = 1;
456 f->buf_index = 0;
457 }
458}
459
460static void qemu_fill_buffer(QEMUFile *f)
461{
462 int len;
463
464 if (!f->get_buffer)
465 return;
466
467 if (f->is_write)
468 abort();
469
470 len = f->get_buffer(f->opaque, f->buf, f->buf_offset, IO_BUF_SIZE);
471 if (len > 0) {
472 f->buf_index = 0;
473 f->buf_size = len;
474 f->buf_offset += len;
475 } else if (len != -EAGAIN)
476 f->has_error = 1;
477}
478
479int qemu_fclose(QEMUFile *f)
480{
481 int ret = 0;
482 qemu_fflush(f);
483 if (f->close)
484 ret = f->close(f->opaque);
485 qemu_free(f);
486 return ret;
487}
488
489void qemu_file_put_notify(QEMUFile *f)
490{
491 f->put_buffer(f->opaque, NULL, 0, 0);
492}
493
494void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
495{
496 int l;
497
498 if (!f->has_error && f->is_write == 0 && f->buf_index > 0) {
499 fprintf(stderr,
500 "Attempted to write to buffer while read buffer is not empty\n");
501 abort();
502 }
503
504 while (!f->has_error && size > 0) {
505 l = IO_BUF_SIZE - f->buf_index;
506 if (l > size)
507 l = size;
508 memcpy(f->buf + f->buf_index, buf, l);
509 f->is_write = 1;
510 f->buf_index += l;
511 buf += l;
512 size -= l;
513 if (f->buf_index >= IO_BUF_SIZE)
514 qemu_fflush(f);
515 }
516}
517
518void qemu_put_byte(QEMUFile *f, int v)
519{
520 if (!f->has_error && f->is_write == 0 && f->buf_index > 0) {
521 fprintf(stderr,
522 "Attempted to write to buffer while read buffer is not empty\n");
523 abort();
524 }
525
526 f->buf[f->buf_index++] = v;
527 f->is_write = 1;
528 if (f->buf_index >= IO_BUF_SIZE)
529 qemu_fflush(f);
530}
531
532int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size1)
533{
534 int size, l;
535
536 if (f->is_write)
537 abort();
538
539 size = size1;
540 while (size > 0) {
541 l = f->buf_size - f->buf_index;
542 if (l == 0) {
543 qemu_fill_buffer(f);
544 l = f->buf_size - f->buf_index;
545 if (l == 0)
546 break;
547 }
548 if (l > size)
549 l = size;
550 memcpy(buf, f->buf + f->buf_index, l);
551 f->buf_index += l;
552 buf += l;
553 size -= l;
554 }
555 return size1 - size;
556}
557
558int qemu_get_byte(QEMUFile *f)
559{
560 if (f->is_write)
561 abort();
562
563 if (f->buf_index >= f->buf_size) {
564 qemu_fill_buffer(f);
565 if (f->buf_index >= f->buf_size)
566 return 0;
567 }
568 return f->buf[f->buf_index++];
569}
570
571int64_t qemu_ftell(QEMUFile *f)
572{
573 return f->buf_offset - f->buf_size + f->buf_index;
574}
575
576int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence)
577{
578 if (whence == SEEK_SET) {
579 /* nothing to do */
580 } else if (whence == SEEK_CUR) {
581 pos += qemu_ftell(f);
582 } else {
583 /* SEEK_END not supported */
584 return -1;
585 }
586 if (f->put_buffer) {
587 qemu_fflush(f);
588 f->buf_offset = pos;
589 } else {
590 f->buf_offset = pos;
591 f->buf_index = 0;
592 f->buf_size = 0;
593 }
594 return pos;
595}
596
597int qemu_file_rate_limit(QEMUFile *f)
598{
599 if (f->rate_limit)
600 return f->rate_limit(f->opaque);
601
602 return 0;
603}
604
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200605int64_t qemu_file_get_rate_limit(QEMUFile *f)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700606{
David 'Digit' Turner986acc92011-05-10 16:50:01 +0200607 if (f->get_rate_limit)
608 return f->get_rate_limit(f->opaque);
609
610 return 0;
611}
612
613int64_t qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate)
614{
615 /* any failed or completed migration keeps its state to allow probing of
616 * migration data, but has no associated file anymore */
617 if (f && f->set_rate_limit)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700618 return f->set_rate_limit(f->opaque, new_rate);
619
620 return 0;
621}
622
623void qemu_put_be16(QEMUFile *f, unsigned int v)
624{
625 qemu_put_byte(f, v >> 8);
626 qemu_put_byte(f, v);
627}
628
629void qemu_put_be32(QEMUFile *f, unsigned int v)
630{
631 qemu_put_byte(f, v >> 24);
632 qemu_put_byte(f, v >> 16);
633 qemu_put_byte(f, v >> 8);
634 qemu_put_byte(f, v);
635}
636
637void qemu_put_be64(QEMUFile *f, uint64_t v)
638{
639 qemu_put_be32(f, v >> 32);
640 qemu_put_be32(f, v);
641}
642
643unsigned int qemu_get_be16(QEMUFile *f)
644{
645 unsigned int v;
646 v = qemu_get_byte(f) << 8;
647 v |= qemu_get_byte(f);
648 return v;
649}
650
651unsigned int qemu_get_be32(QEMUFile *f)
652{
653 unsigned int v;
654 v = qemu_get_byte(f) << 24;
655 v |= qemu_get_byte(f) << 16;
656 v |= qemu_get_byte(f) << 8;
657 v |= qemu_get_byte(f);
658 return v;
659}
660
661uint64_t qemu_get_be64(QEMUFile *f)
662{
663 uint64_t v;
664 v = (uint64_t)qemu_get_be32(f) << 32;
665 v |= qemu_get_be32(f);
666 return v;
667}
668
669void qemu_put_struct(QEMUFile* f, const QField* fields, const void* s)
670{
671 const QField* qf = fields;
672
Ot ten Thije7fd67eb2010-07-29 10:26:01 +0100673 /* Iterate over struct fields */
674 while (qf->type != Q_FIELD_END) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700675 uint8_t* p = (uint8_t*)s + qf->offset;
676
677 switch (qf->type) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700678 case Q_FIELD_BYTE:
679 qemu_put_byte(f, p[0]);
680 break;
681 case Q_FIELD_INT16:
682 qemu_put_be16(f, ((uint16_t*)p)[0]);
683 break;
684 case Q_FIELD_INT32:
685 qemu_put_be32(f, ((uint32_t*)p)[0]);
686 break;
687 case Q_FIELD_INT64:
688 qemu_put_be64(f, ((uint64_t*)p)[0]);
689 break;
690 case Q_FIELD_BUFFER:
Ot ten Thije7fd67eb2010-07-29 10:26:01 +0100691 if (qf[1].type != Q_FIELD_BUFFER_SIZE ||
692 qf[2].type != Q_FIELD_BUFFER_SIZE)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700693 {
694 fprintf(stderr, "%s: invalid QFIELD_BUFFER item passed as argument. aborting\n",
695 __FUNCTION__ );
696 exit(1);
697 }
698 else
699 {
Ot ten Thije7fd67eb2010-07-29 10:26:01 +0100700 uint32_t size = ((uint32_t)qf[1].offset << 16) | (uint32_t)qf[2].offset;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700701
702 qemu_put_buffer(f, p, size);
703 qf += 2;
704 }
705 break;
706 default:
707 fprintf(stderr, "%s: invalid fields list passed as argument. aborting\n", __FUNCTION__);
708 exit(1);
709 }
710 qf++;
711 }
712}
713
714int qemu_get_struct(QEMUFile* f, const QField* fields, void* s)
715{
716 const QField* qf = fields;
717
Ot ten Thije7fd67eb2010-07-29 10:26:01 +0100718 /* Iterate over struct fields */
719 while (qf->type != Q_FIELD_END) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700720 uint8_t* p = (uint8_t*)s + qf->offset;
721
722 switch (qf->type) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700723 case Q_FIELD_BYTE:
724 p[0] = qemu_get_byte(f);
725 break;
726 case Q_FIELD_INT16:
727 ((uint16_t*)p)[0] = qemu_get_be16(f);
728 break;
729 case Q_FIELD_INT32:
730 ((uint32_t*)p)[0] = qemu_get_be32(f);
731 break;
732 case Q_FIELD_INT64:
733 ((uint64_t*)p)[0] = qemu_get_be64(f);
734 break;
735 case Q_FIELD_BUFFER:
Ot ten Thije7fd67eb2010-07-29 10:26:01 +0100736 if (qf[1].type != Q_FIELD_BUFFER_SIZE ||
737 qf[2].type != Q_FIELD_BUFFER_SIZE)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700738 {
739 fprintf(stderr, "%s: invalid QFIELD_BUFFER item passed as argument.\n",
740 __FUNCTION__ );
741 return -1;
742 }
743 else
744 {
Ot ten Thije7fd67eb2010-07-29 10:26:01 +0100745 uint32_t size = ((uint32_t)qf[1].offset << 16) | (uint32_t)qf[2].offset;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700746 int ret = qemu_get_buffer(f, p, size);
747
748 if (ret != size) {
749 fprintf(stderr, "%s: not enough bytes to load structure\n", __FUNCTION__);
750 return -1;
751 }
752 qf += 2;
753 }
754 break;
755 default:
756 fprintf(stderr, "%s: invalid fields list passed as argument. aborting\n", __FUNCTION__);
757 exit(1);
758 }
759 qf++;
760 }
761 return 0;
762}
763
Ot ten Thije871da2a2010-09-20 10:29:22 +0100764/* write a float to file */
765void qemu_put_float(QEMUFile *f, float v)
766{
767 uint8_t *bytes = (uint8_t*) &v;
768 qemu_put_buffer(f, bytes, sizeof(float));
769}
770
771/* read a float from file */
772float qemu_get_float(QEMUFile *f)
773{
774 uint8_t bytes[sizeof(float)];
775 qemu_get_buffer(f, bytes, sizeof(float));
776
777 return *((float*) bytes);
778}
779
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700780typedef struct SaveStateEntry {
781 char idstr[256];
782 int instance_id;
783 int version_id;
784 int section_id;
785 SaveLiveStateHandler *save_live_state;
786 SaveStateHandler *save_state;
787 LoadStateHandler *load_state;
788 void *opaque;
789 struct SaveStateEntry *next;
790} SaveStateEntry;
791
792static SaveStateEntry *first_se;
793
794/* TODO: Individual devices generally have very little idea about the rest
795 of the system, so instance_id should be removed/replaced.
796 Meanwhile pass -1 as instance_id if you do not already have a clearly
797 distinguishing id for all instances of your device class. */
798int register_savevm_live(const char *idstr,
799 int instance_id,
800 int version_id,
801 SaveLiveStateHandler *save_live_state,
802 SaveStateHandler *save_state,
803 LoadStateHandler *load_state,
804 void *opaque)
805{
806 SaveStateEntry *se, **pse;
807 static int global_section_id;
808
809 se = qemu_malloc(sizeof(SaveStateEntry));
810 pstrcpy(se->idstr, sizeof(se->idstr), idstr);
811 se->instance_id = (instance_id == -1) ? 0 : instance_id;
812 se->version_id = version_id;
813 se->section_id = global_section_id++;
814 se->save_live_state = save_live_state;
815 se->save_state = save_state;
816 se->load_state = load_state;
817 se->opaque = opaque;
818 se->next = NULL;
819
820 /* add at the end of list */
821 pse = &first_se;
822 while (*pse != NULL) {
823 if (instance_id == -1
824 && strcmp(se->idstr, (*pse)->idstr) == 0
825 && se->instance_id <= (*pse)->instance_id)
826 se->instance_id = (*pse)->instance_id + 1;
827 pse = &(*pse)->next;
828 }
829 *pse = se;
830 return 0;
831}
832
833int register_savevm(const char *idstr,
834 int instance_id,
835 int version_id,
836 SaveStateHandler *save_state,
837 LoadStateHandler *load_state,
838 void *opaque)
839{
840 return register_savevm_live(idstr, instance_id, version_id,
841 NULL, save_state, load_state, opaque);
842}
843
844void unregister_savevm(const char *idstr, void *opaque)
845{
846 SaveStateEntry **pse;
847
848 pse = &first_se;
849 while (*pse != NULL) {
850 if (strcmp((*pse)->idstr, idstr) == 0 && (*pse)->opaque == opaque) {
851 SaveStateEntry *next = (*pse)->next;
852 qemu_free(*pse);
853 *pse = next;
854 continue;
855 }
856 pse = &(*pse)->next;
857 }
858}
859
860#define QEMU_VM_FILE_MAGIC 0x5145564d
861#define QEMU_VM_FILE_VERSION_COMPAT 0x00000002
862#define QEMU_VM_FILE_VERSION 0x00000003
863
864#define QEMU_VM_EOF 0x00
865#define QEMU_VM_SECTION_START 0x01
866#define QEMU_VM_SECTION_PART 0x02
867#define QEMU_VM_SECTION_END 0x03
868#define QEMU_VM_SECTION_FULL 0x04
869
870int qemu_savevm_state_begin(QEMUFile *f)
871{
872 SaveStateEntry *se;
873
874 qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
875 qemu_put_be32(f, QEMU_VM_FILE_VERSION);
876
877 for (se = first_se; se != NULL; se = se->next) {
878 int len;
879
880 if (se->save_live_state == NULL)
881 continue;
882
883 /* Section type */
884 qemu_put_byte(f, QEMU_VM_SECTION_START);
885 qemu_put_be32(f, se->section_id);
886
887 /* ID string */
888 len = strlen(se->idstr);
889 qemu_put_byte(f, len);
890 qemu_put_buffer(f, (uint8_t *)se->idstr, len);
891
892 qemu_put_be32(f, se->instance_id);
893 qemu_put_be32(f, se->version_id);
894
895 se->save_live_state(f, QEMU_VM_SECTION_START, se->opaque);
896 }
897
898 if (qemu_file_has_error(f))
899 return -EIO;
900
901 return 0;
902}
903
904int qemu_savevm_state_iterate(QEMUFile *f)
905{
906 SaveStateEntry *se;
907 int ret = 1;
908
909 for (se = first_se; se != NULL; se = se->next) {
910 if (se->save_live_state == NULL)
911 continue;
912
913 /* Section type */
914 qemu_put_byte(f, QEMU_VM_SECTION_PART);
915 qemu_put_be32(f, se->section_id);
916
917 ret &= !!se->save_live_state(f, QEMU_VM_SECTION_PART, se->opaque);
918 }
919
920 if (ret)
921 return 1;
922
923 if (qemu_file_has_error(f))
924 return -EIO;
925
926 return 0;
927}
928
929int qemu_savevm_state_complete(QEMUFile *f)
930{
931 SaveStateEntry *se;
932
933 for (se = first_se; se != NULL; se = se->next) {
934 if (se->save_live_state == NULL)
935 continue;
936
937 /* Section type */
938 qemu_put_byte(f, QEMU_VM_SECTION_END);
939 qemu_put_be32(f, se->section_id);
940
941 se->save_live_state(f, QEMU_VM_SECTION_END, se->opaque);
942 }
943
944 for(se = first_se; se != NULL; se = se->next) {
945 int len;
946
Ot ten Thije8f2de6d2010-09-30 14:17:10 +0100947 if (se->save_state == NULL)
948 continue;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700949
950 /* Section type */
951 qemu_put_byte(f, QEMU_VM_SECTION_FULL);
952 qemu_put_be32(f, se->section_id);
953
954 /* ID string */
955 len = strlen(se->idstr);
956 qemu_put_byte(f, len);
957 qemu_put_buffer(f, (uint8_t *)se->idstr, len);
958
959 qemu_put_be32(f, se->instance_id);
960 qemu_put_be32(f, se->version_id);
961
962 se->save_state(f, se->opaque);
963 }
964
965 qemu_put_byte(f, QEMU_VM_EOF);
966
967 if (qemu_file_has_error(f))
968 return -EIO;
969
970 return 0;
971}
972
973int qemu_savevm_state(QEMUFile *f)
974{
975 int saved_vm_running;
976 int ret;
977
978 saved_vm_running = vm_running;
979 vm_stop(0);
980
981 bdrv_flush_all();
982
983 ret = qemu_savevm_state_begin(f);
984 if (ret < 0)
985 goto out;
986
987 do {
988 ret = qemu_savevm_state_iterate(f);
989 if (ret < 0)
990 goto out;
991 } while (ret == 0);
992
993 ret = qemu_savevm_state_complete(f);
994
995out:
996 if (qemu_file_has_error(f))
997 ret = -EIO;
998
999 if (!ret && saved_vm_running)
1000 vm_start();
1001
1002 return ret;
1003}
1004
1005static SaveStateEntry *find_se(const char *idstr, int instance_id)
1006{
1007 SaveStateEntry *se;
1008
1009 for(se = first_se; se != NULL; se = se->next) {
1010 if (!strcmp(se->idstr, idstr) &&
1011 instance_id == se->instance_id)
1012 return se;
1013 }
1014 return NULL;
1015}
1016
1017typedef struct LoadStateEntry {
1018 SaveStateEntry *se;
1019 int section_id;
1020 int version_id;
1021 struct LoadStateEntry *next;
1022} LoadStateEntry;
1023
1024static int qemu_loadvm_state_v2(QEMUFile *f)
1025{
1026 SaveStateEntry *se;
1027 int len, ret, instance_id, record_len, version_id;
1028 int64_t total_len, end_pos, cur_pos;
1029 char idstr[256];
1030
1031 total_len = qemu_get_be64(f);
1032 end_pos = total_len + qemu_ftell(f);
1033 for(;;) {
1034 if (qemu_ftell(f) >= end_pos)
1035 break;
1036 len = qemu_get_byte(f);
1037 qemu_get_buffer(f, (uint8_t *)idstr, len);
1038 idstr[len] = '\0';
1039 instance_id = qemu_get_be32(f);
1040 version_id = qemu_get_be32(f);
1041 record_len = qemu_get_be32(f);
1042 cur_pos = qemu_ftell(f);
1043 se = find_se(idstr, instance_id);
1044 if (!se) {
1045 fprintf(stderr, "qemu: warning: instance 0x%x of device '%s' not present in current VM\n",
1046 instance_id, idstr);
1047 } else {
1048 ret = se->load_state(f, se->opaque, version_id);
1049 if (ret < 0) {
1050 fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
1051 instance_id, idstr);
1052 return ret;
1053 }
1054 }
1055 /* always seek to exact end of record */
1056 qemu_fseek(f, cur_pos + record_len, SEEK_SET);
1057 }
1058
1059 if (qemu_file_has_error(f))
1060 return -EIO;
1061
1062 return 0;
1063}
1064
1065int qemu_loadvm_state(QEMUFile *f)
1066{
1067 LoadStateEntry *first_le = NULL;
1068 uint8_t section_type;
1069 unsigned int v;
1070 int ret;
1071
1072 v = qemu_get_be32(f);
1073 if (v != QEMU_VM_FILE_MAGIC)
1074 return -EINVAL;
1075
1076 v = qemu_get_be32(f);
1077 if (v == QEMU_VM_FILE_VERSION_COMPAT)
1078 return qemu_loadvm_state_v2(f);
1079 if (v != QEMU_VM_FILE_VERSION)
1080 return -ENOTSUP;
1081
1082 while ((section_type = qemu_get_byte(f)) != QEMU_VM_EOF) {
1083 uint32_t instance_id, version_id, section_id;
1084 LoadStateEntry *le;
1085 SaveStateEntry *se;
1086 char idstr[257];
1087 int len;
1088
1089 switch (section_type) {
1090 case QEMU_VM_SECTION_START:
1091 case QEMU_VM_SECTION_FULL:
1092 /* Read section start */
1093 section_id = qemu_get_be32(f);
1094 len = qemu_get_byte(f);
1095 qemu_get_buffer(f, (uint8_t *)idstr, len);
1096 idstr[len] = 0;
1097 instance_id = qemu_get_be32(f);
1098 version_id = qemu_get_be32(f);
1099
1100 /* Find savevm section */
1101 se = find_se(idstr, instance_id);
1102 if (se == NULL) {
1103 fprintf(stderr, "Unknown savevm section or instance '%s' %d\n", idstr, instance_id);
1104 ret = -EINVAL;
1105 goto out;
1106 }
1107
1108 /* Validate version */
1109 if (version_id > se->version_id) {
1110 fprintf(stderr, "savevm: unsupported version %d for '%s' v%d\n",
1111 version_id, idstr, se->version_id);
1112 ret = -EINVAL;
1113 goto out;
1114 }
1115
1116 /* Add entry */
1117 le = qemu_mallocz(sizeof(*le));
1118
1119 le->se = se;
1120 le->section_id = section_id;
1121 le->version_id = version_id;
1122 le->next = first_le;
1123 first_le = le;
1124
1125 le->se->load_state(f, le->se->opaque, le->version_id);
1126 break;
1127 case QEMU_VM_SECTION_PART:
1128 case QEMU_VM_SECTION_END:
1129 section_id = qemu_get_be32(f);
1130
1131 for (le = first_le; le && le->section_id != section_id; le = le->next);
1132 if (le == NULL) {
1133 fprintf(stderr, "Unknown savevm section %d\n", section_id);
1134 ret = -EINVAL;
1135 goto out;
1136 }
1137
1138 le->se->load_state(f, le->se->opaque, le->version_id);
1139 break;
1140 default:
1141 fprintf(stderr, "Unknown savevm section type %d\n", section_type);
1142 ret = -EINVAL;
1143 goto out;
1144 }
1145 }
1146
1147 ret = 0;
1148
1149out:
1150 while (first_le) {
1151 LoadStateEntry *le = first_le;
1152 first_le = first_le->next;
1153 qemu_free(le);
1154 }
1155
1156 if (qemu_file_has_error(f))
1157 ret = -EIO;
1158
1159 return ret;
1160}
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001161#if 0
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001162static BlockDriverState *get_bs_snapshots(void)
1163{
1164 BlockDriverState *bs;
1165 int i;
1166
1167 if (bs_snapshots)
1168 return bs_snapshots;
1169 for(i = 0; i <= nb_drives; i++) {
1170 bs = drives_table[i].bdrv;
1171 if (bdrv_can_snapshot(bs))
1172 goto ok;
1173 }
1174 return NULL;
1175 ok:
1176 bs_snapshots = bs;
1177 return bs;
1178}
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001179#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001180static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
1181 const char *name)
1182{
1183 QEMUSnapshotInfo *sn_tab, *sn;
1184 int nb_sns, i, ret;
1185
1186 ret = -ENOENT;
1187 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1188 if (nb_sns < 0)
1189 return ret;
1190 for(i = 0; i < nb_sns; i++) {
1191 sn = &sn_tab[i];
1192 if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
1193 *sn_info = *sn;
1194 ret = 0;
1195 break;
1196 }
1197 }
1198 qemu_free(sn_tab);
1199 return ret;
1200}
1201
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001202static int
1203monitor_output_channel_cb(void* opaque, const char* fmt, va_list ap)
1204{
1205 return monitor_vprintf((Monitor*) opaque, fmt, ap);
1206}
1207
1208
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001209void do_savevm(Monitor *mon, const char *name)
1210{
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001211 OutputChannel *oc = output_channel_alloc(mon, monitor_output_channel_cb);
1212 do_savevm_oc(oc, name);
1213 output_channel_free(oc);
1214}
1215
1216void do_savevm_oc(OutputChannel *err, const char *name)
1217{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001218 BlockDriverState *bs, *bs1;
1219 QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001220 int must_delete, ret;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001221 BlockDriverInfo bdi1, *bdi = &bdi1;
1222 QEMUFile *f;
1223 int saved_vm_running;
1224 uint32_t vm_state_size;
1225#ifdef _WIN32
1226 struct _timeb tb;
1227#else
1228 struct timeval tv;
1229#endif
1230
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001231 bs = bdrv_snapshots();
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001232 if (!bs) {
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001233 output_channel_printf(err, "No block device can accept snapshots\n");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001234 return;
1235 }
1236
1237 /* ??? Should this occur after vm_stop? */
1238 qemu_aio_flush();
1239
1240 saved_vm_running = vm_running;
1241 vm_stop(0);
1242
1243 must_delete = 0;
1244 if (name) {
1245 ret = bdrv_snapshot_find(bs, old_sn, name);
1246 if (ret >= 0) {
1247 must_delete = 1;
1248 }
1249 }
1250 memset(sn, 0, sizeof(*sn));
1251 if (must_delete) {
1252 pstrcpy(sn->name, sizeof(sn->name), old_sn->name);
1253 pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str);
1254 } else {
1255 if (name)
1256 pstrcpy(sn->name, sizeof(sn->name), name);
1257 }
1258
1259 /* fill auxiliary fields */
1260#ifdef _WIN32
1261 _ftime(&tb);
1262 sn->date_sec = tb.time;
1263 sn->date_nsec = tb.millitm * 1000000;
1264#else
1265 gettimeofday(&tv, NULL);
1266 sn->date_sec = tv.tv_sec;
1267 sn->date_nsec = tv.tv_usec * 1000;
1268#endif
David 'Digit' Turner5973c772011-05-10 07:06:00 +02001269 sn->vm_clock_nsec = qemu_get_clock_ns(vm_clock);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001270
1271 if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001272 output_channel_printf(err, "Device %s does not support VM state snapshots\n",
1273 bdrv_get_device_name(bs));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001274 goto the_end;
1275 }
1276
1277 /* save the VM state */
David 'Digit' Turner986acc92011-05-10 16:50:01 +02001278 f = qemu_fopen_bdrv(bs, 1);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001279 if (!f) {
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001280 output_channel_printf(err, "Could not open VM state file\n");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001281 goto the_end;
1282 }
1283 ret = qemu_savevm_state(f);
1284 vm_state_size = qemu_ftell(f);
1285 qemu_fclose(f);
1286 if (ret < 0) {
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001287 output_channel_printf(err, "Error %d while writing VM\n", ret);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001288 goto the_end;
1289 }
1290
1291 /* create the snapshots */
1292
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001293 bs1 = NULL;
1294 while ((bs1 = bdrv_next(bs1))) {
Ot ten Thije8f2de6d2010-09-30 14:17:10 +01001295 if (bdrv_can_snapshot(bs1)) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001296 if (must_delete) {
1297 ret = bdrv_snapshot_delete(bs1, old_sn->id_str);
1298 if (ret < 0) {
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001299 output_channel_printf(err,
1300 "Error while deleting snapshot on '%s'\n",
1301 bdrv_get_device_name(bs1));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001302 }
1303 }
1304 /* Write VM state size only to the image that contains the state */
1305 sn->vm_state_size = (bs == bs1 ? vm_state_size : 0);
1306 ret = bdrv_snapshot_create(bs1, sn);
1307 if (ret < 0) {
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001308 output_channel_printf(err, "Error while creating snapshot on '%s'\n",
1309 bdrv_get_device_name(bs1));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001310 }
1311 }
1312 }
1313
1314 the_end:
1315 if (saved_vm_running)
1316 vm_start();
1317}
1318
1319void do_loadvm(Monitor *mon, const char *name)
1320{
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001321 OutputChannel *oc = output_channel_alloc(mon, monitor_output_channel_cb);
Tim Baverstock622b8f42010-12-07 11:36:59 +00001322 android_snapshot_update_time_request = 1;
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001323 do_loadvm_oc(oc, name);
1324 output_channel_free(oc);
1325}
1326
1327void do_loadvm_oc(OutputChannel *err, const char *name)
1328{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001329 BlockDriverState *bs, *bs1;
1330 BlockDriverInfo bdi1, *bdi = &bdi1;
1331 QEMUSnapshotInfo sn;
1332 QEMUFile *f;
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001333 int ret;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001334 int saved_vm_running;
1335
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001336 bs = bdrv_snapshots();
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001337 if (!bs) {
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001338 output_channel_printf(err, "No block device supports snapshots\n");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001339 return;
1340 }
1341
1342 /* Flush all IO requests so they don't interfere with the new state. */
1343 qemu_aio_flush();
1344
1345 saved_vm_running = vm_running;
1346 vm_stop(0);
1347
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001348 bs1 = NULL;
1349 while ((bs1 = bdrv_next(bs))) {
Ot ten Thije8f2de6d2010-09-30 14:17:10 +01001350 if (bdrv_can_snapshot(bs1)) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001351 ret = bdrv_snapshot_goto(bs1, name);
1352 if (ret < 0) {
1353 if (bs != bs1)
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001354 output_channel_printf(err, "Warning: ");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001355 switch(ret) {
1356 case -ENOTSUP:
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001357 output_channel_printf(err,
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001358 "Snapshots not supported on device '%s'\n",
1359 bdrv_get_device_name(bs1));
1360 break;
1361 case -ENOENT:
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001362 output_channel_printf(err, "Could not find snapshot '%s' on "
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001363 "device '%s'\n",
1364 name, bdrv_get_device_name(bs1));
1365 break;
1366 default:
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001367 output_channel_printf(err, "Error %d while activating snapshot on"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001368 " '%s'\n", ret, bdrv_get_device_name(bs1));
1369 break;
1370 }
1371 /* fatal on snapshot block device */
1372 if (bs == bs1)
1373 goto the_end;
1374 }
1375 }
1376 }
1377
1378 if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001379 output_channel_printf(err, "Device %s does not support VM state snapshots\n",
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001380 bdrv_get_device_name(bs));
1381 return;
1382 }
1383
1384 /* Don't even try to load empty VM states */
1385 ret = bdrv_snapshot_find(bs, &sn, name);
1386 if ((ret >= 0) && (sn.vm_state_size == 0))
1387 goto the_end;
1388
1389 /* restore the VM state */
David 'Digit' Turner986acc92011-05-10 16:50:01 +02001390 f = qemu_fopen_bdrv(bs, 0);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001391 if (!f) {
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001392 output_channel_printf(err, "Could not open VM state file\n");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001393 goto the_end;
1394 }
1395 ret = qemu_loadvm_state(f);
1396 qemu_fclose(f);
1397 if (ret < 0) {
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001398 output_channel_printf(err, "Error %d while loading VM state\n", ret);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001399 }
1400 the_end:
1401 if (saved_vm_running)
1402 vm_start();
1403}
1404
1405void do_delvm(Monitor *mon, const char *name)
1406{
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001407 OutputChannel *oc = output_channel_alloc(mon, monitor_output_channel_cb);
1408 do_delvm_oc(oc, name);
1409 output_channel_free(oc);
1410}
1411void do_delvm_oc(OutputChannel *err, const char *name)
1412{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001413 BlockDriverState *bs, *bs1;
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001414 int ret;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001415
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001416 bs = bdrv_snapshots();
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001417 if (!bs) {
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001418 output_channel_printf(err, "No block device supports snapshots\n");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001419 return;
1420 }
1421
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001422 bs1 = NULL;
1423 while ((bs1 = bdrv_next(bs1))) {
Ot ten Thije8f2de6d2010-09-30 14:17:10 +01001424 if (bdrv_can_snapshot(bs1)) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001425 ret = bdrv_snapshot_delete(bs1, name);
1426 if (ret < 0) {
1427 if (ret == -ENOTSUP)
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001428 output_channel_printf(err,
1429 "Snapshots not supported on device '%s'\n",
1430 bdrv_get_device_name(bs1));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001431 else
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001432 output_channel_printf(err, "Error %d while deleting snapshot on "
1433 "'%s'\n", ret, bdrv_get_device_name(bs1));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001434 }
1435 }
1436 }
1437}
1438
1439void do_info_snapshots(Monitor *mon)
1440{
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001441 OutputChannel *oc = output_channel_alloc(mon, monitor_output_channel_cb);
1442 do_info_snapshots_oc(oc, oc);
1443 output_channel_free(oc);
1444}
1445
1446void do_info_snapshots_oc(OutputChannel *out, OutputChannel *err)
1447{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001448 BlockDriverState *bs, *bs1;
1449 QEMUSnapshotInfo *sn_tab, *sn;
1450 int nb_sns, i;
1451 char buf[256];
1452
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001453 bs = bdrv_snapshots();
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001454 if (!bs) {
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001455 output_channel_printf(err, "No available block device supports snapshots\n");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001456 return;
1457 }
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001458 output_channel_printf(out, "Snapshot devices:");
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001459 bs1 = NULL;
1460 while ((bs1 = bdrv_next(bs1))) {
Ot ten Thije8f2de6d2010-09-30 14:17:10 +01001461 if (bdrv_can_snapshot(bs1)) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001462 if (bs == bs1)
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001463 output_channel_printf(out, " %s", bdrv_get_device_name(bs1));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001464 }
1465 }
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001466 output_channel_printf(out, "\n");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001467
1468 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1469 if (nb_sns < 0) {
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001470 output_channel_printf(err, "bdrv_snapshot_list: error %d\n", nb_sns);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001471 return;
1472 }
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001473 output_channel_printf(out, "Snapshot list (from %s):\n",
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001474 bdrv_get_device_name(bs));
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001475 output_channel_printf(out, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001476 for(i = 0; i < nb_sns; i++) {
1477 sn = &sn_tab[i];
Ot ten Thije2ff39a32010-10-06 17:48:15 +01001478 output_channel_printf(out, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001479 }
1480 qemu_free(sn_tab);
1481}