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

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);
1.1.1.7 ! root      293:         } else if (ret == -EFBIG) {
        !           294:             error("The image size is too large for file format '%s'", fmt);
1.1       root      295:         } else {
                    296:             error("Error while formatting");
                    297:         }
                    298:     }
                    299:     return 0;
                    300: }
                    301: 
                    302: static int img_commit(int argc, char **argv)
                    303: {
                    304:     int c, ret;
                    305:     const char *filename, *fmt;
                    306:     BlockDriver *drv;
                    307:     BlockDriverState *bs;
                    308: 
                    309:     fmt = NULL;
                    310:     for(;;) {
                    311:         c = getopt(argc, argv, "f:h");
                    312:         if (c == -1)
                    313:             break;
                    314:         switch(c) {
                    315:         case 'h':
                    316:             help();
                    317:             break;
                    318:         case 'f':
                    319:             fmt = optarg;
                    320:             break;
                    321:         }
                    322:     }
1.1.1.4   root      323:     if (optind >= argc)
1.1       root      324:         help();
                    325:     filename = argv[optind++];
                    326: 
                    327:     bs = bdrv_new("");
                    328:     if (!bs)
                    329:         error("Not enough memory");
                    330:     if (fmt) {
                    331:         drv = bdrv_find_format(fmt);
                    332:         if (!drv)
                    333:             error("Unknown file format '%s'", fmt);
                    334:     } else {
                    335:         drv = NULL;
                    336:     }
1.1.1.5   root      337:     if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
1.1       root      338:         error("Could not open '%s'", filename);
                    339:     }
                    340:     ret = bdrv_commit(bs);
                    341:     switch(ret) {
                    342:     case 0:
                    343:         printf("Image committed.\n");
                    344:         break;
                    345:     case -ENOENT:
                    346:         error("No disk inserted");
                    347:         break;
                    348:     case -EACCES:
                    349:         error("Image is read-only");
                    350:         break;
                    351:     case -ENOTSUP:
                    352:         error("Image is already committed");
                    353:         break;
                    354:     default:
                    355:         error("Error while committing image");
                    356:         break;
                    357:     }
                    358: 
                    359:     bdrv_delete(bs);
                    360:     return 0;
                    361: }
                    362: 
                    363: static int is_not_zero(const uint8_t *sector, int len)
                    364: {
                    365:     int i;
                    366:     len >>= 2;
                    367:     for(i = 0;i < len; i++) {
                    368:         if (((uint32_t *)sector)[i] != 0)
                    369:             return 1;
                    370:     }
                    371:     return 0;
                    372: }
                    373: 
1.1.1.5   root      374: /*
                    375:  * Returns true iff the first sector pointed to by 'buf' contains at least
                    376:  * a non-NUL byte.
                    377:  *
                    378:  * 'pnum' is set to the number of sectors (including and immediately following
                    379:  * the first one) that are known to be in the same allocated/unallocated state.
                    380:  */
