Annotation of qemu/qemu-img.c, revision 1.1.1.6

1.1       root        1: /*
1.1.1.3   root        2:  * QEMU disk image utility
1.1.1.4   root        3:  *
                      4:  * Copyright (c) 2003-2008 Fabrice Bellard
                      5:  *
1.1       root        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:  */
1.1.1.4   root       24: #include "qemu-common.h"
1.1.1.5   root       25: #include "osdep.h"
1.1.1.4   root       26: #include "block_int.h"
                     27: #include <assert.h>
1.1       root       28: 
1.1.1.2   root       29: #ifdef _WIN32
1.1.1.4   root       30: #define WIN32_LEAN_AND_MEAN
1.1.1.2   root       31: #include <windows.h>
                     32: #endif
                     33: 
1.1.1.5   root       34: /* Default to cache=writeback as data integrity is not important for qemu-tcg. */
                     35: #define BRDV_O_FLAGS BDRV_O_CACHE_WB
1.1       root       36: 
1.1.1.5   root       37: static void QEMU_NORETURN error(const char *fmt, ...)
1.1       root       38: {
                     39:     va_list ap;
                     40:     va_start(ap, fmt);
                     41:     fprintf(stderr, "qemu-img: ");
                     42:     vfprintf(stderr, fmt, ap);
                     43:     fprintf(stderr, "\n");
                     44:     exit(1);
                     45:     va_end(ap);
                     46: }
                     47: 
                     48: static void format_print(void *opaque, const char *name)
                     49: {
                     50:     printf(" %s", name);
                     51: }
                     52: 
1.1.1.5   root       53: /* Please keep in synch with qemu-img.texi */
1.1.1.4   root       54: static void help(void)
1.1       root       55: {
1.1.1.4   root       56:     printf("qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fabrice Bellard\n"
1.1       root       57:            "usage: qemu-img command [command options]\n"
                     58:            "QEMU disk image utility\n"
                     59:            "\n"
                     60:            "Command syntax:\n"
1.1.1.4   root       61:            "  create [-e] [-6] [-b base_image] [-f fmt] filename [size]\n"
1.1       root       62:            "  commit [-f fmt] filename\n"
1.1.1.5   root       63:            "  convert [-c] [-e] [-6] [-f fmt] [-O output_fmt] [-B output_base_image] filename [filename2 [...]] output_filename\n"
1.1       root       64:            "  info [-f fmt] filename\n"
1.1.1.5   root       65:            "  snapshot [-l | -a snapshot | -c snapshot | -d snapshot] filename\n"
1.1       root       66:            "\n"
                     67:            "Command parameters:\n"
                     68:            "  'filename' is a disk image filename\n"
                     69:            "  'base_image' is the read-only disk image which is used as base for a copy on\n"
                     70:            "    write image; the copy on write image only stores the modified data\n"
1.1.1.5   root       71:            "  'output_base_image' forces the output image to be created as a copy on write\n"
                     72:            "    image of the specified base image; 'output_base_image' should have the same\n"
                     73:            "    content as the input's base image, however the path, image format, etc may\n"
                     74:            "    differ\n"
1.1       root       75:            "  'fmt' is the disk image format. It is guessed automatically in most cases\n"
1.1.1.5   root       76:            "  'size' is the disk image size in kilobytes. Optional suffixes\n"
1.1.1.6 ! root       77:            "    'M' (megabyte, 1024 * 1024) and 'G' (gigabyte, 1024 * 1024 * 1024) are\n"
        !            78:            "    supported any 'k' or 'K' is ignored\n"
1.1       root       79:            "  'output_filename' is the destination disk image filename\n"
                     80:            "  'output_fmt' is the destination format\n"
                     81:            "  '-c' indicates that target image must be compressed (qcow format only)\n"
                     82:            "  '-e' indicates that the target image must be encrypted (qcow format only)\n"
1.1.1.4   root       83:            "  '-6' indicates that the target image must use compatibility level 6 (vmdk format only)\n"
1.1.1.5   root       84:            "  '-h' with or without a command shows this help and lists the supported formats\n"
                     85:            "\n"
                     86:            "Parameters to snapshot subcommand:\n"
                     87:            "  'snapshot' is the name of the snapshot to create, apply or delete\n"
                     88:            "  '-a' applies a snapshot (revert disk to saved state)\n"
                     89:            "  '-c' creates a snapshot\n"
                     90:            "  '-d' deletes a snapshot\n"
                     91:            "  '-l' lists all snapshots in the given image\n"
1.1       root       92:            );
1.1.1.5   root       93:     printf("\nSupported formats:");
1.1       root       94:     bdrv_iterate_format(format_print, NULL);
                     95:     printf("\n");
                     96:     exit(1);
                     97: }
                     98: 
                     99: #if defined(WIN32)
                    100: /* XXX: put correct support for win32 */
                    101: static int read_password(char *buf, int buf_size)
                    102: {
                    103:     int c, i;
                    104:     printf("Password: ");
                    105:     fflush(stdout);
                    106:     i = 0;
                    107:     for(;;) {
                    108:         c = getchar();
                    109:         if (c == '\n')
                    110:             break;
                    111:         if (i < (buf_size - 1))
                    112:             buf[i++] = c;
                    113:     }
                    114:     buf[i] = '\0';
                    115:     return 0;
                    116: }
                    117: 
                    118: #else
                    119: 
                    120: #include <termios.h>
                    121: 
                    122: static struct termios oldtty;
                    123: 
                    124: static void term_exit(void)
                    125: {
                    126:     tcsetattr (0, TCSANOW, &oldtty);
                    127: }
                    128: 
                    129: static void term_init(void)
                    130: {
                    131:     struct termios tty;
                    132: 
                    133:     tcgetattr (0, &tty);
                    134:     oldtty = tty;
                    135: 
                    136:     tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
                    137:                           |INLCR|IGNCR|ICRNL|IXON);
                    138:     tty.c_oflag |= OPOST;
                    139:     tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
                    140:     tty.c_cflag &= ~(CSIZE|PARENB);
                    141:     tty.c_cflag |= CS8;
                    142:     tty.c_cc[VMIN] = 1;
                    143:     tty.c_cc[VTIME] = 0;
