blob: 207535f4f710c0f9d862a125b79e4faaf8a613e9 [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"
thsec36ba12007-09-16 21:59:02 +000025#include "block_int.h"
balrog926c2d22007-10-31 01:11:44 +000026#include <assert.h>
bellardea2384d2004-08-01 21:59:26 +000027
bellarde8445332006-06-14 15:32:10 +000028#ifdef _WIN32
ths4fddf622007-12-17 04:42:29 +000029#define WIN32_LEAN_AND_MEAN
bellarde8445332006-06-14 15:32:10 +000030#include <windows.h>
31#endif
32
aurel32137519c2008-11-30 19:12:49 +000033/* Default to cache=writeback as data integrity is not important for qemu-tcg. */
34#define BRDV_O_FLAGS BDRV_O_CACHE_WB
35
pbrook3f379ab2007-11-11 03:33:13 +000036static void __attribute__((noreturn)) error(const char *fmt, ...)
bellardea2384d2004-08-01 21:59:26 +000037{
38 va_list ap;
39 va_start(ap, fmt);
bellard57d1a2b2004-08-03 21:15:11 +000040 fprintf(stderr, "qemu-img: ");
bellardea2384d2004-08-01 21:59:26 +000041 vfprintf(stderr, fmt, ap);
42 fprintf(stderr, "\n");
43 exit(1);
44 va_end(ap);
45}
46
47static void format_print(void *opaque, const char *name)
48{
49 printf(" %s", name);
50}
51
pbrook3f379ab2007-11-11 03:33:13 +000052static void help(void)
bellardea2384d2004-08-01 21:59:26 +000053{
bellard68d0f702008-01-06 17:21:48 +000054 printf("qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fabrice Bellard\n"
bellard57d1a2b2004-08-03 21:15:11 +000055 "usage: qemu-img command [command options]\n"
bellardea2384d2004-08-01 21:59:26 +000056 "QEMU disk image utility\n"
57 "\n"
58 "Command syntax:\n"
thsec36ba12007-09-16 21:59:02 +000059 " create [-e] [-6] [-b base_image] [-f fmt] filename [size]\n"
bellardea2384d2004-08-01 21:59:26 +000060 " commit [-f fmt] filename\n"
thsf58c7b32008-06-05 21:53:49 +000061 " convert [-c] [-e] [-6] [-f fmt] [-O output_fmt] [-B output_base_image] filename [filename2 [...]] output_filename\n"
bellardea2384d2004-08-01 21:59:26 +000062 " info [-f fmt] filename\n"
63 "\n"
64 "Command parameters:\n"
65 " 'filename' is a disk image filename\n"
66 " 'base_image' is the read-only disk image which is used as base for a copy on\n"
67 " write image; the copy on write image only stores the modified data\n"
thsf58c7b32008-06-05 21:53:49 +000068 " 'output_base_image' forces the output image to be created as a copy on write\n"
69 " image of the specified base image; 'output_base_image' should have the same\n"
70 " content as the input's base image, however the path, image format, etc may\n"
71 " differ\n"
bellardea2384d2004-08-01 21:59:26 +000072 " 'fmt' is the disk image format. It is guessed automatically in most cases\n"
73 " 'size' is the disk image size in kilobytes. Optional suffixes 'M' (megabyte)\n"
74 " and 'G' (gigabyte) are supported\n"
75 " 'output_filename' is the destination disk image filename\n"
76 " 'output_fmt' is the destination format\n"
77 " '-c' indicates that target image must be compressed (qcow format only)\n"
78 " '-e' indicates that the target image must be encrypted (qcow format only)\n"
thsec36ba12007-09-16 21:59:02 +000079 " '-6' indicates that the target image must use compatibility level 6 (vmdk format only)\n"
bellardea2384d2004-08-01 21:59:26 +000080 );
81 printf("\nSupported format:");
82 bdrv_iterate_format(format_print, NULL);
83 printf("\n");
84 exit(1);
85}
86
bellardea2384d2004-08-01 21:59:26 +000087#if defined(WIN32)
88/* XXX: put correct support for win32 */
89static int read_password(char *buf, int buf_size)
90{
91 int c, i;
92 printf("Password: ");
93 fflush(stdout);
94 i = 0;
95 for(;;) {
96 c = getchar();
97 if (c == '\n')
98 break;
99 if (i < (buf_size - 1))
100 buf[i++] = c;
101 }
102 buf[i] = '\0';
103 return 0;
104}
105
106#else
107
108#include <termios.h>
109
110static struct termios oldtty;
111
112static void term_exit(void)
113{
114 tcsetattr (0, TCSANOW, &oldtty);
115}
116
117static void term_init(void)
118{
119 struct termios tty;
120
121 tcgetattr (0, &tty);
122 oldtty = tty;
123
124 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
125 |INLCR|IGNCR|ICRNL|IXON);
126 tty.c_oflag |= OPOST;
127 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
128 tty.c_cflag &= ~(CSIZE|PARENB);
129 tty.c_cflag |= CS8;
130 tty.c_cc[VMIN] = 1;
131 tty.c_cc[VTIME] = 0;
ths3b46e622007-09-17 08:09:54 +0000132
bellardea2384d2004-08-01 21:59:26 +0000133 tcsetattr (0, TCSANOW, &tty);
134
135 atexit(term_exit);
136}
137
pbrook3f379ab2007-11-11 03:33:13 +0000138static int read_password(char *buf, int buf_size)
bellardea2384d2004-08-01 21:59:26 +0000139{
140 uint8_t ch;
141 int i, ret;
142
143 printf("password: ");
144 fflush(stdout);
145 term_init();
146 i = 0;
147 for(;;) {
148 ret = read(0, &ch, 1);
149 if (ret == -1) {
150 if (errno == EAGAIN || errno == EINTR) {
151 continue;
152 } else {
153 ret = -1;
154 break;
155 }
156 } else if (ret == 0) {
157 ret = -1;
158 break;
159 } else {
160 if (ch == '\r') {
161 ret = 0;
162 break;
163 }
164 if (i < (buf_size - 1))
165 buf[i++] = ch;
166 }
167 }
168 term_exit();
169 buf[i] = '\0';
170 printf("\n");
171 return ret;
172}
173#endif
174
bellard75c23802004-08-27 21:28:58 +0000175static BlockDriverState *bdrv_new_open(const char *filename,
176 const char *fmt)
177{
178 BlockDriverState *bs;
179 BlockDriver *drv;
180 char password[256];
181
182 bs = bdrv_new("");
183 if (!bs)
184 error("Not enough memory");
185 if (fmt) {
186 drv = bdrv_find_format(fmt);
187 if (!drv)
188 error("Unknown file format '%s'", fmt);
189 } else {
190 drv = NULL;
191 }
aurel32137519c2008-11-30 19:12:49 +0000192 if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
bellard75c23802004-08-27 21:28:58 +0000193 error("Could not open '%s'", filename);
194 }
195 if (bdrv_is_encrypted(bs)) {
196 printf("Disk image '%s' is encrypted.\n", filename);
197 if (read_password(password, sizeof(password)) < 0)
198 error("No password given");
199 if (bdrv_set_key(bs, password) < 0)
200 error("invalid password");
201 }
202 return bs;
203}
204
bellardea2384d2004-08-01 21:59:26 +0000205static int img_create(int argc, char **argv)
206{
thsec36ba12007-09-16 21:59:02 +0000207 int c, ret, flags;
bellardea2384d2004-08-01 21:59:26 +0000208 const char *fmt = "raw";
209 const char *filename;
210 const char *base_filename = NULL;
ths96b8f132007-12-17 01:35:20 +0000211 uint64_t size;
bellardea2384d2004-08-01 21:59:26 +0000212 const char *p;
213 BlockDriver *drv;
ths3b46e622007-09-17 08:09:54 +0000214
thsec36ba12007-09-16 21:59:02 +0000215 flags = 0;
bellardea2384d2004-08-01 21:59:26 +0000216 for(;;) {
thsec36ba12007-09-16 21:59:02 +0000217 c = getopt(argc, argv, "b:f:he6");
bellardea2384d2004-08-01 21:59:26 +0000218 if (c == -1)
219 break;
220 switch(c) {
221 case 'h':
222 help();
223 break;
224 case 'b':
225 base_filename = optarg;
226 break;
227 case 'f':
228 fmt = optarg;
229 break;
230 case 'e':
thsec36ba12007-09-16 21:59:02 +0000231 flags |= BLOCK_FLAG_ENCRYPT;
bellardea2384d2004-08-01 21:59:26 +0000232 break;
thsd8871c52007-10-24 16:11:42 +0000233 case '6':
thsec36ba12007-09-16 21:59:02 +0000234 flags |= BLOCK_FLAG_COMPAT6;
thsd8871c52007-10-24 16:11:42 +0000235 break;
bellardea2384d2004-08-01 21:59:26 +0000236 }
237 }
ths5fafdf22007-09-16 21:08:06 +0000238 if (optind >= argc)
bellardea2384d2004-08-01 21:59:26 +0000239 help();
240 filename = argv[optind++];
241 size = 0;
bellard75c23802004-08-27 21:28:58 +0000242 if (base_filename) {
aliguorie94f3a62008-08-01 15:04:00 +0000243 BlockDriverState *bs;
bellard75c23802004-08-27 21:28:58 +0000244 bs = bdrv_new_open(base_filename, NULL);
245 bdrv_get_geometry(bs, &size);
246 size *= 512;
247 bdrv_delete(bs);
248 } else {
bellardea2384d2004-08-01 21:59:26 +0000249 if (optind >= argc)
250 help();
251 p = argv[optind];
252 size = strtoul(p, (char **)&p, 0);
253 if (*p == 'M') {
254 size *= 1024 * 1024;
255 } else if (*p == 'G') {
256 size *= 1024 * 1024 * 1024;
257 } else if (*p == 'k' || *p == 'K' || *p == '\0') {
258 size *= 1024;
259 } else {
260 help();
261 }
262 }
263 drv = bdrv_find_format(fmt);
264 if (!drv)
265 error("Unknown file format '%s'", fmt);
ths0cfec832007-06-23 16:02:43 +0000266 printf("Formatting '%s', fmt=%s",
bellardea2384d2004-08-01 21:59:26 +0000267 filename, fmt);
thsec36ba12007-09-16 21:59:02 +0000268 if (flags & BLOCK_FLAG_ENCRYPT)
bellardea2384d2004-08-01 21:59:26 +0000269 printf(", encrypted");
thsec36ba12007-09-16 21:59:02 +0000270 if (flags & BLOCK_FLAG_COMPAT6)
271 printf(", compatibility level=6");
bellard75c23802004-08-27 21:28:58 +0000272 if (base_filename) {
273 printf(", backing_file=%s",
bellardea2384d2004-08-01 21:59:26 +0000274 base_filename);
bellard75c23802004-08-27 21:28:58 +0000275 }
ths96b8f132007-12-17 01:35:20 +0000276 printf(", size=%" PRIu64 " kB\n", size / 1024);
thsec36ba12007-09-16 21:59:02 +0000277 ret = bdrv_create(drv, filename, size / 512, base_filename, flags);
bellardea2384d2004-08-01 21:59:26 +0000278 if (ret < 0) {
279 if (ret == -ENOTSUP) {
bellard3c565212004-09-29 21:29:14 +0000280 error("Formatting or formatting option not supported for file format '%s'", fmt);
bellardea2384d2004-08-01 21:59:26 +0000281 } else {
282 error("Error while formatting");
283 }
284 }
285 return 0;
286}
287
288static int img_commit(int argc, char **argv)
289{
290 int c, ret;
291 const char *filename, *fmt;
292 BlockDriver *drv;
293 BlockDriverState *bs;
294
295 fmt = NULL;
296 for(;;) {
297 c = getopt(argc, argv, "f:h");
298 if (c == -1)
299 break;
300 switch(c) {
301 case 'h':
302 help();
303 break;
304 case 'f':
305 fmt = optarg;
306 break;
307 }
308 }
ths5fafdf22007-09-16 21:08:06 +0000309 if (optind >= argc)
bellardea2384d2004-08-01 21:59:26 +0000310 help();
311 filename = argv[optind++];
312
313 bs = bdrv_new("");
314 if (!bs)
315 error("Not enough memory");
316 if (fmt) {
317 drv = bdrv_find_format(fmt);
318 if (!drv)
319 error("Unknown file format '%s'", fmt);
320 } else {
321 drv = NULL;
322 }
aurel32137519c2008-11-30 19:12:49 +0000323 if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
bellardea2384d2004-08-01 21:59:26 +0000324 error("Could not open '%s'", filename);
325 }
326 ret = bdrv_commit(bs);
327 switch(ret) {
328 case 0:
329 printf("Image committed.\n");
330 break;
331 case -ENOENT:
332 error("No disk inserted");
333 break;
334 case -EACCES:
335 error("Image is read-only");
336 break;
337 case -ENOTSUP:
338 error("Image is already committed");
339 break;
340 default:
341 error("Error while committing image");
342 break;
343 }
344
345 bdrv_delete(bs);
346 return 0;
347}
348
349static int is_not_zero(const uint8_t *sector, int len)
350{
351 int i;
352 len >>= 2;
353 for(i = 0;i < len; i++) {
354 if (((uint32_t *)sector)[i] != 0)
355 return 1;
356 }
357 return 0;
358}
359
thsf58c7b32008-06-05 21:53:49 +0000360/*
361 * Returns true iff the first sector pointed to by 'buf' contains at least
362 * a non-NUL byte.
363 *
364 * 'pnum' is set to the number of sectors (including and immediately following
365 * the first one) that are known to be in the same allocated/unallocated state.
366 */
bellardea2384d2004-08-01 21:59:26 +0000367static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
368{
369 int v, i;
370
371 if (n <= 0) {
372 *pnum = 0;
373 return 0;
374 }
375 v = is_not_zero(buf, 512);
376 for(i = 1; i < n; i++) {
377 buf += 512;
378 if (v != is_not_zero(buf, 512))
379 break;
380 }
381 *pnum = i;
382 return v;
383}
384
bellardea2384d2004-08-01 21:59:26 +0000385#define IO_BUF_SIZE 65536
386
387static int img_convert(int argc, char **argv)
388{
balrog926c2d22007-10-31 01:11:44 +0000389 int c, ret, n, n1, bs_n, bs_i, flags, cluster_size, cluster_sectors;
thsf58c7b32008-06-05 21:53:49 +0000390 const char *fmt, *out_fmt, *out_baseimg, *out_filename;
bellardea2384d2004-08-01 21:59:26 +0000391 BlockDriver *drv;
balrog926c2d22007-10-31 01:11:44 +0000392 BlockDriverState **bs, *out_bs;
ths96b8f132007-12-17 01:35:20 +0000393 int64_t total_sectors, nb_sectors, sector_num, bs_offset;
394 uint64_t bs_sectors;
bellardea2384d2004-08-01 21:59:26 +0000395 uint8_t buf[IO_BUF_SIZE];
396 const uint8_t *buf1;
bellardfaea38e2006-08-05 21:31:00 +0000397 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +0000398
399 fmt = NULL;
400 out_fmt = "raw";
thsf58c7b32008-06-05 21:53:49 +0000401 out_baseimg = NULL;
thsec36ba12007-09-16 21:59:02 +0000402 flags = 0;
bellardea2384d2004-08-01 21:59:26 +0000403 for(;;) {
thsf58c7b32008-06-05 21:53:49 +0000404 c = getopt(argc, argv, "f:O:B:hce6");
bellardea2384d2004-08-01 21:59:26 +0000405 if (c == -1)
406 break;
407 switch(c) {
408 case 'h':
409 help();
410 break;
411 case 'f':
412 fmt = optarg;
413 break;
414 case 'O':
415 out_fmt = optarg;
416 break;
thsf58c7b32008-06-05 21:53:49 +0000417 case 'B':
418 out_baseimg = optarg;
419 break;
bellardea2384d2004-08-01 21:59:26 +0000420 case 'c':
thsec36ba12007-09-16 21:59:02 +0000421 flags |= BLOCK_FLAG_COMPRESS;
bellardea2384d2004-08-01 21:59:26 +0000422 break;
423 case 'e':
thsec36ba12007-09-16 21:59:02 +0000424 flags |= BLOCK_FLAG_ENCRYPT;
425 break;
426 case '6':
427 flags |= BLOCK_FLAG_COMPAT6;
bellardea2384d2004-08-01 21:59:26 +0000428 break;
429 }
430 }
ths3b46e622007-09-17 08:09:54 +0000431
balrog926c2d22007-10-31 01:11:44 +0000432 bs_n = argc - optind - 1;
433 if (bs_n < 1) help();
434
435 out_filename = argv[argc - 1];
thsf58c7b32008-06-05 21:53:49 +0000436
437 if (bs_n > 1 && out_baseimg)
438 error("-B makes no sense when concatenating multiple input images");
balrog926c2d22007-10-31 01:11:44 +0000439
440 bs = calloc(bs_n, sizeof(BlockDriverState *));
441 if (!bs)
442 error("Out of memory");
443
444 total_sectors = 0;
445 for (bs_i = 0; bs_i < bs_n; bs_i++) {
446 bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt);
447 if (!bs[bs_i])
448 error("Could not open '%s'", argv[optind + bs_i]);
449 bdrv_get_geometry(bs[bs_i], &bs_sectors);
450 total_sectors += bs_sectors;
451 }
bellardea2384d2004-08-01 21:59:26 +0000452
453 drv = bdrv_find_format(out_fmt);
454 if (!drv)
thsd34dda52007-02-10 22:59:40 +0000455 error("Unknown file format '%s'", out_fmt);
thsec36ba12007-09-16 21:59:02 +0000456 if (flags & BLOCK_FLAG_COMPRESS && drv != &bdrv_qcow && drv != &bdrv_qcow2)
bellardea2384d2004-08-01 21:59:26 +0000457 error("Compression not supported for this file format");
thsec36ba12007-09-16 21:59:02 +0000458 if (flags & BLOCK_FLAG_ENCRYPT && drv != &bdrv_qcow && drv != &bdrv_qcow2)
bellardea2384d2004-08-01 21:59:26 +0000459 error("Encryption not supported for this file format");
thsd8871c52007-10-24 16:11:42 +0000460 if (flags & BLOCK_FLAG_COMPAT6 && drv != &bdrv_vmdk)
thsec36ba12007-09-16 21:59:02 +0000461 error("Alternative compatibility level not supported for this file format");
462 if (flags & BLOCK_FLAG_ENCRYPT && flags & BLOCK_FLAG_COMPRESS)
bellardea2384d2004-08-01 21:59:26 +0000463 error("Compression and encryption not supported at the same time");
balrog926c2d22007-10-31 01:11:44 +0000464
thsf58c7b32008-06-05 21:53:49 +0000465 ret = bdrv_create(drv, out_filename, total_sectors, out_baseimg, flags);
bellardea2384d2004-08-01 21:59:26 +0000466 if (ret < 0) {
467 if (ret == -ENOTSUP) {
bellard3c565212004-09-29 21:29:14 +0000468 error("Formatting not supported for file format '%s'", fmt);
bellardea2384d2004-08-01 21:59:26 +0000469 } else {
470 error("Error while formatting '%s'", out_filename);
471 }
472 }
ths3b46e622007-09-17 08:09:54 +0000473
bellardea2384d2004-08-01 21:59:26 +0000474 out_bs = bdrv_new_open(out_filename, out_fmt);
475
balrog926c2d22007-10-31 01:11:44 +0000476 bs_i = 0;
477 bs_offset = 0;
478 bdrv_get_geometry(bs[0], &bs_sectors);
479
480 if (flags & BLOCK_FLAG_COMPRESS) {
bellardfaea38e2006-08-05 21:31:00 +0000481 if (bdrv_get_info(out_bs, &bdi) < 0)
482 error("could not get block driver info");
483 cluster_size = bdi.cluster_size;
bellardea2384d2004-08-01 21:59:26 +0000484 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE)
485 error("invalid cluster size");
486 cluster_sectors = cluster_size >> 9;
487 sector_num = 0;
488 for(;;) {
balrog926c2d22007-10-31 01:11:44 +0000489 int64_t bs_num;
490 int remainder;
491 uint8_t *buf2;
492
bellardea2384d2004-08-01 21:59:26 +0000493 nb_sectors = total_sectors - sector_num;
494 if (nb_sectors <= 0)
495 break;
496 if (nb_sectors >= cluster_sectors)
497 n = cluster_sectors;
498 else
499 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000500
501 bs_num = sector_num - bs_offset;
502 assert (bs_num >= 0);
503 remainder = n;
504 buf2 = buf;
505 while (remainder > 0) {
506 int nlow;
507 while (bs_num == bs_sectors) {
508 bs_i++;
509 assert (bs_i < bs_n);
510 bs_offset += bs_sectors;
511 bdrv_get_geometry(bs[bs_i], &bs_sectors);
512 bs_num = 0;
513 /* printf("changing part: sector_num=%lld, "
514 "bs_i=%d, bs_offset=%lld, bs_sectors=%lld\n",
515 sector_num, bs_i, bs_offset, bs_sectors); */
516 }
517 assert (bs_num < bs_sectors);
518
519 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
520
521 if (bdrv_read(bs[bs_i], bs_num, buf2, nlow) < 0)
522 error("error while reading");
523
524 buf2 += nlow * 512;
525 bs_num += nlow;
526
527 remainder -= nlow;
528 }
529 assert (remainder == 0);
530
bellardea2384d2004-08-01 21:59:26 +0000531 if (n < cluster_sectors)
532 memset(buf + n * 512, 0, cluster_size - n * 512);
533 if (is_not_zero(buf, cluster_size)) {
ths5fafdf22007-09-16 21:08:06 +0000534 if (bdrv_write_compressed(out_bs, sector_num, buf,
bellardfaea38e2006-08-05 21:31:00 +0000535 cluster_sectors) != 0)
bellardec3757d2006-06-14 15:50:07 +0000536 error("error while compressing sector %" PRId64,
537 sector_num);
bellardea2384d2004-08-01 21:59:26 +0000538 }
539 sector_num += n;
540 }
bellardfaea38e2006-08-05 21:31:00 +0000541 /* signal EOF to align */
542 bdrv_write_compressed(out_bs, 0, NULL, 0);
bellardea2384d2004-08-01 21:59:26 +0000543 } else {
thsf58c7b32008-06-05 21:53:49 +0000544 sector_num = 0; // total number of sectors converted so far
bellardea2384d2004-08-01 21:59:26 +0000545 for(;;) {
546 nb_sectors = total_sectors - sector_num;
547 if (nb_sectors <= 0)
548 break;
549 if (nb_sectors >= (IO_BUF_SIZE / 512))
550 n = (IO_BUF_SIZE / 512);
551 else
552 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000553
554 while (sector_num - bs_offset >= bs_sectors) {
555 bs_i ++;
556 assert (bs_i < bs_n);
557 bs_offset += bs_sectors;
558 bdrv_get_geometry(bs[bs_i], &bs_sectors);
559 /* printf("changing part: sector_num=%lld, bs_i=%d, "
560 "bs_offset=%lld, bs_sectors=%lld\n",
561 sector_num, bs_i, bs_offset, bs_sectors); */
562 }
563
564 if (n > bs_offset + bs_sectors - sector_num)
565 n = bs_offset + bs_sectors - sector_num;
566
thsf58c7b32008-06-05 21:53:49 +0000567 /* If the output image is being created as a copy on write image,
568 assume that sectors which are unallocated in the input image
569 are present in both the output's and input's base images (no
570 need to copy them). */
571 if (out_baseimg) {
572 if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset, n, &n1)) {
573 sector_num += n1;
574 continue;
575 }
576 /* The next 'n1' sectors are allocated in the input image. Copy
577 only those as they may be followed by unallocated sectors. */
578 n = n1;
579 }
580
balrog926c2d22007-10-31 01:11:44 +0000581 if (bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n) < 0)
bellardea2384d2004-08-01 21:59:26 +0000582 error("error while reading");
583 /* NOTE: at the same time we convert, we do not write zero
584 sectors to have a chance to compress the image. Ideally, we
585 should add a specific call to have the info to go faster */
586 buf1 = buf;
587 while (n > 0) {
thsf58c7b32008-06-05 21:53:49 +0000588 /* If the output image is being created as a copy on write image,
589 copy all sectors even the ones containing only NUL bytes,
590 because they may differ from the sectors in the base image. */
591 if (out_baseimg || is_allocated_sectors(buf1, n, &n1)) {
ths5fafdf22007-09-16 21:08:06 +0000592 if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
bellardea2384d2004-08-01 21:59:26 +0000593 error("error while writing");
594 }
595 sector_num += n1;
596 n -= n1;
597 buf1 += n1 * 512;
598 }
599 }
600 }
601 bdrv_delete(out_bs);
balrog926c2d22007-10-31 01:11:44 +0000602 for (bs_i = 0; bs_i < bs_n; bs_i++)
603 bdrv_delete(bs[bs_i]);
604 free(bs);
bellardea2384d2004-08-01 21:59:26 +0000605 return 0;
606}
607
bellard57d1a2b2004-08-03 21:15:11 +0000608#ifdef _WIN32
609static int64_t get_allocated_file_size(const char *filename)
610{
bellarde8445332006-06-14 15:32:10 +0000611 typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
612 get_compressed_t get_compressed;
bellard57d1a2b2004-08-03 21:15:11 +0000613 struct _stati64 st;
bellarde8445332006-06-14 15:32:10 +0000614
615 /* WinNT support GetCompressedFileSize to determine allocate size */
616 get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
617 if (get_compressed) {
618 DWORD high, low;
619 low = get_compressed(filename, &high);
620 if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
621 return (((int64_t) high) << 32) + low;
622 }
623
ths5fafdf22007-09-16 21:08:06 +0000624 if (_stati64(filename, &st) < 0)
bellard57d1a2b2004-08-03 21:15:11 +0000625 return -1;
626 return st.st_size;
627}
628#else
629static int64_t get_allocated_file_size(const char *filename)
630{
631 struct stat st;
ths5fafdf22007-09-16 21:08:06 +0000632 if (stat(filename, &st) < 0)
bellard57d1a2b2004-08-03 21:15:11 +0000633 return -1;
634 return (int64_t)st.st_blocks * 512;
635}
636#endif
637
bellardfaea38e2006-08-05 21:31:00 +0000638static void dump_snapshots(BlockDriverState *bs)
639{
640 QEMUSnapshotInfo *sn_tab, *sn;
641 int nb_sns, i;
642 char buf[256];
643
644 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
645 if (nb_sns <= 0)
646 return;
647 printf("Snapshot list:\n");
648 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
649 for(i = 0; i < nb_sns; i++) {
650 sn = &sn_tab[i];
651 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
652 }
653 qemu_free(sn_tab);
654}
655
bellardea2384d2004-08-01 21:59:26 +0000656static int img_info(int argc, char **argv)
657{
658 int c;
659 const char *filename, *fmt;
660 BlockDriver *drv;
661 BlockDriverState *bs;
662 char fmt_name[128], size_buf[128], dsize_buf[128];
ths96b8f132007-12-17 01:35:20 +0000663 uint64_t total_sectors;
664 int64_t allocated_size;
bellard93b6b2a2006-08-01 15:51:11 +0000665 char backing_filename[1024];
666 char backing_filename2[1024];
bellardfaea38e2006-08-05 21:31:00 +0000667 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +0000668
669 fmt = NULL;
670 for(;;) {
671 c = getopt(argc, argv, "f:h");
672 if (c == -1)
673 break;
674 switch(c) {
675 case 'h':
676 help();
677 break;
678 case 'f':
679 fmt = optarg;
680 break;
681 }
682 }
ths5fafdf22007-09-16 21:08:06 +0000683 if (optind >= argc)
bellardea2384d2004-08-01 21:59:26 +0000684 help();
685 filename = argv[optind++];
686
687 bs = bdrv_new("");
688 if (!bs)
689 error("Not enough memory");
690 if (fmt) {
691 drv = bdrv_find_format(fmt);
692 if (!drv)
693 error("Unknown file format '%s'", fmt);
694 } else {
695 drv = NULL;
696 }
aurel32137519c2008-11-30 19:12:49 +0000697 if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
bellardea2384d2004-08-01 21:59:26 +0000698 error("Could not open '%s'", filename);
699 }
700 bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
701 bdrv_get_geometry(bs, &total_sectors);
702 get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
bellard57d1a2b2004-08-03 21:15:11 +0000703 allocated_size = get_allocated_file_size(filename);
704 if (allocated_size < 0)
blueswir1a10ea302008-08-24 10:30:33 +0000705 snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
bellardde167e42005-04-28 21:15:08 +0000706 else
ths5fafdf22007-09-16 21:08:06 +0000707 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
bellardde167e42005-04-28 21:15:08 +0000708 allocated_size);
bellardea2384d2004-08-01 21:59:26 +0000709 printf("image: %s\n"
710 "file format: %s\n"
bellardec3757d2006-06-14 15:50:07 +0000711 "virtual size: %s (%" PRId64 " bytes)\n"
bellardea2384d2004-08-01 21:59:26 +0000712 "disk size: %s\n",
ths5fafdf22007-09-16 21:08:06 +0000713 filename, fmt_name, size_buf,
bellardec3757d2006-06-14 15:50:07 +0000714 (total_sectors * 512),
bellardea2384d2004-08-01 21:59:26 +0000715 dsize_buf);
716 if (bdrv_is_encrypted(bs))
717 printf("encrypted: yes\n");
bellardfaea38e2006-08-05 21:31:00 +0000718 if (bdrv_get_info(bs, &bdi) >= 0) {
ths5fafdf22007-09-16 21:08:06 +0000719 if (bdi.cluster_size != 0)
bellardfaea38e2006-08-05 21:31:00 +0000720 printf("cluster_size: %d\n", bdi.cluster_size);
721 }
bellard93b6b2a2006-08-01 15:51:11 +0000722 bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
bellardfaea38e2006-08-05 21:31:00 +0000723 if (backing_filename[0] != '\0') {
bellard93b6b2a2006-08-01 15:51:11 +0000724 path_combine(backing_filename2, sizeof(backing_filename2),
725 filename, backing_filename);
ths5fafdf22007-09-16 21:08:06 +0000726 printf("backing file: %s (actual path: %s)\n",
bellard93b6b2a2006-08-01 15:51:11 +0000727 backing_filename,
728 backing_filename2);
bellardfaea38e2006-08-05 21:31:00 +0000729 }
730 dump_snapshots(bs);
bellardea2384d2004-08-01 21:59:26 +0000731 bdrv_delete(bs);
732 return 0;
733}
734
735int main(int argc, char **argv)
736{
737 const char *cmd;
738
739 bdrv_init();
740 if (argc < 2)
741 help();
742 cmd = argv[1];
bellarde3888182004-10-09 16:44:06 +0000743 optind++;
bellardea2384d2004-08-01 21:59:26 +0000744 if (!strcmp(cmd, "create")) {
745 img_create(argc, argv);
746 } else if (!strcmp(cmd, "commit")) {
747 img_commit(argc, argv);
748 } else if (!strcmp(cmd, "convert")) {
749 img_convert(argc, argv);
750 } else if (!strcmp(cmd, "info")) {
751 img_info(argc, argv);
752 } else {
753 help();
754 }
755 return 0;
756}