1.1       root      381: static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
                    382: {
                    383:     int v, i;
                    384: 
                    385:     if (n <= 0) {
                    386:         *pnum = 0;
                    387:         return 0;
                    388:     }
                    389:     v = is_not_zero(buf, 512);
                    390:     for(i = 1; i < n; i++) {
                    391:         buf += 512;
                    392:         if (v != is_not_zero(buf, 512))
                    393:             break;
                    394:     }
                    395:     *pnum = i;
                    396:     return v;
                    397: }
                    398: 
                    399: #define IO_BUF_SIZE 65536
                    400: 
                    401: static int img_convert(int argc, char **argv)
                    402: {
1.1.1.4   root      403:     int c, ret, n, n1, bs_n, bs_i, flags, cluster_size, cluster_sectors;
1.1.1.5   root      404:     const char *fmt, *out_fmt, *out_baseimg, *out_filename;
1.1       root      405:     BlockDriver *drv;
1.1.1.4   root      406:     BlockDriverState **bs, *out_bs;
                    407:     int64_t total_sectors, nb_sectors, sector_num, bs_offset;
                    408:     uint64_t bs_sectors;
1.1       root      409:     uint8_t buf[IO_BUF_SIZE];
                    410:     const uint8_t *buf1;
1.1.1.3   root      411:     BlockDriverInfo bdi;
1.1       root      412: 
                    413:     fmt = NULL;
                    414:     out_fmt = "raw";
1.1.1.5   root      415:     out_baseimg = NULL;
1.1.1.4   root      416:     flags = 0;
1.1       root      417:     for(;;) {
1.1.1.5   root      418:         c = getopt(argc, argv, "f:O:B:hce6");
1.1       root      419:         if (c == -1)
                    420:             break;
                    421:         switch(c) {
                    422:         case 'h':
                    423:             help();
                    424:             break;
                    425:         case 'f':
                    426:             fmt = optarg;
                    427:             break;
                    428:         case 'O':
                    429:             out_fmt = optarg;
                    430:             break;
1.1.1.5   root      431:         case 'B':
                    432:             out_baseimg = optarg;
                    433:             break;
1.1       root      434:         case 'c':
1.1.1.4   root      435:             flags |= BLOCK_FLAG_COMPRESS;
1.1       root      436:             break;
                    437:         case 'e':
1.1.1.4   root      438:             flags |= BLOCK_FLAG_ENCRYPT;
                    439:             break;
                    440:         case '6':
                    441:             flags |= BLOCK_FLAG_COMPAT6;
1.1       root      442:             break;
                    443:         }
                    444:     }
1.1.1.4   root      445: 
                    446:     bs_n = argc - optind - 1;
                    447:     if (bs_n < 1) help();
                    448: 
                    449:     out_filename = argv[argc - 1];
1.1.1.5   root      450: 
                    451:     if (bs_n > 1 && out_baseimg)
                    452:         error("-B makes no sense when concatenating multiple input images");
1.1.1.4   root      453:         
                    454:     bs = calloc(bs_n, sizeof(BlockDriverState *));
                    455:     if (!bs)
                    456:         error("Out of memory");
                    457: 
                    458:     total_sectors = 0;
                    459:     for (bs_i = 0; bs_i < bs_n; bs_i++) {
                    460:         bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt);
                    461:         if (!bs[bs_i])
                    462:             error("Could not open '%s'", argv[optind + bs_i]);
                    463:         bdrv_get_geometry(bs[bs_i], &bs_sectors);
                    464:         total_sectors += bs_sectors;
                    465:     }
1.1       root      466: 
                    467:     drv = bdrv_find_format(out_fmt);
                    468:     if (!drv)
1.1.1.4   root      469:         error("Unknown file format '%s'", out_fmt);
                    470:     if (flags & BLOCK_FLAG_COMPRESS && drv != &bdrv_qcow && drv != &bdrv_qcow2)
1.1       root      471:         error("Compression not supported for this file format");
1.1.1.4   root      472:     if (flags & BLOCK_FLAG_ENCRYPT && drv != &bdrv_qcow && drv != &bdrv_qcow2)
1.1       root      473:         error("Encryption not supported for this file format");
1.1.1.4   root      474:     if (flags & BLOCK_FLAG_COMPAT6 && drv != &bdrv_vmdk)
                    475:         error("Alternative compatibility level not supported for this file format");
                    476:     if (flags & BLOCK_FLAG_ENCRYPT && flags & BLOCK_FLAG_COMPRESS)
1.1       root      477:         error("Compression and encryption not supported at the same time");
1.1.1.4   root      478: 
1.1.1.5   root      479:     ret = bdrv_create(drv, out_filename, total_sectors, out_baseimg, flags);
1.1       root      480:     if (ret < 0) {
                    481:         if (ret == -ENOTSUP) {
1.1.1.7 ! root      482:             error("Formatting not supported for file format '%s'", out_fmt);
        !           483:         } else if (ret == -EFBIG) {
        !           484:             error("The image size is too large for file format '%s'", out_fmt);
1.1       root      485:         } else {
                    486:             error("Error while formatting '%s'", out_filename);
                    487:         }
                    488:     }