1.1.1.4   root      144: 
1.1       root      145:     tcsetattr (0, TCSANOW, &tty);
                    146: 
                    147:     atexit(term_exit);
                    148: }
                    149: 
1.1.1.4   root      150: static int read_password(char *buf, int buf_size)
1.1       root      151: {
                    152:     uint8_t ch;
                    153:     int i, ret;
                    154: 
                    155:     printf("password: ");
                    156:     fflush(stdout);
                    157:     term_init();
                    158:     i = 0;
                    159:     for(;;) {
                    160:         ret = read(0, &ch, 1);
                    161:         if (ret == -1) {
                    162:             if (errno == EAGAIN || errno == EINTR) {
                    163:                 continue;
                    164:             } else {
                    165:                 ret = -1;
                    166:                 break;
                    167:             }
                    168:         } else if (ret == 0) {
                    169:             ret = -1;
                    170:             break;
                    171:         } else {
                    172:             if (ch == '\r') {
                    173:                 ret = 0;
                    174:                 break;
                    175:             }
                    176:             if (i < (buf_size - 1))
                    177:                 buf[i++] = ch;
                    178:         }
                    179:     }
                    180:     term_exit();
                    181:     buf[i] = '\0';
                    182:     printf("\n");
                    183:     return ret;
                    184: }
                    185: #endif
                    186: 
                    187: static BlockDriverState *bdrv_new_open(const char *filename,
                    188:                                        const char *fmt)
                    189: {
                    190:     BlockDriverState *bs;
                    191:     BlockDriver *drv;
                    192:     char password[256];
                    193: 
                    194:     bs = bdrv_new("");
                    195:     if (!bs)
                    196:         error("Not enough memory");
                    197:     if (fmt) {
                    198:         drv = bdrv_find_format(fmt);
                    199:         if (!drv)
                    200:             error("Unknown file format '%s'", fmt);
                    201:     } else {
                    202:         drv = NULL;
                    203:     }
1.1.1.5   root      204:     if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
1.1       root      205:         error("Could not open '%s'", filename);
                    206:     }
                    207:     if (bdrv_is_encrypted(bs)) {
                    208:         printf("Disk image '%s' is encrypted.\n", filename);
                    209:         if (read_password(password, sizeof(password)) < 0)
                    210:             error("No password given");
                    211:         if (bdrv_set_key(bs, password) < 0)
                    212:             error("invalid password");
                    213:     }
                    214:     return bs;
                    215: }
                    216: 
                    217: static int img_create(int argc, char **argv)
                    218: {
1.1.1.4   root      219:     int c, ret, flags;
1.1       root      220:     const char *fmt = "raw";
                    221:     const char *filename;
                    222:     const char *base_filename = NULL;
1.1.1.4   root      223:     uint64_t size;
1.1       root      224:     const char *p;
                    225:     BlockDriver *drv;
1.1.1.4   root      226: 
                    227:     flags = 0;
1.1       root      228:     for(;;) {
1.1.1.4   root      229:         c = getopt(argc, argv, "b:f:he6");
1.1       root      230:         if (c == -1)
                    231:             break;
                    232:         switch(c) {
                    233:         case 'h':
                    234:             help();
                    235:             break;
                    236:         case 'b':
                    237:             base_filename = optarg;
                    238:             break;
                    239:         case 'f':
                    240:             fmt = optarg;
                    241:             break;
                    242:         case 'e':
1.1.1.4   root      243:             flags |= BLOCK_FLAG_ENCRYPT;
                    244:             break;
                    245:         case '6':
                    246:             flags |= BLOCK_FLAG_COMPAT6;
1.1       root      247:             break;
                    248:         }
                    249:     }
1.1.1.4   root      250:     if (optind >= argc)
1.1       root      251:         help();
                    252:     filename = argv[optind++];
                    253:     size = 0;
                    254:     if (base_filename) {
                    255:         BlockDriverState *bs;
                    256:         bs = bdrv_new_open(base_filename, NULL);
                    257:         bdrv_get_geometry(bs, &size);
                    258:         size *= 512;
                    259:         bdrv_delete(bs);
                    260:     } else {
                    261:         if (optind >= argc)
                    262:             help();
                    263:         p = argv[optind];
                    264:         size = strtoul(p, (char **)&p, 0);
                    265:         if (*p == 'M') {
                    266:             size *= 1024 * 1024;
                    267:         } else if (*p == 'G') {
                    268:             size *= 1024 * 1024 * 1024;
                    269:         } else if (*p == 'k' || *p == 'K' || *p == '\0') {
                    270:             size *= 1024;
                    271:         } else {
                    272:             help();
                    273:         }
                    274:     }
                    275:     drv = bdrv_find_format(fmt);
                    276:     if (!drv)
                    277:         error("Unknown file format '%s'", fmt);
1.1.1.4   root      278:     printf("Formatting '%s', fmt=%s",
1.1       root      279:            filename, fmt);
1.1.1.4   root      280:     if (flags & BLOCK_FLAG_ENCRYPT)
1.1       root      281:         printf(", encrypted");
1.1.1.4   root      282:     if (flags & BLOCK_FLAG_COMPAT6)
                    283:         printf(", compatibility level=6");
1.1       root      284:     if (base_filename) {
                    285:         printf(", backing_file=%s",
                    286:                base_filename);
                    287:     }
1.1.1.4   root      288:     printf(", size=%" PRIu64 " kB\n", size / 1024);
                    289:     ret = bdrv_create(drv, filename, size / 512, base_filename, flags);
1.1       root      290:     if (ret < 0) {
                    291:         if (ret == -ENOTSUP) {
                    292:             error("Formatting or formatting option not supported for file format '%s'", fmt);
                    293:         } else {
                    294:             error("Error while formatting");
                    295:         }
                    296:     }
                    297:     return 0;
                    298: }
                    299: 
                    300: static int img_commit(int argc, char **argv)
                    301: {
                    302:     int c, ret;
                    303:     const char *filename, *fmt;
                    304:     BlockDriver *drv;
                    305:     BlockDriverState *bs;
                    306: 
                    307:     fmt = NULL;
                    308:     for(;;) {
                    309:         c = getopt(argc, argv, "f:h");
                    310:         if (c == -1)
                    311:             break;
                    312:         switch(c) {
                    313:         case 'h':
                    314:             help();
                    315:             break;
                    316:         case 'f':
                    317:             fmt = optarg;
                    318:             break;
                    319:         }
                    320:     }
1.1.1.4   root      321:     if (optind >= argc)
1.1       root      322:         help();
                    323:     filename = argv[optind++];
                    324: 
                    325:     bs = bdrv_new("");
                    326:     if (!bs)
                    327:         error("Not enough memory");
                    328:     if (fmt) {
                    329:         drv = bdrv_find_format(fmt);
                    330:         if (!drv)
                    331:             error("Unknown file format '%s'", fmt);
                    332:     } else {
                    333:         drv = NULL;
                    334:     }
1.1.1.5   root      335:     if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
1.1       root      336:         error("Could not open '%s'", filename);
                    337:     }
                    338:     ret = bdrv_commit(bs);
                    339:     switch(ret) {
                    340:     case 0:
                    341:         printf("Image committed.\n");
                    342:         break;
                    343:     case -ENOENT:
                    344:         error("No disk inserted");
                    345:         break;
                    346:     case -EACCES:
                    347:         error("Image is read-only");
                    348:         break;
                    349:     case -ENOTSUP:
                    350:         error("Image is already committed");
                    351:         break;
                    352:     default:
                    353:         error("Error while committing image");
                    354:         break;
                    355:     }
                    356: 
                    357:     bdrv_delete(bs);
                    358:     return 0;
                    359: }
                    360: 
                    361: static int is_not_zero(const uint8_t *sector, int len)
                    362: {
                    363:     int i;
                    364:     len >>= 2;
                    365:     for(i = 0;i < len; i++) {
                    366:         if (((uint32_t *)sector)[i] != 0)
                    367:             return 1;
                    368:     }
                    369:     return 0;
                    370: }
                    371: 
