]> git.proxmox.com Git - mirror_qemu.git/blame - qemu-img.c
64 bit file I/O by default
[mirror_qemu.git] / qemu-img.c
CommitLineData
ea2384d3
FB
1/*
2 * create a COW disk image
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * 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 */
24#include "vl.h"
25
26void *get_mmap_addr(unsigned long size)
27{
28 return NULL;
29}
30
31void qemu_free(void *ptr)
32{
33 free(ptr);
34}
35
36void *qemu_malloc(size_t size)
37{
38 return malloc(size);
39}
40
41void *qemu_mallocz(size_t size)
42{
43 void *ptr;
44 ptr = qemu_malloc(size);
45 if (!ptr)
46 return NULL;
47 memset(ptr, 0, size);
48 return ptr;
49}
50
51char *qemu_strdup(const char *str)
52{
53 char *ptr;
54 ptr = qemu_malloc(strlen(str) + 1);
55 if (!ptr)
56 return NULL;
57 strcpy(ptr, str);
58 return ptr;
59}
60
61void pstrcpy(char *buf, int buf_size, const char *str)
62{
63 int c;
64 char *q = buf;
65
66 if (buf_size <= 0)
67 return;
68
69 for(;;) {
70 c = *str++;
71 if (c == 0 || q >= buf + buf_size - 1)
72 break;
73 *q++ = c;
74 }
75 *q = '\0';
76}
77
78/* strcat and truncate. */
79char *pstrcat(char *buf, int buf_size, const char *s)
80{
81 int len;
82 len = strlen(buf);
83 if (len < buf_size)
84 pstrcpy(buf + len, buf_size - len, s);
85 return buf;
86}
87
88int strstart(const char *str, const char *val, const char **ptr)
89{
90 const char *p, *q;
91 p = str;
92 q = val;
93 while (*q != '\0') {
94 if (*p != *q)
95 return 0;
96 p++;
97 q++;
98 }
99 if (ptr)
100 *ptr = p;
101 return 1;
102}
103
104void term_printf(const char *fmt, ...)
105{
106 va_list ap;
107 va_start(ap, fmt);
108 vprintf(fmt, ap);
109 va_end(ap);
110}
111
112void __attribute__((noreturn)) error(const char *fmt, ...)
113{
114 va_list ap;
115 va_start(ap, fmt);
116 fprintf(stderr, "qemuimg: ");
117 vfprintf(stderr, fmt, ap);
118 fprintf(stderr, "\n");
119 exit(1);
120 va_end(ap);
121}
122
123static void format_print(void *opaque, const char *name)
124{
125 printf(" %s", name);
126}
127
128void help(void)
129{
130 printf("qemuimg version " QEMU_VERSION ", Copyright (c) 2004 Fabrice Bellard\n"
131 "usage: qemuimg command [command options]\n"
132 "QEMU disk image utility\n"
133 "\n"
134 "Command syntax:\n"
135 " create [-e] [-b base_image] [-f fmt] filename [size]\n"
136 " commit [-f fmt] filename\n"
137 " convert [-c] [-e] [-f fmt] filename [-O output_fmt] output_filename\n"
138 " info [-f fmt] filename\n"
139 "\n"
140 "Command parameters:\n"
141 " 'filename' is a disk image filename\n"
142 " 'base_image' is the read-only disk image which is used as base for a copy on\n"
143 " write image; the copy on write image only stores the modified data\n"
144 " 'fmt' is the disk image format. It is guessed automatically in most cases\n"
145 " 'size' is the disk image size in kilobytes. Optional suffixes 'M' (megabyte)\n"
146 " and 'G' (gigabyte) are supported\n"
147 " 'output_filename' is the destination disk image filename\n"
148 " 'output_fmt' is the destination format\n"
149 " '-c' indicates that target image must be compressed (qcow format only)\n"
150 " '-e' indicates that the target image must be encrypted (qcow format only)\n"
151 );
152 printf("\nSupported format:");
153 bdrv_iterate_format(format_print, NULL);
154 printf("\n");
155 exit(1);
156}
157
158
159#define NB_SUFFIXES 4
160
161static void get_human_readable_size(char *buf, int buf_size, int64_t size)
162{
163 char suffixes[NB_SUFFIXES] = "KMGT";
164 int64_t base;
165 int i;
166
167 if (size <= 999) {
168 snprintf(buf, buf_size, "%lld", size);
169 } else {
170 base = 1024;
171 for(i = 0; i < NB_SUFFIXES; i++) {
172 if (size < (10 * base)) {
173 snprintf(buf, buf_size, "%0.1f%c",
174 (double)size / base,
175 suffixes[i]);
176 break;
177 } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
178 snprintf(buf, buf_size, "%lld%c",
179 (size + (base >> 1)) / base,
180 suffixes[i]);
181 break;
182 }
183 base = base * 1024;
184 }
185 }
186}
187
188#if defined(WIN32)
189/* XXX: put correct support for win32 */
190static int read_password(char *buf, int buf_size)
191{
192 int c, i;
193 printf("Password: ");
194 fflush(stdout);
195 i = 0;
196 for(;;) {
197 c = getchar();
198 if (c == '\n')
199 break;
200 if (i < (buf_size - 1))
201 buf[i++] = c;
202 }
203 buf[i] = '\0';
204 return 0;
205}
206
207#else
208
209#include <termios.h>
210
211static struct termios oldtty;
212
213static void term_exit(void)
214{
215 tcsetattr (0, TCSANOW, &oldtty);
216}
217
218static void term_init(void)
219{
220 struct termios tty;
221
222 tcgetattr (0, &tty);
223 oldtty = tty;
224
225 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
226 |INLCR|IGNCR|ICRNL|IXON);
227 tty.c_oflag |= OPOST;
228 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
229 tty.c_cflag &= ~(CSIZE|PARENB);
230 tty.c_cflag |= CS8;
231 tty.c_cc[VMIN] = 1;
232 tty.c_cc[VTIME] = 0;
233
234 tcsetattr (0, TCSANOW, &tty);
235
236 atexit(term_exit);
237}
238
239int read_password(char *buf, int buf_size)
240{
241 uint8_t ch;
242 int i, ret;
243
244 printf("password: ");
245 fflush(stdout);
246 term_init();
247 i = 0;
248 for(;;) {
249 ret = read(0, &ch, 1);
250 if (ret == -1) {
251 if (errno == EAGAIN || errno == EINTR) {
252 continue;
253 } else {
254 ret = -1;
255 break;
256 }
257 } else if (ret == 0) {
258 ret = -1;
259 break;
260 } else {
261 if (ch == '\r') {
262 ret = 0;
263 break;
264 }
265 if (i < (buf_size - 1))
266 buf[i++] = ch;
267 }
268 }
269 term_exit();
270 buf[i] = '\0';
271 printf("\n");
272 return ret;
273}
274#endif
275
276static int img_create(int argc, char **argv)
277{
278 int c, ret, encrypted;
279 const char *fmt = "raw";
280 const char *filename;
281 const char *base_filename = NULL;
282 int64_t size;
283 const char *p;
284 BlockDriver *drv;
285
286 encrypted = 0;
287 for(;;) {
288 c = getopt(argc, argv, "b:f:he");
289 if (c == -1)
290 break;
291 switch(c) {
292 case 'h':
293 help();
294 break;
295 case 'b':
296 base_filename = optarg;
297 break;
298 case 'f':
299 fmt = optarg;
300 break;
301 case 'e':
302 encrypted = 1;
303 break;
304 }
305 }
306 optind++;
307 if (optind >= argc)
308 help();
309 filename = argv[optind++];
310 size = 0;
311 if (!base_filename) {
312 if (optind >= argc)
313 help();
314 p = argv[optind];
315 size = strtoul(p, (char **)&p, 0);
316 if (*p == 'M') {
317 size *= 1024 * 1024;
318 } else if (*p == 'G') {
319 size *= 1024 * 1024 * 1024;
320 } else if (*p == 'k' || *p == 'K' || *p == '\0') {
321 size *= 1024;
322 } else {
323 help();
324 }
325 }
326 drv = bdrv_find_format(fmt);
327 if (!drv)
328 error("Unknown file format '%s'", fmt);
329 printf("Formating '%s', fmt=%s",
330 filename, fmt);
331 if (encrypted)
332 printf(", encrypted");
333 if (base_filename)
334 printf(", backing_file=%s\n",
335 base_filename);
336 else
337 printf(", size=%lld kB\n", size / 1024);
338 ret = bdrv_create(drv, filename, size / 512, base_filename, encrypted);
339 if (ret < 0) {
340 if (ret == -ENOTSUP) {
341 error("Formatting or formatting option not suppored for file format '%s'", fmt);
342 } else {
343 error("Error while formatting");
344 }
345 }
346 return 0;
347}
348
349static int img_commit(int argc, char **argv)
350{
351 int c, ret;
352 const char *filename, *fmt;
353 BlockDriver *drv;
354 BlockDriverState *bs;
355
356 fmt = NULL;
357 for(;;) {
358 c = getopt(argc, argv, "f:h");
359 if (c == -1)
360 break;
361 switch(c) {
362 case 'h':
363 help();
364 break;
365 case 'f':
366 fmt = optarg;
367 break;
368 }
369 }
370 optind++;
371 if (optind >= argc)
372 help();
373 filename = argv[optind++];
374
375 bs = bdrv_new("");
376 if (!bs)
377 error("Not enough memory");
378 if (fmt) {
379 drv = bdrv_find_format(fmt);
380 if (!drv)
381 error("Unknown file format '%s'", fmt);
382 } else {
383 drv = NULL;
384 }
385 if (bdrv_open2(bs, filename, 0, drv) < 0) {
386 error("Could not open '%s'", filename);
387 }
388 ret = bdrv_commit(bs);
389 switch(ret) {
390 case 0:
391 printf("Image committed.\n");
392 break;
393 case -ENOENT:
394 error("No disk inserted");
395 break;
396 case -EACCES:
397 error("Image is read-only");
398 break;
399 case -ENOTSUP:
400 error("Image is already committed");
401 break;
402 default:
403 error("Error while committing image");
404 break;
405 }
406
407 bdrv_delete(bs);
408 return 0;
409}
410
411static int is_not_zero(const uint8_t *sector, int len)
412{
413 int i;
414 len >>= 2;
415 for(i = 0;i < len; i++) {
416 if (((uint32_t *)sector)[i] != 0)
417 return 1;
418 }
419 return 0;
420}
421
422static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
423{
424 int v, i;
425
426 if (n <= 0) {
427 *pnum = 0;
428 return 0;
429 }
430 v = is_not_zero(buf, 512);
431 for(i = 1; i < n; i++) {
432 buf += 512;
433 if (v != is_not_zero(buf, 512))
434 break;
435 }
436 *pnum = i;
437 return v;
438}
439
440static BlockDriverState *bdrv_new_open(const char *filename,
441 const char *fmt)
442{
443 BlockDriverState *bs;
444 BlockDriver *drv;
445 char password[256];
446
447 bs = bdrv_new("");
448 if (!bs)
449 error("Not enough memory");
450 if (fmt) {
451 drv = bdrv_find_format(fmt);
452 if (!drv)
453 error("Unknown file format '%s'", fmt);
454 } else {
455 drv = NULL;
456 }
457 if (bdrv_open2(bs, filename, 0, drv) < 0) {
458 error("Could not open '%s'", filename);
459 }
460 if (bdrv_is_encrypted(bs)) {
461 printf("Disk image '%s' is encrypted.\n", filename);
462 if (read_password(password, sizeof(password)) < 0)
463 error("No password given");
464 if (bdrv_set_key(bs, password) < 0)
465 error("invalid password");
466 }
467 return bs;
468}
469
470#define IO_BUF_SIZE 65536
471
472static int img_convert(int argc, char **argv)
473{
474 int c, ret, n, n1, compress, cluster_size, cluster_sectors, encrypt;
475 const char *filename, *fmt, *out_fmt, *out_filename;
476 BlockDriver *drv;
477 BlockDriverState *bs, *out_bs;
478 int64_t total_sectors, nb_sectors, sector_num;
479 uint8_t buf[IO_BUF_SIZE];
480 const uint8_t *buf1;
481
482 fmt = NULL;
483 out_fmt = "raw";
484 compress = 0;
485 encrypt = 0;
486 for(;;) {
487 c = getopt(argc, argv, "f:O:hce");
488 if (c == -1)
489 break;
490 switch(c) {
491 case 'h':
492 help();
493 break;
494 case 'f':
495 fmt = optarg;
496 break;
497 case 'O':
498 out_fmt = optarg;
499 break;
500 case 'c':
501 compress = 1;
502 break;
503 case 'e':
504 encrypt = 1;
505 break;
506 }
507 }
508 optind++;
509 if (optind >= argc)
510 help();
511 filename = argv[optind++];
512 if (optind >= argc)
513 help();
514 out_filename = argv[optind++];
515
516 bs = bdrv_new_open(filename, fmt);
517
518 drv = bdrv_find_format(out_fmt);
519 if (!drv)
520 error("Unknown file format '%s'", fmt);
521 if (compress && drv != &bdrv_qcow)
522 error("Compression not supported for this file format");
523 if (encrypt && drv != &bdrv_qcow)
524 error("Encryption not supported for this file format");
525 if (compress && encrypt)
526 error("Compression and encryption not supported at the same time");
527 bdrv_get_geometry(bs, &total_sectors);
528 ret = bdrv_create(drv, out_filename, total_sectors, NULL, encrypt);
529 if (ret < 0) {
530 if (ret == -ENOTSUP) {
531 error("Formatting not suppored for file format '%s'", fmt);
532 } else {
533 error("Error while formatting '%s'", out_filename);
534 }
535 }
536
537 out_bs = bdrv_new_open(out_filename, out_fmt);
538
539 if (compress) {
540 cluster_size = qcow_get_cluster_size(out_bs);
541 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE)
542 error("invalid cluster size");
543 cluster_sectors = cluster_size >> 9;
544 sector_num = 0;
545 for(;;) {
546 nb_sectors = total_sectors - sector_num;
547 if (nb_sectors <= 0)
548 break;
549 if (nb_sectors >= cluster_sectors)
550 n = cluster_sectors;
551 else
552 n = nb_sectors;
553 if (bdrv_read(bs, sector_num, buf, n) < 0)
554 error("error while reading");
555 if (n < cluster_sectors)
556 memset(buf + n * 512, 0, cluster_size - n * 512);
557 if (is_not_zero(buf, cluster_size)) {
558 if (qcow_compress_cluster(out_bs, sector_num, buf) != 0)
559 error("error while compressing sector %lld", sector_num);
560 }
561 sector_num += n;
562 }
563 } else {
564 sector_num = 0;
565 for(;;) {
566 nb_sectors = total_sectors - sector_num;
567 if (nb_sectors <= 0)
568 break;
569 if (nb_sectors >= (IO_BUF_SIZE / 512))
570 n = (IO_BUF_SIZE / 512);
571 else
572 n = nb_sectors;
573 if (bdrv_read(bs, sector_num, buf, n) < 0)
574 error("error while reading");
575 /* NOTE: at the same time we convert, we do not write zero
576 sectors to have a chance to compress the image. Ideally, we
577 should add a specific call to have the info to go faster */
578 buf1 = buf;
579 while (n > 0) {
580 if (is_allocated_sectors(buf1, n, &n1)) {
581 if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
582 error("error while writing");
583 }
584 sector_num += n1;
585 n -= n1;
586 buf1 += n1 * 512;
587 }
588 }
589 }
590 bdrv_delete(out_bs);
591 bdrv_delete(bs);
592 return 0;
593}
594
595static int img_info(int argc, char **argv)
596{
597 int c;
598 const char *filename, *fmt;
599 BlockDriver *drv;
600 BlockDriverState *bs;
601 char fmt_name[128], size_buf[128], dsize_buf[128];
602 int64_t total_sectors;
603 struct stat st;
604
605 fmt = NULL;
606 for(;;) {
607 c = getopt(argc, argv, "f:h");
608 if (c == -1)
609 break;
610 switch(c) {
611 case 'h':
612 help();
613 break;
614 case 'f':
615 fmt = optarg;
616 break;
617 }
618 }
619 optind++;
620 if (optind >= argc)
621 help();
622 filename = argv[optind++];
623
624 bs = bdrv_new("");
625 if (!bs)
626 error("Not enough memory");
627 if (fmt) {
628 drv = bdrv_find_format(fmt);
629 if (!drv)
630 error("Unknown file format '%s'", fmt);
631 } else {
632 drv = NULL;
633 }
634 if (bdrv_open2(bs, filename, 0, drv) < 0) {
635 error("Could not open '%s'", filename);
636 }
637 bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
638 bdrv_get_geometry(bs, &total_sectors);
639 get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
640 if (stat(filename, &st) < 0)
641 error("Could not stat '%s'", filename);
642 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
643 (int64_t)st.st_blocks * 512);
644 printf("image: %s\n"
645 "file format: %s\n"
646 "virtual size: %s (%lld bytes)\n"
647 "disk size: %s\n",
648 filename, fmt_name, size_buf,
649 total_sectors * 512,
650 dsize_buf);
651 if (bdrv_is_encrypted(bs))
652 printf("encrypted: yes\n");
653 bdrv_delete(bs);
654 return 0;
655}
656
657int main(int argc, char **argv)
658{
659 const char *cmd;
660
661 bdrv_init();
662 if (argc < 2)
663 help();
664 cmd = argv[1];
665 if (!strcmp(cmd, "create")) {
666 img_create(argc, argv);
667 } else if (!strcmp(cmd, "commit")) {
668 img_commit(argc, argv);
669 } else if (!strcmp(cmd, "convert")) {
670 img_convert(argc, argv);
671 } else if (!strcmp(cmd, "info")) {
672 img_info(argc, argv);
673 } else {
674 help();
675 }
676 return 0;
677}