1.1.1.4   root      489: 
1.1       root      490:     out_bs = bdrv_new_open(out_filename, out_fmt);
                    491: 
1.1.1.4   root      492:     bs_i = 0;
                    493:     bs_offset = 0;
                    494:     bdrv_get_geometry(bs[0], &bs_sectors);
                    495: 
                    496:     if (flags & BLOCK_FLAG_COMPRESS) {
1.1.1.3   root      497:         if (bdrv_get_info(out_bs, &bdi) < 0)
                    498:             error("could not get block driver info");
                    499:         cluster_size = bdi.cluster_size;
1.1       root      500:         if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE)
                    501:             error("invalid cluster size");
                    502:         cluster_sectors = cluster_size >> 9;
                    503:         sector_num = 0;
                    504:         for(;;) {
1.1.1.4   root      505:             int64_t bs_num;
                    506:             int remainder;
                    507:             uint8_t *buf2;
                    508: 
1.1       root      509:             nb_sectors = total_sectors - sector_num;
                    510:             if (nb_sectors <= 0)
                    511:                 break;
                    512:             if (nb_sectors >= cluster_sectors)
                    513:                 n = cluster_sectors;
                    514:             else
                    515:                 n = nb_sectors;
1.1.1.4   root      516: 
                    517:             bs_num = sector_num - bs_offset;
                    518:             assert (bs_num >= 0);
                    519:             remainder = n;
                    520:             buf2 = buf;
                    521:             while (remainder > 0) {
                    522:                 int nlow;
                    523:                 while (bs_num == bs_sectors) {
                    524:                     bs_i++;
                    525:                     assert (bs_i < bs_n);
                    526:                     bs_offset += bs_sectors;
                    527:                     bdrv_get_geometry(bs[bs_i], &bs_sectors);
                    528:                     bs_num = 0;
                    529:                     /* printf("changing part: sector_num=%lld, "
                    530:                        "bs_i=%d, bs_offset=%lld, bs_sectors=%lld\n",
                    531:                        sector_num, bs_i, bs_offset, bs_sectors); */
                    532:                 }
                    533:                 assert (bs_num < bs_sectors);
                    534: 
                    535:                 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
                    536: 
                    537:                 if (bdrv_read(bs[bs_i], bs_num, buf2, nlow) < 0) 
                    538:                     error("error while reading");
                    539: 
                    540:                 buf2 += nlow * 512;
                    541:                 bs_num += nlow;
                    542: 
                    543:                 remainder -= nlow;
                    544:             }
                    545:             assert (remainder == 0);
                    546: 
1.1       root      547:             if (n < cluster_sectors)
                    548:                 memset(buf + n * 512, 0, cluster_size - n * 512);
                    549:             if (is_not_zero(buf, cluster_size)) {
1.1.1.4   root      550:                 if (bdrv_write_compressed(out_bs, sector_num, buf,
1.1.1.3   root      551:                                           cluster_sectors) != 0)
1.1.1.2   root      552:                     error("error while compressing sector %" PRId64,
                    553:                           sector_num);
1.1       root      554:             }
                    555:             sector_num += n;
                    556:         }
1.1.1.3   root      557:         /* signal EOF to align */
                    558:         bdrv_write_compressed(out_bs, 0, NULL, 0);