1.1.1.5   root      372: /*
                    373:  * Returns true iff the first sector pointed to by 'buf' contains at least
                    374:  * a non-NUL byte.
                    375:  *
                    376:  * 'pnum' is set to the number of sectors (including and immediately following
                    377:  * the first one) that are known to be in the same allocated/unallocated state.
                    378:  */
1.1       root      379: static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
                    380: {
                    381:     int v, i;
                    382: 
                    383:     if (n <= 0) {
                    384:         *pnum = 0;
                    385:         return 0;
                    386:     }
                    387:     v = is_not_zero(buf, 512);
                    388:     for(i = 1; i < n; i++) {
                    389:         buf += 512;
                    390:         if (v != is_not_zero(buf, 512))
                    391:             break;
                    392:     }
                    393:     *pnum = i;
                    394:     return v;
                    395: }
                    396: 
                    397: #define IO_BUF_SIZE 65536
                    398: 
                    399: static int img_convert(int argc, char **argv)
                    400: {
1.1.1.4   root      401:     int c, ret, n, n1, bs_n, bs_i, flags, cluster_size, cluster_sectors;
1.1.1.5   root      402:     const char *fmt, *out_fmt, *out_baseimg, *out_filename;
1.1       root      403:     BlockDriver *drv;
1.1.1.4   root      404:     BlockDriverState **bs, *out_bs;
                    405:     int64_t total_sectors, nb_sectors, sector_num, bs_offset;
                    406:     uint64_t bs_sectors;
1.1       root      407:     uint8_t buf[IO_BUF_SIZE];
                    408:     const uint8_t *buf1;
1.1.1.3   root      409:     BlockDriverInfo bdi;
1.1       root      410: 
                    411:     fmt = NULL;
                    412:     out_fmt = "raw";
1.1.1.5   root      413:     out_baseimg = NULL;
1.1.1.4   root      414:     flags = 0;
1.1       root      415:     for(;;) {
1.1.1.5   root      416:         c = getopt(argc, argv, "f:O:B:hce6");
1.1       root      417:         if (c == -1)
                    418:             break;
                    419:         switch(c) {
                    420:         case 'h':
                    421:             help();
                    422:             break;
                    423:         case 'f':
                    424:             fmt = optarg;
                    425:             break;
                    426:         case 'O':
                    427:             out_fmt = optarg;
                    428:             break;
1.1.1.5   root      429:         case 'B':
                    430:             out_baseimg = optarg;
                    431:             break;
1.1       root      432:         case 'c':
1.1.1.4   root      433:             flags |= BLOCK_FLAG_COMPRESS;
1.1       root      434:             break;
                    435:         case 'e':
1.1.1.4   root      436:             flags |= BLOCK_FLAG_ENCRYPT;
                    437:             break;
                    438:         case '6':
                    439:             flags |= BLOCK_FLAG_COMPAT6;
1.1       root      440:             break;
                    441:         }
                    442:     }
1.1.1.4   root      443: 
                    444:     bs_n = argc - optind - 1;
                    445:     if (bs_n < 1) help();
                    446: 
                    447:     out_filename = argv[argc - 1];
1.1.1.5   root      448: 
                    449:     if (bs_n > 1 && out_baseimg)
                    450:         error("-B makes no sense when concatenating multiple input images");
1.1.1.4   root      451:         
                    452:     bs = calloc(bs_n, sizeof(BlockDriverState *));
                    453:     if (!bs)
                    454:         error("Out of memory");
                    455: 
                    456:     total_sectors = 0;
                    457:     for (bs_i = 0; bs_i < bs_n; bs_i++) {
                    458:         bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt);
                    459:         if (!bs[bs_i])
                    460:             error("Could not open '%s'", argv[optind + bs_i]);
                    461:         bdrv_get_geometry(bs[bs_i], &bs_sectors);
                    462:         total_sectors += bs_sectors;
                    463:     }
