Diff for /qemu/qemu-img.c between versions 1.1.1.3 and 1.1.1.4

version 1.1.1.3, 2018/04/24 16:45:00 version 1.1.1.4, 2018/04/24 16:47:25
Line 1 Line 1
 /*  /*
  * QEMU disk image utility   * QEMU disk image utility
  *    *
  * Copyright (c) 2003-2007 Fabrice Bellard   * Copyright (c) 2003-2008 Fabrice Bellard
  *    *
  * Permission is hereby granted, free of charge, to any person obtaining a copy   * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal   * of this software and associated documentation files (the "Software"), to deal
  * in the Software without restriction, including without limitation the rights   * in the Software without restriction, including without limitation the rights
Line 21 Line 21
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.   * THE SOFTWARE.
  */   */
 #include "vl.h"  #include "qemu-common.h"
   #include "block_int.h"
   #include <assert.h>
   
 #ifdef _WIN32  #ifdef _WIN32
   #define WIN32_LEAN_AND_MEAN
 #include <windows.h>  #include <windows.h>
 #endif  #endif
   
Line 62  char *qemu_strdup(const char *str) Line 65  char *qemu_strdup(const char *str)
     return ptr;      return ptr;
 }  }
   
 void term_printf(const char *fmt, ...)  static void __attribute__((noreturn)) error(const char *fmt, ...)
 {  
     va_list ap;  
     va_start(ap, fmt);  
     vprintf(fmt, ap);  
     va_end(ap);  
 }  
   
 void term_print_filename(const char *filename)  
 {  
     term_printf(filename);  
 }  
   
 void __attribute__((noreturn)) error(const char *fmt, ...)   
 {  {
     va_list ap;      va_list ap;
     va_start(ap, fmt);      va_start(ap, fmt);
Line 91  static void format_print(void *opaque, c Line 81  static void format_print(void *opaque, c
     printf(" %s", name);      printf(" %s", name);
 }  }
   
 void help(void)  static void help(void)
 {  {
     printf("qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2007 Fabrice Bellard\n"      printf("qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fabrice Bellard\n"
            "usage: qemu-img command [command options]\n"             "usage: qemu-img command [command options]\n"
            "QEMU disk image utility\n"             "QEMU disk image utility\n"
            "\n"             "\n"
            "Command syntax:\n"             "Command syntax:\n"
            "  create [-e] [-b base_image] [-f fmt] filename [size]\n"             "  create [-e] [-6] [-b base_image] [-f fmt] filename [size]\n"
            "  commit [-f fmt] filename\n"             "  commit [-f fmt] filename\n"
            "  convert [-c] [-e] [-f fmt] filename [-O output_fmt] output_filename\n"             "  convert [-c] [-e] [-6] [-f fmt] filename [filename2 [...]] [-O output_fmt] output_filename\n"
            "  info [-f fmt] filename\n"             "  info [-f fmt] filename\n"
            "\n"             "\n"
            "Command parameters:\n"             "Command parameters:\n"
Line 114  void help(void) Line 104  void help(void)
            "  'output_fmt' is the destination format\n"             "  'output_fmt' is the destination format\n"
            "  '-c' indicates that target image must be compressed (qcow format only)\n"             "  '-c' indicates that target image must be compressed (qcow format only)\n"
            "  '-e' indicates that the target image must be encrypted (qcow format only)\n"             "  '-e' indicates that the target image must be encrypted (qcow format only)\n"
              "  '-6' indicates that the target image must use compatibility level 6 (vmdk format only)\n"
            );             );
     printf("\nSupported format:");      printf("\nSupported format:");
     bdrv_iterate_format(format_print, NULL);      bdrv_iterate_format(format_print, NULL);
Line 166  static void term_init(void) Line 157  static void term_init(void)
     tty.c_cflag |= CS8;      tty.c_cflag |= CS8;
     tty.c_cc[VMIN] = 1;      tty.c_cc[VMIN] = 1;
     tty.c_cc[VTIME] = 0;      tty.c_cc[VTIME] = 0;
       
     tcsetattr (0, TCSANOW, &tty);      tcsetattr (0, TCSANOW, &tty);
   
     atexit(term_exit);      atexit(term_exit);
 }  }
   
 int read_password(char *buf, int buf_size)  static int read_password(char *buf, int buf_size)
 {  {
     uint8_t ch;      uint8_t ch;
     int i, ret;      int i, ret;
Line 241  static BlockDriverState *bdrv_new_open(c Line 232  static BlockDriverState *bdrv_new_open(c
   
 static int img_create(int argc, char **argv)  static int img_create(int argc, char **argv)
 {  {
     int c, ret, encrypted;      int c, ret, flags;
     const char *fmt = "raw";      const char *fmt = "raw";
     const char *filename;      const char *filename;
     const char *base_filename = NULL;      const char *base_filename = NULL;
     int64_t size;      uint64_t size;
     const char *p;      const char *p;
     BlockDriver *drv;      BlockDriver *drv;
       
     encrypted = 0;      flags = 0;
     for(;;) {      for(;;) {
         c = getopt(argc, argv, "b:f:he");          c = getopt(argc, argv, "b:f:he6");
         if (c == -1)          if (c == -1)
             break;              break;
         switch(c) {          switch(c) {
Line 265  static int img_create(int argc, char **a Line 256  static int img_create(int argc, char **a
             fmt = optarg;              fmt = optarg;
             break;              break;
         case 'e':          case 'e':
             encrypted = 1;              flags |= BLOCK_FLAG_ENCRYPT;
               break;
           case '6':
               flags |= BLOCK_FLAG_COMPAT6;
             break;              break;
         }          }
     }      }
     if (optind >= argc)       if (optind >= argc)
         help();          help();
     filename = argv[optind++];      filename = argv[optind++];
     size = 0;      size = 0;
Line 297  static int img_create(int argc, char **a Line 291  static int img_create(int argc, char **a
     drv = bdrv_find_format(fmt);      drv = bdrv_find_format(fmt);
     if (!drv)      if (!drv)
         error("Unknown file format '%s'", fmt);          error("Unknown file format '%s'", fmt);
     printf("Formating '%s', fmt=%s",      printf("Formatting '%s', fmt=%s",
            filename, fmt);             filename, fmt);
     if (encrypted)      if (flags & BLOCK_FLAG_ENCRYPT)
         printf(", encrypted");          printf(", encrypted");
       if (flags & BLOCK_FLAG_COMPAT6)
           printf(", compatibility level=6");
     if (base_filename) {      if (base_filename) {
         printf(", backing_file=%s",          printf(", backing_file=%s",
                base_filename);                 base_filename);
     }      }
     printf(", size=%" PRId64 " kB\n", (int64_t) (size / 1024));      printf(", size=%" PRIu64 " kB\n", size / 1024);
     ret = bdrv_create(drv, filename, size / 512, base_filename, encrypted);      ret = bdrv_create(drv, filename, size / 512, base_filename, flags);
     if (ret < 0) {      if (ret < 0) {
         if (ret == -ENOTSUP) {          if (ret == -ENOTSUP) {
             error("Formatting or formatting option not supported for file format '%s'", fmt);              error("Formatting or formatting option not supported for file format '%s'", fmt);
Line 338  static int img_commit(int argc, char **a Line 334  static int img_commit(int argc, char **a
             break;              break;
         }          }
     }      }
     if (optind >= argc)       if (optind >= argc)
         help();          help();
     filename = argv[optind++];      filename = argv[optind++];
   
Line 411  static int is_allocated_sectors(const ui Line 407  static int is_allocated_sectors(const ui
   
 static int img_convert(int argc, char **argv)  static int img_convert(int argc, char **argv)
 {  {
     int c, ret, n, n1, compress, cluster_size, cluster_sectors, encrypt;      int c, ret, n, n1, bs_n, bs_i, flags, cluster_size, cluster_sectors;
     const char *filename, *fmt, *out_fmt, *out_filename;      const char *fmt, *out_fmt, *out_filename;
     BlockDriver *drv;      BlockDriver *drv;
     BlockDriverState *bs, *out_bs;      BlockDriverState **bs, *out_bs;
     int64_t total_sectors, nb_sectors, sector_num;      int64_t total_sectors, nb_sectors, sector_num, bs_offset;
       uint64_t bs_sectors;
     uint8_t buf[IO_BUF_SIZE];      uint8_t buf[IO_BUF_SIZE];
     const uint8_t *buf1;      const uint8_t *buf1;
     BlockDriverInfo bdi;      BlockDriverInfo bdi;
   
     fmt = NULL;      fmt = NULL;
     out_fmt = "raw";      out_fmt = "raw";
     compress = 0;      flags = 0;
     encrypt = 0;  
     for(;;) {      for(;;) {
         c = getopt(argc, argv, "f:O:hce");          c = getopt(argc, argv, "f:O:hce6");
         if (c == -1)          if (c == -1)
             break;              break;
         switch(c) {          switch(c) {
Line 439  static int img_convert(int argc, char ** Line 435  static int img_convert(int argc, char **
             out_fmt = optarg;              out_fmt = optarg;
             break;              break;
         case 'c':          case 'c':
             compress = 1;              flags |= BLOCK_FLAG_COMPRESS;
             break;              break;
         case 'e':          case 'e':
             encrypt = 1;              flags |= BLOCK_FLAG_ENCRYPT;
               break;
           case '6':
               flags |= BLOCK_FLAG_COMPAT6;
             break;              break;
         }          }
     }      }
     if (optind >= argc)   
         help();      bs_n = argc - optind - 1;
     filename = argv[optind++];      if (bs_n < 1) help();
     if (optind >= argc)   
         help();      out_filename = argv[argc - 1];
     out_filename = argv[optind++];          
           bs = calloc(bs_n, sizeof(BlockDriverState *));
     bs = bdrv_new_open(filename, fmt);      if (!bs)
           error("Out of memory");
   
       total_sectors = 0;
       for (bs_i = 0; bs_i < bs_n; bs_i++) {
           bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt);
           if (!bs[bs_i])
               error("Could not open '%s'", argv[optind + bs_i]);
           bdrv_get_geometry(bs[bs_i], &bs_sectors);
           total_sectors += bs_sectors;
       }
   
     drv = bdrv_find_format(out_fmt);      drv = bdrv_find_format(out_fmt);
     if (!drv)      if (!drv)
         error("Unknown file format '%s'", fmt);          error("Unknown file format '%s'", out_fmt);
     if (compress && drv != &bdrv_qcow && drv != &bdrv_qcow2)      if (flags & BLOCK_FLAG_COMPRESS && drv != &bdrv_qcow && drv != &bdrv_qcow2)
         error("Compression not supported for this file format");          error("Compression not supported for this file format");
     if (encrypt && drv != &bdrv_qcow && drv != &bdrv_qcow2)      if (flags & BLOCK_FLAG_ENCRYPT && drv != &bdrv_qcow && drv != &bdrv_qcow2)
         error("Encryption not supported for this file format");          error("Encryption not supported for this file format");
     if (compress && encrypt)      if (flags & BLOCK_FLAG_COMPAT6 && drv != &bdrv_vmdk)
           error("Alternative compatibility level not supported for this file format");
       if (flags & BLOCK_FLAG_ENCRYPT && flags & BLOCK_FLAG_COMPRESS)
         error("Compression and encryption not supported at the same time");          error("Compression and encryption not supported at the same time");
     bdrv_get_geometry(bs, &total_sectors);  
     ret = bdrv_create(drv, out_filename, total_sectors, NULL, encrypt);      ret = bdrv_create(drv, out_filename, total_sectors, NULL, flags);
     if (ret < 0) {      if (ret < 0) {
         if (ret == -ENOTSUP) {          if (ret == -ENOTSUP) {
             error("Formatting not supported for file format '%s'", fmt);              error("Formatting not supported for file format '%s'", fmt);
Line 473  static int img_convert(int argc, char ** Line 484  static int img_convert(int argc, char **
             error("Error while formatting '%s'", out_filename);              error("Error while formatting '%s'", out_filename);
         }          }
     }      }
       
     out_bs = bdrv_new_open(out_filename, out_fmt);      out_bs = bdrv_new_open(out_filename, out_fmt);
   
     if (compress) {      bs_i = 0;
       bs_offset = 0;
       bdrv_get_geometry(bs[0], &bs_sectors);
   
       if (flags & BLOCK_FLAG_COMPRESS) {
         if (bdrv_get_info(out_bs, &bdi) < 0)          if (bdrv_get_info(out_bs, &bdi) < 0)
             error("could not get block driver info");              error("could not get block driver info");
         cluster_size = bdi.cluster_size;          cluster_size = bdi.cluster_size;
Line 485  static int img_convert(int argc, char ** Line 500  static int img_convert(int argc, char **
         cluster_sectors = cluster_size >> 9;          cluster_sectors = cluster_size >> 9;
         sector_num = 0;          sector_num = 0;
         for(;;) {          for(;;) {
               int64_t bs_num;
               int remainder;
               uint8_t *buf2;
   
             nb_sectors = total_sectors - sector_num;              nb_sectors = total_sectors - sector_num;
             if (nb_sectors <= 0)              if (nb_sectors <= 0)
                 break;                  break;
Line 492  static int img_convert(int argc, char ** Line 511  static int img_convert(int argc, char **
                 n = cluster_sectors;                  n = cluster_sectors;
             else              else
                 n = nb_sectors;                  n = nb_sectors;
             if (bdrv_read(bs, sector_num, buf, n) < 0)   
                 error("error while reading");              bs_num = sector_num - bs_offset;
               assert (bs_num >= 0);
               remainder = n;
               buf2 = buf;
               while (remainder > 0) {
                   int nlow;
                   while (bs_num == bs_sectors) {
                       bs_i++;
                       assert (bs_i < bs_n);
                       bs_offset += bs_sectors;
                       bdrv_get_geometry(bs[bs_i], &bs_sectors);
                       bs_num = 0;
                       /* printf("changing part: sector_num=%lld, "
                          "bs_i=%d, bs_offset=%lld, bs_sectors=%lld\n",
                          sector_num, bs_i, bs_offset, bs_sectors); */
                   }
                   assert (bs_num < bs_sectors);
   
                   nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
   
                   if (bdrv_read(bs[bs_i], bs_num, buf2, nlow) < 0) 
                       error("error while reading");
   
                   buf2 += nlow * 512;
                   bs_num += nlow;
   
                   remainder -= nlow;
               }
               assert (remainder == 0);
   
             if (n < cluster_sectors)              if (n < cluster_sectors)
                 memset(buf + n * 512, 0, cluster_size - n * 512);                  memset(buf + n * 512, 0, cluster_size - n * 512);
             if (is_not_zero(buf, cluster_size)) {              if (is_not_zero(buf, cluster_size)) {
                 if (bdrv_write_compressed(out_bs, sector_num, buf,                   if (bdrv_write_compressed(out_bs, sector_num, buf,
                                           cluster_sectors) != 0)                                            cluster_sectors) != 0)
                     error("error while compressing sector %" PRId64,                      error("error while compressing sector %" PRId64,
                           sector_num);                            sector_num);
Line 516  static int img_convert(int argc, char ** Line 564  static int img_convert(int argc, char **
                 n = (IO_BUF_SIZE / 512);                  n = (IO_BUF_SIZE / 512);
             else              else
                 n = nb_sectors;                  n = nb_sectors;
             if (bdrv_read(bs, sector_num, buf, n) < 0)   
               while (sector_num - bs_offset >= bs_sectors) {
                   bs_i ++;
                   assert (bs_i < bs_n);
                   bs_offset += bs_sectors;
                   bdrv_get_geometry(bs[bs_i], &bs_sectors);
                   /* printf("changing part: sector_num=%lld, bs_i=%d, "
                     "bs_offset=%lld, bs_sectors=%lld\n",
                      sector_num, bs_i, bs_offset, bs_sectors); */
               }
   
               if (n > bs_offset + bs_sectors - sector_num)
                   n = bs_offset + bs_sectors - sector_num;
   
               if (bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n) < 0) 
                 error("error while reading");                  error("error while reading");
             /* NOTE: at the same time we convert, we do not write zero              /* NOTE: at the same time we convert, we do not write zero
                sectors to have a chance to compress the image. Ideally, we                 sectors to have a chance to compress the image. Ideally, we
Line 524  static int img_convert(int argc, char ** Line 586  static int img_convert(int argc, char **
             buf1 = buf;              buf1 = buf;
             while (n > 0) {              while (n > 0) {
                 if (is_allocated_sectors(buf1, n, &n1)) {                  if (is_allocated_sectors(buf1, n, &n1)) {
                     if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)                       if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
                         error("error while writing");                          error("error while writing");
                 }                  }
                 sector_num += n1;                  sector_num += n1;
Line 534  static int img_convert(int argc, char ** Line 596  static int img_convert(int argc, char **
         }          }
     }      }
     bdrv_delete(out_bs);      bdrv_delete(out_bs);
     bdrv_delete(bs);      for (bs_i = 0; bs_i < bs_n; bs_i++)
           bdrv_delete(bs[bs_i]);
       free(bs);
     return 0;      return 0;
 }  }
   
Line 554  static int64_t get_allocated_file_size(c Line 618  static int64_t get_allocated_file_size(c
             return (((int64_t) high) << 32) + low;              return (((int64_t) high) << 32) + low;
     }      }
   
     if (_stati64(filename, &st) < 0)       if (_stati64(filename, &st) < 0)
         return -1;          return -1;
     return st.st_size;      return st.st_size;
 }  }
Line 562  static int64_t get_allocated_file_size(c Line 626  static int64_t get_allocated_file_size(c
 static int64_t get_allocated_file_size(const char *filename)  static int64_t get_allocated_file_size(const char *filename)
 {  {
     struct stat st;      struct stat st;
     if (stat(filename, &st) < 0)       if (stat(filename, &st) < 0)
         return -1;          return -1;
     return (int64_t)st.st_blocks * 512;      return (int64_t)st.st_blocks * 512;
 }  }
Line 593  static int img_info(int argc, char **arg Line 657  static int img_info(int argc, char **arg
     BlockDriver *drv;      BlockDriver *drv;
     BlockDriverState *bs;      BlockDriverState *bs;
     char fmt_name[128], size_buf[128], dsize_buf[128];      char fmt_name[128], size_buf[128], dsize_buf[128];
     int64_t total_sectors, allocated_size;      uint64_t total_sectors;
       int64_t allocated_size;
     char backing_filename[1024];      char backing_filename[1024];
     char backing_filename2[1024];      char backing_filename2[1024];
     BlockDriverInfo bdi;      BlockDriverInfo bdi;
Line 612  static int img_info(int argc, char **arg Line 677  static int img_info(int argc, char **arg
             break;              break;
         }          }
     }      }
     if (optind >= argc)       if (optind >= argc)
         help();          help();
     filename = argv[optind++];      filename = argv[optind++];
   
Line 636  static int img_info(int argc, char **arg Line 701  static int img_info(int argc, char **arg
     if (allocated_size < 0)      if (allocated_size < 0)
         sprintf(dsize_buf, "unavailable");          sprintf(dsize_buf, "unavailable");
     else      else
         get_human_readable_size(dsize_buf, sizeof(dsize_buf),           get_human_readable_size(dsize_buf, sizeof(dsize_buf),
                                 allocated_size);                                  allocated_size);
     printf("image: %s\n"      printf("image: %s\n"
            "file format: %s\n"             "file format: %s\n"
            "virtual size: %s (%" PRId64 " bytes)\n"             "virtual size: %s (%" PRId64 " bytes)\n"
            "disk size: %s\n",             "disk size: %s\n",
            filename, fmt_name, size_buf,              filename, fmt_name, size_buf,
            (total_sectors * 512),             (total_sectors * 512),
            dsize_buf);             dsize_buf);
     if (bdrv_is_encrypted(bs))      if (bdrv_is_encrypted(bs))
         printf("encrypted: yes\n");          printf("encrypted: yes\n");
     if (bdrv_get_info(bs, &bdi) >= 0) {      if (bdrv_get_info(bs, &bdi) >= 0) {
         if (bdi.cluster_size != 0)           if (bdi.cluster_size != 0)
             printf("cluster_size: %d\n", bdi.cluster_size);              printf("cluster_size: %d\n", bdi.cluster_size);
     }      }
     bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));      bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
     if (backing_filename[0] != '\0') {      if (backing_filename[0] != '\0') {
         path_combine(backing_filename2, sizeof(backing_filename2),          path_combine(backing_filename2, sizeof(backing_filename2),
                      filename, backing_filename);                       filename, backing_filename);
         printf("backing file: %s (actual path: %s)\n",           printf("backing file: %s (actual path: %s)\n",
                backing_filename,                 backing_filename,
                backing_filename2);                 backing_filename2);
     }      }

Removed from v.1.1.1.3  
changed lines
  Added in v.1.1.1.4


unix.superglobalmegacorp.com