1.1       root      559:     } else {
1.1.1.5   root      560:         sector_num = 0; // total number of sectors converted so far
1.1       root      561:         for(;;) {
                    562:             nb_sectors = total_sectors - sector_num;
                    563:             if (nb_sectors <= 0)
                    564:                 break;
                    565:             if (nb_sectors >= (IO_BUF_SIZE / 512))
                    566:                 n = (IO_BUF_SIZE / 512);
                    567:             else
                    568:                 n = nb_sectors;
1.1.1.4   root      569: 
                    570:             while (sector_num - bs_offset >= bs_sectors) {
                    571:                 bs_i ++;
                    572:                 assert (bs_i < bs_n);
                    573:                 bs_offset += bs_sectors;
                    574:                 bdrv_get_geometry(bs[bs_i], &bs_sectors);
                    575:                 /* printf("changing part: sector_num=%lld, bs_i=%d, "
                    576:                   "bs_offset=%lld, bs_sectors=%lld\n",
                    577:                    sector_num, bs_i, bs_offset, bs_sectors); */
                    578:             }
                    579: 
                    580:             if (n > bs_offset + bs_sectors - sector_num)
                    581:                 n = bs_offset + bs_sectors - sector_num;
                    582: 
1.1.1.5   root      583:             /* If the output image is being created as a copy on write image,
                    584:                assume that sectors which are unallocated in the input image
                    585:                are present in both the output's and input's base images (no
                    586:                need to copy them). */
                    587:             if (out_baseimg) {
                    588:                if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset, n, &n1)) {
                    589:                   sector_num += n1;
                    590:                   continue;
                    591:                }
                    592:                /* The next 'n1' sectors are allocated in the input image. Copy
                    593:                   only those as they may be followed by unallocated sectors. */
                    594:                n = n1;
                    595:             }
                    596: 
1.1.1.4   root      597:             if (bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n) < 0) 
1.1       root      598:                 error("error while reading");
                    599:             /* NOTE: at the same time we convert, we do not write zero
                    600:                sectors to have a chance to compress the image. Ideally, we
                    601:                should add a specific call to have the info to go faster */
                    602:             buf1 = buf;
                    603:             while (n > 0) {
1.1.1.5   root      604:                 /* If the output image is being created as a copy on write image,
                    605:                    copy all sectors even the ones containing only NUL bytes,
                    606:                    because they may differ from the sectors in the base image. */
                    607:                 if (out_baseimg || is_allocated_sectors(buf1, n, &n1)) {
1.1.1.4   root      608:                     if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
1.1       root      609:                         error("error while writing");
                    610:                 }
                    611:                 sector_num += n1;
                    612:                 n -= n1;
                    613:                 buf1 += n1 * 512;
                    614:             }
                    615:         }
                    616:     }
                    617:     bdrv_delete(out_bs);
1.1.1.4   root      618:     for (bs_i = 0; bs_i < bs_n; bs_i++)
                    619:         bdrv_delete(bs[bs_i]);
                    620:     free(bs);
1.1       root      621:     return 0;
                    622: }
                    623: 
                    624: #ifdef _WIN32
                    625: static int64_t get_allocated_file_size(const char *filename)
                    626: {
1.1.1.2   root      627:     typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
                    628:     get_compressed_t get_compressed;
1.1       root      629:     struct _stati64 st;
1.1.1.2   root      630: 
                    631:     /* WinNT support GetCompressedFileSize to determine allocate size */
                    632:     get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
                    633:     if (get_compressed) {
                    634:        DWORD high, low;
                    635:        low = get_compressed(filename, &high);
                    636:        if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
                    637:            return (((int64_t) high) << 32) + low;
                    638:     }
                    639: 
1.1.1.4   root      640:     if (_stati64(filename, &st) < 0)
1.1       root      641:         return -1;
                    642:     return st.st_size;
                    643: }
                    644: #else
                    645: static int64_t get_allocated_file_size(const char *filename)
                    646: {
                    647:     struct stat st;
1.1.1.4   root      648:     if (stat(filename, &st) < 0)
1.1       root      649:         return -1;
                    650:     return (int64_t)st.st_blocks * 512;
                    651: }
                    652: #endif
                    653: 
1.1.1.3   root      654: static void dump_snapshots(BlockDriverState *bs)
                    655: {
                    656:     QEMUSnapshotInfo *sn_tab, *sn;
                    657:     int nb_sns, i;
                    658:     char buf[256];
                    659: 
                    660:     nb_sns = bdrv_snapshot_list(bs, &sn_tab);
                    661:     if (nb_sns <= 0)
                    662:         return;
                    663:     printf("Snapshot list:\n");
                    664:     printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
                    665:     for(i = 0; i < nb_sns; i++) {
                    666:         sn = &sn_tab[i];
                    667:         printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
                    668:     }
                    669:     qemu_free(sn_tab);
                    670: }
                    671: 