1.1       root      464: 
                    465:     drv = bdrv_find_format(out_fmt);
                    466:     if (!drv)
1.1.1.4   root      467:         error("Unknown file format '%s'", out_fmt);
                    468:     if (flags & BLOCK_FLAG_COMPRESS && drv != &bdrv_qcow && drv != &bdrv_qcow2)
1.1       root      469:         error("Compression not supported for this file format");
1.1.1.4   root      470:     if (flags & BLOCK_FLAG_ENCRYPT && drv != &bdrv_qcow && drv != &bdrv_qcow2)
1.1       root      471:         error("Encryption not supported for this file format");
1.1.1.4   root      472:     if (flags & BLOCK_FLAG_COMPAT6 && drv != &bdrv_vmdk)
                    473:         error("Alternative compatibility level not supported for this file format");
                    474:     if (flags & BLOCK_FLAG_ENCRYPT && flags & BLOCK_FLAG_COMPRESS)
1.1       root      475:         error("Compression and encryption not supported at the same time");
1.1.1.4   root      476: 
1.1.1.5   root      477:     ret = bdrv_create(drv, out_filename, total_sectors, out_baseimg, flags);
1.1       root      478:     if (ret < 0) {
                    479:         if (ret == -ENOTSUP) {
                    480:             error("Formatting not supported for file format '%s'", fmt);
                    481:         } else {
                    482:             error("Error while formatting '%s'", out_filename);
                    483:         }
                    484:     }
