blob: f9d8b7d99bbe4c82de192c9f86a02c185b4c7e1b [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
pbrook3f379ab2007-11-11 03:33:13 +000033static void __attribute__((noreturn)) error(const char *fmt, ...)
bellardea2384d2004-08-01 21:59:26 +000034{
35 va_list ap;
36 va_start(ap, fmt);
bellard57d1a2b2004-08-03 21:15:11 +000037 fprintf(stderr, "qemu-img: ");
bellardea2384d2004-08-01 21:59:26 +000038 vfprintf(stderr, fmt, ap);
39 fprintf(stderr, "\n");
40 exit(1);
41 va_end(ap);
42}
43
44static void format_print(void *opaque, const char *name)
45{
46 printf(" %s", name);
47}
48
pbrook3f379ab2007-11-11 03:33:13 +000049static void help(void)
bellardea2384d2004-08-01 21:59:26 +000050{
bellard68d0f702008-01-06 17:21:48 +000051 printf("qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fabrice Bellard\n"
bellard57d1a2b2004-08-03 21:15:11 +000052 "usage: qemu-img command [command options]\n"
bellardea2384d2004-08-01 21:59:26 +000053 "QEMU disk image utility\n"
54 "\n"
55 "Command syntax:\n"
thsec36ba12007-09-16 21:59:02 +000056 " create [-e] [-6] [-b base_image] [-f fmt] filename [size]\n"
bellardea2384d2004-08-01 21:59:26 +000057 " commit [-f fmt] filename\n"
thsf58c7b32008-06-05 21:53:49 +000058 " convert [-c] [-e] [-6] [-f fmt] [-O output_fmt] [-B output_base_image] filename [filename2 [...]] output_filename\n"
bellardea2384d2004-08-01 21:59:26 +000059 " info [-f fmt] filename\n"
60 "\n"
61 "Command parameters:\n"
62 " 'filename' is a disk image filename\n"
63 " 'base_image' is the read-only disk image which is used as base for a copy on\n"
64 " write image; the copy on write image only stores the modified data\n"
thsf58c7b32008-06-05 21:53:49 +000065 " 'output_base_image' forces the output image to be created as a copy on write\n"
66 " image of the specified base image; 'output_base_image' should have the same\n"
67 " content as the input's base image, however the path, image format, etc may\n"
68 " differ\n"
bellardea2384d2004-08-01 21:59:26 +000069 " 'fmt' is the disk image format. It is guessed automatically in most cases\n"
70 " 'size' is the disk image size in kilobytes. Optional suffixes 'M' (megabyte)\n"
71 " and 'G' (gigabyte) are supported\n"
72 " 'output_filename' is the destination disk image filename\n"
73 " 'output_fmt' is the destination format\n"
74 " '-c' indicates that target image must be compressed (qcow format only)\n"
75 " '-e' indicates that the target image must be encrypted (qcow format only)\n"
thsec36ba12007-09-16 21:59:02 +000076 " '-6' indicates that the target image must use compatibility level 6 (vmdk format only)\n"
bellardea2384d2004-08-01 21:59:26 +000077 );
78 printf("\nSupported format:");
79 bdrv_iterate_format(format_print, NULL);
80 printf("\n");
81 exit(1);
82}
83
bellardea2384d2004-08-01 21:59:26 +000084#if defined(WIN32)
85/* XXX: put correct support for win32 */
86static int read_password(char *buf, int buf_size)
87{
88 int c, i;
89 printf("Password: ");
90 fflush(stdout);
91 i = 0;
92 for(;;) {
93 c = getchar();
94 if (c == '\n')
95 break;
96 if (i < (buf_size - 1))
97 buf[i++] = c;
98 }
99 buf[i] = '\0';
100 return 0;
101}
102
103#else
104
105#include <termios.h>
106
107static struct termios oldtty;
108
109static void term_exit(void)
110{
111 tcsetattr (0, TCSANOW, &oldtty);
112}
113
114static void term_init(void)
115{
116 struct termios tty;
117
118 tcgetattr (0, &tty);
119 oldtty = tty;
120
121 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
122 |INLCR|IGNCR|ICRNL|IXON);
123 tty.c_oflag |= OPOST;
124 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
125 tty.c_cflag &= ~(CSIZE|PARENB);
126 tty.c_cflag |= CS8;
127 tty.c_cc[VMIN] = 1;
128 tty.c_cc[VTIME] = 0;
ths3b46e622007-09-17 08:09:54 +0000129
bellardea2384d2004-08-01 21:59:26 +0000130 tcsetattr (0, TCSANOW, &tty);
131
132 atexit(term_exit);
133}
134
pbrook3f379ab2007-11-11 03:33:13 +0000135static int read_password(char *buf, int buf_size)
bellardea2384d2004-08-01 21:59:26 +0000136{
137 uint8_t ch;
138 int i, ret;
139
140 printf("password: ");
141 fflush(stdout);
142 term_init();
143 i = 0;
144 for(;;) {
145 ret = read(0, &ch, 1);
146 if (ret == -1) {
147 if (errno == EAGAIN || errno == EINTR) {
148 continue;
149 } else {
150 ret = -1;
151 break;
152 }
153 } else if (ret == 0) {
154 ret = -1;
155 break;
156 } else {
157 if (ch == '\r') {
158 ret = 0;
159 break;
160 }
161 if (i < (buf_size - 1))
162 buf[i++] = ch;
163 }
164 }
165 term_exit();
166 buf[i] = '\0';
167 printf("\n");
168 return ret;
169}
170#endif
171
bellard75c23802004-08-27 21:28:58 +0000172static BlockDriverState *bdrv_new_open(const char *filename,
173 const char *fmt)
174{
175 BlockDriverState *bs;
176 BlockDriver *drv;
177 char password[256];
178
179 bs = bdrv_new("");
180 if (!bs)
181 error("Not enough memory");
182 if (fmt) {
183 drv = bdrv_find_format(fmt);
184 if (!drv)
185 error("Unknown file format '%s'", fmt);
186 } else {
187 drv = NULL;
188 }
189 if (bdrv_open2(bs, filename, 0, drv) < 0) {
190 error("Could not open '%s'", filename);
191 }
192 if (bdrv_is_encrypted(bs)) {
193 printf("Disk image '%s' is encrypted.\n", filename);
194 if (read_password(password, sizeof(password)) < 0)
195 error("No password given");
196 if (bdrv_set_key(bs, password) < 0)
197 error("invalid password");
198 }
199 return bs;
200}
201
bellardea2384d2004-08-01 21:59:26 +0000202static int img_create(int argc, char **argv)
203{
thsec36ba12007-09-16 21:59:02 +0000204 int c, ret, flags;
bellardea2384d2004-08-01 21:59:26 +0000205 const char *fmt = "raw";
206 const char *filename;
207 const char *base_filename = NULL;
ths96b8f132007-12-17 01:35:20 +0000208 uint64_t size;
bellardea2384d2004-08-01 21:59:26 +0000209 const char *p;
210 BlockDriver *drv;
ths3b46e622007-09-17 08:09:54 +0000211
thsec36ba12007-09-16 21:59:02 +0000212 flags = 0;
bellardea2384d2004-08-01 21:59:26 +0000213 for(;;) {
thsec36ba12007-09-16 21:59:02 +0000214 c = getopt(argc, argv, "b:f:he6");
bellardea2384d2004-08-01 21:59:26 +0000215 if (c == -1)
216 break;
217 switch(c) {
218 case 'h':
219 help();
220 break;
221 case 'b':
222 base_filename = optarg;
223 break;
224 case 'f':
225 fmt = optarg;
226 break;
227 case 'e':
thsec36ba12007-09-16 21:59:02 +0000228 flags |= BLOCK_FLAG_ENCRYPT;
bellardea2384d2004-08-01 21:59:26 +0000229 break;
thsd8871c52007-10-24 16:11:42 +0000230 case '6':
thsec36ba12007-09-16 21:59:02 +0000231 flags |= BLOCK_FLAG_COMPAT6;
thsd8871c52007-10-24 16:11:42 +0000232 break;
bellardea2384d2004-08-01 21:59:26 +0000233 }
234 }
ths5fafdf22007-09-16 21:08:06 +0000235 if (optind >= argc)
bellardea2384d2004-08-01 21:59:26 +0000236 help();
237 filename = argv[optind++];
238 size = 0;
bellard75c23802004-08-27 21:28:58 +0000239 if (base_filename) {
240 BlockDriverState *bs;
241 bs = bdrv_new_open(base_filename, NULL);
242 bdrv_get_geometry(bs, &size);
243 size *= 512;
244 bdrv_delete(bs);
245 } else {
bellardea2384d2004-08-01 21:59:26 +0000246 if (optind >= argc)
247 help();
248 p = argv[optind];
249 size = strtoul(p, (char **)&p, 0);
250 if (*p == 'M') {
251 size *= 1024 * 1024;
252 } else if (*p == 'G') {
253 size *= 1024 * 1024 * 1024;
254 } else if (*p == 'k' || *p == 'K' || *p == '\0') {
255 size *= 1024;
256 } else {
257 help();
258 }
259 }
260 drv = bdrv_find_format(fmt);
261 if (!drv)
262 error("Unknown file format '%s'", fmt);
ths0cfec834c2007-06-23 16:02:43 +0000263 printf("Formatting '%s', fmt=%s",
bellardea2384d2004-08-01 21:59:26 +0000264 filename, fmt);
thsec36ba12007-09-16 21:59:02 +0000265 if (flags & BLOCK_FLAG_ENCRYPT)
bellardea2384d2004-08-01 21:59:26 +0000266 printf(", encrypted");
thsec36ba12007-09-16 21:59:02 +0000267 if (flags & BLOCK_FLAG_COMPAT6)
268 printf(", compatibility level=6");
bellard75c23802004-08-27 21:28:58 +0000269 if (base_filename) {
270 printf(", backing_file=%s",
bellardea2384d2004-08-01 21:59:26 +0000271 base_filename);
bellard75c23802004-08-27 21:28:58 +0000272 }
ths96b8f132007-12-17 01:35:20 +0000273 printf(", size=%" PRIu64 " kB\n", size / 1024);
thsec36ba12007-09-16 21:59:02 +0000274 ret = bdrv_create(drv, filename, size / 512, base_filename, flags);
bellardea2384d2004-08-01 21:59:26 +0000275 if (ret < 0) {
276 if (ret == -ENOTSUP) {
bellard3c565212004-09-29 21:29:14 +0000277 error("Formatting or formatting option not supported for file format '%s'", fmt);
bellardea2384d2004-08-01 21:59:26 +0000278 } else {
279 error("Error while formatting");
280 }
281 }
282 return 0;
283}
284
285static int img_commit(int argc, char **argv)
286{
287 int c, ret;
288 const char *filename, *fmt;
289 BlockDriver *drv;
290 BlockDriverState *bs;
291
292 fmt = NULL;
293 for(;;) {
294 c = getopt(argc, argv, "f:h");
295 if (c == -1)
296 break;
297 switch(c) {
298 case 'h':
299 help();
300 break;
301 case 'f':
302 fmt = optarg;
303 break;
304 }
305 }
ths5fafdf22007-09-16 21:08:06 +0000306 if (optind >= argc)
bellardea2384d2004-08-01 21:59:26 +0000307 help();
308 filename = argv[optind++];
309
310 bs = bdrv_new("");
311 if (!bs)
312 error("Not enough memory");
313 if (fmt) {
314 drv = bdrv_find_format(fmt);
315 if (!drv)
316 error("Unknown file format '%s'", fmt);
317 } else {
318 drv = NULL;
319 }
320 if (bdrv_open2(bs, filename, 0, drv) < 0) {
321 error("Could not open '%s'", filename);
322 }
323 ret = bdrv_commit(bs);
324 switch(ret) {
325 case 0:
326 printf("Image committed.\n");
327 break;
328 case -ENOENT:
329 error("No disk inserted");
330 break;
331 case -EACCES:
332 error("Image is read-only");
333 break;
334 case -ENOTSUP:
335 error("Image is already committed");
336 break;
337 default:
338 error("Error while committing image");
339 break;
340 }
341
342 bdrv_delete(bs);
343 return 0;
344}
345
346static int is_not_zero(const uint8_t *sector, int len)
347{
348 int i;
349 len >>= 2;
350 for(i = 0;i < len; i++) {
351 if (((uint32_t *)sector)[i] != 0)
352 return 1;
353 }
354 return 0;
355}
356
thsf58c7b32008-06-05 21:53:49 +0000357/*
358 * Returns true iff the first sector pointed to by 'buf' contains at least
359 * a non-NUL byte.
360 *
361 * 'pnum' is set to the number of sectors (including and immediately following
362 * the first one) that are known to be in the same allocated/unallocated state.
363 */
bellardea2384d2004-08-01 21:59:26 +0000364static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
365{
366 int v, i;
367
368 if (n <= 0) {
369 *pnum = 0;
370 return 0;
371 }
372 v = is_not_zero(buf, 512);
373 for(i = 1; i < n; i++) {
374 buf += 512;
375 if (v != is_not_zero(buf, 512))
376 break;
377 }
378 *pnum = i;
379 return v;
380}
381
bellardea2384d2004-08-01 21:59:26 +0000382#define IO_BUF_SIZE 65536
383
384static int img_convert(int argc, char **argv)
385{
balrog926c2d22007-10-31 01:11:44 +0000386 int c, ret, n, n1, bs_n, bs_i, flags, cluster_size, cluster_sectors;
thsf58c7b32008-06-05 21:53:49 +0000387 const char *fmt, *out_fmt, *out_baseimg, *out_filename;
bellardea2384d2004-08-01 21:59:26 +0000388 BlockDriver *drv;
balrog926c2d22007-10-31 01:11:44 +0000389 BlockDriverState **bs, *out_bs;
ths96b8f132007-12-17 01:35:20 +0000390 int64_t total_sectors, nb_sectors, sector_num, bs_offset;
391 uint64_t bs_sectors;
bellardea2384d2004-08-01 21:59:26 +0000392 uint8_t buf[IO_BUF_SIZE];
393 const uint8_t *buf1;
bellardfaea38e2006-08-05 21:31:00 +0000394 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +0000395
396 fmt = NULL;
397 out_fmt = "raw";
thsf58c7b32008-06-05 21:53:49 +0000398 out_baseimg = NULL;
thsec36ba12007-09-16 21:59:02 +0000399 flags = 0;
bellardea2384d2004-08-01 21:59:26 +0000400 for(;;) {
thsf58c7b32008-06-05 21:53:49 +0000401 c = getopt(argc, argv, "f:O:B:hce6");
bellardea2384d2004-08-01 21:59:26 +0000402 if (c == -1)
403 break;
404 switch(c) {
405 case 'h':
406 help();
407 break;
408 case 'f':
409 fmt = optarg;
410 break;
411 case 'O':
412 out_fmt = optarg;
413 break;
thsf58c7b32008-06-05 21:53:49 +0000414 case 'B':
415 out_baseimg = optarg;
416 break;
bellardea2384d2004-08-01 21:59:26 +0000417 case 'c':
thsec36ba12007-09-16 21:59:02 +0000418 flags |= BLOCK_FLAG_COMPRESS;
bellardea2384d2004-08-01 21:59:26 +0000419 break;
420 case 'e':
thsec36ba12007-09-16 21:59:02 +0000421 flags |= BLOCK_FLAG_ENCRYPT;
422 break;
423 case '6':
424 flags |= BLOCK_FLAG_COMPAT6;
bellardea2384d2004-08-01 21:59:26 +0000425 break;
426 }
427 }
ths3b46e622007-09-17 08:09:54 +0000428
balrog926c2d22007-10-31 01:11:44 +0000429 bs_n = argc - optind - 1;
430 if (bs_n < 1) help();
431
432 out_filename = argv[argc - 1];
thsf58c7b32008-06-05 21:53:49 +0000433
434 if (bs_n > 1 && out_baseimg)
435 error("-B makes no sense when concatenating multiple input images");
balrog926c2d22007-10-31 01:11:44 +0000436
437 bs = calloc(bs_n, sizeof(BlockDriverState *));
438 if (!bs)
439 error("Out of memory");
440
441 total_sectors = 0;
442 for (bs_i = 0; bs_i < bs_n; bs_i++) {
443 bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt);
444 if (!bs[bs_i])
445 error("Could not open '%s'", argv[optind + bs_i]);
446 bdrv_get_geometry(bs[bs_i], &bs_sectors);
447 total_sectors += bs_sectors;
448 }
bellardea2384d2004-08-01 21:59:26 +0000449
450 drv = bdrv_find_format(out_fmt);
451 if (!drv)
thsd34dda52007-02-10 22:59:40 +0000452 error("Unknown file format '%s'", out_fmt);
thsec36ba12007-09-16 21:59:02 +0000453 if (flags & BLOCK_FLAG_COMPRESS && drv != &bdrv_qcow && drv != &bdrv_qcow2)
bellardea2384d2004-08-01 21:59:26 +0000454 error("Compression not supported for this file format");
thsec36ba12007-09-16 21:59:02 +0000455 if (flags & BLOCK_FLAG_ENCRYPT && drv != &bdrv_qcow && drv != &bdrv_qcow2)
bellardea2384d2004-08-01 21:59:26 +0000456 error("Encryption not supported for this file format");
thsd8871c52007-10-24 16:11:42 +0000457 if (flags & BLOCK_FLAG_COMPAT6 && drv != &bdrv_vmdk)
thsec36ba12007-09-16 21:59:02 +0000458 error("Alternative compatibility level not supported for this file format");
459 if (flags & BLOCK_FLAG_ENCRYPT && flags & BLOCK_FLAG_COMPRESS)
bellardea2384d2004-08-01 21:59:26 +0000460 error("Compression and encryption not supported at the same time");
balrog926c2d22007-10-31 01:11:44 +0000461
thsf58c7b32008-06-05 21:53:49 +0000462 ret = bdrv_create(drv, out_filename, total_sectors, out_baseimg, flags);
bellardea2384d2004-08-01 21:59:26 +0000463 if (ret < 0) {
464 if (ret == -ENOTSUP) {
bellard3c565212004-09-29 21:29:14 +0000465 error("Formatting not supported for file format '%s'", fmt);
bellardea2384d2004-08-01 21:59:26 +0000466 } else {
467 error("Error while formatting '%s'", out_filename);
468 }
469 }
ths3b46e622007-09-17 08:09:54 +0000470
bellardea2384d2004-08-01 21:59:26 +0000471 out_bs = bdrv_new_open(out_filename, out_fmt);
472
balrog926c2d22007-10-31 01:11:44 +0000473 bs_i = 0;
474 bs_offset = 0;
475 bdrv_get_geometry(bs[0], &bs_sectors);
476
477 if (flags & BLOCK_FLAG_COMPRESS) {
bellardfaea38e2006-08-05 21:31:00 +0000478 if (bdrv_get_info(out_bs, &bdi) < 0)
479 error("could not get block driver info");
480 cluster_size = bdi.cluster_size;
bellardea2384d2004-08-01 21:59:26 +0000481 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE)
482 error("invalid cluster size");
483 cluster_sectors = cluster_size >> 9;
484 sector_num = 0;
485 for(;;) {
balrog926c2d22007-10-31 01:11:44 +0000486 int64_t bs_num;
487 int remainder;
488 uint8_t *buf2;
489
bellardea2384d2004-08-01 21:59:26 +0000490 nb_sectors = total_sectors - sector_num;
491 if (nb_sectors <= 0)
492 break;
493 if (nb_sectors >= cluster_sectors)
494 n = cluster_sectors;
495 else
496 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000497
498 bs_num = sector_num - bs_offset;
499 assert (bs_num >= 0);
500 remainder = n;
501 buf2 = buf;
502 while (remainder > 0) {
503 int nlow;
504 while (bs_num == bs_sectors) {
505 bs_i++;
506 assert (bs_i < bs_n);
507 bs_offset += bs_sectors;
508 bdrv_get_geometry(bs[bs_i], &bs_sectors);
509 bs_num = 0;
510 /* printf("changing part: sector_num=%lld, "
511 "bs_i=%d, bs_offset=%lld, bs_sectors=%lld\n",
512 sector_num, bs_i, bs_offset, bs_sectors); */
513 }
514 assert (bs_num < bs_sectors);
515
516 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
517
518 if (bdrv_read(bs[bs_i], bs_num, buf2, nlow) < 0)
519 error("error while reading");
520
521 buf2 += nlow * 512;
522 bs_num += nlow;
523
524 remainder -= nlow;
525 }
526 assert (remainder == 0);
527
bellardea2384d2004-08-01 21:59:26 +0000528 if (n < cluster_sectors)
529 memset(buf + n * 512, 0, cluster_size - n * 512);
530 if (is_not_zero(buf, cluster_size)) {
ths5fafdf22007-09-16 21:08:06 +0000531 if (bdrv_write_compressed(out_bs, sector_num, buf,
bellardfaea38e2006-08-05 21:31:00 +0000532 cluster_sectors) != 0)
bellardec3757d2006-06-14 15:50:07 +0000533 error("error while compressing sector %" PRId64,
534 sector_num);
bellardea2384d2004-08-01 21:59:26 +0000535 }
536 sector_num += n;
537 }
bellardfaea38e2006-08-05 21:31:00 +0000538 /* signal EOF to align */
539 bdrv_write_compressed(out_bs, 0, NULL, 0);
bellardea2384d2004-08-01 21:59:26 +0000540 } else {
thsf58c7b32008-06-05 21:53:49 +0000541 sector_num = 0; // total number of sectors converted so far
bellardea2384d2004-08-01 21:59:26 +0000542 for(;;) {
543 nb_sectors = total_sectors - sector_num;
544 if (nb_sectors <= 0)
545 break;
546 if (nb_sectors >= (IO_BUF_SIZE / 512))
547 n = (IO_BUF_SIZE / 512);
548 else
549 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000550
551 while (sector_num - bs_offset >= bs_sectors) {
552 bs_i ++;
553 assert (bs_i < bs_n);
554 bs_offset += bs_sectors;
555 bdrv_get_geometry(bs[bs_i], &bs_sectors);
556 /* printf("changing part: sector_num=%lld, bs_i=%d, "
557 "bs_offset=%lld, bs_sectors=%lld\n",
558 sector_num, bs_i, bs_offset, bs_sectors); */
559 }
560
561 if (n > bs_offset + bs_sectors - sector_num)
562 n = bs_offset + bs_sectors - sector_num;
563
thsf58c7b32008-06-05 21:53:49 +0000564 /* If the output image is being created as a copy on write image,
565 assume that sectors which are unallocated in the input image
566 are present in both the output's and input's base images (no
567 need to copy them). */
568 if (out_baseimg) {
569 if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset, n, &n1)) {
570 sector_num += n1;
571 continue;
572 }
573 /* The next 'n1' sectors are allocated in the input image. Copy
574 only those as they may be followed by unallocated sectors. */
575 n = n1;
576 }
577
balrog926c2d22007-10-31 01:11:44 +0000578 if (bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n) < 0)
bellardea2384d2004-08-01 21:59:26 +0000579 error("error while reading");
580 /* NOTE: at the same time we convert, we do not write zero
581 sectors to have a chance to compress the image. Ideally, we
582 should add a specific call to have the info to go faster */
583 buf1 = buf;
584 while (n > 0) {
thsf58c7b32008-06-05 21:53:49 +0000585 /* If the output image is being created as a copy on write image,
586 copy all sectors even the ones containing only NUL bytes,
587 because they may differ from the sectors in the base image. */
588 if (out_baseimg || is_allocated_sectors(buf1, n, &n1)) {
ths5fafdf22007-09-16 21:08:06 +0000589 if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
bellardea2384d2004-08-01 21:59:26 +0000590 error("error while writing");
591 }
592 sector_num += n1;
593 n -= n1;
594 buf1 += n1 * 512;
595 }
596 }
597 }
598 bdrv_delete(out_bs);
balrog926c2d22007-10-31 01:11:44 +0000599 for (bs_i = 0; bs_i < bs_n; bs_i++)
600 bdrv_delete(bs[bs_i]);
601 free(bs);
bellardea2384d2004-08-01 21:59:26 +0000602 return 0;
603}
604
bellard57d1a2b2004-08-03 21:15:11 +0000605#ifdef _WIN32
606static int64_t get_allocated_file_size(const char *filename)
607{
bellarde8445332006-06-14 15:32:10 +0000608 typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
609 get_compressed_t get_compressed;
bellard57d1a2b2004-08-03 21:15:11 +0000610 struct _stati64 st;
bellarde8445332006-06-14 15:32:10 +0000611
612 /* WinNT support GetCompressedFileSize to determine allocate size */
613 get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
614 if (get_compressed) {
615 DWORD high, low;
616 low = get_compressed(filename, &high);
617 if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
618 return (((int64_t) high) << 32) + low;
619 }
620
ths5fafdf22007-09-16 21:08:06 +0000621 if (_stati64(filename, &st) < 0)
bellard57d1a2b2004-08-03 21:15:11 +0000622 return -1;
623 return st.st_size;
624}
625#else
626static int64_t get_allocated_file_size(const char *filename)
627{
628 struct stat st;
ths5fafdf22007-09-16 21:08:06 +0000629 if (stat(filename, &st) < 0)
bellard57d1a2b2004-08-03 21:15:11 +0000630 return -1;
631 return (int64_t)st.st_blocks * 512;
632}
633#endif
634
bellardfaea38e2006-08-05 21:31:00 +0000635static void dump_snapshots(BlockDriverState *bs)
636{
637 QEMUSnapshotInfo *sn_tab, *sn;
638 int nb_sns, i;
639 char buf[256];
640
641 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
642 if (nb_sns <= 0)
643 return;
644 printf("Snapshot list:\n");
645 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
646 for(i = 0; i < nb_sns; i++) {
647 sn = &sn_tab[i];
648 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
649 }
650 qemu_free(sn_tab);
651}
652
bellardea2384d2004-08-01 21:59:26 +0000653static int img_info(int argc, char **argv)
654{
655 int c;
656 const char *filename, *fmt;
657 BlockDriver *drv;
658 BlockDriverState *bs;
659 char fmt_name[128], size_buf[128], dsize_buf[128];
ths96b8f132007-12-17 01:35:20 +0000660 uint64_t total_sectors;
661 int64_t allocated_size;
bellard93b6b2a2006-08-01 15:51:11 +0000662 char backing_filename[1024];
663 char backing_filename2[1024];
bellardfaea38e2006-08-05 21:31:00 +0000664 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +0000665
666 fmt = NULL;
667 for(;;) {
668 c = getopt(argc, argv, "f:h");
669 if (c == -1)
670 break;
671 switch(c) {
672 case 'h':
673 help();
674 break;
675 case 'f':
676 fmt = optarg;
677 break;
678 }
679 }
ths5fafdf22007-09-16 21:08:06 +0000680 if (optind >= argc)
bellardea2384d2004-08-01 21:59:26 +0000681 help();
682 filename = argv[optind++];
683
684 bs = bdrv_new("");
685 if (!bs)
686 error("Not enough memory");
687 if (fmt) {
688 drv = bdrv_find_format(fmt);
689 if (!drv)
690 error("Unknown file format '%s'", fmt);
691 } else {
692 drv = NULL;
693 }
694 if (bdrv_open2(bs, filename, 0, drv) < 0) {
695 error("Could not open '%s'", filename);
696 }
697 bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
698 bdrv_get_geometry(bs, &total_sectors);
699 get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
bellard57d1a2b2004-08-03 21:15:11 +0000700 allocated_size = get_allocated_file_size(filename);
701 if (allocated_size < 0)
bellardde167e42005-04-28 21:15:08 +0000702 sprintf(dsize_buf, "unavailable");
703 else
ths5fafdf22007-09-16 21:08:06 +0000704 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
bellardde167e42005-04-28 21:15:08 +0000705 allocated_size);
bellardea2384d2004-08-01 21:59:26 +0000706 printf("image: %s\n"
707 "file format: %s\n"
bellardec3757d2006-06-14 15:50:07 +0000708 "virtual size: %s (%" PRId64 " bytes)\n"
bellardea2384d2004-08-01 21:59:26 +0000709 "disk size: %s\n",
ths5fafdf22007-09-16 21:08:06 +0000710 filename, fmt_name, size_buf,
bellardec3757d2006-06-14 15:50:07 +0000711 (total_sectors * 512),
bellardea2384d2004-08-01 21:59:26 +0000712 dsize_buf);
713 if (bdrv_is_encrypted(bs))
714 printf("encrypted: yes\n");
bellardfaea38e2006-08-05 21:31:00 +0000715 if (bdrv_get_info(bs, &bdi) >= 0) {
ths5fafdf22007-09-16 21:08:06 +0000716 if (bdi.cluster_size != 0)
bellardfaea38e2006-08-05 21:31:00 +0000717 printf("cluster_size: %d\n", bdi.cluster_size);
718 }
bellard93b6b2a2006-08-01 15:51:11 +0000719 bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
bellardfaea38e2006-08-05 21:31:00 +0000720 if (backing_filename[0] != '\0') {
bellard93b6b2a2006-08-01 15:51:11 +0000721 path_combine(backing_filename2, sizeof(backing_filename2),
722 filename, backing_filename);
ths5fafdf22007-09-16 21:08:06 +0000723 printf("backing file: %s (actual path: %s)\n",
bellard93b6b2a2006-08-01 15:51:11 +0000724 backing_filename,
725 backing_filename2);
bellardfaea38e2006-08-05 21:31:00 +0000726 }
727 dump_snapshots(bs);
bellardea2384d2004-08-01 21:59:26 +0000728 bdrv_delete(bs);
729 return 0;
730}
731
732int main(int argc, char **argv)
733{
734 const char *cmd;
735
736 bdrv_init();
737 if (argc < 2)
738 help();
739 cmd = argv[1];
bellarde3888182004-10-09 16:44:06 +0000740 optind++;
bellardea2384d2004-08-01 21:59:26 +0000741 if (!strcmp(cmd, "create")) {
742 img_create(argc, argv);
743 } else if (!strcmp(cmd, "commit")) {
744 img_commit(argc, argv);
745 } else if (!strcmp(cmd, "convert")) {
746 img_convert(argc, argv);
747 } else if (!strcmp(cmd, "info")) {
748 img_info(argc, argv);
749 } else {
750 help();
751 }
752 return 0;
753}