1.1       root      672: static int img_info(int argc, char **argv)
                    673: {
                    674:     int c;
                    675:     const char *filename, *fmt;
                    676:     BlockDriver *drv;
                    677:     BlockDriverState *bs;
                    678:     char fmt_name[128], size_buf[128], dsize_buf[128];
1.1.1.4   root      679:     uint64_t total_sectors;
                    680:     int64_t allocated_size;
1.1.1.3   root      681:     char backing_filename[1024];
                    682:     char backing_filename2[1024];
                    683:     BlockDriverInfo bdi;
1.1       root      684: 
                    685:     fmt = NULL;
                    686:     for(;;) {
                    687:         c = getopt(argc, argv, "f:h");
                    688:         if (c == -1)
                    689:             break;
                    690:         switch(c) {
                    691:         case 'h':
                    692:             help();
                    693:             break;
                    694:         case 'f':
                    695:             fmt = optarg;
                    696:             break;
                    697:         }
                    698:     }
1.1.1.4   root      699:     if (optind >= argc)
1.1       root      700:         help();
                    701:     filename = argv[optind++];
                    702: 
                    703:     bs = bdrv_new("");
                    704:     if (!bs)
                    705:         error("Not enough memory");
                    706:     if (fmt) {
                    707:         drv = bdrv_find_format(fmt);
                    708:         if (!drv)
                    709:             error("Unknown file format '%s'", fmt);
                    710:     } else {
                    711:         drv = NULL;
                    712:     }
1.1.1.5   root      713:     if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
1.1       root      714:         error("Could not open '%s'", filename);
                    715:     }
                    716:     bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
                    717:     bdrv_get_geometry(bs, &total_sectors);
                    718:     get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
                    719:     allocated_size = get_allocated_file_size(filename);
                    720:     if (allocated_size < 0)
1.1.1.5   root      721:         snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
1.1       root      722:     else
1.1.1.4   root      723:         get_human_readable_size(dsize_buf, sizeof(dsize_buf),
1.1       root      724:                                 allocated_size);
                    725:     printf("image: %s\n"
                    726:            "file format: %s\n"
1.1.1.2   root      727:            "virtual size: %s (%" PRId64 " bytes)\n"
1.1       root      728:            "disk size: %s\n",
1.1.1.4   root      729:            filename, fmt_name, size_buf,
1.1.1.2   root      730:            (total_sectors * 512),
1.1       root      731:            dsize_buf);
                    732:     if (bdrv_is_encrypted(bs))
                    733:         printf("encrypted: yes\n");
1.1.1.3   root      734:     if (bdrv_get_info(bs, &bdi) >= 0) {
1.1.1.4   root      735:         if (bdi.cluster_size != 0)
1.1.1.3   root      736:             printf("cluster_size: %d\n", bdi.cluster_size);
                    737:     }
                    738:     bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
                    739:     if (backing_filename[0] != '\0') {
                    740:         path_combine(backing_filename2, sizeof(backing_filename2),
                    741:                      filename, backing_filename);
1.1.1.4   root      742:         printf("backing file: %s (actual path: %s)\n",
1.1.1.3   root      743:                backing_filename,
                    744:                backing_filename2);
                    745:     }
                    746:     dump_snapshots(bs);
1.1       root      747:     bdrv_delete(bs);
                    748:     return 0;
                    749: }
                    750: 
