blob: 29149a23c8af3b01ff283c669a295b7fd015220d [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"
aliguori15859692009-04-21 23:11:53 +000061 " check [-f fmt] filename\n"
aliguori9230eaf2009-03-28 17:55:19 +000062 " create [-e] [-6] [-F fmt] [-b base_image] [-f fmt] filename [size]\n"
bellardea2384d2004-08-01 21:59:26 +000063 " commit [-f fmt] filename\n"
thsf58c7b32008-06-05 21:53:49 +000064 " convert [-c] [-e] [-6] [-f fmt] [-O output_fmt] [-B output_base_image] filename [filename2 [...]] output_filename\n"
bellardea2384d2004-08-01 21:59:26 +000065 " info [-f fmt] filename\n"
blueswir1d2c639d2009-01-24 18:19:25 +000066 " snapshot [-l | -a snapshot | -c snapshot | -d snapshot] filename\n"
bellardea2384d2004-08-01 21:59:26 +000067 "\n"
68 "Command parameters:\n"
69 " 'filename' is a disk image filename\n"
70 " 'base_image' is the read-only disk image which is used as base for a copy on\n"
71 " write image; the copy on write image only stores the modified data\n"
thsf58c7b32008-06-05 21:53:49 +000072 " 'output_base_image' forces the output image to be created as a copy on write\n"
73 " image of the specified base image; 'output_base_image' should have the same\n"
74 " content as the input's base image, however the path, image format, etc may\n"
75 " differ\n"
bellardea2384d2004-08-01 21:59:26 +000076 " 'fmt' is the disk image format. It is guessed automatically in most cases\n"
blueswir1d2c639d2009-01-24 18:19:25 +000077 " 'size' is the disk image size in kilobytes. Optional suffixes\n"
aurel322fbc4092009-03-08 19:49:51 +000078 " 'M' (megabyte, 1024 * 1024) and 'G' (gigabyte, 1024 * 1024 * 1024) are\n"
79 " supported any 'k' or 'K' is ignored\n"
bellardea2384d2004-08-01 21:59:26 +000080 " 'output_filename' is the destination disk image filename\n"
81 " 'output_fmt' is the destination format\n"
82 " '-c' indicates that target image must be compressed (qcow format only)\n"
83 " '-e' indicates that the target image must be encrypted (qcow format only)\n"
thsec36ba12007-09-16 21:59:02 +000084 " '-6' indicates that the target image must use compatibility level 6 (vmdk format only)\n"
blueswir1d2c639d2009-01-24 18:19:25 +000085 " '-h' with or without a command shows this help and lists the supported formats\n"
aliguorif7b4a942009-01-07 17:40:15 +000086 "\n"
blueswir1d2c639d2009-01-24 18:19:25 +000087 "Parameters to snapshot subcommand:\n"
88 " 'snapshot' is the name of the snapshot to create, apply or delete\n"
89 " '-a' applies a snapshot (revert disk to saved state)\n"
90 " '-c' creates a snapshot\n"
91 " '-d' deletes a snapshot\n"
92 " '-l' lists all snapshots in the given image\n"
bellardea2384d2004-08-01 21:59:26 +000093 );
blueswir1d2c639d2009-01-24 18:19:25 +000094 printf("\nSupported formats:");
bellardea2384d2004-08-01 21:59:26 +000095 bdrv_iterate_format(format_print, NULL);
96 printf("\n");
97 exit(1);
98}
99
bellardea2384d2004-08-01 21:59:26 +0000100#if defined(WIN32)
101/* XXX: put correct support for win32 */
102static int read_password(char *buf, int buf_size)
103{
104 int c, i;
105 printf("Password: ");
106 fflush(stdout);
107 i = 0;
108 for(;;) {
109 c = getchar();
110 if (c == '\n')
111 break;
112 if (i < (buf_size - 1))
113 buf[i++] = c;
114 }
115 buf[i] = '\0';
116 return 0;
117}
118
119#else
120
121#include <termios.h>
122
123static struct termios oldtty;
124
125static void term_exit(void)
126{
127 tcsetattr (0, TCSANOW, &oldtty);
128}
129
130static void term_init(void)
131{
132 struct termios tty;
133
134 tcgetattr (0, &tty);
135 oldtty = tty;
136
137 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
138 |INLCR|IGNCR|ICRNL|IXON);
139 tty.c_oflag |= OPOST;
140 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
141 tty.c_cflag &= ~(CSIZE|PARENB);
142 tty.c_cflag |= CS8;
143 tty.c_cc[VMIN] = 1;
144 tty.c_cc[VTIME] = 0;
ths3b46e622007-09-17 08:09:54 +0000145
bellardea2384d2004-08-01 21:59:26 +0000146 tcsetattr (0, TCSANOW, &tty);
147
148 atexit(term_exit);
149}
150
pbrook3f379ab2007-11-11 03:33:13 +0000151static int read_password(char *buf, int buf_size)
bellardea2384d2004-08-01 21:59:26 +0000152{
153 uint8_t ch;
154 int i, ret;
155
156 printf("password: ");
157 fflush(stdout);
158 term_init();
159 i = 0;
160 for(;;) {
161 ret = read(0, &ch, 1);
162 if (ret == -1) {
163 if (errno == EAGAIN || errno == EINTR) {
164 continue;
165 } else {
166 ret = -1;
167 break;
168 }
169 } else if (ret == 0) {
170 ret = -1;
171 break;
172 } else {
173 if (ch == '\r') {
174 ret = 0;
175 break;
176 }
177 if (i < (buf_size - 1))
178 buf[i++] = ch;
179 }
180 }
181 term_exit();
182 buf[i] = '\0';
183 printf("\n");
184 return ret;
185}
186#endif
187
bellard75c23802004-08-27 21:28:58 +0000188static BlockDriverState *bdrv_new_open(const char *filename,
189 const char *fmt)
190{
191 BlockDriverState *bs;
192 BlockDriver *drv;
193 char password[256];
194
195 bs = bdrv_new("");
196 if (!bs)
197 error("Not enough memory");
198 if (fmt) {
199 drv = bdrv_find_format(fmt);
200 if (!drv)
201 error("Unknown file format '%s'", fmt);
202 } else {
203 drv = NULL;
204 }
aurel32137519c2008-11-30 19:12:49 +0000205 if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
bellard75c23802004-08-27 21:28:58 +0000206 error("Could not open '%s'", filename);
207 }
208 if (bdrv_is_encrypted(bs)) {
209 printf("Disk image '%s' is encrypted.\n", filename);
210 if (read_password(password, sizeof(password)) < 0)
211 error("No password given");
212 if (bdrv_set_key(bs, password) < 0)
213 error("invalid password");
214 }
215 return bs;
216}
217
bellardea2384d2004-08-01 21:59:26 +0000218static int img_create(int argc, char **argv)
219{
thsec36ba12007-09-16 21:59:02 +0000220 int c, ret, flags;
bellardea2384d2004-08-01 21:59:26 +0000221 const char *fmt = "raw";
aliguori9230eaf2009-03-28 17:55:19 +0000222 const char *base_fmt = NULL;
bellardea2384d2004-08-01 21:59:26 +0000223 const char *filename;
224 const char *base_filename = NULL;
ths96b8f132007-12-17 01:35:20 +0000225 uint64_t size;
aurel3224501482009-03-08 19:49:44 +0000226 double sizef;
bellardea2384d2004-08-01 21:59:26 +0000227 const char *p;
228 BlockDriver *drv;
ths3b46e622007-09-17 08:09:54 +0000229
thsec36ba12007-09-16 21:59:02 +0000230 flags = 0;
bellardea2384d2004-08-01 21:59:26 +0000231 for(;;) {
aliguori9230eaf2009-03-28 17:55:19 +0000232 c = getopt(argc, argv, "F:b:f:he6");
bellardea2384d2004-08-01 21:59:26 +0000233 if (c == -1)
234 break;
235 switch(c) {
236 case 'h':
237 help();
238 break;
aliguori9230eaf2009-03-28 17:55:19 +0000239 case 'F':
240 base_fmt = optarg;
241 break;
bellardea2384d2004-08-01 21:59:26 +0000242 case 'b':
243 base_filename = optarg;
244 break;
245 case 'f':
246 fmt = optarg;
247 break;
248 case 'e':
thsec36ba12007-09-16 21:59:02 +0000249 flags |= BLOCK_FLAG_ENCRYPT;
bellardea2384d2004-08-01 21:59:26 +0000250 break;
thsd8871c52007-10-24 16:11:42 +0000251 case '6':
thsec36ba12007-09-16 21:59:02 +0000252 flags |= BLOCK_FLAG_COMPAT6;
thsd8871c52007-10-24 16:11:42 +0000253 break;
bellardea2384d2004-08-01 21:59:26 +0000254 }
255 }
ths5fafdf22007-09-16 21:08:06 +0000256 if (optind >= argc)
bellardea2384d2004-08-01 21:59:26 +0000257 help();
258 filename = argv[optind++];
259 size = 0;
bellard75c23802004-08-27 21:28:58 +0000260 if (base_filename) {
aliguorie94f3a62008-08-01 15:04:00 +0000261 BlockDriverState *bs;
aliguori9230eaf2009-03-28 17:55:19 +0000262 BlockDriver *base_drv = NULL;
263
264 if (base_fmt) {
265 base_drv = bdrv_find_format(base_fmt);
266 if (base_drv == NULL)
267 error("Unknown basefile format '%s'", base_fmt);
268 }
269
270 bs = bdrv_new_open(base_filename, base_fmt);
bellard75c23802004-08-27 21:28:58 +0000271 bdrv_get_geometry(bs, &size);
272 size *= 512;
273 bdrv_delete(bs);
274 } else {
bellardea2384d2004-08-01 21:59:26 +0000275 if (optind >= argc)
276 help();
277 p = argv[optind];
aurel3224501482009-03-08 19:49:44 +0000278 sizef = strtod(p, (char **)&p);
bellardea2384d2004-08-01 21:59:26 +0000279 if (*p == 'M') {
aurel3224501482009-03-08 19:49:44 +0000280 size = (uint64_t)(sizef * 1024 * 1024);
bellardea2384d2004-08-01 21:59:26 +0000281 } else if (*p == 'G') {
aurel3224501482009-03-08 19:49:44 +0000282 size = (uint64_t)(sizef * 1024 * 1024 * 1024);
bellardea2384d2004-08-01 21:59:26 +0000283 } else if (*p == 'k' || *p == 'K' || *p == '\0') {
aurel3224501482009-03-08 19:49:44 +0000284 size = (uint64_t)(sizef * 1024);
bellardea2384d2004-08-01 21:59:26 +0000285 } else {
286 help();
287 }
288 }
289 drv = bdrv_find_format(fmt);
290 if (!drv)
291 error("Unknown file format '%s'", fmt);
ths0cfec832007-06-23 16:02:43 +0000292 printf("Formatting '%s', fmt=%s",
bellardea2384d2004-08-01 21:59:26 +0000293 filename, fmt);
thsec36ba12007-09-16 21:59:02 +0000294 if (flags & BLOCK_FLAG_ENCRYPT)
bellardea2384d2004-08-01 21:59:26 +0000295 printf(", encrypted");
thsec36ba12007-09-16 21:59:02 +0000296 if (flags & BLOCK_FLAG_COMPAT6)
297 printf(", compatibility level=6");
bellard75c23802004-08-27 21:28:58 +0000298 if (base_filename) {
299 printf(", backing_file=%s",
bellardea2384d2004-08-01 21:59:26 +0000300 base_filename);
aliguori9230eaf2009-03-28 17:55:19 +0000301 if (base_fmt)
302 printf(", backing_fmt=%s",
303 base_fmt);
bellard75c23802004-08-27 21:28:58 +0000304 }
ths96b8f132007-12-17 01:35:20 +0000305 printf(", size=%" PRIu64 " kB\n", size / 1024);
aliguori9230eaf2009-03-28 17:55:19 +0000306 ret = bdrv_create2(drv, filename, size / 512, base_filename, base_fmt, flags);
bellardea2384d2004-08-01 21:59:26 +0000307 if (ret < 0) {
308 if (ret == -ENOTSUP) {
bellard3c565212004-09-29 21:29:14 +0000309 error("Formatting or formatting option not supported for file format '%s'", fmt);
aurel326e9ea0c2009-04-15 14:42:46 +0000310 } else if (ret == -EFBIG) {
311 error("The image size is too large for file format '%s'", fmt);
bellardea2384d2004-08-01 21:59:26 +0000312 } else {
313 error("Error while formatting");
314 }
315 }
316 return 0;
317}
318
aliguori15859692009-04-21 23:11:53 +0000319static int img_check(int argc, char **argv)
320{
321 int c, ret;
322 const char *filename, *fmt;
323 BlockDriver *drv;
324 BlockDriverState *bs;
325
326 fmt = NULL;
327 for(;;) {
328 c = getopt(argc, argv, "f:h");
329 if (c == -1)
330 break;
331 switch(c) {
332 case 'h':
333 help();
334 break;
335 case 'f':
336 fmt = optarg;
337 break;
338 }
339 }
340 if (optind >= argc)
341 help();
342 filename = argv[optind++];
343
344 bs = bdrv_new("");
345 if (!bs)
346 error("Not enough memory");
347 if (fmt) {
348 drv = bdrv_find_format(fmt);
349 if (!drv)
350 error("Unknown file format '%s'", fmt);
351 } else {
352 drv = NULL;
353 }
354 if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
355 error("Could not open '%s'", filename);
356 }
357 ret = bdrv_check(bs);
358 switch(ret) {
359 case 0:
360 printf("No errors were found on the image.\n");
361 break;
362 case -ENOTSUP:
363 error("This image format does not support checks");
364 break;
365 default:
366 if (ret < 0) {
367 error("An error occurred during the check");
368 } else {
369 printf("%d errors were found on the image.\n", ret);
370 }
371 break;
372 }
373
374 bdrv_delete(bs);
375 return 0;
376}
377
bellardea2384d2004-08-01 21:59:26 +0000378static int img_commit(int argc, char **argv)
379{
380 int c, ret;
381 const char *filename, *fmt;
382 BlockDriver *drv;
383 BlockDriverState *bs;
384
385 fmt = NULL;
386 for(;;) {
387 c = getopt(argc, argv, "f:h");
388 if (c == -1)
389 break;
390 switch(c) {
391 case 'h':
392 help();
393 break;
394 case 'f':
395 fmt = optarg;
396 break;
397 }
398 }
ths5fafdf22007-09-16 21:08:06 +0000399 if (optind >= argc)
bellardea2384d2004-08-01 21:59:26 +0000400 help();
401 filename = argv[optind++];
402
403 bs = bdrv_new("");
404 if (!bs)
405 error("Not enough memory");
406 if (fmt) {
407 drv = bdrv_find_format(fmt);
408 if (!drv)
409 error("Unknown file format '%s'", fmt);
410 } else {
411 drv = NULL;
412 }
aurel32137519c2008-11-30 19:12:49 +0000413 if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
bellardea2384d2004-08-01 21:59:26 +0000414 error("Could not open '%s'", filename);
415 }
416 ret = bdrv_commit(bs);
417 switch(ret) {
418 case 0:
419 printf("Image committed.\n");
420 break;
421 case -ENOENT:
422 error("No disk inserted");
423 break;
424 case -EACCES:
425 error("Image is read-only");
426 break;
427 case -ENOTSUP:
428 error("Image is already committed");
429 break;
430 default:
431 error("Error while committing image");
432 break;
433 }
434
435 bdrv_delete(bs);
436 return 0;
437}
438
439static int is_not_zero(const uint8_t *sector, int len)
440{
441 int i;
442 len >>= 2;
443 for(i = 0;i < len; i++) {
444 if (((uint32_t *)sector)[i] != 0)
445 return 1;
446 }
447 return 0;
448}
449
thsf58c7b32008-06-05 21:53:49 +0000450/*
451 * Returns true iff the first sector pointed to by 'buf' contains at least
452 * a non-NUL byte.
453 *
454 * 'pnum' is set to the number of sectors (including and immediately following
455 * the first one) that are known to be in the same allocated/unallocated state.
456 */
bellardea2384d2004-08-01 21:59:26 +0000457static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
458{
459 int v, i;
460
461 if (n <= 0) {
462 *pnum = 0;
463 return 0;
464 }
465 v = is_not_zero(buf, 512);
466 for(i = 1; i < n; i++) {
467 buf += 512;
468 if (v != is_not_zero(buf, 512))
469 break;
470 }
471 *pnum = i;
472 return v;
473}
474
bellardea2384d2004-08-01 21:59:26 +0000475#define IO_BUF_SIZE 65536
476
477static int img_convert(int argc, char **argv)
478{
balrog926c2d22007-10-31 01:11:44 +0000479 int c, ret, n, n1, bs_n, bs_i, flags, cluster_size, cluster_sectors;
thsf58c7b32008-06-05 21:53:49 +0000480 const char *fmt, *out_fmt, *out_baseimg, *out_filename;
bellardea2384d2004-08-01 21:59:26 +0000481 BlockDriver *drv;
balrog926c2d22007-10-31 01:11:44 +0000482 BlockDriverState **bs, *out_bs;
ths96b8f132007-12-17 01:35:20 +0000483 int64_t total_sectors, nb_sectors, sector_num, bs_offset;
484 uint64_t bs_sectors;
bellardea2384d2004-08-01 21:59:26 +0000485 uint8_t buf[IO_BUF_SIZE];
486 const uint8_t *buf1;
bellardfaea38e2006-08-05 21:31:00 +0000487 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +0000488
489 fmt = NULL;
490 out_fmt = "raw";
thsf58c7b32008-06-05 21:53:49 +0000491 out_baseimg = NULL;
thsec36ba12007-09-16 21:59:02 +0000492 flags = 0;
bellardea2384d2004-08-01 21:59:26 +0000493 for(;;) {
thsf58c7b32008-06-05 21:53:49 +0000494 c = getopt(argc, argv, "f:O:B:hce6");
bellardea2384d2004-08-01 21:59:26 +0000495 if (c == -1)
496 break;
497 switch(c) {
498 case 'h':
499 help();
500 break;
501 case 'f':
502 fmt = optarg;
503 break;
504 case 'O':
505 out_fmt = optarg;
506 break;
thsf58c7b32008-06-05 21:53:49 +0000507 case 'B':
508 out_baseimg = optarg;
509 break;
bellardea2384d2004-08-01 21:59:26 +0000510 case 'c':
thsec36ba12007-09-16 21:59:02 +0000511 flags |= BLOCK_FLAG_COMPRESS;
bellardea2384d2004-08-01 21:59:26 +0000512 break;
513 case 'e':
thsec36ba12007-09-16 21:59:02 +0000514 flags |= BLOCK_FLAG_ENCRYPT;
515 break;
516 case '6':
517 flags |= BLOCK_FLAG_COMPAT6;
bellardea2384d2004-08-01 21:59:26 +0000518 break;
519 }
520 }
ths3b46e622007-09-17 08:09:54 +0000521
balrog926c2d22007-10-31 01:11:44 +0000522 bs_n = argc - optind - 1;
523 if (bs_n < 1) help();
524
525 out_filename = argv[argc - 1];
thsf58c7b32008-06-05 21:53:49 +0000526
527 if (bs_n > 1 && out_baseimg)
528 error("-B makes no sense when concatenating multiple input images");
balrog926c2d22007-10-31 01:11:44 +0000529
530 bs = calloc(bs_n, sizeof(BlockDriverState *));
531 if (!bs)
532 error("Out of memory");
533
534 total_sectors = 0;
535 for (bs_i = 0; bs_i < bs_n; bs_i++) {
536 bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt);
537 if (!bs[bs_i])
538 error("Could not open '%s'", argv[optind + bs_i]);
539 bdrv_get_geometry(bs[bs_i], &bs_sectors);
540 total_sectors += bs_sectors;
541 }
bellardea2384d2004-08-01 21:59:26 +0000542
543 drv = bdrv_find_format(out_fmt);
544 if (!drv)
thsd34dda52007-02-10 22:59:40 +0000545 error("Unknown file format '%s'", out_fmt);
thsec36ba12007-09-16 21:59:02 +0000546 if (flags & BLOCK_FLAG_COMPRESS && drv != &bdrv_qcow && drv != &bdrv_qcow2)
bellardea2384d2004-08-01 21:59:26 +0000547 error("Compression not supported for this file format");
thsec36ba12007-09-16 21:59:02 +0000548 if (flags & BLOCK_FLAG_ENCRYPT && drv != &bdrv_qcow && drv != &bdrv_qcow2)
bellardea2384d2004-08-01 21:59:26 +0000549 error("Encryption not supported for this file format");
thsd8871c52007-10-24 16:11:42 +0000550 if (flags & BLOCK_FLAG_COMPAT6 && drv != &bdrv_vmdk)
thsec36ba12007-09-16 21:59:02 +0000551 error("Alternative compatibility level not supported for this file format");
552 if (flags & BLOCK_FLAG_ENCRYPT && flags & BLOCK_FLAG_COMPRESS)
bellardea2384d2004-08-01 21:59:26 +0000553 error("Compression and encryption not supported at the same time");
balrog926c2d22007-10-31 01:11:44 +0000554
thsf58c7b32008-06-05 21:53:49 +0000555 ret = bdrv_create(drv, out_filename, total_sectors, out_baseimg, flags);
bellardea2384d2004-08-01 21:59:26 +0000556 if (ret < 0) {
557 if (ret == -ENOTSUP) {
aliguori93c65b42009-04-05 17:40:43 +0000558 error("Formatting not supported for file format '%s'", out_fmt);
aurel326e9ea0c2009-04-15 14:42:46 +0000559 } else if (ret == -EFBIG) {
560 error("The image size is too large for file format '%s'", out_fmt);
bellardea2384d2004-08-01 21:59:26 +0000561 } else {
562 error("Error while formatting '%s'", out_filename);
563 }
564 }
ths3b46e622007-09-17 08:09:54 +0000565
bellardea2384d2004-08-01 21:59:26 +0000566 out_bs = bdrv_new_open(out_filename, out_fmt);
567
balrog926c2d22007-10-31 01:11:44 +0000568 bs_i = 0;
569 bs_offset = 0;
570 bdrv_get_geometry(bs[0], &bs_sectors);
571
572 if (flags & BLOCK_FLAG_COMPRESS) {
bellardfaea38e2006-08-05 21:31:00 +0000573 if (bdrv_get_info(out_bs, &bdi) < 0)
574 error("could not get block driver info");
575 cluster_size = bdi.cluster_size;
bellardea2384d2004-08-01 21:59:26 +0000576 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE)
577 error("invalid cluster size");
578 cluster_sectors = cluster_size >> 9;
579 sector_num = 0;
580 for(;;) {
balrog926c2d22007-10-31 01:11:44 +0000581 int64_t bs_num;
582 int remainder;
583 uint8_t *buf2;
584
bellardea2384d2004-08-01 21:59:26 +0000585 nb_sectors = total_sectors - sector_num;
586 if (nb_sectors <= 0)
587 break;
588 if (nb_sectors >= cluster_sectors)
589 n = cluster_sectors;
590 else
591 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000592
593 bs_num = sector_num - bs_offset;
594 assert (bs_num >= 0);
595 remainder = n;
596 buf2 = buf;
597 while (remainder > 0) {
598 int nlow;
599 while (bs_num == bs_sectors) {
600 bs_i++;
601 assert (bs_i < bs_n);
602 bs_offset += bs_sectors;
603 bdrv_get_geometry(bs[bs_i], &bs_sectors);
604 bs_num = 0;
605 /* printf("changing part: sector_num=%lld, "
606 "bs_i=%d, bs_offset=%lld, bs_sectors=%lld\n",
607 sector_num, bs_i, bs_offset, bs_sectors); */
608 }
609 assert (bs_num < bs_sectors);
610
611 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
612
613 if (bdrv_read(bs[bs_i], bs_num, buf2, nlow) < 0)
614 error("error while reading");
615
616 buf2 += nlow * 512;
617 bs_num += nlow;
618
619 remainder -= nlow;
620 }
621 assert (remainder == 0);
622
bellardea2384d2004-08-01 21:59:26 +0000623 if (n < cluster_sectors)
624 memset(buf + n * 512, 0, cluster_size - n * 512);
625 if (is_not_zero(buf, cluster_size)) {
ths5fafdf22007-09-16 21:08:06 +0000626 if (bdrv_write_compressed(out_bs, sector_num, buf,
bellardfaea38e2006-08-05 21:31:00 +0000627 cluster_sectors) != 0)
bellardec3757d2006-06-14 15:50:07 +0000628 error("error while compressing sector %" PRId64,
629 sector_num);
bellardea2384d2004-08-01 21:59:26 +0000630 }
631 sector_num += n;
632 }
bellardfaea38e2006-08-05 21:31:00 +0000633 /* signal EOF to align */
634 bdrv_write_compressed(out_bs, 0, NULL, 0);
bellardea2384d2004-08-01 21:59:26 +0000635 } else {
thsf58c7b32008-06-05 21:53:49 +0000636 sector_num = 0; // total number of sectors converted so far
bellardea2384d2004-08-01 21:59:26 +0000637 for(;;) {
638 nb_sectors = total_sectors - sector_num;
639 if (nb_sectors <= 0)
640 break;
641 if (nb_sectors >= (IO_BUF_SIZE / 512))
642 n = (IO_BUF_SIZE / 512);
643 else
644 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000645
646 while (sector_num - bs_offset >= bs_sectors) {
647 bs_i ++;
648 assert (bs_i < bs_n);
649 bs_offset += bs_sectors;
650 bdrv_get_geometry(bs[bs_i], &bs_sectors);
651 /* printf("changing part: sector_num=%lld, bs_i=%d, "
652 "bs_offset=%lld, bs_sectors=%lld\n",
653 sector_num, bs_i, bs_offset, bs_sectors); */
654 }
655
656 if (n > bs_offset + bs_sectors - sector_num)
657 n = bs_offset + bs_sectors - sector_num;
658
aliguori93c65b42009-04-05 17:40:43 +0000659 if (drv != &bdrv_host_device) {
660 if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
661 n, &n1)) {
662 sector_num += n1;
663 continue;
664 }
665 /* The next 'n1' sectors are allocated in the input image. Copy
666 only those as they may be followed by unallocated sectors. */
667 n = n1;
668 } else {
669 n1 = n;
thsf58c7b32008-06-05 21:53:49 +0000670 }
671
balrog926c2d22007-10-31 01:11:44 +0000672 if (bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n) < 0)
bellardea2384d2004-08-01 21:59:26 +0000673 error("error while reading");
674 /* NOTE: at the same time we convert, we do not write zero
675 sectors to have a chance to compress the image. Ideally, we
676 should add a specific call to have the info to go faster */
677 buf1 = buf;
678 while (n > 0) {
thsf58c7b32008-06-05 21:53:49 +0000679 /* If the output image is being created as a copy on write image,
680 copy all sectors even the ones containing only NUL bytes,
aliguori93c65b42009-04-05 17:40:43 +0000681 because they may differ from the sectors in the base image.
682
683 If the output is to a host device, we also write out
684 sectors that are entirely 0, since whatever data was
685 already there is garbage, not 0s. */
686 if (drv == &bdrv_host_device || out_baseimg ||
687 is_allocated_sectors(buf1, n, &n1)) {
ths5fafdf22007-09-16 21:08:06 +0000688 if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
bellardea2384d2004-08-01 21:59:26 +0000689 error("error while writing");
690 }
691 sector_num += n1;
692 n -= n1;
693 buf1 += n1 * 512;
694 }
695 }
696 }
697 bdrv_delete(out_bs);
balrog926c2d22007-10-31 01:11:44 +0000698 for (bs_i = 0; bs_i < bs_n; bs_i++)
699 bdrv_delete(bs[bs_i]);
700 free(bs);
bellardea2384d2004-08-01 21:59:26 +0000701 return 0;
702}
703
bellard57d1a2b2004-08-03 21:15:11 +0000704#ifdef _WIN32
705static int64_t get_allocated_file_size(const char *filename)
706{
bellarde8445332006-06-14 15:32:10 +0000707 typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
708 get_compressed_t get_compressed;
bellard57d1a2b2004-08-03 21:15:11 +0000709 struct _stati64 st;
bellarde8445332006-06-14 15:32:10 +0000710
711 /* WinNT support GetCompressedFileSize to determine allocate size */
712 get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
713 if (get_compressed) {
714 DWORD high, low;
715 low = get_compressed(filename, &high);
716 if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
717 return (((int64_t) high) << 32) + low;
718 }
719
ths5fafdf22007-09-16 21:08:06 +0000720 if (_stati64(filename, &st) < 0)
bellard57d1a2b2004-08-03 21:15:11 +0000721 return -1;
722 return st.st_size;
723}
724#else
725static int64_t get_allocated_file_size(const char *filename)
726{
727 struct stat st;
ths5fafdf22007-09-16 21:08:06 +0000728 if (stat(filename, &st) < 0)
bellard57d1a2b2004-08-03 21:15:11 +0000729 return -1;
730 return (int64_t)st.st_blocks * 512;
731}
732#endif
733
bellardfaea38e2006-08-05 21:31:00 +0000734static void dump_snapshots(BlockDriverState *bs)
735{
736 QEMUSnapshotInfo *sn_tab, *sn;
737 int nb_sns, i;
738 char buf[256];
739
740 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
741 if (nb_sns <= 0)
742 return;
743 printf("Snapshot list:\n");
744 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
745 for(i = 0; i < nb_sns; i++) {
746 sn = &sn_tab[i];
747 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
748 }
749 qemu_free(sn_tab);
750}
751
bellardea2384d2004-08-01 21:59:26 +0000752static int img_info(int argc, char **argv)
753{
754 int c;
755 const char *filename, *fmt;
756 BlockDriver *drv;
757 BlockDriverState *bs;
758 char fmt_name[128], size_buf[128], dsize_buf[128];
ths96b8f132007-12-17 01:35:20 +0000759 uint64_t total_sectors;
760 int64_t allocated_size;
bellard93b6b2a2006-08-01 15:51:11 +0000761 char backing_filename[1024];
762 char backing_filename2[1024];
bellardfaea38e2006-08-05 21:31:00 +0000763 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +0000764
765 fmt = NULL;
766 for(;;) {
767 c = getopt(argc, argv, "f:h");
768 if (c == -1)
769 break;
770 switch(c) {
771 case 'h':
772 help();
773 break;
774 case 'f':
775 fmt = optarg;
776 break;
777 }
778 }
ths5fafdf22007-09-16 21:08:06 +0000779 if (optind >= argc)
bellardea2384d2004-08-01 21:59:26 +0000780 help();
781 filename = argv[optind++];
782
783 bs = bdrv_new("");
784 if (!bs)
785 error("Not enough memory");
786 if (fmt) {
787 drv = bdrv_find_format(fmt);
788 if (!drv)
789 error("Unknown file format '%s'", fmt);
790 } else {
791 drv = NULL;
792 }
aurel32137519c2008-11-30 19:12:49 +0000793 if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
bellardea2384d2004-08-01 21:59:26 +0000794 error("Could not open '%s'", filename);
795 }
796 bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
797 bdrv_get_geometry(bs, &total_sectors);
798 get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
bellard57d1a2b2004-08-03 21:15:11 +0000799 allocated_size = get_allocated_file_size(filename);
800 if (allocated_size < 0)
blueswir1a10ea302008-08-24 10:30:33 +0000801 snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
bellardde167e42005-04-28 21:15:08 +0000802 else
ths5fafdf22007-09-16 21:08:06 +0000803 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
bellardde167e42005-04-28 21:15:08 +0000804 allocated_size);
bellardea2384d2004-08-01 21:59:26 +0000805 printf("image: %s\n"
806 "file format: %s\n"
bellardec3757d2006-06-14 15:50:07 +0000807 "virtual size: %s (%" PRId64 " bytes)\n"
bellardea2384d2004-08-01 21:59:26 +0000808 "disk size: %s\n",
ths5fafdf22007-09-16 21:08:06 +0000809 filename, fmt_name, size_buf,
bellardec3757d2006-06-14 15:50:07 +0000810 (total_sectors * 512),
bellardea2384d2004-08-01 21:59:26 +0000811 dsize_buf);
812 if (bdrv_is_encrypted(bs))
813 printf("encrypted: yes\n");
bellardfaea38e2006-08-05 21:31:00 +0000814 if (bdrv_get_info(bs, &bdi) >= 0) {
ths5fafdf22007-09-16 21:08:06 +0000815 if (bdi.cluster_size != 0)
bellardfaea38e2006-08-05 21:31:00 +0000816 printf("cluster_size: %d\n", bdi.cluster_size);
817 }
bellard93b6b2a2006-08-01 15:51:11 +0000818 bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
bellardfaea38e2006-08-05 21:31:00 +0000819 if (backing_filename[0] != '\0') {
bellard93b6b2a2006-08-01 15:51:11 +0000820 path_combine(backing_filename2, sizeof(backing_filename2),
821 filename, backing_filename);
ths5fafdf22007-09-16 21:08:06 +0000822 printf("backing file: %s (actual path: %s)\n",
bellard93b6b2a2006-08-01 15:51:11 +0000823 backing_filename,
824 backing_filename2);
bellardfaea38e2006-08-05 21:31:00 +0000825 }
826 dump_snapshots(bs);
bellardea2384d2004-08-01 21:59:26 +0000827 bdrv_delete(bs);
828 return 0;
829}
830
aliguorif7b4a942009-01-07 17:40:15 +0000831#define SNAPSHOT_LIST 1
832#define SNAPSHOT_CREATE 2
833#define SNAPSHOT_APPLY 3
834#define SNAPSHOT_DELETE 4
835
836static void img_snapshot(int argc, char **argv)
837{
838 BlockDriverState *bs;
839 QEMUSnapshotInfo sn;
840 char *filename, *snapshot_name = NULL;
aliguori40a45392009-01-15 21:42:12 +0000841 int c, ret;
aliguorif7b4a942009-01-07 17:40:15 +0000842 int action = 0;
843 qemu_timeval tv;
844
845 /* Parse commandline parameters */
846 for(;;) {
847 c = getopt(argc, argv, "la:c:d:h");
848 if (c == -1)
849 break;
850 switch(c) {
851 case 'h':
852 help();
853 return;
854 case 'l':
855 if (action) {
856 help();
857 return;
858 }
859 action = SNAPSHOT_LIST;
860 break;
861 case 'a':
862 if (action) {
863 help();
864 return;
865 }
866 action = SNAPSHOT_APPLY;
867 snapshot_name = optarg;
868 break;
869 case 'c':
870 if (action) {
871 help();
872 return;
873 }
874 action = SNAPSHOT_CREATE;
875 snapshot_name = optarg;
876 break;
877 case 'd':
878 if (action) {
879 help();
880 return;
881 }
882 action = SNAPSHOT_DELETE;
883 snapshot_name = optarg;
884 break;
885 }
886 }
887
888 if (optind >= argc)
889 help();
890 filename = argv[optind++];
891
892 /* Open the image */
893 bs = bdrv_new("");
894 if (!bs)
895 error("Not enough memory");
896
897 if (bdrv_open2(bs, filename, 0, NULL) < 0) {
898 error("Could not open '%s'", filename);
899 }
900
901 /* Perform the requested action */
902 switch(action) {
903 case SNAPSHOT_LIST:
904 dump_snapshots(bs);
905 break;
906
907 case SNAPSHOT_CREATE:
908 memset(&sn, 0, sizeof(sn));
909 pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
910
911 qemu_gettimeofday(&tv);
912 sn.date_sec = tv.tv_sec;
913 sn.date_nsec = tv.tv_usec * 1000;
914
915 ret = bdrv_snapshot_create(bs, &sn);
916 if (ret)
917 error("Could not create snapshot '%s': %d (%s)",
918 snapshot_name, ret, strerror(-ret));
919 break;
920
921 case SNAPSHOT_APPLY:
922 ret = bdrv_snapshot_goto(bs, snapshot_name);
923 if (ret)
924 error("Could not apply snapshot '%s': %d (%s)",
925 snapshot_name, ret, strerror(-ret));
926 break;
927
928 case SNAPSHOT_DELETE:
929 ret = bdrv_snapshot_delete(bs, snapshot_name);
930 if (ret)
931 error("Could not delete snapshot '%s': %d (%s)",
932 snapshot_name, ret, strerror(-ret));
933 break;
934 }
935
936 /* Cleanup */
937 bdrv_delete(bs);
938}
939
bellardea2384d2004-08-01 21:59:26 +0000940int main(int argc, char **argv)
941{
942 const char *cmd;
943
944 bdrv_init();
945 if (argc < 2)
946 help();
947 cmd = argv[1];
aurel328f9b1572009-02-09 18:14:31 +0000948 argc--; argv++;
bellardea2384d2004-08-01 21:59:26 +0000949 if (!strcmp(cmd, "create")) {
950 img_create(argc, argv);
aliguori15859692009-04-21 23:11:53 +0000951 } else if (!strcmp(cmd, "check")) {
952 img_check(argc, argv);
bellardea2384d2004-08-01 21:59:26 +0000953 } else if (!strcmp(cmd, "commit")) {
954 img_commit(argc, argv);
955 } else if (!strcmp(cmd, "convert")) {
956 img_convert(argc, argv);
957 } else if (!strcmp(cmd, "info")) {
958 img_info(argc, argv);
aliguorif7b4a942009-01-07 17:40:15 +0000959 } else if (!strcmp(cmd, "snapshot")) {
960 img_snapshot(argc, argv);
bellardea2384d2004-08-01 21:59:26 +0000961 } else {
962 help();
963 }
964 return 0;
965}