1.1.1.4   root      485: 
1.1       root      486:     out_bs = bdrv_new_open(out_filename, out_fmt);
                    487: 
1.1.1.4   root      488:     bs_i = 0;
                    489:     bs_offset = 0;
                    490:     bdrv_get_geometry(bs[0], &bs_sectors);
                    491: 
                    492:     if (flags & BLOCK_FLAG_COMPRESS) {
1.1.1.3   root      493:         if (bdrv_get_info(out_bs, &bdi) < 0)
                    494:             error("could not get block driver info");
                    495:         cluster_size = bdi.cluster_size;
1.1       root      496:         if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE)
                    497:             error("invalid cluster size");
                    498:         cluster_sectors = cluster_size >> 9;
                    499:         sector_num = 0;
                    500:         for(;;) {
1.1.1.4   root      501:             int64_t bs_num;
                    502:             int remainder;
                    503:             uint8_t *buf2;
                    504: 
1.1       root      505:             nb_sectors = total_sectors - sector_num;
                    506:             if (nb_sectors <= 0)
                    507:                 break;
                    508:             if (nb_sectors >= cluster_sectors)
                    509:                 n = cluster_sectors;
                    510:             else
                    511:                 n = nb_sectors;
1.1.1.4   root      512: 
                    513:             bs_num = sector_num - bs_offset;
                    514:             assert (bs_num >= 0);
                    515:             remainder = n;
                    516:             buf2 = buf;
                    517:             while (remainder > 0) {
                    518:                 int nlow;
                    519:                 while (bs_num == bs_sectors) {
                    520:                     bs_i++;
                    521:                     assert (bs_i < bs_n);
                    522:                     bs_offset += bs_sectors;
                    523:                     bdrv_get_geometry(bs[bs_i], &bs_sectors);
                    524:                     bs_num = 0;
                    525:                     /* printf("changing part: sector_num=%lld, "
                    526:                        "bs_i=%d, bs_offset=%lld, bs_sectors=%lld\n",
                    527:                        sector_num, bs_i, bs_offset, bs_sectors); */
                    528:                 }
                    529:                 assert (bs_num < bs_sectors);
                    530: 
                    531:                 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
                    532: 
                    533:                 if (bdrv_read(bs[bs_i], bs_num, buf2, nlow) < 0) 
                    534:                     error("error while reading");
                    535: 
                    536:                 buf2 += nlow * 512;
                    537:                 bs_num += nlow;
                    538: 
                    539:                 remainder -= nlow;
                    540:             }
                    541:             assert (remainder == 0);
                    542: 
1.1       root      543:             if (n < cluster_sectors)
                    544:                 memset(buf + n * 512, 0, cluster_size - n * 512);
                    545:             if (is_not_zero(buf, cluster_size)) {
1.1.1.4   root      546:                 if (bdrv_write_compressed(out_bs, sector_num, buf,
1.1.1.3   root      547:                                           cluster_sectors) != 0)
1.1.1.2   root      548:                     error("error while compressing sector %" PRId64,
                    549:                           sector_num);
1.1       root      550:             }
                    551:             sector_num += n;
                    552:         }
