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

version 1.1.1.11, 2018/04/24 18:24:09 version 1.1.1.12, 2018/04/24 18:34:02
Line 23 Line 23
  */   */
 #include "qemu-common.h"  #include "qemu-common.h"
 #include "qemu-option.h"  #include "qemu-option.h"
   #include "qemu-error.h"
 #include "osdep.h"  #include "osdep.h"
   #include "sysemu.h"
 #include "block_int.h"  #include "block_int.h"
 #include <stdio.h>  #include <stdio.h>
   
Line 39  typedef struct img_cmd_t { Line 41  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
   
 static void error(const char *fmt, ...)  
 {  
     va_list ap;  
     va_start(ap, fmt);  
     fprintf(stderr, "qemu-img: ");  
     vfprintf(stderr, fmt, ap);  
     fprintf(stderr, "\n");  
     va_end(ap);  
 }  
   
 static void format_print(void *opaque, const char *name)  static void format_print(void *opaque, const char *name)
 {  {
     printf(" %s", name);      printf(" %s", name);
Line 187  static int read_password(char *buf, int  Line 179  static int read_password(char *buf, int 
 }  }
 #endif  #endif
   
   static int print_block_option_help(const char *filename, const char *fmt)
   {
       BlockDriver *drv, *proto_drv;
       QEMUOptionParameter *create_options = NULL;
   
       /* Find driver and parse its options */
       drv = bdrv_find_format(fmt);
       if (!drv) {
           error_report("Unknown file format '%s'", fmt);
           return 1;
       }
   
       proto_drv = bdrv_find_protocol(filename);
       if (!proto_drv) {
           error_report("Unknown protocol '%s'", filename);
           return 1;
       }
   
       create_options = append_option_parameters(create_options,
                                                 drv->create_options);
       create_options = append_option_parameters(create_options,
                                                 proto_drv->create_options);
       print_option_help(create_options);
       free_option_parameters(create_options);
       return 0;
   }
   
 static BlockDriverState *bdrv_new_open(const char *filename,  static BlockDriverState *bdrv_new_open(const char *filename,
                                        const char *fmt,                                         const char *fmt,
                                        int flags)                                         int flags)
Line 194  static BlockDriverState *bdrv_new_open(c Line 213  static BlockDriverState *bdrv_new_open(c
     BlockDriverState *bs;      BlockDriverState *bs;
     BlockDriver *drv;      BlockDriver *drv;
     char password[256];      char password[256];
       int ret;
   
       bs = bdrv_new("image");
   
     bs = bdrv_new("");  
     if (!bs) {  
         error("Not enough memory");  
         goto fail;  
     }  
     if (fmt) {      if (fmt) {
         drv = bdrv_find_format(fmt);          drv = bdrv_find_format(fmt);
         if (!drv) {          if (!drv) {
             error("Unknown file format '%s'", fmt);              error_report("Unknown file format '%s'", fmt);
             goto fail;              goto fail;
         }          }
     } else {      } else {
         drv = NULL;          drv = NULL;
     }      }
     if (bdrv_open(bs, filename, flags, drv) < 0) {  
         error("Could not open '%s'", filename);      ret = bdrv_open(bs, filename, flags, drv);
       if (ret < 0) {
           error_report("Could not open '%s': %s", filename, strerror(-ret));
         goto fail;          goto fail;
     }      }
   
     if (bdrv_is_encrypted(bs)) {      if (bdrv_is_encrypted(bs)) {
         printf("Disk image '%s' is encrypted.\n", filename);          printf("Disk image '%s' is encrypted.\n", filename);
         if (read_password(password, sizeof(password)) < 0) {          if (read_password(password, sizeof(password)) < 0) {
             error("No password given");              error_report("No password given");
             goto fail;              goto fail;
         }          }
         if (bdrv_set_key(bs, password) < 0) {          if (bdrv_set_key(bs, password) < 0) {
             error("invalid password");              error_report("invalid password");
             goto fail;              goto fail;
         }          }
     }      }
Line 233  fail: Line 253  fail:
 }  }
   
 static int add_old_style_options(const char *fmt, QEMUOptionParameter *list,  static int add_old_style_options(const char *fmt, QEMUOptionParameter *list,
     int flags, const char *base_filename, const char *base_fmt)                                   const char *base_filename,
                                    const char *base_fmt)
 {  {
     if (flags & BLOCK_FLAG_ENCRYPT) {  
         if (set_option_parameter(list, BLOCK_OPT_ENCRYPT, "on")) {  
             error("Encryption not supported for file format '%s'", fmt);  
             return -1;  
         }  
     }  
     if (flags & BLOCK_FLAG_COMPAT6) {  
         if (set_option_parameter(list, BLOCK_OPT_COMPAT6, "on")) {  
             error("VMDK version 6 not supported for file format '%s'", fmt);  
             return -1;  
         }  
     }  
   
     if (base_filename) {      if (base_filename) {
         if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) {          if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) {
             error("Backing file not supported for file format '%s'", fmt);              error_report("Backing file not supported for file format '%s'",
                            fmt);
             return -1;              return -1;
         }          }
     }      }
     if (base_fmt) {      if (base_fmt) {
         if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {          if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {
             error("Backing file format not supported for file format '%s'", fmt);              error_report("Backing file format not supported for file "
                            "format '%s'", fmt);
             return -1;              return -1;
         }          }
     }      }
Line 265  static int add_old_style_options(const c Line 275  static int add_old_style_options(const c
   
 static int img_create(int argc, char **argv)  static int img_create(int argc, char **argv)
 {  {
     int c, ret = 0, flags;      int c, ret = 0;
       uint64_t img_size = -1;
     const char *fmt = "raw";      const char *fmt = "raw";
     const char *base_fmt = NULL;      const char *base_fmt = NULL;
     const char *filename;      const char *filename;
     const char *base_filename = NULL;      const char *base_filename = NULL;
     BlockDriver *drv, *proto_drv;  
     QEMUOptionParameter *param = NULL, *create_options = NULL;  
     char *options = NULL;      char *options = NULL;
   
     flags = 0;  
     for(;;) {      for(;;) {
         c = getopt(argc, argv, "F:b:f:he6o:");          c = getopt(argc, argv, "F:b:f:he6o:");
         if (c == -1)          if (c == -1) {
             break;              break;
           }
         switch(c) {          switch(c) {
           case '?':
         case 'h':          case 'h':
             help();              help();
             break;              break;
Line 293  static int img_create(int argc, char **a Line 303  static int img_create(int argc, char **a
             fmt = optarg;              fmt = optarg;
             break;              break;
         case 'e':          case 'e':
             flags |= BLOCK_FLAG_ENCRYPT;              error_report("qemu-img: option -e is deprecated, please use \'-o "
             break;                    "encryption\' instead!");
               return 1;
         case '6':          case '6':
             flags |= BLOCK_FLAG_COMPAT6;              error_report("qemu-img: option -6 is deprecated, please use \'-o "
             break;                    "compat6\' instead!");
               return 1;
         case 'o':          case 'o':
             options = optarg;              options = optarg;
             break;              break;
Line 305  static int img_create(int argc, char **a Line 317  static int img_create(int argc, char **a
     }      }
   
     /* Get the filename */      /* Get the filename */
     if (optind >= argc)      if (optind >= argc) {
         help();          help();
     filename = argv[optind++];  
   
     /* Find driver and parse its options */  
     drv = bdrv_find_format(fmt);  
     if (!drv) {  
         error("Unknown file format '%s'", fmt);  
         return 1;  
     }  
   
     proto_drv = bdrv_find_protocol(filename);  
     if (!proto_drv) {  
         error("Unknown protocol '%s'", filename);  
         return 1;  
     }      }
       filename = argv[optind++];
   
     create_options = append_option_parameters(create_options,      /* Get image size, if specified */
                                               drv->create_options);      if (optind < argc) {
     create_options = append_option_parameters(create_options,          int64_t sval;
                                               proto_drv->create_options);          sval = strtosz_suffix(argv[optind++], NULL, STRTOSZ_DEFSUFFIX_B);
           if (sval < 0) {
     if (options && !strcmp(options, "?")) {              error_report("Invalid image size specified! You may use k, M, G or "
         print_option_help(create_options);                    "T suffixes for ");
         goto out;              error_report("kilobytes, megabytes, gigabytes and terabytes.");
     }  
   
     /* Create parameter list with default values */  
     param = parse_option_parameters("", create_options, param);  
     set_option_parameter_int(param, BLOCK_OPT_SIZE, -1);  
   
     /* Parse -o options */  
     if (options) {  
         param = parse_option_parameters(options, create_options, param);  
         if (param == NULL) {  
             error("Invalid options for file format '%s'.", fmt);  
             ret = -1;              ret = -1;
             goto out;              goto out;
         }          }
           img_size = (uint64_t)sval;
     }      }
   
     /* Add size to parameters */      if (options && !strcmp(options, "?")) {
     if (optind < argc) {          ret = print_block_option_help(filename, fmt);
         set_option_parameter(param, BLOCK_OPT_SIZE, argv[optind++]);  
     }  
   
     /* Add old-style options to parameters */  
     ret = add_old_style_options(fmt, param, flags, base_filename, base_fmt);  
     if (ret < 0) {  
         goto out;          goto out;
     }      }
   
     // The size for the image must always be specified, with one exception:      ret = bdrv_img_create(filename, fmt, base_filename, base_fmt,
     // If we are using a backing file, we can obtain the size from there                            options, img_size, BDRV_O_FLAGS);
     if (get_option_parameter(param, BLOCK_OPT_SIZE)->value.n == -1) {  
   
         QEMUOptionParameter *backing_file =  
             get_option_parameter(param, BLOCK_OPT_BACKING_FILE);  
         QEMUOptionParameter *backing_fmt =  
             get_option_parameter(param, BLOCK_OPT_BACKING_FMT);  
   
         if (backing_file && backing_file->value.s) {  
             BlockDriverState *bs;  
             uint64_t size;  
             const char *fmt = NULL;  
             char buf[32];  
   
             if (backing_fmt && backing_fmt->value.s) {  
                  if (bdrv_find_format(backing_fmt->value.s)) {  
                      fmt = backing_fmt->value.s;  
                 } else {  
                      error("Unknown backing file format '%s'",  
                         backing_fmt->value.s);  
                      ret = -1;  
                      goto out;  
                 }  
             }  
   
             bs = bdrv_new_open(backing_file->value.s, fmt, BDRV_O_FLAGS);  
             if (!bs) {  
                 ret = -1;  
                 goto out;  
             }  
             bdrv_get_geometry(bs, &size);  
             size *= 512;  
             bdrv_delete(bs);  
   
             snprintf(buf, sizeof(buf), "%" PRId64, size);  
             set_option_parameter(param, BLOCK_OPT_SIZE, buf);  
         } else {  
             error("Image creation needs a size parameter");  
             ret = -1;  
             goto out;  
         }  
     }  
   
     printf("Formatting '%s', fmt=%s ", filename, fmt);  
     print_option_parameters(param);  
     puts("");  
   
     ret = bdrv_create(drv, filename, param);  
     free_option_parameters(create_options);  
     free_option_parameters(param);  
   
     if (ret < 0) {  
         if (ret == -ENOTSUP) {  
             error("Formatting or formatting option not supported for file format '%s'", fmt);  
         } else if (ret == -EFBIG) {  
             error("The image size is too large for file format '%s'", fmt);  
         } else {  
             error("%s: error while creating %s: %s", filename, fmt, strerror(-ret));  
         }  
     }  
 out:  out:
     if (ret) {      if (ret) {
         return 1;          return 1;
Line 443  static int img_check(int argc, char **ar Line 368  static int img_check(int argc, char **ar
     fmt = NULL;      fmt = NULL;
     for(;;) {      for(;;) {
         c = getopt(argc, argv, "f:h");          c = getopt(argc, argv, "f:h");
         if (c == -1)          if (c == -1) {
             break;              break;
           }
         switch(c) {          switch(c) {
           case '?':
         case 'h':          case 'h':
             help();              help();
             break;              break;
Line 454  static int img_check(int argc, char **ar Line 381  static int img_check(int argc, char **ar
             break;              break;
         }          }
     }      }
     if (optind >= argc)      if (optind >= argc) {
         help();          help();
       }
     filename = argv[optind++];      filename = argv[optind++];
   
     bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS);      bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS);
Line 465  static int img_check(int argc, char **ar Line 393  static int img_check(int argc, char **ar
     ret = bdrv_check(bs, &result);      ret = bdrv_check(bs, &result);
   
     if (ret == -ENOTSUP) {      if (ret == -ENOTSUP) {
         error("This image format does not support checks");          error_report("This image format does not support checks");
         bdrv_delete(bs);          bdrv_delete(bs);
         return 1;          return 1;
     }      }
Line 519  static int img_commit(int argc, char **a Line 447  static int img_commit(int argc, char **a
     fmt = NULL;      fmt = NULL;
     for(;;) {      for(;;) {
         c = getopt(argc, argv, "f:h");          c = getopt(argc, argv, "f:h");
         if (c == -1)          if (c == -1) {
             break;              break;
           }
         switch(c) {          switch(c) {
           case '?':
         case 'h':          case 'h':
             help();              help();
             break;              break;
Line 530  static int img_commit(int argc, char **a Line 460  static int img_commit(int argc, char **a
             break;              break;
         }          }
     }      }
     if (optind >= argc)      if (optind >= argc) {
         help();          help();
       }
     filename = argv[optind++];      filename = argv[optind++];
   
     bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);      bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
Line 544  static int img_commit(int argc, char **a Line 475  static int img_commit(int argc, char **a
         printf("Image committed.\n");          printf("Image committed.\n");
         break;          break;
     case -ENOENT:      case -ENOENT:
         error("No disk inserted");          error_report("No disk inserted");
         break;          break;
     case -EACCES:      case -EACCES:
         error("Image is read-only");          error_report("Image is read-only");
         break;          break;
     case -ENOTSUP:      case -ENOTSUP:
         error("Image is already committed");          error_report("Image is already committed");
         break;          break;
     default:      default:
         error("Error while committing image");          error_report("Error while committing image");
         break;          break;
     }      }
   
Line 635  static int compare_sectors(const uint8_t Line 566  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, flags, 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;      const char *fmt, *out_fmt, *out_baseimg, *out_filename;
     BlockDriver *drv, *proto_drv;      BlockDriver *drv, *proto_drv;
     BlockDriverState **bs = NULL, *out_bs = NULL;      BlockDriverState **bs = NULL, *out_bs = NULL;
Line 645  static int img_convert(int argc, char ** Line 576  static int img_convert(int argc, char **
     const uint8_t *buf1;      const uint8_t *buf1;
     BlockDriverInfo bdi;      BlockDriverInfo bdi;
     QEMUOptionParameter *param = NULL, *create_options = NULL;      QEMUOptionParameter *param = NULL, *create_options = NULL;
       QEMUOptionParameter *out_baseimg_param;
     char *options = NULL;      char *options = NULL;
       const char *snapshot_name = NULL;
   
     fmt = NULL;      fmt = NULL;
     out_fmt = "raw";      out_fmt = "raw";
     out_baseimg = NULL;      out_baseimg = NULL;
     flags = 0;      compress = 0;
     for(;;) {      for(;;) {
         c = getopt(argc, argv, "f:O:B:hce6o:");          c = getopt(argc, argv, "f:O:B:s:hce6o:");
         if (c == -1)          if (c == -1) {
             break;              break;
           }
         switch(c) {          switch(c) {
           case '?':
         case 'h':          case 'h':
             help();              help();
             break;              break;
Line 669  static int img_convert(int argc, char ** Line 604  static int img_convert(int argc, char **
             out_baseimg = optarg;              out_baseimg = optarg;
             break;              break;
         case 'c':          case 'c':
             flags |= BLOCK_FLAG_COMPRESS;              compress = 1;
             break;              break;
         case 'e':          case 'e':
             flags |= BLOCK_FLAG_ENCRYPT;              error_report("qemu-img: option -e is deprecated, please use \'-o "
             break;                    "encryption\' instead!");
               return 1;
         case '6':          case '6':
             flags |= BLOCK_FLAG_COMPAT6;              error_report("qemu-img: option -6 is deprecated, please use \'-o "
             break;                    "compat6\' instead!");
               return 1;
         case 'o':          case 'o':
             options = optarg;              options = optarg;
             break;              break;
           case 's':
               snapshot_name = optarg;
               break;
         }          }
     }      }
   
     bs_n = argc - optind - 1;      bs_n = argc - optind - 1;
     if (bs_n < 1) help();      if (bs_n < 1) {
           help();
       }
   
     out_filename = argv[argc - 1];      out_filename = argv[argc - 1];
   
       if (options && !strcmp(options, "?")) {
           ret = print_block_option_help(out_filename, out_fmt);
           goto out;
       }
   
     if (bs_n > 1 && out_baseimg) {      if (bs_n > 1 && out_baseimg) {
         error("-B makes no sense when concatenating multiple input images");          error_report("-B makes no sense when concatenating multiple input "
         return 1;                       "images");
           ret = -1;
           goto out;
     }      }
                   
     bs = calloc(bs_n, sizeof(BlockDriverState *));      bs = qemu_mallocz(bs_n * sizeof(BlockDriverState *));
     if (!bs) {  
         error("Out of memory");  
         return 1;  
     }  
   
     total_sectors = 0;      total_sectors = 0;
     for (bs_i = 0; bs_i < bs_n; bs_i++) {      for (bs_i = 0; bs_i < bs_n; bs_i++) {
         bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS);          bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS);
         if (!bs[bs_i]) {          if (!bs[bs_i]) {
             error("Could not open '%s'", argv[optind + bs_i]);              error_report("Could not open '%s'", argv[optind + bs_i]);
             ret = -1;              ret = -1;
             goto out;              goto out;
         }          }
Line 711  static int img_convert(int argc, char ** Line 656  static int img_convert(int argc, char **
         total_sectors += bs_sectors;          total_sectors += bs_sectors;
     }      }
   
       if (snapshot_name != NULL) {
           if (bs_n > 1) {
               error_report("No support for concatenating multiple snapshot\n");
               ret = -1;
               goto out;
           }
           if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
               error_report("Failed to load snapshot\n");
               ret = -1;
               goto out;
           }
       }
   
     /* Find driver and parse its options */      /* Find driver and parse its options */
     drv = bdrv_find_format(out_fmt);      drv = bdrv_find_format(out_fmt);
     if (!drv) {      if (!drv) {
         error("Unknown file format '%s'", out_fmt);          error_report("Unknown file format '%s'", out_fmt);
         ret = -1;          ret = -1;
         goto out;          goto out;
     }      }
   
     proto_drv = bdrv_find_protocol(out_filename);      proto_drv = bdrv_find_protocol(out_filename);
     if (!proto_drv) {      if (!proto_drv) {
         error("Unknown protocol '%s'", out_filename);          error_report("Unknown protocol '%s'", out_filename);
         ret = -1;          ret = -1;
         goto out;          goto out;
     }      }
Line 730  static int img_convert(int argc, char ** Line 688  static int img_convert(int argc, char **
                                               drv->create_options);                                                drv->create_options);
     create_options = append_option_parameters(create_options,      create_options = append_option_parameters(create_options,
                                               proto_drv->create_options);                                                proto_drv->create_options);
     if (options && !strcmp(options, "?")) {  
         print_option_help(create_options);  
         goto out;  
     }  
   
     if (options) {      if (options) {
         param = parse_option_parameters(options, create_options, param);          param = parse_option_parameters(options, create_options, param);
         if (param == NULL) {          if (param == NULL) {
             error("Invalid options for file format '%s'.", out_fmt);              error_report("Invalid options for file format '%s'.", out_fmt);
             ret = -1;              ret = -1;
             goto out;              goto out;
         }          }
Line 747  static int img_convert(int argc, char ** Line 701  static int img_convert(int argc, char **
     }      }
   
     set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);      set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
     ret = add_old_style_options(out_fmt, param, flags, out_baseimg, NULL);      ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);
     if (ret < 0) {      if (ret < 0) {
         goto out;          goto out;
     }      }
   
       /* Get backing file name if -o backing_file was used */
       out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
       if (out_baseimg_param) {
           out_baseimg = out_baseimg_param->value.s;
       }
   
     /* Check if compression is supported */      /* Check if compression is supported */
     if (flags & BLOCK_FLAG_COMPRESS) {      if (compress) {
         QEMUOptionParameter *encryption =          QEMUOptionParameter *encryption =
             get_option_parameter(param, BLOCK_OPT_ENCRYPT);              get_option_parameter(param, BLOCK_OPT_ENCRYPT);
   
         if (!drv->bdrv_write_compressed) {          if (!drv->bdrv_write_compressed) {
             error("Compression not supported for this file format");              error_report("Compression not supported for this file format");
             ret = -1;              ret = -1;
             goto out;              goto out;
         }          }
   
         if (encryption && encryption->value.n) {          if (encryption && encryption->value.n) {
             error("Compression and encryption not supported at the same time");              error_report("Compression and encryption not supported at "
                            "the same time");
             ret = -1;              ret = -1;
             goto out;              goto out;
         }          }
Line 774  static int img_convert(int argc, char ** Line 735  static int img_convert(int argc, char **
     ret = bdrv_create(drv, out_filename, param);      ret = bdrv_create(drv, out_filename, param);
     if (ret < 0) {      if (ret < 0) {
         if (ret == -ENOTSUP) {          if (ret == -ENOTSUP) {
             error("Formatting not supported for file format '%s'", out_fmt);              error_report("Formatting not supported for file format '%s'",
                            out_fmt);
         } else if (ret == -EFBIG) {          } else if (ret == -EFBIG) {
             error("The image size is too large for file format '%s'", out_fmt);              error_report("The image size is too large for file format '%s'",
                            out_fmt);
         } else {          } else {
             error("%s: error while converting %s: %s", out_filename, out_fmt, strerror(-ret));              error_report("%s: error while converting %s: %s",
                            out_filename, out_fmt, strerror(-ret));
         }          }
         goto out;          goto out;
     }      }
Line 795  static int img_convert(int argc, char ** Line 759  static int img_convert(int argc, char **
     bdrv_get_geometry(bs[0], &bs_sectors);      bdrv_get_geometry(bs[0], &bs_sectors);
     buf = qemu_malloc(IO_BUF_SIZE);      buf = qemu_malloc(IO_BUF_SIZE);
   
     if (flags & BLOCK_FLAG_COMPRESS) {      if (compress) {
         ret = bdrv_get_info(out_bs, &bdi);          ret = bdrv_get_info(out_bs, &bdi);
         if (ret < 0) {          if (ret < 0) {
             error("could not get block driver info");              error_report("could not get block driver info");
             goto out;              goto out;
         }          }
         cluster_size = bdi.cluster_size;          cluster_size = bdi.cluster_size;
         if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {          if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
             error("invalid cluster size");              error_report("invalid cluster size");
             ret = -1;              ret = -1;
             goto out;              goto out;
         }          }
Line 844  static int img_convert(int argc, char ** Line 808  static int img_convert(int argc, char **
   
                 ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);                  ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
                 if (ret < 0) {                  if (ret < 0) {
                     error("error while reading");                      error_report("error while reading");
                     goto out;                      goto out;
                 }                  }
   
Line 855  static int img_convert(int argc, char ** Line 819  static int img_convert(int argc, char **
             }              }
             assert (remainder == 0);              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)) {
                 ret = bdrv_write_compressed(out_bs, sector_num, buf,                  ret = bdrv_write_compressed(out_bs, sector_num, buf,
                                             cluster_sectors);                                              cluster_sectors);
                 if (ret != 0) {                  if (ret != 0) {
                     error("error while compressing sector %" PRId64,                      error_report("error while compressing sector %" PRId64,
                           sector_num);                            sector_num);
                     goto out;                      goto out;
                 }                  }
Line 876  static int img_convert(int argc, char ** Line 841  static int img_convert(int argc, char **
         sector_num = 0; // total number of sectors converted so far          sector_num = 0; // total number of sectors converted so far
         for(;;) {          for(;;) {
             nb_sectors = total_sectors - sector_num;              nb_sectors = total_sectors - sector_num;
             if (nb_sectors <= 0)              if (nb_sectors <= 0) {
                 break;                  break;
             if (nb_sectors >= (IO_BUF_SIZE / 512))              }
               if (nb_sectors >= (IO_BUF_SIZE / 512)) {
                 n = (IO_BUF_SIZE / 512);                  n = (IO_BUF_SIZE / 512);
             else              } else {
                 n = nb_sectors;                  n = nb_sectors;
               }
   
             while (sector_num - bs_offset >= bs_sectors) {              while (sector_num - bs_offset >= bs_sectors) {
                 bs_i ++;                  bs_i ++;
Line 893  static int img_convert(int argc, char ** Line 860  static int img_convert(int argc, char **
                    sector_num, bs_i, bs_offset, bs_sectors); */                     sector_num, bs_i, bs_offset, bs_sectors); */
             }              }
   
             if (n > bs_offset + bs_sectors - sector_num)              if (n > bs_offset + bs_sectors - sector_num) {
                 n = bs_offset + bs_sectors - sector_num;                  n = bs_offset + bs_sectors - sector_num;
               }
   
             if (has_zero_init) {              if (has_zero_init) {
                 /* If the output image is being created as a copy on write image,                  /* If the output image is being created as a copy on write image,
Line 917  static int img_convert(int argc, char ** Line 885  static int img_convert(int argc, char **
   
             ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);              ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
             if (ret < 0) {              if (ret < 0) {
                 error("error while reading");                  error_report("error while reading");
                 goto out;                  goto out;
             }              }
             /* NOTE: at the same time we convert, we do not write zero              /* NOTE: at the same time we convert, we do not write zero
Line 936  static int img_convert(int argc, char ** Line 904  static int img_convert(int argc, char **
                     is_allocated_sectors(buf1, n, &n1)) {                      is_allocated_sectors(buf1, n, &n1)) {
                     ret = bdrv_write(out_bs, sector_num, buf1, n1);                      ret = bdrv_write(out_bs, sector_num, buf1, n1);
                     if (ret < 0) {                      if (ret < 0) {
                         error("error while writing");                          error_report("error while writing");
                         goto out;                          goto out;
                     }                      }
                 }                  }
Line 953  out: Line 921  out:
     if (out_bs) {      if (out_bs) {
         bdrv_delete(out_bs);          bdrv_delete(out_bs);
     }      }
     for (bs_i = 0; bs_i < bs_n; bs_i++) {      if (bs) {
         if (bs[bs_i]) {          for (bs_i = 0; bs_i < bs_n; bs_i++) {
             bdrv_delete(bs[bs_i]);              if (bs[bs_i]) {
                   bdrv_delete(bs[bs_i]);
               }
         }          }
           qemu_free(bs);
     }      }
     free(bs);  
     if (ret) {      if (ret) {
         return 1;          return 1;
     }      }
Line 1028  static int img_info(int argc, char **arg Line 998  static int img_info(int argc, char **arg
     fmt = NULL;      fmt = NULL;
     for(;;) {      for(;;) {
         c = getopt(argc, argv, "f:h");          c = getopt(argc, argv, "f:h");
         if (c == -1)          if (c == -1) {
             break;              break;
           }
         switch(c) {          switch(c) {
           case '?':
         case 'h':          case 'h':
             help();              help();
             break;              break;
Line 1039  static int img_info(int argc, char **arg Line 1011  static int img_info(int argc, char **arg
             break;              break;
         }          }
     }      }
     if (optind >= argc)      if (optind >= argc) {
         help();          help();
       }
     filename = argv[optind++];      filename = argv[optind++];
   
     bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING);      bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING);
Line 1051  static int img_info(int argc, char **arg Line 1024  static int img_info(int argc, char **arg
     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 = get_allocated_file_size(filename);
     if (allocated_size < 0)      if (allocated_size < 0) {
         snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");          snprintf(dsize_buf, sizeof(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"
Line 1063  static int img_info(int argc, char **arg Line 1037  static int img_info(int argc, char **arg
            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') {
Line 1096  static int img_snapshot(int argc, char * Line 1072  static int img_snapshot(int argc, char *
     int action = 0;      int action = 0;
     qemu_timeval tv;      qemu_timeval tv;
   
     bdrv_oflags = BDRV_O_RDWR;      bdrv_oflags = BDRV_O_FLAGS | BDRV_O_RDWR;
     /* Parse commandline parameters */      /* Parse commandline parameters */
     for(;;) {      for(;;) {
         c = getopt(argc, argv, "la:c:d:h");          c = getopt(argc, argv, "la:c:d:h");
         if (c == -1)          if (c == -1) {
             break;              break;
           }
         switch(c) {          switch(c) {
           case '?':
         case 'h':          case 'h':
             help();              help();
             return 0;              return 0;
Line 1141  static int img_snapshot(int argc, char * Line 1119  static int img_snapshot(int argc, char *
         }          }
     }      }
   
     if (optind >= argc)      if (optind >= argc) {
         help();          help();
       }
     filename = argv[optind++];      filename = argv[optind++];
   
     /* Open the image */      /* Open the image */
Line 1166  static int img_snapshot(int argc, char * Line 1145  static int img_snapshot(int argc, char *
         sn.date_nsec = tv.tv_usec * 1000;          sn.date_nsec = tv.tv_usec * 1000;
   
         ret = bdrv_snapshot_create(bs, &sn);          ret = bdrv_snapshot_create(bs, &sn);
         if (ret)          if (ret) {
             error("Could not create snapshot '%s': %d (%s)",              error_report("Could not create snapshot '%s': %d (%s)",
                 snapshot_name, ret, strerror(-ret));                  snapshot_name, ret, strerror(-ret));
           }
         break;          break;
   
     case SNAPSHOT_APPLY:      case SNAPSHOT_APPLY:
         ret = bdrv_snapshot_goto(bs, snapshot_name);          ret = bdrv_snapshot_goto(bs, snapshot_name);
         if (ret)          if (ret) {
             error("Could not apply snapshot '%s': %d (%s)",              error_report("Could not apply snapshot '%s': %d (%s)",
                 snapshot_name, ret, strerror(-ret));                  snapshot_name, ret, strerror(-ret));
           }
         break;          break;
   
     case SNAPSHOT_DELETE:      case SNAPSHOT_DELETE:
         ret = bdrv_snapshot_delete(bs, snapshot_name);          ret = bdrv_snapshot_delete(bs, snapshot_name);
         if (ret)          if (ret) {
             error("Could not delete snapshot '%s': %d (%s)",              error_report("Could not delete snapshot '%s': %d (%s)",
                 snapshot_name, ret, strerror(-ret));                  snapshot_name, ret, strerror(-ret));
           }
         break;          break;
     }      }
   
Line 1210  static int img_rebase(int argc, char **a Line 1192  static int img_rebase(int argc, char **a
   
     for(;;) {      for(;;) {
         c = getopt(argc, argv, "uhf:F:b:");          c = getopt(argc, argv, "uhf:F:b:");
         if (c == -1)          if (c == -1) {
             break;              break;
           }
         switch(c) {          switch(c) {
           case '?':
         case 'h':          case 'h':
             help();              help();
             return 0;              return 0;
Line 1231  static int img_rebase(int argc, char **a Line 1215  static int img_rebase(int argc, char **a
         }          }
     }      }
   
     if ((optind >= argc) || !out_baseimg)      if ((optind >= argc) || !out_baseimg) {
         help();          help();
       }
     filename = argv[optind++];      filename = argv[optind++];
   
     /*      /*
Line 1254  static int img_rebase(int argc, char **a Line 1239  static int img_rebase(int argc, char **a
     if (!unsafe && bs->backing_format[0] != '\0') {      if (!unsafe && bs->backing_format[0] != '\0') {
         old_backing_drv = bdrv_find_format(bs->backing_format);          old_backing_drv = bdrv_find_format(bs->backing_format);
         if (old_backing_drv == NULL) {          if (old_backing_drv == NULL) {
             error("Invalid format name: '%s'", bs->backing_format);              error_report("Invalid format name: '%s'", bs->backing_format);
             ret = -1;              ret = -1;
             goto out;              goto out;
         }          }
Line 1263  static int img_rebase(int argc, char **a Line 1248  static int img_rebase(int argc, char **a
     if (out_basefmt != NULL) {      if (out_basefmt != NULL) {
         new_backing_drv = bdrv_find_format(out_basefmt);          new_backing_drv = bdrv_find_format(out_basefmt);
         if (new_backing_drv == NULL) {          if (new_backing_drv == NULL) {
             error("Invalid format name: '%s'", out_basefmt);              error_report("Invalid format name: '%s'", out_basefmt);
             ret = -1;              ret = -1;
             goto out;              goto out;
         }          }
Line 1282  static int img_rebase(int argc, char **a Line 1267  static int img_rebase(int argc, char **a
         ret = bdrv_open(bs_old_backing, backing_name, BDRV_O_FLAGS,          ret = bdrv_open(bs_old_backing, backing_name, BDRV_O_FLAGS,
                         old_backing_drv);                          old_backing_drv);
         if (ret) {          if (ret) {
             error("Could not open old backing file '%s'", backing_name);              error_report("Could not open old backing file '%s'", backing_name);
             goto out;              goto out;
         }          }
   
Line 1290  static int img_rebase(int argc, char **a Line 1275  static int img_rebase(int argc, char **a
         ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS,          ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS,
                         new_backing_drv);                          new_backing_drv);
         if (ret) {          if (ret) {
             error("Could not open new backing file '%s'", out_baseimg);              error_report("Could not open new backing file '%s'", out_baseimg);
             goto out;              goto out;
         }          }
     }      }
Line 1334  static int img_rebase(int argc, char **a Line 1319  static int img_rebase(int argc, char **a
             /* Read old and new backing file */              /* Read old and new backing file */
             ret = bdrv_read(bs_old_backing, sector, buf_old, n);              ret = bdrv_read(bs_old_backing, sector, buf_old, n);
             if (ret < 0) {              if (ret < 0) {
                 error("error while reading from old backing file");                  error_report("error while reading from old backing file");
                 goto out;                  goto out;
             }              }
             ret = bdrv_read(bs_new_backing, sector, buf_new, n);              ret = bdrv_read(bs_new_backing, sector, buf_new, n);
             if (ret < 0) {              if (ret < 0) {
                 error("error while reading from new backing file");                  error_report("error while reading from new backing file");
                 goto out;                  goto out;
             }              }
   
Line 1355  static int img_rebase(int argc, char **a Line 1340  static int img_rebase(int argc, char **a
                     ret = bdrv_write(bs, sector + written,                      ret = bdrv_write(bs, sector + written,
                         buf_old + written * 512, pnum);                          buf_old + written * 512, pnum);
                     if (ret < 0) {                      if (ret < 0) {
                         error("Error while writing to COW image: %s",                          error_report("Error while writing to COW image: %s",
                             strerror(-ret));                              strerror(-ret));
                         goto out;                          goto out;
                     }                      }
Line 1376  static int img_rebase(int argc, char **a Line 1361  static int img_rebase(int argc, char **a
      */       */
     ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);      ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
     if (ret == -ENOSPC) {      if (ret == -ENOSPC) {
         error("Could not change the backing file to '%s': No space left in "          error_report("Could not change the backing file to '%s': No "
             "the file header", out_baseimg);                       "space left in the file header", out_baseimg);
     } else if (ret < 0) {      } else if (ret < 0) {
         error("Could not change the backing file to '%s': %s",          error_report("Could not change the backing file to '%s': %s",
             out_baseimg, strerror(-ret));              out_baseimg, strerror(-ret));
     }      }
   
Line 1408  static int img_resize(int argc, char **a Line 1393  static int img_resize(int argc, char **a
     int c, ret, relative;      int c, ret, relative;
     const char *filename, *fmt, *size;      const char *filename, *fmt, *size;
     int64_t n, total_size;      int64_t n, total_size;
     BlockDriverState *bs;      BlockDriverState *bs = NULL;
     QEMUOptionParameter *param;      QEMUOptionParameter *param;
     QEMUOptionParameter resize_options[] = {      QEMUOptionParameter resize_options[] = {
         {          {
Line 1426  static int img_resize(int argc, char **a Line 1411  static int img_resize(int argc, char **a
             break;              break;
         }          }
         switch(c) {          switch(c) {
           case '?':
         case 'h':          case 'h':
             help();              help();
             break;              break;
Line 1459  static int img_resize(int argc, char **a Line 1445  static int img_resize(int argc, char **a
     param = parse_option_parameters("", resize_options, NULL);      param = parse_option_parameters("", resize_options, NULL);
     if (set_option_parameter(param, BLOCK_OPT_SIZE, size)) {      if (set_option_parameter(param, BLOCK_OPT_SIZE, size)) {
         /* Error message already printed when size parsing fails */          /* Error message already printed when size parsing fails */
         exit(1);          ret = -1;
           goto out;
     }      }
     n = get_option_parameter(param, BLOCK_OPT_SIZE)->value.n;      n = get_option_parameter(param, BLOCK_OPT_SIZE)->value.n;
     free_option_parameters(param);      free_option_parameters(param);
   
     bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);      bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
     if (!bs) {      if (!bs) {
         return 1;          ret = -1;
           goto out;
     }      }
   
     if (relative) {      if (relative) {
Line 1475  static int img_resize(int argc, char **a Line 1463  static int img_resize(int argc, char **a
         total_size = n;          total_size = n;
     }      }
     if (total_size <= 0) {      if (total_size <= 0) {
         error("New image size must be positive");          error_report("New image size must be positive");
         ret = -1;          ret = -1;
         goto out;          goto out;
     }      }
Line 1486  static int img_resize(int argc, char **a Line 1474  static int img_resize(int argc, char **a
         printf("Image resized.\n");          printf("Image resized.\n");
         break;          break;
     case -ENOTSUP:      case -ENOTSUP:
         error("This image format does not support resize");          error_report("This image format does not support resize");
         break;          break;
     case -EACCES:      case -EACCES:
         error("Image is read-only");          error_report("Image is read-only");
         break;          break;
     default:      default:
         error("Error resizing image (%d)", -ret);          error_report("Error resizing image (%d)", -ret);
         break;          break;
     }      }
 out:  out:
     bdrv_delete(bs);      if (bs) {
           bdrv_delete(bs);
       }
     if (ret) {      if (ret) {
         return 1;          return 1;
     }      }
Line 1517  int main(int argc, char **argv) Line 1507  int main(int argc, char **argv)
     const img_cmd_t *cmd;      const img_cmd_t *cmd;
     const char *cmdname;      const char *cmdname;
   
       error_set_progname(argv[0]);
   
     bdrv_init();      bdrv_init();
     if (argc < 2)      if (argc < 2)
         help();          help();

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


unix.superglobalmegacorp.com