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