1.1.1.3   root      553:         /* signal EOF to align */
                    554:         bdrv_write_compressed(out_bs, 0, NULL, 0);
1.1       root      555:     } else {
1.1.1.5   root      556:         sector_num = 0; // total number of sectors converted so far
1.1       root      557:         for(;;) {
                    558:             nb_sectors = total_sectors - sector_num;
                    559:             if (nb_sectors <= 0)
                    560:                 break;
                    561:             if (nb_sectors >= (IO_BUF_SIZE / 512))
                    562:                 n = (IO_BUF_SIZE / 512);
                    563:             else
                    564:                 n = nb_sectors;
1.1.1.4   root      565: 
                    566:             while (sector_num - bs_offset >= bs_sectors) {
                    567:                 bs_i ++;
                    568:                 assert (bs_i < bs_n);
                    569:                 bs_offset += bs_sectors;
                    570:                 bdrv_get_geometry(bs[bs_i], &bs_sectors);
                    571:                 /* printf("changing part: sector_num=%lld, bs_i=%d, "
                    572:                   "bs_offset=%lld, bs_sectors=%lld\n",
                    573:                    sector_num, bs_i, bs_offset, bs_sectors); */
                    574:             }
                    575: 
                    576:             if (n > bs_offset + bs_sectors - sector_num)
                    577:                 n = bs_offset + bs_sectors - sector_num;
                    578: 
1.1.1.5   root      579:             /* If the output image is being created as a copy on write image,
                    580:                assume that sectors which are unallocated in the input image
                    581:                are present in both the output's and input's base images (no
                    582:                need to copy them). */
                    583:             if (out_baseimg) {
                    584:                if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset, n, &n1)) {
                    585:                   sector_num += n1;
                    586:                   continue;
                    587:                }
                    588:                /* The next 'n1' sectors are allocated in the input image. Copy
                    589:                   only those as they may be followed by unallocated sectors. */
                    590:                n = n1;
                    591:             }
                    592: 
1.1.1.4   root      593:             if (bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n) < 0) 
1.1       root      594:                 error("error while reading");
                    595:             /* NOTE: at the same time we convert, we do not write zero
                    596:                sectors to have a chance to compress the image. Ideally, we
                    597:                should add a specific call to have the info to go faster */
                    598:             buf1 = buf;
                    599:             while (n > 0) {
1.1.1.5   root      600:                 /* If the output image is being created as a copy on write image,
                    601:                    copy all sectors even the ones containing only NUL bytes,
                    602:                    because they may differ from the sectors in the base image. */
                    603:                 if (out_baseimg || is_allocated_sectors(buf1, n, &n1)) {
1.1.1.4   root      604:                     if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
1.1       root      605:                         error("error while writing");
                    606:                 }
                    607:                 sector_num += n1;
                    608:                 n -= n1;
                    609:                 buf1 += n1 * 512;
                    610:             }
                    611:         }
                    612:     }
                    613:     bdrv_delete(out_bs);
1.1.1.4   root      614:     for (bs_i = 0; bs_i < bs_n; bs_i++)
                    615:         bdrv_delete(bs[bs_i]);
                    616:     free(bs);
1.1       root      617:     return 0;
                    618: }
                    619: 
                    620: #ifdef _WIN32
                    621: static int64_t get_allocated_file_size(const char *filename)
                    622: {
1.1.1.2   root      623:     typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
                    624:     get_compressed_t get_compressed;
1.1       root      625:     struct _stati64 st;
1.1.1.2   root      626: 
                    627:     /* WinNT support GetCompressedFileSize to determine allocate size */
                    628:     get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
                    629:     if (get_compressed) {
                    630:        DWORD high, low;
                    631:        low = get_compressed(filename, &high);
                    632:        if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
                    633:            return (((int64_t) high) << 32) + low;
                    634:     }
                    635: 
1.1.1.4   root      636:     if (_stati64(filename, &st) < 0)
1.1       root      637:         return -1;
                    638:     return st.st_size;
                    639: }
                    640: #else
                    641: static int64_t get_allocated_file_size(const char *filename)
                    642: {
                    643:     struct stat st;
1.1.1.4   root      644:     if (stat(filename, &st) < 0)
1.1       root      645:         return -1;
                    646:     return (int64_t)st.st_blocks * 512;
                    647: }
                    648: #endif
                    649: 
