blob: 732f8896492e0cb45afd46cf354b9ddcbfe270cc [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>
bellardea2384d2004-08-01 21:59:26 +000028
bellarde8445332006-06-14 15:32:10 +000029#ifdef _WIN32
ths4fddf622007-12-17 04:42:29 +000030#define WIN32_LEAN_AND_MEAN
bellarde8445332006-06-14 15:32:10 +000031#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
blueswir17d99a002009-01-14 19:00:36 +000037static void 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
pbrook3f379ab2007-11-11 03:33:13 +000053static void help(void)
bellardea2384d2004-08-01 21:59:26 +000054{
bellard68d0f702008-01-06 17:21:48 +000055 printf("qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fabrice Bellard\n"
bellard57d1a2b2004-08-03 21:15:11 +000056 "usage: qemu-img command [command options]\n"
bellardea2384d2004-08-01 21:59:26 +000057 "QEMU disk image utility\n"
58 "\n"
59 "Command syntax:\n"
thsec36ba12007-09-16 21:59:02 +000060 " create [-e] [-6] [-b base_image] [-f fmt] filename [size]\n"
bellardea2384d2004-08-01 21:59:26 +000061 " commit [-f fmt] filename\n"
thsf58c7b32008-06-05 21:53:49 +000062 " convert [-c] [-e] [-6] [-f fmt] [-O output_fmt] [-B output_base_image] filename [filename2 [...]] output_filename\n"
bellardea2384d2004-08-01 21:59:26 +000063 " info [-f fmt] filename\n"
aliguorif7b4a942009-01-07 17:40:15 +000064 " snapshot [-l|-a snapshot|-c snapshot|-d snapshot] filename\n"
bellardea2384d2004-08-01 21:59:26 +000065 "\n"
66 "Command parameters:\n"
67 " 'filename' is a disk image filename\n"
68 " 'base_image' is the read-only disk image which is used as base for a copy on\n"
69 " write image; the copy on write image only stores the modified data\n"
thsf58c7b32008-06-05 21:53:49 +000070 " 'output_base_image' forces the output image to be created as a copy on write\n"
71 " image of the specified base image; 'output_base_image' should have the same\n"
72 " content as the input's base image, however the path, image format, etc may\n"
73 " differ\n"
bellardea2384d2004-08-01 21:59:26 +000074 " 'fmt' is the disk image format. It is guessed automatically in most cases\n"
75 " 'size' is the disk image size in kilobytes. Optional suffixes 'M' (megabyte)\n"
76 " and 'G' (gigabyte) are supported\n"
77 " 'output_filename' is the destination disk image filename\n"
78 " 'output_fmt' is the destination format\n"
79 " '-c' indicates that target image must be compressed (qcow format only)\n"
80 " '-e' indicates that the target image must be encrypted (qcow format only)\n"
thsec36ba12007-09-16 21:59:02 +000081 " '-6' indicates that the target image must use compatibility level 6 (vmdk format only)\n"
aliguorif7b4a942009-01-07 17:40:15 +000082 "\n"
83 " Parameters to snapshot subcommand:\n"
84 " 'snapshot' is the name of the snapshot to create, apply or delete\n"
85 " '-a' applies a snapshot (revert disk to saved state)\n"
86 " '-c' creates a snapshot\n"
87 " '-d' deletes a snapshot\n"
88 " '-l' lists all snapshots in the given image\n"
bellardea2384d2004-08-01 21:59:26 +000089 );
90 printf("\nSupported format:");
91 bdrv_iterate_format(format_print, NULL);
92 printf("\n");
93 exit(1);
94}
95
bellardea2384d2004-08-01 21:59:26 +000096#if defined(WIN32)
97/* XXX: put correct support for win32 */
98static int read_password(char *buf, int buf_size)
99{
100 int c, i;
101 printf("Password: ");
102 fflush(stdout);
103 i = 0;
104 for(;;) {
105 c = getchar();
106 if (c == '\n')
107 break;
108 if (i < (buf_size - 1))
109 buf[i++] = c;
110 }
111 buf[i] = '\0';
112 return 0;
113}
114
115#else
116
117#include <termios.h>
118
119static struct termios oldtty;
120
121static void term_exit(void)
122{
123 tcsetattr (0, TCSANOW, &oldtty);
124}
125
126static void term_init(void)
127{
128 struct termios tty;
129
130 tcgetattr (0, &tty);
131 oldtty = tty;
132
133 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
134 |INLCR|IGNCR|ICRNL|IXON);
135 tty.c_oflag |= OPOST;
136 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
137 tty.c_cflag &= ~(CSIZE|PARENB);
138 tty.c_cflag |= CS8;
139 tty.c_cc[VMIN] = 1;
140 tty.c_cc[VTIME] = 0;
ths3b46e622007-09-17 08:09:54 +0000141
bellardea2384d2004-08-01 21:59:26 +0000142 tcsetattr (0, TCSANOW, &tty);
143
144 atexit(term_exit);
145}
146
pbrook3f379ab2007-11-11 03:33:13 +0000147static int read_password(char *buf, int buf_size)
bellardea2384d2004-08-01 21:59:26 +0000148{
149 uint8_t ch;
150 int i, ret;
151
152 printf("password: ");
153 fflush(stdout);
154 term_init();
155 i = 0;
156 for(;;) {
157 ret = read(0, &ch, 1);
158 if (ret == -1) {
159 if (errno == EAGAIN || errno == EINTR) {
160 continue;
161 } else {
162 ret = -1;
163 break;
164 }
165 } else if (ret == 0) {
166 ret = -1;
167 break;
168 } else {
169 if (ch == '\r') {
170 ret = 0;
171 break;
172 }
173 if (i < (buf_size - 1))
174 buf[i++] = ch;
175 }
176 }
177 term_exit();
178 buf[i] = '\0';
179 printf("\n");
180 return ret;
181}
182#endif
183
bellard75c23802004-08-27 21:28:58 +0000184static BlockDriverState *bdrv_new_open(const char *filename,
185 const char *fmt)
186{
187 BlockDriverState *bs;
188 BlockDriver *drv;
189 char password[256];
190
191 bs = bdrv_new("");
192 if (!bs)
193 error("Not enough memory");
194 if (fmt) {
195 drv = bdrv_find_format(fmt);
196 if (!drv)
197 error("Unknown file format '%s'", fmt);
198 } else {
199 drv = NULL;
200 }
aurel32137519c2008-11-30 19:12:49 +0000201 if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
bellard75c23802004-08-27 21:28:58 +0000202 error("Could not open '%s'", filename);
203 }
204 if (bdrv_is_encrypted(bs)) {
205 printf("Disk image '%s' is encrypted.\n", filename);
206 if (read_password(password, sizeof(password)) < 0)
207 error("No password given");
208 if (bdrv_set_key(bs, password) < 0)
209 error("invalid password");
210 }
211 return bs;
212}
213
bellardea2384d2004-08-01 21:59:26 +0000214static int img_create(int argc, char **argv)
215{
thsec36ba12007-09-16 21:59:02 +0000216 int c, ret, flags;
bellardea2384d2004-08-01 21:59:26 +0000217 const char *fmt = "raw";
218 const char *filename;
219 const char *base_filename = NULL;
ths96b8f132007-12-17 01:35:20 +0000220 uint64_t size;
bellardea2384d2004-08-01 21:59:26 +0000221 const char *p;
222 BlockDriver *drv;
ths3b46e622007-09-17 08:09:54 +0000223
thsec36ba12007-09-16 21:59:02 +0000224 flags = 0;
bellardea2384d2004-08-01 21:59:26 +0000225 for(;;) {
thsec36ba12007-09-16 21:59:02 +0000226 c = getopt(argc, argv, "b:f:he6");
bellardea2384d2004-08-01 21:59:26 +0000227 if (c == -1)
228 break;
229 switch(c) {
230 case 'h':
231 help();
232 break;
233 case 'b':
234 base_filename = optarg;
235 break;
236 case 'f':
237 fmt = optarg;
238 break;
239 case 'e':
thsec36ba12007-09-16 21:59:02 +0000240 flags |= BLOCK_FLAG_ENCRYPT;
bellardea2384d2004-08-01 21:59:26 +0000241 break;
thsd8871c52007-10-24 16:11:42 +0000242 case '6':
thsec36ba12007-09-16 21:59:02 +0000243 flags |= BLOCK_FLAG_COMPAT6;
thsd8871c52007-10-24 16:11:42 +0000244 break;
bellardea2384d2004-08-01 21:59:26 +0000245 }
246 }
ths5fafdf22007-09-16 21:08:06 +0000247 if (optind >= argc)
bellardea2384d2004-08-01 21:59:26 +0000248 help();
249 filename = argv[optind++];
250 size = 0;
bellard75c23802004-08-27 21:28:58 +0000251 if (base_filename) {
aliguorie94f3a62008-08-01 15:04:00 +0000252 BlockDriverState *bs;
bellard75c23802004-08-27 21:28:58 +0000253 bs = bdrv_new_open(base_filename, NULL);
254 bdrv_get_geometry(bs, &size);
255 size *= 512;
256 bdrv_delete(bs);
257 } else {
bellardea2384d2004-08-01 21:59:26 +0000258 if (optind >= argc)
259 help();
260 p = argv[optind];
261 size = strtoul(p, (char **)&p, 0);
262 if (*p == 'M') {
263 size *= 1024 * 1024;
264 } else if (*p == 'G') {
265 size *= 1024 * 1024 * 1024;
266 } else if (*p == 'k' || *p == 'K' || *p == '\0') {
267 size *= 1024;
268 } else {
269 help();
270 }
271 }
272 drv = bdrv_find_format(fmt);
273 if (!drv)
274 error("Unknown file format '%s'", fmt);
ths0cfec832007-06-23 16:02:43 +0000275 printf("Formatting '%s', fmt=%s",
bellardea2384d2004-08-01 21:59:26 +0000276 filename, fmt);
thsec36ba12007-09-16 21:59:02 +0000277 if (flags & BLOCK_FLAG_ENCRYPT)
bellardea2384d2004-08-01 21:59:26 +0000278 printf(", encrypted");
thsec36ba12007-09-16 21:59:02 +0000279 if (flags & BLOCK_FLAG_COMPAT6)
280 printf(", compatibility level=6");
bellard75c23802004-08-27 21:28:58 +0000281 if (base_filename) {
282 printf(", backing_file=%s",
bellardea2384d2004-08-01 21:59:26 +0000283 base_filename);
bellard75c23802004-08-27 21:28:58 +0000284 }
ths96b8f132007-12-17 01:35:20 +0000285 printf(", size=%" PRIu64 " kB\n", size / 1024);
thsec36ba12007-09-16 21:59:02 +0000286 ret = bdrv_create(drv, filename, size / 512, base_filename, flags);
bellardea2384d2004-08-01 21:59:26 +0000287 if (ret < 0) {
288 if (ret == -ENOTSUP) {
bellard3c565212004-09-29 21:29:14 +0000289 error("Formatting or formatting option not supported for file format '%s'", fmt);
bellardea2384d2004-08-01 21:59:26 +0000290 } else {
291 error("Error while formatting");
292 }
293 }
294 return 0;
295}
296
297static int img_commit(int argc, char **argv)
298{
299 int c, ret;
300 const char *filename, *fmt;
301 BlockDriver *drv;
302 BlockDriverState *bs;
303
304 fmt = NULL;
305 for(;;) {
306 c = getopt(argc, argv, "f:h");
307 if (c == -1)
308 break;
309 switch(c) {
310 case 'h':
311 help();
312 break;
313 case 'f':
314 fmt = optarg;
315 break;
316 }
317 }
ths5fafdf22007-09-16 21:08:06 +0000318 if (optind >= argc)
bellardea2384d2004-08-01 21:59:26 +0000319 help();
320 filename = argv[optind++];
321
322 bs = bdrv_new("");
323 if (!bs)
324 error("Not enough memory");
325 if (fmt) {
326 drv = bdrv_find_format(fmt);
327 if (!drv)
328 error("Unknown file format '%s'", fmt);
329 } else {
330 drv = NULL;
331 }
aurel32137519c2008-11-30 19:12:49 +0000332 if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
bellardea2384d2004-08-01 21:59:26 +0000333 error("Could not open '%s'", filename);
334 }
335 ret = bdrv_commit(bs);
336 switch(ret) {
337 case 0:
338 printf("Image committed.\n");
339 break;
340 case -ENOENT:
341 error("No disk inserted");
342 break;
343 case -EACCES:
344 error("Image is read-only");
345 break;
346 case -ENOTSUP:
347 error("Image is already committed");
348 break;
349 default:
350 error("Error while committing image");
351 break;
352 }
353
354 bdrv_delete(bs);
355 return 0;
356}
357
358static int is_not_zero(const uint8_t *sector, int len)
359{
360 int i;
361 len >>= 2;
362 for(i = 0;i < len; i++) {
363 if (((uint32_t *)sector)[i] != 0)
364 return 1;
365 }
366 return 0;
367}
368
thsf58c7b32008-06-05 21:53:49 +0000369/*
370 * Returns true iff the first sector pointed to by 'buf' contains at least
371 * a non-NUL byte.
372 *
373 * 'pnum' is set to the number of sectors (including and immediately following
374 * the first one) that are known to be in the same allocated/unallocated state.
375 */
bellardea2384d2004-08-01 21:59:26 +0000376static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
377{
378 int v, i;
379
380 if (n <= 0) {
381 *pnum = 0;
382 return 0;
383 }
384 v = is_not_zero(buf, 512);
385 for(i = 1; i < n; i++) {
386 buf += 512;
387 if (v != is_not_zero(buf, 512))
388 break;
389 }
390 *pnum = i;
391 return v;
392}
393
bellardea2384d2004-08-01 21:59:26 +0000394#define IO_BUF_SIZE 65536
395
396static int img_convert(int argc, char **argv)
397{
balrog926c2d22007-10-31 01:11:44 +0000398 int c, ret, n, n1, bs_n, bs_i, flags, cluster_size, cluster_sectors;
thsf58c7b32008-06-05 21:53:49 +0000399 const char *fmt, *out_fmt, *out_baseimg, *out_filename;
bellardea2384d2004-08-01 21:59:26 +0000400 BlockDriver *drv;
balrog926c2d22007-10-31 01:11:44 +0000401 BlockDriverState **bs, *out_bs;
ths96b8f132007-12-17 01:35:20 +0000402 int64_t total_sectors, nb_sectors, sector_num, bs_offset;
403 uint64_t bs_sectors;
bellardea2384d2004-08-01 21:59:26 +0000404 uint8_t buf[IO_BUF_SIZE];
405 const uint8_t *buf1;
bellardfaea38e2006-08-05 21:31:00 +0000406 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +0000407
408 fmt = NULL;
409 out_fmt = "raw";
thsf58c7b32008-06-05 21:53:49 +0000410 out_baseimg = NULL;
thsec36ba12007-09-16 21:59:02 +0000411 flags = 0;
bellardea2384d2004-08-01 21:59:26 +0000412 for(;;) {
thsf58c7b32008-06-05 21:53:49 +0000413 c = getopt(argc, argv, "f:O:B:hce6");
bellardea2384d2004-08-01 21:59:26 +0000414 if (c == -1)
415 break;
416 switch(c) {
417 case 'h':
418 help();
419 break;
420 case 'f':
421 fmt = optarg;
422 break;
423 case 'O':
424 out_fmt = optarg;
425 break;
thsf58c7b32008-06-05 21:53:49 +0000426 case 'B':
427 out_baseimg = optarg;
428 break;
bellardea2384d2004-08-01 21:59:26 +0000429 case 'c':
thsec36ba12007-09-16 21:59:02 +0000430 flags |= BLOCK_FLAG_COMPRESS;
bellardea2384d2004-08-01 21:59:26 +0000431 break;
432 case 'e':
thsec36ba12007-09-16 21:59:02 +0000433 flags |= BLOCK_FLAG_ENCRYPT;
434 break;
435 case '6':
436 flags |= BLOCK_FLAG_COMPAT6;
bellardea2384d2004-08-01 21:59:26 +0000437 break;
438 }
439 }
ths3b46e622007-09-17 08:09:54 +0000440
balrog926c2d22007-10-31 01:11:44 +0000441 bs_n = argc - optind - 1;
442 if (bs_n < 1) help();
443
444 out_filename = argv[argc - 1];
thsf58c7b32008-06-05 21:53:49 +0000445
446 if (bs_n > 1 && out_baseimg)
447 error("-B makes no sense when concatenating multiple input images");
balrog926c2d22007-10-31 01:11:44 +0000448
449 bs = calloc(bs_n, sizeof(BlockDriverState *));
450 if (!bs)
451 error("Out of memory");
452
453 total_sectors = 0;
454 for (bs_i = 0; bs_i < bs_n; bs_i++) {
455 bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt);
456 if (!bs[bs_i])
457 error("Could not open '%s'", argv[optind + bs_i]);
458 bdrv_get_geometry(bs[bs_i], &bs_sectors);
459 total_sectors += bs_sectors;
460 }
bellardea2384d2004-08-01 21:59:26 +0000461
462 drv = bdrv_find_format(out_fmt);
463 if (!drv)
thsd34dda52007-02-10 22:59:40 +0000464 error("Unknown file format '%s'", out_fmt);
thsec36ba12007-09-16 21:59:02 +0000465 if (flags & BLOCK_FLAG_COMPRESS && drv != &bdrv_qcow && drv != &bdrv_qcow2)
bellardea2384d2004-08-01 21:59:26 +0000466 error("Compression not supported for this file format");
thsec36ba12007-09-16 21:59:02 +0000467 if (flags & BLOCK_FLAG_ENCRYPT && drv != &bdrv_qcow && drv != &bdrv_qcow2)
bellardea2384d2004-08-01 21:59:26 +0000468 error("Encryption not supported for this file format");
thsd8871c52007-10-24 16:11:42 +0000469 if (flags & BLOCK_FLAG_COMPAT6 && drv != &bdrv_vmdk)
thsec36ba12007-09-16 21:59:02 +0000470 error("Alternative compatibility level not supported for this file format");
471 if (flags & BLOCK_FLAG_ENCRYPT && flags & BLOCK_FLAG_COMPRESS)
bellardea2384d2004-08-01 21:59:26 +0000472 error("Compression and encryption not supported at the same time");
balrog926c2d22007-10-31 01:11:44 +0000473
thsf58c7b32008-06-05 21:53:49 +0000474 ret = bdrv_create(drv, out_filename, total_sectors, out_baseimg, flags);
bellardea2384d2004-08-01 21:59:26 +0000475 if (ret < 0) {
476 if (ret == -ENOTSUP) {
bellard3c565212004-09-29 21:29:14 +0000477 error("Formatting not supported for file format '%s'", fmt);
bellardea2384d2004-08-01 21:59:26 +0000478 } else {
479 error("Error while formatting '%s'", out_filename);
480 }
481 }
ths3b46e622007-09-17 08:09:54 +0000482
bellardea2384d2004-08-01 21:59:26 +0000483 out_bs = bdrv_new_open(out_filename, out_fmt);
484
balrog926c2d22007-10-31 01:11:44 +0000485 bs_i = 0;
486 bs_offset = 0;
487 bdrv_get_geometry(bs[0], &bs_sectors);
488
489 if (flags & BLOCK_FLAG_COMPRESS) {
bellardfaea38e2006-08-05 21:31:00 +0000490 if (bdrv_get_info(out_bs, &bdi) < 0)
491 error("could not get block driver info");
492 cluster_size = bdi.cluster_size;
bellardea2384d2004-08-01 21:59:26 +0000493 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE)
494 error("invalid cluster size");
495 cluster_sectors = cluster_size >> 9;
496 sector_num = 0;
497 for(;;) {
balrog926c2d22007-10-31 01:11:44 +0000498 int64_t bs_num;
499 int remainder;
500 uint8_t *buf2;
501
bellardea2384d2004-08-01 21:59:26 +0000502 nb_sectors = total_sectors - sector_num;
503 if (nb_sectors <= 0)
504 break;
505 if (nb_sectors >= cluster_sectors)
506 n = cluster_sectors;
507 else
508 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000509
510 bs_num = sector_num - bs_offset;
511 assert (bs_num >= 0);
512 remainder = n;
513 buf2 = buf;
514 while (remainder > 0) {
515 int nlow;
516 while (bs_num == bs_sectors) {
517 bs_i++;
518 assert (bs_i < bs_n);
519 bs_offset += bs_sectors;
520 bdrv_get_geometry(bs[bs_i], &bs_sectors);
521 bs_num = 0;
522 /* printf("changing part: sector_num=%lld, "
523 "bs_i=%d, bs_offset=%lld, bs_sectors=%lld\n",
524 sector_num, bs_i, bs_offset, bs_sectors); */
525 }
526 assert (bs_num < bs_sectors);
527
528 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
529
530 if (bdrv_read(bs[bs_i], bs_num, buf2, nlow) < 0)
531 error("error while reading");
532
533 buf2 += nlow * 512;
534 bs_num += nlow;
535
536 remainder -= nlow;
537 }
538 assert (remainder == 0);
539
bellardea2384d2004-08-01 21:59:26 +0000540 if (n < cluster_sectors)
541 memset(buf + n * 512, 0, cluster_size - n * 512);
542 if (is_not_zero(buf, cluster_size)) {
ths5fafdf22007-09-16 21:08:06 +0000543 if (bdrv_write_compressed(out_bs, sector_num, buf,
bellardfaea38e2006-08-05 21:31:00 +0000544 cluster_sectors) != 0)
bellardec3757d2006-06-14 15:50:07 +0000545 error("error while compressing sector %" PRId64,
546 sector_num);
bellardea2384d2004-08-01 21:59:26 +0000547 }
548 sector_num += n;
549 }
bellardfaea38e2006-08-05 21:31:00 +0000550 /* signal EOF to align */
551 bdrv_write_compressed(out_bs, 0, NULL, 0);
bellardea2384d2004-08-01 21:59:26 +0000552 } else {
thsf58c7b32008-06-05 21:53:49 +0000553 sector_num = 0; // total number of sectors converted so far
bellardea2384d2004-08-01 21:59:26 +0000554 for(;;) {
555 nb_sectors = total_sectors - sector_num;
556 if (nb_sectors <= 0)
557 break;
558 if (nb_sectors >= (IO_BUF_SIZE / 512))
559 n = (IO_BUF_SIZE / 512);
560 else
561 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000562
563 while (sector_num - bs_offset >= bs_sectors) {
564 bs_i ++;
565 assert (bs_i < bs_n);
566 bs_offset += bs_sectors;
567 bdrv_get_geometry(bs[bs_i], &bs_sectors);
568 /* printf("changing part: sector_num=%lld, bs_i=%d, "
569 "bs_offset=%lld, bs_sectors=%lld\n",
570 sector_num, bs_i, bs_offset, bs_sectors); */
571 }
572
573 if (n > bs_offset + bs_sectors - sector_num)
574 n = bs_offset + bs_sectors - sector_num;
575
thsf58c7b32008-06-05 21:53:49 +0000576 /* If the output image is being created as a copy on write image,
577 assume that sectors which are unallocated in the input image
578 are present in both the output's and input's base images (no
579 need to copy them). */
580 if (out_baseimg) {
581 if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset, n, &n1)) {
582 sector_num += n1;
583 continue;
584 }
585 /* The next 'n1' sectors are allocated in the input image. Copy
586 only those as they may be followed by unallocated sectors. */
587 n = n1;
588 }
589
balrog926c2d22007-10-31 01:11:44 +0000590 if (bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n) < 0)
bellardea2384d2004-08-01 21:59:26 +0000591 error("error while reading");
592 /* NOTE: at the same time we convert, we do not write zero
593 sectors to have a chance to compress the image. Ideally, we
594 should add a specific call to have the info to go faster */
595 buf1 = buf;
596 while (n > 0) {
thsf58c7b32008-06-05 21:53:49 +0000597 /* If the output image is being created as a copy on write image,
598 copy all sectors even the ones containing only NUL bytes,
599 because they may differ from the sectors in the base image. */
600 if (out_baseimg || is_allocated_sectors(buf1, n, &n1)) {
ths5fafdf22007-09-16 21:08:06 +0000601 if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
bellardea2384d2004-08-01 21:59:26 +0000602 error("error while writing");
603 }
604 sector_num += n1;
605 n -= n1;
606 buf1 += n1 * 512;
607 }
608 }
609 }
610 bdrv_delete(out_bs);
balrog926c2d22007-10-31 01:11:44 +0000611 for (bs_i = 0; bs_i < bs_n; bs_i++)
612 bdrv_delete(bs[bs_i]);
613 free(bs);
bellardea2384d2004-08-01 21:59:26 +0000614 return 0;
615}
616
bellard57d1a2b2004-08-03 21:15:11 +0000617#ifdef _WIN32
618static int64_t get_allocated_file_size(const char *filename)
619{
bellarde8445332006-06-14 15:32:10 +0000620 typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
621 get_compressed_t get_compressed;
bellard57d1a2b2004-08-03 21:15:11 +0000622 struct _stati64 st;
bellarde8445332006-06-14 15:32:10 +0000623
624 /* WinNT support GetCompressedFileSize to determine allocate size */
625 get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
626 if (get_compressed) {
627 DWORD high, low;
628 low = get_compressed(filename, &high);
629 if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
630 return (((int64_t) high) << 32) + low;
631 }
632
ths5fafdf22007-09-16 21:08:06 +0000633 if (_stati64(filename, &st) < 0)
bellard57d1a2b2004-08-03 21:15:11 +0000634 return -1;
635 return st.st_size;
636}
637#else
638static int64_t get_allocated_file_size(const char *filename)
639{
640 struct stat st;
ths5fafdf22007-09-16 21:08:06 +0000641 if (stat(filename, &st) < 0)
bellard57d1a2b2004-08-03 21:15:11 +0000642 return -1;
643 return (int64_t)st.st_blocks * 512;
644}
645#endif
646
bellardfaea38e2006-08-05 21:31:00 +0000647static void dump_snapshots(BlockDriverState *bs)
648{
649 QEMUSnapshotInfo *sn_tab, *sn;
650 int nb_sns, i;
651 char buf[256];
652
653 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
654 if (nb_sns <= 0)
655 return;
656 printf("Snapshot list:\n");
657 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
658 for(i = 0; i < nb_sns; i++) {
659 sn = &sn_tab[i];
660 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
661 }
662 qemu_free(sn_tab);
663}
664
bellardea2384d2004-08-01 21:59:26 +0000665static int img_info(int argc, char **argv)
666{
667 int c;
668 const char *filename, *fmt;
669 BlockDriver *drv;
670 BlockDriverState *bs;
671 char fmt_name[128], size_buf[128], dsize_buf[128];
ths96b8f132007-12-17 01:35:20 +0000672 uint64_t total_sectors;
673 int64_t allocated_size;
bellard93b6b2a2006-08-01 15:51:11 +0000674 char backing_filename[1024];
675 char backing_filename2[1024];
bellardfaea38e2006-08-05 21:31:00 +0000676 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +0000677
678 fmt = NULL;
679 for(;;) {
680 c = getopt(argc, argv, "f:h");
681 if (c == -1)
682 break;
683 switch(c) {
684 case 'h':
685 help();
686 break;
687 case 'f':
688 fmt = optarg;
689 break;
690 }
691 }
ths5fafdf22007-09-16 21:08:06 +0000692 if (optind >= argc)
bellardea2384d2004-08-01 21:59:26 +0000693 help();
694 filename = argv[optind++];
695
696 bs = bdrv_new("");
697 if (!bs)
698 error("Not enough memory");
699 if (fmt) {
700 drv = bdrv_find_format(fmt);
701 if (!drv)
702 error("Unknown file format '%s'", fmt);
703 } else {
704 drv = NULL;
705 }
aurel32137519c2008-11-30 19:12:49 +0000706 if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
bellardea2384d2004-08-01 21:59:26 +0000707 error("Could not open '%s'", filename);
708 }
709 bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
710 bdrv_get_geometry(bs, &total_sectors);
711 get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
bellard57d1a2b2004-08-03 21:15:11 +0000712 allocated_size = get_allocated_file_size(filename);
713 if (allocated_size < 0)
blueswir1a10ea302008-08-24 10:30:33 +0000714 snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
bellardde167e42005-04-28 21:15:08 +0000715 else
ths5fafdf22007-09-16 21:08:06 +0000716 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
bellardde167e42005-04-28 21:15:08 +0000717 allocated_size);
bellardea2384d2004-08-01 21:59:26 +0000718 printf("image: %s\n"
719 "file format: %s\n"
bellardec3757d2006-06-14 15:50:07 +0000720 "virtual size: %s (%" PRId64 " bytes)\n"
bellardea2384d2004-08-01 21:59:26 +0000721 "disk size: %s\n",
ths5fafdf22007-09-16 21:08:06 +0000722 filename, fmt_name, size_buf,
bellardec3757d2006-06-14 15:50:07 +0000723 (total_sectors * 512),
bellardea2384d2004-08-01 21:59:26 +0000724 dsize_buf);
725 if (bdrv_is_encrypted(bs))
726 printf("encrypted: yes\n");
bellardfaea38e2006-08-05 21:31:00 +0000727 if (bdrv_get_info(bs, &bdi) >= 0) {
ths5fafdf22007-09-16 21:08:06 +0000728 if (bdi.cluster_size != 0)
bellardfaea38e2006-08-05 21:31:00 +0000729 printf("cluster_size: %d\n", bdi.cluster_size);
aliguori7e739a52009-01-22 18:57:38 +0000730 if (bdi.highest_alloc)
malc4f94dc62009-01-24 14:38:06 +0000731 printf("highest_alloc: %" PRId64 "\n", bdi.highest_alloc);
aliguori7e739a52009-01-22 18:57:38 +0000732 if (bdi.num_free_bytes)
malc4f94dc62009-01-24 14:38:06 +0000733 printf("num_free_bytes: %" PRId64 "\n", bdi.num_free_bytes);
bellardfaea38e2006-08-05 21:31:00 +0000734 }
bellard93b6b2a2006-08-01 15:51:11 +0000735 bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
bellardfaea38e2006-08-05 21:31:00 +0000736 if (backing_filename[0] != '\0') {
bellard93b6b2a2006-08-01 15:51:11 +0000737 path_combine(backing_filename2, sizeof(backing_filename2),
738 filename, backing_filename);
ths5fafdf22007-09-16 21:08:06 +0000739 printf("backing file: %s (actual path: %s)\n",
bellard93b6b2a2006-08-01 15:51:11 +0000740 backing_filename,
741 backing_filename2);
bellardfaea38e2006-08-05 21:31:00 +0000742 }
743 dump_snapshots(bs);
bellardea2384d2004-08-01 21:59:26 +0000744 bdrv_delete(bs);
745 return 0;
746}
747
aliguorif7b4a942009-01-07 17:40:15 +0000748#define SNAPSHOT_LIST 1
749#define SNAPSHOT_CREATE 2
750#define SNAPSHOT_APPLY 3
751#define SNAPSHOT_DELETE 4
752
753static void img_snapshot(int argc, char **argv)
754{
755 BlockDriverState *bs;
756 QEMUSnapshotInfo sn;
757 char *filename, *snapshot_name = NULL;
aliguori40a45392009-01-15 21:42:12 +0000758 int c, ret;
aliguorif7b4a942009-01-07 17:40:15 +0000759 int action = 0;
760 qemu_timeval tv;
761
762 /* Parse commandline parameters */
763 for(;;) {
764 c = getopt(argc, argv, "la:c:d:h");
765 if (c == -1)
766 break;
767 switch(c) {
768 case 'h':
769 help();
770 return;
771 case 'l':
772 if (action) {
773 help();
774 return;
775 }
776 action = SNAPSHOT_LIST;
777 break;
778 case 'a':
779 if (action) {
780 help();
781 return;
782 }
783 action = SNAPSHOT_APPLY;
784 snapshot_name = optarg;
785 break;
786 case 'c':
787 if (action) {
788 help();
789 return;
790 }
791 action = SNAPSHOT_CREATE;
792 snapshot_name = optarg;
793 break;
794 case 'd':
795 if (action) {
796 help();
797 return;
798 }
799 action = SNAPSHOT_DELETE;
800 snapshot_name = optarg;
801 break;
802 }
803 }
804
805 if (optind >= argc)
806 help();
807 filename = argv[optind++];
808
809 /* Open the image */
810 bs = bdrv_new("");
811 if (!bs)
812 error("Not enough memory");
813
814 if (bdrv_open2(bs, filename, 0, NULL) < 0) {
815 error("Could not open '%s'", filename);
816 }
817
818 /* Perform the requested action */
819 switch(action) {
820 case SNAPSHOT_LIST:
821 dump_snapshots(bs);
822 break;
823
824 case SNAPSHOT_CREATE:
825 memset(&sn, 0, sizeof(sn));
826 pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
827
828 qemu_gettimeofday(&tv);
829 sn.date_sec = tv.tv_sec;
830 sn.date_nsec = tv.tv_usec * 1000;
831
832 ret = bdrv_snapshot_create(bs, &sn);
833 if (ret)
834 error("Could not create snapshot '%s': %d (%s)",
835 snapshot_name, ret, strerror(-ret));
836 break;
837
838 case SNAPSHOT_APPLY:
839 ret = bdrv_snapshot_goto(bs, snapshot_name);
840 if (ret)
841 error("Could not apply snapshot '%s': %d (%s)",
842 snapshot_name, ret, strerror(-ret));
843 break;
844
845 case SNAPSHOT_DELETE:
846 ret = bdrv_snapshot_delete(bs, snapshot_name);
847 if (ret)
848 error("Could not delete snapshot '%s': %d (%s)",
849 snapshot_name, ret, strerror(-ret));
850 break;
851 }
852
853 /* Cleanup */
854 bdrv_delete(bs);
855}
856
bellardea2384d2004-08-01 21:59:26 +0000857int main(int argc, char **argv)
858{
859 const char *cmd;
860
861 bdrv_init();
862 if (argc < 2)
863 help();
864 cmd = argv[1];
bellarde3888182004-10-09 16:44:06 +0000865 optind++;
bellardea2384d2004-08-01 21:59:26 +0000866 if (!strcmp(cmd, "create")) {
867 img_create(argc, argv);
868 } else if (!strcmp(cmd, "commit")) {
869 img_commit(argc, argv);
870 } else if (!strcmp(cmd, "convert")) {
871 img_convert(argc, argv);
872 } else if (!strcmp(cmd, "info")) {
873 img_info(argc, argv);
aliguorif7b4a942009-01-07 17:40:15 +0000874 } else if (!strcmp(cmd, "snapshot")) {
875 img_snapshot(argc, argv);
bellardea2384d2004-08-01 21:59:26 +0000876 } else {
877 help();
878 }
879 return 0;
880}