blob: ab380c8a44368b916161e032d13e127e4afb54cf [file] [log] [blame]
bellardea2384d2004-08-01 21:59:26 +00001/*
bellardfb43f4d2006-08-07 21:34:46 +00002 * QEMU disk image utility
ths5fafdf22007-09-16 21:08:06 +00003 *
bellard68d0f702008-01-06 17:21:48 +00004 * Copyright (c) 2003-2008 Fabrice Bellard
ths5fafdf22007-09-16 21:08:06 +00005 *
bellardea2384d2004-08-01 21:59:26 +00006 * 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 */
pbrookfaf07962007-11-11 02:51:17 +000024#include "qemu-common.h"
aliguorif7b4a942009-01-07 17:40:15 +000025#include "osdep.h"
thsec36ba12007-09-16 21:59:02 +000026#include "block_int.h"
balrog926c2d22007-10-31 01:11:44 +000027#include <assert.h>
aliguori9230eaf2009-03-28 17:55:19 +000028#include <stdio.h>
bellardea2384d2004-08-01 21:59:26 +000029
bellarde8445332006-06-14 15:32:10 +000030#ifdef _WIN32
31#include <windows.h>
32#endif
33
aurel32137519c2008-11-30 19:12:49 +000034/* Default to cache=writeback as data integrity is not important for qemu-tcg. */
35#define BRDV_O_FLAGS BDRV_O_CACHE_WB
36
malca5e50b22009-02-01 22:19:27 +000037static void QEMU_NORETURN error(const char *fmt, ...)
bellardea2384d2004-08-01 21:59:26 +000038{
39 va_list ap;
40 va_start(ap, fmt);
bellard57d1a2b2004-08-03 21:15:11 +000041 fprintf(stderr, "qemu-img: ");
bellardea2384d2004-08-01 21:59:26 +000042 vfprintf(stderr, fmt, ap);
43 fprintf(stderr, "\n");
44 exit(1);
45 va_end(ap);
46}
47
48static void format_print(void *opaque, const char *name)
49{
50 printf(" %s", name);
51}
52
blueswir1d2c639d2009-01-24 18:19:25 +000053/* Please keep in synch with qemu-img.texi */
pbrook3f379ab2007-11-11 03:33:13 +000054static void help(void)
bellardea2384d2004-08-01 21:59:26 +000055{
bellard68d0f702008-01-06 17:21:48 +000056 printf("qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fabrice Bellard\n"
bellard57d1a2b2004-08-03 21:15:11 +000057 "usage: qemu-img command [command options]\n"
bellardea2384d2004-08-01 21:59:26 +000058 "QEMU disk image utility\n"
59 "\n"
60 "Command syntax:\n"
aliguori9230eaf2009-03-28 17:55:19 +000061 " create [-e] [-6] [-F fmt] [-b base_image] [-f fmt] filename [size]\n"
bellardea2384d2004-08-01 21:59:26 +000062 " commit [-f fmt] filename\n"
thsf58c7b32008-06-05 21:53:49 +000063 " convert [-c] [-e] [-6] [-f fmt] [-O output_fmt] [-B output_base_image] filename [filename2 [...]] output_filename\n"
bellardea2384d2004-08-01 21:59:26 +000064 " info [-f fmt] filename\n"
blueswir1d2c639d2009-01-24 18:19:25 +000065 " snapshot [-l | -a snapshot | -c snapshot | -d snapshot] filename\n"
bellardea2384d2004-08-01 21:59:26 +000066 "\n"
67 "Command parameters:\n"
68 " 'filename' is a disk image filename\n"
69 " 'base_image' is the read-only disk image which is used as base for a copy on\n"
70 " write image; the copy on write image only stores the modified data\n"
thsf58c7b32008-06-05 21:53:49 +000071 " 'output_base_image' forces the output image to be created as a copy on write\n"
72 " image of the specified base image; 'output_base_image' should have the same\n"
73 " content as the input's base image, however the path, image format, etc may\n"
74 " differ\n"
bellardea2384d2004-08-01 21:59:26 +000075 " 'fmt' is the disk image format. It is guessed automatically in most cases\n"
blueswir1d2c639d2009-01-24 18:19:25 +000076 " 'size' is the disk image size in kilobytes. Optional suffixes\n"
aurel322fbc4092009-03-08 19:49:51 +000077 " 'M' (megabyte, 1024 * 1024) and 'G' (gigabyte, 1024 * 1024 * 1024) are\n"
78 " supported any 'k' or 'K' is ignored\n"
bellardea2384d2004-08-01 21:59:26 +000079 " 'output_filename' is the destination disk image filename\n"
80 " 'output_fmt' is the destination format\n"
81 " '-c' indicates that target image must be compressed (qcow format only)\n"
82 " '-e' indicates that the target image must be encrypted (qcow format only)\n"
thsec36ba12007-09-16 21:59:02 +000083 " '-6' indicates that the target image must use compatibility level 6 (vmdk format only)\n"
blueswir1d2c639d2009-01-24 18:19:25 +000084 " '-h' with or without a command shows this help and lists the supported formats\n"
aliguorif7b4a942009-01-07 17:40:15 +000085 "\n"
blueswir1d2c639d2009-01-24 18:19:25 +000086 "Parameters to snapshot subcommand:\n"
87 " 'snapshot' is the name of the snapshot to create, apply or delete\n"
88 " '-a' applies a snapshot (revert disk to saved state)\n"
89 " '-c' creates a snapshot\n"
90 " '-d' deletes a snapshot\n"
91 " '-l' lists all snapshots in the given image\n"
bellardea2384d2004-08-01 21:59:26 +000092 );
blueswir1d2c639d2009-01-24 18:19:25 +000093 printf("\nSupported formats:");
bellardea2384d2004-08-01 21:59:26 +000094 bdrv_iterate_format(format_print, NULL);
95 printf("\n");
96 exit(1);
97}
98
bellardea2384d2004-08-01 21:59:26 +000099#if defined(WIN32)
100/* XXX: put correct support for win32 */
101static int read_password(char *buf, int buf_size)
102{
103 int c, i;
104 printf("Password: ");
105 fflush(stdout);
106 i = 0;
107 for(;;) {
108 c = getchar();
109 if (c == '\n')
110 break;
111 if (i < (buf_size - 1))
112 buf[i++] = c;
113 }
114 buf[i] = '\0';
115 return 0;
116}
117
118#else
119
120#include <termios.h>
121
122static struct termios oldtty;
123
124static void term_exit(void)
125{
126 tcsetattr (0, TCSANOW, &oldtty);
127}
128
129static void term_init(void)
130{
131 struct termios tty;
132
133 tcgetattr (0, &tty);
134 oldtty = tty;
135
136 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
137 |INLCR|IGNCR|ICRNL|IXON);
138 tty.c_oflag |= OPOST;
139 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
140 tty.c_cflag &= ~(CSIZE|PARENB);
141 tty.c_cflag |= CS8;
142 tty.c_cc[VMIN] = 1;
143 tty.c_cc[VTIME] = 0;
ths3b46e622007-09-17 08:09:54 +0000144
bellardea2384d2004-08-01 21:59:26 +0000145 tcsetattr (0, TCSANOW, &tty);
146
147 atexit(term_exit);
148}
149
pbrook3f379ab2007-11-11 03:33:13 +0000150static int read_password(char *buf, int buf_size)
bellardea2384d2004-08-01 21:59:26 +0000151{
152 uint8_t ch;
153 int i, ret;
154
155 printf("password: ");
156 fflush(stdout);
157 term_init();
158 i = 0;
159 for(;;) {
160 ret = read(0, &ch, 1);
161 if (ret == -1) {
162 if (errno == EAGAIN || errno == EINTR) {
163 continue;
164 } else {
165 ret = -1;
166 break;
167 }
168 } else if (ret == 0) {
169 ret = -1;
170 break;
171 } else {
172 if (ch == '\r') {
173 ret = 0;
174 break;
175 }
176 if (i < (buf_size - 1))
177 buf[i++] = ch;
178 }
179 }
180 term_exit();
181 buf[i] = '\0';
182 printf("\n");
183 return ret;
184}
185#endif
186
bellard75c23802004-08-27 21:28:58 +0000187static BlockDriverState *bdrv_new_open(const char *filename,
188 const char *fmt)
189{
190 BlockDriverState *bs;
191 BlockDriver *drv;
192 char password[256];
193
194 bs = bdrv_new("");
195 if (!bs)
196 error("Not enough memory");
197 if (fmt) {
198 drv = bdrv_find_format(fmt);
199 if (!drv)
200 error("Unknown file format '%s'", fmt);
201 } else {
202 drv = NULL;
203 }
aurel32137519c2008-11-30 19:12:49 +0000204 if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
bellard75c23802004-08-27 21:28:58 +0000205 error("Could not open '%s'", filename);
206 }
207 if (bdrv_is_encrypted(bs)) {
208 printf("Disk image '%s' is encrypted.\n", filename);
209 if (read_password(password, sizeof(password)) < 0)
210 error("No password given");
211 if (bdrv_set_key(bs, password) < 0)
212 error("invalid password");
213 }
214 return bs;
215}
216
bellardea2384d2004-08-01 21:59:26 +0000217static int img_create(int argc, char **argv)
218{
thsec36ba12007-09-16 21:59:02 +0000219 int c, ret, flags;
bellardea2384d2004-08-01 21:59:26 +0000220 const char *fmt = "raw";
aliguori9230eaf2009-03-28 17:55:19 +0000221 const char *base_fmt = NULL;
bellardea2384d2004-08-01 21:59:26 +0000222 const char *filename;
223 const char *base_filename = NULL;
ths96b8f132007-12-17 01:35:20 +0000224 uint64_t size;
aurel3224501482009-03-08 19:49:44 +0000225 double sizef;
bellardea2384d2004-08-01 21:59:26 +0000226 const char *p;
227 BlockDriver *drv;
ths3b46e622007-09-17 08:09:54 +0000228
thsec36ba12007-09-16 21:59:02 +0000229 flags = 0;
bellardea2384d2004-08-01 21:59:26 +0000230 for(;;) {
aliguori9230eaf2009-03-28 17:55:19 +0000231 c = getopt(argc, argv, "F:b:f:he6");
bellardea2384d2004-08-01 21:59:26 +0000232 if (c == -1)
233 break;
234 switch(c) {
235 case 'h':
236 help();
237 break;
aliguori9230eaf2009-03-28 17:55:19 +0000238 case 'F':
239 base_fmt = optarg;
240 break;
bellardea2384d2004-08-01 21:59:26 +0000241 case 'b':
242 base_filename = optarg;
243 break;
244 case 'f':
245 fmt = optarg;
246 break;
247 case 'e':
thsec36ba12007-09-16 21:59:02 +0000248 flags |= BLOCK_FLAG_ENCRYPT;
bellardea2384d2004-08-01 21:59:26 +0000249 break;
thsd8871c52007-10-24 16:11:42 +0000250 case '6':
thsec36ba12007-09-16 21:59:02 +0000251 flags |= BLOCK_FLAG_COMPAT6;
thsd8871c52007-10-24 16:11:42 +0000252 break;
bellardea2384d2004-08-01 21:59:26 +0000253 }
254 }
ths5fafdf22007-09-16 21:08:06 +0000255 if (optind >= argc)
bellardea2384d2004-08-01 21:59:26 +0000256 help();
257 filename = argv[optind++];
258 size = 0;
bellard75c23802004-08-27 21:28:58 +0000259 if (base_filename) {
aliguorie94f3a62008-08-01 15:04:00 +0000260 BlockDriverState *bs;
aliguori9230eaf2009-03-28 17:55:19 +0000261 BlockDriver *base_drv = NULL;
262
263 if (base_fmt) {
264 base_drv = bdrv_find_format(base_fmt);
265 if (base_drv == NULL)
266 error("Unknown basefile format '%s'", base_fmt);
267 }
268
269 bs = bdrv_new_open(base_filename, base_fmt);
bellard75c23802004-08-27 21:28:58 +0000270 bdrv_get_geometry(bs, &size);
271 size *= 512;
272 bdrv_delete(bs);
273 } else {
bellardea2384d2004-08-01 21:59:26 +0000274 if (optind >= argc)
275 help();
276 p = argv[optind];
aurel3224501482009-03-08 19:49:44 +0000277 sizef = strtod(p, (char **)&p);
bellardea2384d2004-08-01 21:59:26 +0000278 if (*p == 'M') {
aurel3224501482009-03-08 19:49:44 +0000279 size = (uint64_t)(sizef * 1024 * 1024);
bellardea2384d2004-08-01 21:59:26 +0000280 } else if (*p == 'G') {
aurel3224501482009-03-08 19:49:44 +0000281 size = (uint64_t)(sizef * 1024 * 1024 * 1024);
bellardea2384d2004-08-01 21:59:26 +0000282 } else if (*p == 'k' || *p == 'K' || *p == '\0') {
aurel3224501482009-03-08 19:49:44 +0000283 size = (uint64_t)(sizef * 1024);
bellardea2384d2004-08-01 21:59:26 +0000284 } else {
285 help();
286 }
287 }
288 drv = bdrv_find_format(fmt);
289 if (!drv)
290 error("Unknown file format '%s'", fmt);
ths0cfec832007-06-23 16:02:43 +0000291 printf("Formatting '%s', fmt=%s",
bellardea2384d2004-08-01 21:59:26 +0000292 filename, fmt);
thsec36ba12007-09-16 21:59:02 +0000293 if (flags & BLOCK_FLAG_ENCRYPT)
bellardea2384d2004-08-01 21:59:26 +0000294 printf(", encrypted");
thsec36ba12007-09-16 21:59:02 +0000295 if (flags & BLOCK_FLAG_COMPAT6)
296 printf(", compatibility level=6");
bellard75c23802004-08-27 21:28:58 +0000297 if (base_filename) {
298 printf(", backing_file=%s",
bellardea2384d2004-08-01 21:59:26 +0000299 base_filename);
aliguori9230eaf2009-03-28 17:55:19 +0000300 if (base_fmt)
301 printf(", backing_fmt=%s",
302 base_fmt);
bellard75c23802004-08-27 21:28:58 +0000303 }
ths96b8f132007-12-17 01:35:20 +0000304 printf(", size=%" PRIu64 " kB\n", size / 1024);
aliguori9230eaf2009-03-28 17:55:19 +0000305 ret = bdrv_create2(drv, filename, size / 512, base_filename, base_fmt, flags);
bellardea2384d2004-08-01 21:59:26 +0000306 if (ret < 0) {
307 if (ret == -ENOTSUP) {
bellard3c565212004-09-29 21:29:14 +0000308 error("Formatting or formatting option not supported for file format '%s'", fmt);
bellardea2384d2004-08-01 21:59:26 +0000309 } else {
310 error("Error while formatting");
311 }
312 }
313 return 0;
314}
315
316static int img_commit(int argc, char **argv)
317{
318 int c, ret;
319 const char *filename, *fmt;
320 BlockDriver *drv;
321 BlockDriverState *bs;
322
323 fmt = NULL;
324 for(;;) {
325 c = getopt(argc, argv, "f:h");
326 if (c == -1)
327 break;
328 switch(c) {
329 case 'h':
330 help();
331 break;
332 case 'f':
333 fmt = optarg;
334 break;
335 }
336 }
ths5fafdf22007-09-16 21:08:06 +0000337 if (optind >= argc)
bellardea2384d2004-08-01 21:59:26 +0000338 help();
339 filename = argv[optind++];
340
341 bs = bdrv_new("");
342 if (!bs)
343 error("Not enough memory");
344 if (fmt) {
345 drv = bdrv_find_format(fmt);
346 if (!drv)
347 error("Unknown file format '%s'", fmt);
348 } else {
349 drv = NULL;
350 }
aurel32137519c2008-11-30 19:12:49 +0000351 if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
bellardea2384d2004-08-01 21:59:26 +0000352 error("Could not open '%s'", filename);
353 }
354 ret = bdrv_commit(bs);
355 switch(ret) {
356 case 0:
357 printf("Image committed.\n");
358 break;
359 case -ENOENT:
360 error("No disk inserted");
361 break;
362 case -EACCES:
363 error("Image is read-only");
364 break;
365 case -ENOTSUP:
366 error("Image is already committed");
367 break;
368 default:
369 error("Error while committing image");
370 break;
371 }
372
373 bdrv_delete(bs);
374 return 0;
375}
376
377static int is_not_zero(const uint8_t *sector, int len)
378{
379 int i;
380 len >>= 2;
381 for(i = 0;i < len; i++) {
382 if (((uint32_t *)sector)[i] != 0)
383 return 1;
384 }
385 return 0;
386}
387
thsf58c7b32008-06-05 21:53:49 +0000388/*
389 * Returns true iff the first sector pointed to by 'buf' contains at least
390 * a non-NUL byte.
391 *
392 * 'pnum' is set to the number of sectors (including and immediately following
393 * the first one) that are known to be in the same allocated/unallocated state.
394 */
bellardea2384d2004-08-01 21:59:26 +0000395static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
396{
397 int v, i;
398
399 if (n <= 0) {
400 *pnum = 0;
401 return 0;
402 }
403 v = is_not_zero(buf, 512);
404 for(i = 1; i < n; i++) {
405 buf += 512;
406 if (v != is_not_zero(buf, 512))
407 break;
408 }
409 *pnum = i;
410 return v;
411}
412
bellardea2384d2004-08-01 21:59:26 +0000413#define IO_BUF_SIZE 65536
414
415static int img_convert(int argc, char **argv)
416{
balrog926c2d22007-10-31 01:11:44 +0000417 int c, ret, n, n1, bs_n, bs_i, flags, cluster_size, cluster_sectors;
thsf58c7b32008-06-05 21:53:49 +0000418 const char *fmt, *out_fmt, *out_baseimg, *out_filename;
bellardea2384d2004-08-01 21:59:26 +0000419 BlockDriver *drv;
balrog926c2d22007-10-31 01:11:44 +0000420 BlockDriverState **bs, *out_bs;
ths96b8f132007-12-17 01:35:20 +0000421 int64_t total_sectors, nb_sectors, sector_num, bs_offset;
422 uint64_t bs_sectors;
bellardea2384d2004-08-01 21:59:26 +0000423 uint8_t buf[IO_BUF_SIZE];
424 const uint8_t *buf1;
bellardfaea38e2006-08-05 21:31:00 +0000425 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +0000426
427 fmt = NULL;
428 out_fmt = "raw";
thsf58c7b32008-06-05 21:53:49 +0000429 out_baseimg = NULL;
thsec36ba12007-09-16 21:59:02 +0000430 flags = 0;
bellardea2384d2004-08-01 21:59:26 +0000431 for(;;) {
thsf58c7b32008-06-05 21:53:49 +0000432 c = getopt(argc, argv, "f:O:B:hce6");
bellardea2384d2004-08-01 21:59:26 +0000433 if (c == -1)
434 break;
435 switch(c) {
436 case 'h':
437 help();
438 break;
439 case 'f':
440 fmt = optarg;
441 break;
442 case 'O':
443 out_fmt = optarg;
444 break;
thsf58c7b32008-06-05 21:53:49 +0000445 case 'B':
446 out_baseimg = optarg;
447 break;
bellardea2384d2004-08-01 21:59:26 +0000448 case 'c':
thsec36ba12007-09-16 21:59:02 +0000449 flags |= BLOCK_FLAG_COMPRESS;
bellardea2384d2004-08-01 21:59:26 +0000450 break;
451 case 'e':
thsec36ba12007-09-16 21:59:02 +0000452 flags |= BLOCK_FLAG_ENCRYPT;
453 break;
454 case '6':
455 flags |= BLOCK_FLAG_COMPAT6;
bellardea2384d2004-08-01 21:59:26 +0000456 break;
457 }
458 }
ths3b46e622007-09-17 08:09:54 +0000459
balrog926c2d22007-10-31 01:11:44 +0000460 bs_n = argc - optind - 1;
461 if (bs_n < 1) help();
462
463 out_filename = argv[argc - 1];
thsf58c7b32008-06-05 21:53:49 +0000464
465 if (bs_n > 1 && out_baseimg)
466 error("-B makes no sense when concatenating multiple input images");
balrog926c2d22007-10-31 01:11:44 +0000467
468 bs = calloc(bs_n, sizeof(BlockDriverState *));
469 if (!bs)
470 error("Out of memory");
471
472 total_sectors = 0;
473 for (bs_i = 0; bs_i < bs_n; bs_i++) {
474 bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt);
475 if (!bs[bs_i])
476 error("Could not open '%s'", argv[optind + bs_i]);
477 bdrv_get_geometry(bs[bs_i], &bs_sectors);
478 total_sectors += bs_sectors;
479 }
bellardea2384d2004-08-01 21:59:26 +0000480
481 drv = bdrv_find_format(out_fmt);
482 if (!drv)
thsd34dda52007-02-10 22:59:40 +0000483 error("Unknown file format '%s'", out_fmt);
thsec36ba12007-09-16 21:59:02 +0000484 if (flags & BLOCK_FLAG_COMPRESS && drv != &bdrv_qcow && drv != &bdrv_qcow2)
bellardea2384d2004-08-01 21:59:26 +0000485 error("Compression not supported for this file format");
thsec36ba12007-09-16 21:59:02 +0000486 if (flags & BLOCK_FLAG_ENCRYPT && drv != &bdrv_qcow && drv != &bdrv_qcow2)
bellardea2384d2004-08-01 21:59:26 +0000487 error("Encryption not supported for this file format");
thsd8871c52007-10-24 16:11:42 +0000488 if (flags & BLOCK_FLAG_COMPAT6 && drv != &bdrv_vmdk)
thsec36ba12007-09-16 21:59:02 +0000489 error("Alternative compatibility level not supported for this file format");
490 if (flags & BLOCK_FLAG_ENCRYPT && flags & BLOCK_FLAG_COMPRESS)
bellardea2384d2004-08-01 21:59:26 +0000491 error("Compression and encryption not supported at the same time");
balrog926c2d22007-10-31 01:11:44 +0000492
thsf58c7b32008-06-05 21:53:49 +0000493 ret = bdrv_create(drv, out_filename, total_sectors, out_baseimg, flags);
bellardea2384d2004-08-01 21:59:26 +0000494 if (ret < 0) {
495 if (ret == -ENOTSUP) {
bellard3c565212004-09-29 21:29:14 +0000496 error("Formatting not supported for file format '%s'", fmt);
bellardea2384d2004-08-01 21:59:26 +0000497 } else {
498 error("Error while formatting '%s'", out_filename);
499 }
500 }
ths3b46e622007-09-17 08:09:54 +0000501
bellardea2384d2004-08-01 21:59:26 +0000502 out_bs = bdrv_new_open(out_filename, out_fmt);
503
balrog926c2d22007-10-31 01:11:44 +0000504 bs_i = 0;
505 bs_offset = 0;
506 bdrv_get_geometry(bs[0], &bs_sectors);
507
508 if (flags & BLOCK_FLAG_COMPRESS) {
bellardfaea38e2006-08-05 21:31:00 +0000509 if (bdrv_get_info(out_bs, &bdi) < 0)
510 error("could not get block driver info");
511 cluster_size = bdi.cluster_size;
bellardea2384d2004-08-01 21:59:26 +0000512 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE)
513 error("invalid cluster size");
514 cluster_sectors = cluster_size >> 9;
515 sector_num = 0;
516 for(;;) {
balrog926c2d22007-10-31 01:11:44 +0000517 int64_t bs_num;
518 int remainder;
519 uint8_t *buf2;
520
bellardea2384d2004-08-01 21:59:26 +0000521 nb_sectors = total_sectors - sector_num;
522 if (nb_sectors <= 0)
523 break;
524 if (nb_sectors >= cluster_sectors)
525 n = cluster_sectors;
526 else
527 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000528
529 bs_num = sector_num - bs_offset;
530 assert (bs_num >= 0);
531 remainder = n;
532 buf2 = buf;
533 while (remainder > 0) {
534 int nlow;
535 while (bs_num == bs_sectors) {
536 bs_i++;
537 assert (bs_i < bs_n);
538 bs_offset += bs_sectors;
539 bdrv_get_geometry(bs[bs_i], &bs_sectors);
540 bs_num = 0;
541 /* printf("changing part: sector_num=%lld, "
542 "bs_i=%d, bs_offset=%lld, bs_sectors=%lld\n",
543 sector_num, bs_i, bs_offset, bs_sectors); */
544 }
545 assert (bs_num < bs_sectors);
546
547 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
548
549 if (bdrv_read(bs[bs_i], bs_num, buf2, nlow) < 0)
550 error("error while reading");
551
552 buf2 += nlow * 512;
553 bs_num += nlow;
554
555 remainder -= nlow;
556 }
557 assert (remainder == 0);
558
bellardea2384d2004-08-01 21:59:26 +0000559 if (n < cluster_sectors)
560 memset(buf + n * 512, 0, cluster_size - n * 512);
561 if (is_not_zero(buf, cluster_size)) {
ths5fafdf22007-09-16 21:08:06 +0000562 if (bdrv_write_compressed(out_bs, sector_num, buf,
bellardfaea38e2006-08-05 21:31:00 +0000563 cluster_sectors) != 0)
bellardec3757d2006-06-14 15:50:07 +0000564 error("error while compressing sector %" PRId64,
565 sector_num);
bellardea2384d2004-08-01 21:59:26 +0000566 }
567 sector_num += n;
568 }
bellardfaea38e2006-08-05 21:31:00 +0000569 /* signal EOF to align */
570 bdrv_write_compressed(out_bs, 0, NULL, 0);
bellardea2384d2004-08-01 21:59:26 +0000571 } else {
thsf58c7b32008-06-05 21:53:49 +0000572 sector_num = 0; // total number of sectors converted so far
bellardea2384d2004-08-01 21:59:26 +0000573 for(;;) {
574 nb_sectors = total_sectors - sector_num;
575 if (nb_sectors <= 0)
576 break;
577 if (nb_sectors >= (IO_BUF_SIZE / 512))
578 n = (IO_BUF_SIZE / 512);
579 else
580 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000581
582 while (sector_num - bs_offset >= bs_sectors) {
583 bs_i ++;
584 assert (bs_i < bs_n);
585 bs_offset += bs_sectors;
586 bdrv_get_geometry(bs[bs_i], &bs_sectors);
587 /* printf("changing part: sector_num=%lld, bs_i=%d, "
588 "bs_offset=%lld, bs_sectors=%lld\n",
589 sector_num, bs_i, bs_offset, bs_sectors); */
590 }
591
592 if (n > bs_offset + bs_sectors - sector_num)
593 n = bs_offset + bs_sectors - sector_num;
594
thsf58c7b32008-06-05 21:53:49 +0000595 /* If the output image is being created as a copy on write image,
596 assume that sectors which are unallocated in the input image
597 are present in both the output's and input's base images (no
598 need to copy them). */
599 if (out_baseimg) {
600 if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset, n, &n1)) {
601 sector_num += n1;
602 continue;
603 }
604 /* The next 'n1' sectors are allocated in the input image. Copy
605 only those as they may be followed by unallocated sectors. */
606 n = n1;
607 }
608
balrog926c2d22007-10-31 01:11:44 +0000609 if (bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n) < 0)
bellardea2384d2004-08-01 21:59:26 +0000610 error("error while reading");
611 /* NOTE: at the same time we convert, we do not write zero
612 sectors to have a chance to compress the image. Ideally, we
613 should add a specific call to have the info to go faster */
614 buf1 = buf;
615 while (n > 0) {
thsf58c7b32008-06-05 21:53:49 +0000616 /* If the output image is being created as a copy on write image,
617 copy all sectors even the ones containing only NUL bytes,
618 because they may differ from the sectors in the base image. */
619 if (out_baseimg || is_allocated_sectors(buf1, n, &n1)) {
ths5fafdf22007-09-16 21:08:06 +0000620 if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
bellardea2384d2004-08-01 21:59:26 +0000621 error("error while writing");
622 }
623 sector_num += n1;
624 n -= n1;
625 buf1 += n1 * 512;
626 }
627 }
628 }
629 bdrv_delete(out_bs);
balrog926c2d22007-10-31 01:11:44 +0000630 for (bs_i = 0; bs_i < bs_n; bs_i++)
631 bdrv_delete(bs[bs_i]);
632 free(bs);
bellardea2384d2004-08-01 21:59:26 +0000633 return 0;
634}
635
bellard57d1a2b2004-08-03 21:15:11 +0000636#ifdef _WIN32
637static int64_t get_allocated_file_size(const char *filename)
638{
bellarde8445332006-06-14 15:32:10 +0000639 typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
640 get_compressed_t get_compressed;
bellard57d1a2b2004-08-03 21:15:11 +0000641 struct _stati64 st;
bellarde8445332006-06-14 15:32:10 +0000642
643 /* WinNT support GetCompressedFileSize to determine allocate size */
644 get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
645 if (get_compressed) {
646 DWORD high, low;
647 low = get_compressed(filename, &high);
648 if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
649 return (((int64_t) high) << 32) + low;
650 }
651
ths5fafdf22007-09-16 21:08:06 +0000652 if (_stati64(filename, &st) < 0)
bellard57d1a2b2004-08-03 21:15:11 +0000653 return -1;
654 return st.st_size;
655}
656#else
657static int64_t get_allocated_file_size(const char *filename)
658{
659 struct stat st;
ths5fafdf22007-09-16 21:08:06 +0000660 if (stat(filename, &st) < 0)
bellard57d1a2b2004-08-03 21:15:11 +0000661 return -1;
662 return (int64_t)st.st_blocks * 512;
663}
664#endif
665
bellardfaea38e2006-08-05 21:31:00 +0000666static void dump_snapshots(BlockDriverState *bs)
667{
668 QEMUSnapshotInfo *sn_tab, *sn;
669 int nb_sns, i;
670 char buf[256];
671
672 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
673 if (nb_sns <= 0)
674 return;
675 printf("Snapshot list:\n");
676 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
677 for(i = 0; i < nb_sns; i++) {
678 sn = &sn_tab[i];
679 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
680 }
681 qemu_free(sn_tab);
682}
683
bellardea2384d2004-08-01 21:59:26 +0000684static int img_info(int argc, char **argv)
685{
686 int c;
687 const char *filename, *fmt;
688 BlockDriver *drv;
689 BlockDriverState *bs;
690 char fmt_name[128], size_buf[128], dsize_buf[128];
ths96b8f132007-12-17 01:35:20 +0000691 uint64_t total_sectors;
692 int64_t allocated_size;
bellard93b6b2a2006-08-01 15:51:11 +0000693 char backing_filename[1024];
694 char backing_filename2[1024];
bellardfaea38e2006-08-05 21:31:00 +0000695 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +0000696
697 fmt = NULL;
698 for(;;) {
699 c = getopt(argc, argv, "f:h");
700 if (c == -1)
701 break;
702 switch(c) {
703 case 'h':
704 help();
705 break;
706 case 'f':
707 fmt = optarg;
708 break;
709 }
710 }
ths5fafdf22007-09-16 21:08:06 +0000711 if (optind >= argc)
bellardea2384d2004-08-01 21:59:26 +0000712 help();
713 filename = argv[optind++];
714
715 bs = bdrv_new("");
716 if (!bs)
717 error("Not enough memory");
718 if (fmt) {
719 drv = bdrv_find_format(fmt);
720 if (!drv)
721 error("Unknown file format '%s'", fmt);
722 } else {
723 drv = NULL;
724 }
aurel32137519c2008-11-30 19:12:49 +0000725 if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
bellardea2384d2004-08-01 21:59:26 +0000726 error("Could not open '%s'", filename);
727 }
728 bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
729 bdrv_get_geometry(bs, &total_sectors);
730 get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
bellard57d1a2b2004-08-03 21:15:11 +0000731 allocated_size = get_allocated_file_size(filename);
732 if (allocated_size < 0)
blueswir1a10ea302008-08-24 10:30:33 +0000733 snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
bellardde167e42005-04-28 21:15:08 +0000734 else
ths5fafdf22007-09-16 21:08:06 +0000735 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
bellardde167e42005-04-28 21:15:08 +0000736 allocated_size);
bellardea2384d2004-08-01 21:59:26 +0000737 printf("image: %s\n"
738 "file format: %s\n"
bellardec3757d2006-06-14 15:50:07 +0000739 "virtual size: %s (%" PRId64 " bytes)\n"
bellardea2384d2004-08-01 21:59:26 +0000740 "disk size: %s\n",
ths5fafdf22007-09-16 21:08:06 +0000741 filename, fmt_name, size_buf,
bellardec3757d2006-06-14 15:50:07 +0000742 (total_sectors * 512),
bellardea2384d2004-08-01 21:59:26 +0000743 dsize_buf);
744 if (bdrv_is_encrypted(bs))
745 printf("encrypted: yes\n");
bellardfaea38e2006-08-05 21:31:00 +0000746 if (bdrv_get_info(bs, &bdi) >= 0) {
ths5fafdf22007-09-16 21:08:06 +0000747 if (bdi.cluster_size != 0)
bellardfaea38e2006-08-05 21:31:00 +0000748 printf("cluster_size: %d\n", bdi.cluster_size);
749 }
bellard93b6b2a2006-08-01 15:51:11 +0000750 bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
bellardfaea38e2006-08-05 21:31:00 +0000751 if (backing_filename[0] != '\0') {
bellard93b6b2a2006-08-01 15:51:11 +0000752 path_combine(backing_filename2, sizeof(backing_filename2),
753 filename, backing_filename);
ths5fafdf22007-09-16 21:08:06 +0000754 printf("backing file: %s (actual path: %s)\n",
bellard93b6b2a2006-08-01 15:51:11 +0000755 backing_filename,
756 backing_filename2);
bellardfaea38e2006-08-05 21:31:00 +0000757 }
758 dump_snapshots(bs);
bellardea2384d2004-08-01 21:59:26 +0000759 bdrv_delete(bs);
760 return 0;
761}
762
aliguorif7b4a942009-01-07 17:40:15 +0000763#define SNAPSHOT_LIST 1
764#define SNAPSHOT_CREATE 2
765#define SNAPSHOT_APPLY 3
766#define SNAPSHOT_DELETE 4
767
768static void img_snapshot(int argc, char **argv)
769{
770 BlockDriverState *bs;
771 QEMUSnapshotInfo sn;
772 char *filename, *snapshot_name = NULL;
aliguori40a45392009-01-15 21:42:12 +0000773 int c, ret;
aliguorif7b4a942009-01-07 17:40:15 +0000774 int action = 0;
775 qemu_timeval tv;
776
777 /* Parse commandline parameters */
778 for(;;) {
779 c = getopt(argc, argv, "la:c:d:h");
780 if (c == -1)
781 break;
782 switch(c) {
783 case 'h':
784 help();
785 return;
786 case 'l':
787 if (action) {
788 help();
789 return;
790 }
791 action = SNAPSHOT_LIST;
792 break;
793 case 'a':
794 if (action) {
795 help();
796 return;
797 }
798 action = SNAPSHOT_APPLY;
799 snapshot_name = optarg;
800 break;
801 case 'c':
802 if (action) {
803 help();
804 return;
805 }
806 action = SNAPSHOT_CREATE;
807 snapshot_name = optarg;
808 break;
809 case 'd':
810 if (action) {
811 help();
812 return;
813 }
814 action = SNAPSHOT_DELETE;
815 snapshot_name = optarg;
816 break;
817 }
818 }
819
820 if (optind >= argc)
821 help();
822 filename = argv[optind++];
823
824 /* Open the image */
825 bs = bdrv_new("");
826 if (!bs)
827 error("Not enough memory");
828
829 if (bdrv_open2(bs, filename, 0, NULL) < 0) {
830 error("Could not open '%s'", filename);
831 }
832
833 /* Perform the requested action */
834 switch(action) {
835 case SNAPSHOT_LIST:
836 dump_snapshots(bs);
837 break;
838
839 case SNAPSHOT_CREATE:
840 memset(&sn, 0, sizeof(sn));
841 pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
842
843 qemu_gettimeofday(&tv);
844 sn.date_sec = tv.tv_sec;
845 sn.date_nsec = tv.tv_usec * 1000;
846
847 ret = bdrv_snapshot_create(bs, &sn);
848 if (ret)
849 error("Could not create snapshot '%s': %d (%s)",
850 snapshot_name, ret, strerror(-ret));
851 break;
852
853 case SNAPSHOT_APPLY:
854 ret = bdrv_snapshot_goto(bs, snapshot_name);
855 if (ret)
856 error("Could not apply snapshot '%s': %d (%s)",
857 snapshot_name, ret, strerror(-ret));
858 break;
859
860 case SNAPSHOT_DELETE:
861 ret = bdrv_snapshot_delete(bs, snapshot_name);
862 if (ret)
863 error("Could not delete snapshot '%s': %d (%s)",
864 snapshot_name, ret, strerror(-ret));
865 break;
866 }
867
868 /* Cleanup */
869 bdrv_delete(bs);
870}
871
bellardea2384d2004-08-01 21:59:26 +0000872int main(int argc, char **argv)
873{
874 const char *cmd;
875
876 bdrv_init();
877 if (argc < 2)
878 help();
879 cmd = argv[1];
aurel328f9b1572009-02-09 18:14:31 +0000880 argc--; argv++;
bellardea2384d2004-08-01 21:59:26 +0000881 if (!strcmp(cmd, "create")) {
882 img_create(argc, argv);
883 } else if (!strcmp(cmd, "commit")) {
884 img_commit(argc, argv);
885 } else if (!strcmp(cmd, "convert")) {
886 img_convert(argc, argv);
887 } else if (!strcmp(cmd, "info")) {
888 img_info(argc, argv);
aliguorif7b4a942009-01-07 17:40:15 +0000889 } else if (!strcmp(cmd, "snapshot")) {
890 img_snapshot(argc, argv);
bellardea2384d2004-08-01 21:59:26 +0000891 } else {
892 help();
893 }
894 return 0;
895}