1.1.1.3   root      650: static void dump_snapshots(BlockDriverState *bs)
                    651: {
                    652:     QEMUSnapshotInfo *sn_tab, *sn;
                    653:     int nb_sns, i;
                    654:     char buf[256];
                    655: 
                    656:     nb_sns = bdrv_snapshot_list(bs, &sn_tab);
                    657:     if (nb_sns <= 0)
                    658:         return;
                    659:     printf("Snapshot list:\n");
                    660:     printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
                    661:     for(i = 0; i < nb_sns; i++) {
                    662:         sn = &sn_tab[i];
                    663:         printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
                    664:     }
                    665:     qemu_free(sn_tab);
                    666: }
                    667: 
1.1       root      668: static int img_info(int argc, char **argv)
                    669: {
                    670:     int c;
                    671:     const char *filename, *fmt;
                    672:     BlockDriver *drv;
                    673:     BlockDriverState *bs;
                    674:     char fmt_name[128], size_buf[128], dsize_buf[128];
1.1.1.4   root      675:     uint64_t total_sectors;
                    676:     int64_t allocated_size;
1.1.1.3   root      677:     char backing_filename[1024];
                    678:     char backing_filename2[1024];
                    679:     BlockDriverInfo bdi;
1.1       root      680: 
                    681:     fmt = NULL;
                    682:     for(;;) {
                    683:         c = getopt(argc, argv, "f:h");
                    684:         if (c == -1)
                    685:             break;
                    686:         switch(c) {
                    687:         case 'h':
                    688:             help();
                    689:             break;
                    690:         case 'f':
                    691:             fmt = optarg;
                    692:             break;
                    693:         }
                    694:     }
1.1.1.4   root      695:     if (optind >= argc)
1.1       root      696:         help();
                    697:     filename = argv[optind++];
                    698: 
                    699:     bs = bdrv_new("");
                    700:     if (!bs)
                    701:         error("Not enough memory");
                    702:     if (fmt) {
                    703:         drv = bdrv_find_format(fmt);
                    704:         if (!drv)
                    705:             error("Unknown file format '%s'", fmt);
                    706:     } else {
                    707:         drv = NULL;
                    708:     }
1.1.1.5   root      709:     if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
1.1       root      710:         error("Could not open '%s'", filename);
                    711:     }
                    712:     bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
                    713:     bdrv_get_geometry(bs, &total_sectors);
                    714:     get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
                    715:     allocated_size = get_allocated_file_size(filename);
                    716:     if (allocated_size < 0)
1.1.1.5   root      717:         snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
1.1       root      718:     else
1.1.1.4   root      719:         get_human_readable_size(dsize_buf, sizeof(dsize_buf),
1.1       root      720:                                 allocated_size);
                    721:     printf("image: %s\n"
                    722:            "file format: %s\n"
1.1.1.2   root      723:            "virtual size: %s (%" PRId64 " bytes)\n"
1.1       root      724:            "disk size: %s\n",
1.1.1.4   root      725:            filename, fmt_name, size_buf,
1.1.1.2   root      726:            (total_sectors * 512),
1.1       root      727:            dsize_buf);
                    728:     if (bdrv_is_encrypted(bs))
                    729:         printf("encrypted: yes\n");
1.1.1.3   root      730:     if (bdrv_get_info(bs, &bdi) >= 0) {
1.1.1.4   root      731:         if (bdi.cluster_size != 0)
1.1.1.3   root      732:             printf("cluster_size: %d\n", bdi.cluster_size);
                    733:     }
                    734:     bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
                    735:     if (backing_filename[0] != '\0') {
                    736:         path_combine(backing_filename2, sizeof(backing_filename2),
                    737:                      filename, backing_filename);
1.1.1.4   root      738:         printf("backing file: %s (actual path: %s)\n",
1.1.1.3   root      739:                backing_filename,
                    740:                backing_filename2);
                    741:     }
                    742:     dump_snapshots(bs);
1.1       root      743:     bdrv_delete(bs);
                    744:     return 0;
                    745: }
                    746: 