1.1.1.5   root      751: #define SNAPSHOT_LIST   1
                    752: #define SNAPSHOT_CREATE 2
                    753: #define SNAPSHOT_APPLY  3
                    754: #define SNAPSHOT_DELETE 4
                    755: 
                    756: static void img_snapshot(int argc, char **argv)
                    757: {
                    758:     BlockDriverState *bs;
                    759:     QEMUSnapshotInfo sn;
                    760:     char *filename, *snapshot_name = NULL;
                    761:     int c, ret;
                    762:     int action = 0;
                    763:     qemu_timeval tv;
                    764: 
                    765:     /* Parse commandline parameters */
                    766:     for(;;) {
                    767:         c = getopt(argc, argv, "la:c:d:h");
                    768:         if (c == -1)
                    769:             break;
                    770:         switch(c) {
                    771:         case 'h':
                    772:             help();
                    773:             return;
                    774:         case 'l':
                    775:             if (action) {
                    776:                 help();
                    777:                 return;
                    778:             }
                    779:             action = SNAPSHOT_LIST;
                    780:             break;
                    781:         case 'a':
                    782:             if (action) {
                    783:                 help();
                    784:                 return;
                    785:             }
                    786:             action = SNAPSHOT_APPLY;
                    787:             snapshot_name = optarg;
                    788:             break;
                    789:         case 'c':
                    790:             if (action) {
                    791:                 help();
                    792:                 return;
                    793:             }
                    794:             action = SNAPSHOT_CREATE;
                    795:             snapshot_name = optarg;
                    796:             break;
                    797:         case 'd':
                    798:             if (action) {
                    799:                 help();
                    800:                 return;
                    801:             }
                    802:             action = SNAPSHOT_DELETE;
                    803:             snapshot_name = optarg;
                    804:             break;
                    805:         }
                    806:     }
                    807: 
                    808:     if (optind >= argc)
                    809:         help();
                    810:     filename = argv[optind++];
                    811: 
                    812:     /* Open the image */
                    813:     bs = bdrv_new("");
                    814:     if (!bs)
                    815:         error("Not enough memory");
                    816: 
                    817:     if (bdrv_open2(bs, filename, 0, NULL) < 0) {
                    818:         error("Could not open '%s'", filename);
                    819:     }
                    820: 
                    821:     /* Perform the requested action */
                    822:     switch(action) {
                    823:     case SNAPSHOT_LIST:
                    824:         dump_snapshots(bs);
                    825:         break;
                    826: 
                    827:     case SNAPSHOT_CREATE:
                    828:         memset(&sn, 0, sizeof(sn));
                    829:         pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
                    830: 
                    831:         qemu_gettimeofday(&tv);
                    832:         sn.date_sec = tv.tv_sec;
                    833:         sn.date_nsec = tv.tv_usec * 1000;
                    834: 
                    835:         ret = bdrv_snapshot_create(bs, &sn);
                    836:         if (ret)
                    837:             error("Could not create snapshot '%s': %d (%s)",
                    838:                 snapshot_name, ret, strerror(-ret));
                    839:         break;
                    840: 
                    841:     case SNAPSHOT_APPLY:
                    842:         ret = bdrv_snapshot_goto(bs, snapshot_name);
                    843:         if (ret)
                    844:             error("Could not apply snapshot '%s': %d (%s)",
                    845:                 snapshot_name, ret, strerror(-ret));
                    846:         break;
                    847: 
                    848:     case SNAPSHOT_DELETE:
                    849:         ret = bdrv_snapshot_delete(bs, snapshot_name);
                    850:         if (ret)
                    851:             error("Could not delete snapshot '%s': %d (%s)",
                    852:                 snapshot_name, ret, strerror(-ret));
                    853:         break;
                    854:     }
                    855: 
                    856:     /* Cleanup */
                    857:     bdrv_delete(bs);
                    858: }
                    859: 
1.1       root      860: int main(int argc, char **argv)
                    861: {
                    862:     const char *cmd;
                    863: 
                    864:     bdrv_init();
                    865:     if (argc < 2)
                    866:         help();
                    867:     cmd = argv[1];
1.1.1.5   root      868:     argc--; argv++;
1.1       root      869:     if (!strcmp(cmd, "create")) {
                    870:         img_create(argc, argv);
                    871:     } else if (!strcmp(cmd, "commit")) {
                    872:         img_commit(argc, argv);
                    873:     } else if (!strcmp(cmd, "convert")) {
                    874:         img_convert(argc, argv);
                    875:     } else if (!strcmp(cmd, "info")) {
                    876:         img_info(argc, argv);
1.1.1.5   root      877:     } else if (!strcmp(cmd, "snapshot")) {
                    878:         img_snapshot(argc, argv);
1.1       root      879:     } else {
                    880:         help();
                    881:     }
                    882:     return 0;
                    883: }

unix.superglobalmegacorp.com