Diff for /qemu/qemu-img.c between versions 1.1.1.12 and 1.1.1.13

version 1.1.1.12, 2018/04/24 18:34:02 version 1.1.1.13, 2018/04/24 18:56:18
Line 40  typedef struct img_cmd_t { Line 40  typedef struct img_cmd_t {
   
 /* Default to cache=writeback as data integrity is not important for qemu-tcg. */  /* Default to cache=writeback as data integrity is not important for qemu-tcg. */
 #define BDRV_O_FLAGS BDRV_O_CACHE_WB  #define BDRV_O_FLAGS BDRV_O_CACHE_WB
   #define BDRV_DEFAULT_CACHE "writeback"
   
 static void format_print(void *opaque, const char *name)  static void format_print(void *opaque, const char *name)
 {  {
Line 64  static void help(void) Line 65  static void help(void)
            "Command parameters:\n"             "Command parameters:\n"
            "  'filename' is a disk image filename\n"             "  'filename' is a disk image filename\n"
            "  'fmt' is the disk image format. It is guessed automatically in most cases\n"             "  'fmt' is the disk image format. It is guessed automatically in most cases\n"
              "  'cache' is the cache mode used to write the output disk image, the valid\n"
              "    options are: 'none', 'writeback' (default), 'writethrough' and 'unsafe'\n"
            "  'size' is the disk image size in bytes. Optional suffixes\n"             "  'size' is the disk image size in bytes. Optional suffixes\n"
            "    'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M)\n"             "    'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M)\n"
            "    and T (terabyte, 1024G) are supported. 'b' is ignored.\n"             "    and T (terabyte, 1024G) are supported. 'b' is ignored.\n"
Line 77  static void help(void) Line 80  static void help(void)
            "       match exactly. The image doesn't need a working backing file before\n"             "       match exactly. The image doesn't need a working backing file before\n"
            "       rebasing in this case (useful for renaming the backing file)\n"             "       rebasing in this case (useful for renaming the backing file)\n"
            "  '-h' with or without a command shows this help and lists the supported formats\n"             "  '-h' with or without a command shows this help and lists the supported formats\n"
              "  '-p' show progress of command (only certain commands)\n"
            "\n"             "\n"
            "Parameters to snapshot subcommand:\n"             "Parameters to snapshot subcommand:\n"
            "  'snapshot' is the name of the snapshot to create, apply or delete\n"             "  'snapshot' is the name of the snapshot to create, apply or delete\n"
Line 179  static int read_password(char *buf, int  Line 183  static int read_password(char *buf, int 
 }  }
 #endif  #endif
   
   static int set_cache_flag(const char *mode, int *flags)
   {
       *flags &= ~BDRV_O_CACHE_MASK;
   
       if (!strcmp(mode, "none") || !strcmp(mode, "off")) {
           *flags |= BDRV_O_CACHE_WB;
           *flags |= BDRV_O_NOCACHE;
       } else if (!strcmp(mode, "writeback")) {
           *flags |= BDRV_O_CACHE_WB;
       } else if (!strcmp(mode, "unsafe")) {
           *flags |= BDRV_O_CACHE_WB;
           *flags |= BDRV_O_NO_FLUSH;
       } else if (!strcmp(mode, "writethrough")) {
           /* this is the default */
       } else {
           return -1;
       }
   
       return 0;
   }
   
 static int print_block_option_help(const char *filename, const char *fmt)  static int print_block_option_help(const char *filename, const char *fmt)
 {  {
     BlockDriver *drv, *proto_drv;      BlockDriver *drv, *proto_drv;
Line 303  static int img_create(int argc, char **a Line 328  static int img_create(int argc, char **a
             fmt = optarg;              fmt = optarg;
             break;              break;
         case 'e':          case 'e':
             error_report("qemu-img: option -e is deprecated, please use \'-o "              error_report("option -e is deprecated, please use \'-o "
                   "encryption\' instead!");                    "encryption\' instead!");
             return 1;              return 1;
         case '6':          case '6':
             error_report("qemu-img: option -6 is deprecated, please use \'-o "              error_report("option -6 is deprecated, please use \'-o "
                   "compat6\' instead!");                    "compat6\' instead!");
             return 1;              return 1;
         case 'o':          case 'o':
Line 440  static int img_check(int argc, char **ar Line 465  static int img_check(int argc, char **ar
   
 static int img_commit(int argc, char **argv)  static int img_commit(int argc, char **argv)
 {  {
     int c, ret;      int c, ret, flags;
     const char *filename, *fmt;      const char *filename, *fmt, *cache;
     BlockDriverState *bs;      BlockDriverState *bs;
   
     fmt = NULL;      fmt = NULL;
       cache = BDRV_DEFAULT_CACHE;
     for(;;) {      for(;;) {
         c = getopt(argc, argv, "f:h");          c = getopt(argc, argv, "f:ht:");
         if (c == -1) {          if (c == -1) {
             break;              break;
         }          }
Line 458  static int img_commit(int argc, char **a Line 484  static int img_commit(int argc, char **a
         case 'f':          case 'f':
             fmt = optarg;              fmt = optarg;
             break;              break;
           case 't':
               cache = optarg;
               break;
         }          }
     }      }
     if (optind >= argc) {      if (optind >= argc) {
Line 465  static int img_commit(int argc, char **a Line 494  static int img_commit(int argc, char **a
     }      }
     filename = argv[optind++];      filename = argv[optind++];
   
     bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);      flags = BDRV_O_RDWR;
       ret = set_cache_flag(cache, &flags);
       if (ret < 0) {
           error_report("Invalid cache option: %s", cache);
           return -1;
       }
   
       bs = bdrv_new_open(filename, fmt, flags);
     if (!bs) {      if (!bs) {
         return 1;          return 1;
     }      }
Line 495  static int img_commit(int argc, char **a Line 531  static int img_commit(int argc, char **a
     return 0;      return 0;
 }  }
   
   /*
    * Checks whether the sector is not a zero sector.
    *
    * Attention! The len must be a multiple of 4 * sizeof(long) due to
    * restriction of optimizations in this function.
    */
 static int is_not_zero(const uint8_t *sector, int len)  static int is_not_zero(const uint8_t *sector, int len)
 {  {
       /*
        * Use long as the biggest available internal data type that fits into the
        * CPU register and unroll the loop to smooth out the effect of memory
        * latency.
        */
   
     int i;      int i;
     len >>= 2;      long d0, d1, d2, d3;
     for(i = 0;i < len; i++) {      const long * const data = (const long *) sector;
         if (((uint32_t *)sector)[i] != 0)  
       len /= sizeof(long);
   
       for(i = 0; i < len; i += 4) {
           d0 = data[i + 0];
           d1 = data[i + 1];
           d2 = data[i + 2];
           d3 = data[i + 3];
   
           if (d0 || d1 || d2 || d3) {
             return 1;              return 1;
           }
     }      }
   
     return 0;      return 0;
 }  }
   
Line 567  static int compare_sectors(const uint8_t Line 626  static int compare_sectors(const uint8_t
 static int img_convert(int argc, char **argv)  static int img_convert(int argc, char **argv)
 {  {
     int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;      int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;
     const char *fmt, *out_fmt, *out_baseimg, *out_filename;      int progress = 0, flags;
       const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename;
     BlockDriver *drv, *proto_drv;      BlockDriver *drv, *proto_drv;
     BlockDriverState **bs = NULL, *out_bs = NULL;      BlockDriverState **bs = NULL, *out_bs = NULL;
     int64_t total_sectors, nb_sectors, sector_num, bs_offset;      int64_t total_sectors, nb_sectors, sector_num, bs_offset;
Line 579  static int img_convert(int argc, char ** Line 639  static int img_convert(int argc, char **
     QEMUOptionParameter *out_baseimg_param;      QEMUOptionParameter *out_baseimg_param;
     char *options = NULL;      char *options = NULL;
     const char *snapshot_name = NULL;      const char *snapshot_name = NULL;
       float local_progress;
   
     fmt = NULL;      fmt = NULL;
     out_fmt = "raw";      out_fmt = "raw";
       cache = "unsafe";
     out_baseimg = NULL;      out_baseimg = NULL;
     compress = 0;      compress = 0;
     for(;;) {      for(;;) {
         c = getopt(argc, argv, "f:O:B:s:hce6o:");          c = getopt(argc, argv, "f:O:B:s:hce6o:pt:");
         if (c == -1) {          if (c == -1) {
             break;              break;
         }          }
Line 607  static int img_convert(int argc, char ** Line 669  static int img_convert(int argc, char **
             compress = 1;              compress = 1;
             break;              break;
         case 'e':          case 'e':
             error_report("qemu-img: option -e is deprecated, please use \'-o "              error_report("option -e is deprecated, please use \'-o "
                   "encryption\' instead!");                    "encryption\' instead!");
             return 1;              return 1;
         case '6':          case '6':
             error_report("qemu-img: option -6 is deprecated, please use \'-o "              error_report("option -6 is deprecated, please use \'-o "
                   "compat6\' instead!");                    "compat6\' instead!");
             return 1;              return 1;
         case 'o':          case 'o':
Line 620  static int img_convert(int argc, char ** Line 682  static int img_convert(int argc, char **
         case 's':          case 's':
             snapshot_name = optarg;              snapshot_name = optarg;
             break;              break;
           case 'p':
               progress = 1;
               break;
           case 't':
               cache = optarg;
               break;
         }          }
     }      }
   
Line 642  static int img_convert(int argc, char ** Line 710  static int img_convert(int argc, char **
         goto out;          goto out;
     }      }
                   
       qemu_progress_init(progress, 2.0);
       qemu_progress_print(0, 100);
   
     bs = qemu_mallocz(bs_n * sizeof(BlockDriverState *));      bs = qemu_mallocz(bs_n * sizeof(BlockDriverState *));
   
     total_sectors = 0;      total_sectors = 0;
Line 658  static int img_convert(int argc, char ** Line 729  static int img_convert(int argc, char **
   
     if (snapshot_name != NULL) {      if (snapshot_name != NULL) {
         if (bs_n > 1) {          if (bs_n > 1) {
             error_report("No support for concatenating multiple snapshot\n");              error_report("No support for concatenating multiple snapshot");
             ret = -1;              ret = -1;
             goto out;              goto out;
         }          }
         if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {          if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
             error_report("Failed to load snapshot\n");              error_report("Failed to load snapshot");
             ret = -1;              ret = -1;
             goto out;              goto out;
         }          }
Line 747  static int img_convert(int argc, char ** Line 818  static int img_convert(int argc, char **
         goto out;          goto out;
     }      }
   
     out_bs = bdrv_new_open(out_filename, out_fmt,      flags = BDRV_O_RDWR;
         BDRV_O_FLAGS | BDRV_O_RDWR | BDRV_O_NO_FLUSH);      ret = set_cache_flag(cache, &flags);
       if (ret < 0) {
           error_report("Invalid cache option: %s", cache);
           return -1;
       }
   
       out_bs = bdrv_new_open(out_filename, out_fmt, flags);
     if (!out_bs) {      if (!out_bs) {
         ret = -1;          ret = -1;
         goto out;          goto out;
Line 773  static int img_convert(int argc, char ** Line 850  static int img_convert(int argc, char **
         }          }
         cluster_sectors = cluster_size >> 9;          cluster_sectors = cluster_size >> 9;
         sector_num = 0;          sector_num = 0;
   
           nb_sectors = total_sectors;
           local_progress = (float)100 /
               (nb_sectors / MIN(nb_sectors, cluster_sectors));
   
         for(;;) {          for(;;) {
             int64_t bs_num;              int64_t bs_num;
             int remainder;              int remainder;
Line 832  static int img_convert(int argc, char ** Line 914  static int img_convert(int argc, char **
                 }                  }
             }              }
             sector_num += n;              sector_num += n;
               qemu_progress_print(local_progress, 100);
         }          }
         /* signal EOF to align */          /* signal EOF to align */
         bdrv_write_compressed(out_bs, 0, NULL, 0);          bdrv_write_compressed(out_bs, 0, NULL, 0);
Line 839  static int img_convert(int argc, char ** Line 922  static int img_convert(int argc, char **
         int has_zero_init = bdrv_has_zero_init(out_bs);          int has_zero_init = bdrv_has_zero_init(out_bs);
   
         sector_num = 0; // total number of sectors converted so far          sector_num = 0; // total number of sectors converted so far
           nb_sectors = total_sectors - sector_num;
           local_progress = (float)100 /
               (nb_sectors / MIN(nb_sectors, IO_BUF_SIZE / 512));
   
         for(;;) {          for(;;) {
             nb_sectors = total_sectors - sector_num;              nb_sectors = total_sectors - sector_num;
             if (nb_sectors <= 0) {              if (nb_sectors <= 0) {
Line 912  static int img_convert(int argc, char ** Line 999  static int img_convert(int argc, char **
                 n -= n1;                  n -= n1;
                 buf1 += n1 * 512;                  buf1 += n1 * 512;
             }              }
               qemu_progress_print(local_progress, 100);
         }          }
     }      }
 out:  out:
       qemu_progress_end();
     free_option_parameters(create_options);      free_option_parameters(create_options);
     free_option_parameters(param);      free_option_parameters(param);
     qemu_free(buf);      qemu_free(buf);
Line 935  out: Line 1024  out:
     return 0;      return 0;
 }  }
   
 #ifdef _WIN32  
 static int64_t get_allocated_file_size(const char *filename)  
 {  
     typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);  
     get_compressed_t get_compressed;  
     struct _stati64 st;  
   
     /* WinNT support GetCompressedFileSize to determine allocate size */  
     get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");  
     if (get_compressed) {  
         DWORD high, low;  
         low = get_compressed(filename, &high);  
         if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)  
             return (((int64_t) high) << 32) + low;  
     }  
   
     if (_stati64(filename, &st) < 0)  
         return -1;  
     return st.st_size;  
 }  
 #else  
 static int64_t get_allocated_file_size(const char *filename)  
 {  
     struct stat st;  
     if (stat(filename, &st) < 0)  
         return -1;  
     return (int64_t)st.st_blocks * 512;  
 }  
 #endif  
   
 static void dump_snapshots(BlockDriverState *bs)  static void dump_snapshots(BlockDriverState *bs)
 {  {
Line 1023  static int img_info(int argc, char **arg Line 1083  static int img_info(int argc, char **arg
     bdrv_get_format(bs, fmt_name, sizeof(fmt_name));      bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
     bdrv_get_geometry(bs, &total_sectors);      bdrv_get_geometry(bs, &total_sectors);
     get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);      get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
     allocated_size = get_allocated_file_size(filename);      allocated_size = bdrv_get_allocated_file_size(bs);
     if (allocated_size < 0) {      if (allocated_size < 0) {
         snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");          snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
     } else {      } else {
Line 1181  static int img_rebase(int argc, char **a Line 1241  static int img_rebase(int argc, char **a
     BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;      BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
     BlockDriver *old_backing_drv, *new_backing_drv;      BlockDriver *old_backing_drv, *new_backing_drv;
     char *filename;      char *filename;
     const char *fmt, *out_basefmt, *out_baseimg;      const char *fmt, *cache, *out_basefmt, *out_baseimg;
     int c, flags, ret;      int c, flags, ret;
     int unsafe = 0;      int unsafe = 0;
       int progress = 0;
   
     /* Parse commandline parameters */      /* Parse commandline parameters */
     fmt = NULL;      fmt = NULL;
       cache = BDRV_DEFAULT_CACHE;
     out_baseimg = NULL;      out_baseimg = NULL;
     out_basefmt = NULL;      out_basefmt = NULL;
   
     for(;;) {      for(;;) {
         c = getopt(argc, argv, "uhf:F:b:");          c = getopt(argc, argv, "uhf:F:b:pt:");
         if (c == -1) {          if (c == -1) {
             break;              break;
         }          }
Line 1212  static int img_rebase(int argc, char **a Line 1273  static int img_rebase(int argc, char **a
         case 'u':          case 'u':
             unsafe = 1;              unsafe = 1;
             break;              break;
           case 'p':
               progress = 1;
               break;
           case 't':
               cache = optarg;
               break;
         }          }
     }      }
   
     if ((optind >= argc) || !out_baseimg) {      if ((optind >= argc) || (!unsafe && !out_baseimg)) {
         help();          help();
     }      }
     filename = argv[optind++];      filename = argv[optind++];
   
       qemu_progress_init(progress, 2.0);
       qemu_progress_print(0, 100);
   
       flags = BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
       ret = set_cache_flag(cache, &flags);
       if (ret < 0) {
           error_report("Invalid cache option: %s", cache);
           return -1;
       }
   
     /*      /*
      * Open the images.       * Open the images.
      *       *
      * Ignore the old backing file for unsafe rebase in case we want to correct       * Ignore the old backing file for unsafe rebase in case we want to correct
      * the reference to a renamed or moved backing file.       * the reference to a renamed or moved backing file.
      */       */
     flags = BDRV_O_FLAGS | BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);  
     bs = bdrv_new_open(filename, fmt, flags);      bs = bdrv_new_open(filename, fmt, flags);
     if (!bs) {      if (!bs) {
         return 1;          return 1;
Line 1295  static int img_rebase(int argc, char **a Line 1371  static int img_rebase(int argc, char **a
         int n;          int n;
         uint8_t * buf_old;          uint8_t * buf_old;
         uint8_t * buf_new;          uint8_t * buf_new;
           float local_progress;
   
         buf_old = qemu_malloc(IO_BUF_SIZE);          buf_old = qemu_malloc(IO_BUF_SIZE);
         buf_new = qemu_malloc(IO_BUF_SIZE);          buf_new = qemu_malloc(IO_BUF_SIZE);
   
         bdrv_get_geometry(bs, &num_sectors);          bdrv_get_geometry(bs, &num_sectors);
   
           local_progress = (float)100 /
               (num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512));
         for (sector = 0; sector < num_sectors; sector += n) {          for (sector = 0; sector < num_sectors; sector += n) {
   
             /* How many sectors can we handle with the next read? */              /* How many sectors can we handle with the next read? */
Line 1348  static int img_rebase(int argc, char **a Line 1427  static int img_rebase(int argc, char **a
   
                 written += pnum;                  written += pnum;
             }              }
               qemu_progress_print(local_progress, 100);
         }          }
   
         qemu_free(buf_old);          qemu_free(buf_old);
Line 1368  static int img_rebase(int argc, char **a Line 1448  static int img_rebase(int argc, char **a
             out_baseimg, strerror(-ret));              out_baseimg, strerror(-ret));
     }      }
   
       qemu_progress_print(100, 0);
     /*      /*
      * TODO At this point it is possible to check if any clusters that are       * TODO At this point it is possible to check if any clusters that are
      * allocated in the COW file are the same in the backing file. If so, they       * allocated in the COW file are the same in the backing file. If so, they
Line 1375  static int img_rebase(int argc, char **a Line 1456  static int img_rebase(int argc, char **a
      * backing file, in case of a crash this would lead to corruption.       * backing file, in case of a crash this would lead to corruption.
      */       */
 out:  out:
       qemu_progress_end();
     /* Cleanup */      /* Cleanup */
     if (!unsafe) {      if (!unsafe) {
         bdrv_delete(bs_old_backing);          if (bs_old_backing != NULL) {
         bdrv_delete(bs_new_backing);              bdrv_delete(bs_old_backing);
           }
           if (bs_new_backing != NULL) {
               bdrv_delete(bs_new_backing);
           }
     }      }
   
     bdrv_delete(bs);      bdrv_delete(bs);
Line 1404  static int img_resize(int argc, char **a Line 1490  static int img_resize(int argc, char **a
         { NULL }          { NULL }
     };      };
   
       /* Remove size from argv manually so that negative numbers are not treated
        * as options by getopt. */
       if (argc < 3) {
           help();
           return 1;
       }
   
       size = argv[--argc];
   
       /* Parse getopt arguments */
     fmt = NULL;      fmt = NULL;
     for(;;) {      for(;;) {
         c = getopt(argc, argv, "f:h");          c = getopt(argc, argv, "f:h");
Line 1420  static int img_resize(int argc, char **a Line 1516  static int img_resize(int argc, char **a
             break;              break;
         }          }
     }      }
     if (optind + 1 >= argc) {      if (optind >= argc) {
         help();          help();
     }      }
     filename = argv[optind++];      filename = argv[optind++];
     size = argv[optind++];  
   
     /* Choose grow, shrink, or absolute resize mode */      /* Choose grow, shrink, or absolute resize mode */
     switch (size[0]) {      switch (size[0]) {

Removed from v.1.1.1.12  
changed lines
  Added in v.1.1.1.13


unix.superglobalmegacorp.com