1.1.1.5   root      747: #define SNAPSHOT_LIST   1
                    748: #define SNAPSHOT_CREATE 2
                    749: #define SNAPSHOT_APPLY  3
                    750: #define SNAPSHOT_DELETE 4
                    751: 
                    752: static void img_snapshot(int argc, char **argv)
                    753: {
                    754:     BlockDriverState *bs;
                    755:     QEMUSnapshotInfo sn;
                    756:     char *filename, *snapshot_name = NULL;
                    757:     int c, ret;
                    758:     int action = 0;
                    759:     qemu_timeval tv;
                    760: 
                    761:     /* Parse commandline parameters */
                    762:     for(;;) {
                    763:         c = getopt(argc, argv, "la:c:d:h");
                    764:         if (c == -1)
                    765:             break;
                    766:         switch(c) {
                    767:         case 'h':
                    768:             help();
                    769:             return;
                    770:         case 'l':
                    771:             if (action) {
                    772:                 help();
                    773:                 return;
                    774:             }
                    775:             action = SNAPSHOT_LIST;
                    776:             break;
                    777:         case 'a':
                    778:             if (action) {
                    779:                 help();
                    780:                 return;
                    781:             }
                    782:             action = SNAPSHOT_APPLY;
                    783:             snapshot_name = optarg;
                    784:             break;
                    785:         case 'c':
                    786:             if (action) {
                    787:                 help();
                    788:                 return;
                    789:             }
                    790:             action = SNAPSHOT_CREATE;
                    791:             snapshot_name = optarg;
                    792:             break;
                    793:         case 'd':
                    794:             if (action) {
                    795:                 help();
                    796:                 return;
                    797:             }
                    798:             action = SNAPSHOT_DELETE;
                    799:             snapshot_name = optarg;
                    800:             break;
                    801:         }
                    802:     }
                    803: 
                    804:     if (optind >= argc)
                    805:         help();
                    806:     filename = argv[optind++];
                    807: 
                    808:     /* Open the image */
                    809:     bs = bdrv_new("");
                    810:     if (!bs)
                    811:         error("Not enough memory");
                    812: 
                    813:     if (bdrv_open2(bs, filename, 0, NULL) < 0) {
                    814:         error("Could not open '%s'", filename);
                    815:     }
                    816: 
                    817:     /* Perform the requested action */
                    818:     switch(action) {
                    819:     case SNAPSHOT_LIST:
                    820:         dump_snapshots(bs);
                    821:         break;
                    822: 
                    823:     case SNAPSHOT_CREATE:
                    824:         memset(&sn, 0, sizeof(sn));
                    825:         pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
                    826: 
                    827:         qemu_gettimeofday(&tv);
                    828:         sn.date_sec = tv.tv_sec;
                    829:         sn.date_nsec = tv.tv_usec * 1000;
                    830: 
                    831:         ret = bdrv_snapshot_create(bs, &sn);
                    832:         if (ret)
                    833:             error("Could not create snapshot '%s': %d (%s)",
                    834:                 snapshot_name, ret, strerror(-ret));
                    835:         break;
                    836: 
                    837:     case SNAPSHOT_APPLY:
                    838:         ret = bdrv_snapshot_goto(bs, snapshot_name);
                    839:         if (ret)
                    840:             error("Could not apply snapshot '%s': %d (%s)",
                    841:                 snapshot_name, ret, strerror(-ret));
                    842:         break;
                    843: 
                    844:     case SNAPSHOT_DELETE:
                    845:         ret = bdrv_snapshot_delete(bs, snapshot_name);
                    846:         if (ret)
                    847:             error("Could not delete snapshot '%s': %d (%s)",
                    848:                 snapshot_name, ret, strerror(-ret));
                    849:         break;
                    850:     }
                    851: 
                    852:     /* Cleanup */
                    853:     bdrv_delete(bs);
                    854: }
                    855: 
1.1       root      856: int main(int argc, char **argv)
                    857: {
                    858:     const char *cmd;
                    859: 
                    860:     bdrv_init();
                    861:     if (argc < 2)
                    862:         help();
                    863:     cmd = argv[1];
1.1.1.5   root      864:     argc--; argv++;
1.1       root      865:     if (!strcmp(cmd, "create")) {
                    866:         img_create(argc, argv);
                    867:     } else if (!strcmp(cmd, "commit")) {
                    868:         img_commit(argc, argv);
                    869:     } else if (!strcmp(cmd, "convert")) {
                    870:         img_convert(argc, argv);
                    871:     } else if (!strcmp(cmd, "info")) {
                    872:         img_info(argc, argv);
1.1.1.5   root      873:     } else if (!strcmp(cmd, "snapshot")) {
                    874:         img_snapshot(argc, argv);
1.1       root      875:     } else {
                    876:         help();
                    877:     }
                    878:     return 0;
                    879: }

unix.superglobalmegacorp.com