Diff for /qemu/qemu-io.c between versions 1.1.1.6 and 1.1.1.7

version 1.1.1.6, 2018/04/24 19:17:56 version 1.1.1.7, 2018/04/24 19:35:19
Line 15 Line 15
 #include <libgen.h>  #include <libgen.h>
   
 #include "qemu-common.h"  #include "qemu-common.h"
   #include "main-loop.h"
 #include "block_int.h"  #include "block_int.h"
 #include "cmd.h"  #include "cmd.h"
   #include "trace/control.h"
   
 #define VERSION "0.0.1"  #define VERSION "0.0.1"
   
Line 130  static void print_report(const char *op, Line 132  static void print_report(const char *op,
 static void *  static void *
 create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern)  create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern)
 {  {
     size_t *sizes = calloc(nr_iov, sizeof(size_t));      size_t *sizes = g_new0(size_t, nr_iov);
     size_t count = 0;      size_t count = 0;
     void *buf = NULL;      void *buf = NULL;
     void *p;      void *p;
Line 172  create_iovec(QEMUIOVector *qiov, char ** Line 174  create_iovec(QEMUIOVector *qiov, char **
     }      }
   
 fail:  fail:
     free(sizes);      g_free(sizes);
     return buf;      return buf;
 }  }
   
Line 218  static int do_pwrite(char *buf, int64_t  Line 220  static int do_pwrite(char *buf, int64_t 
     return 1;      return 1;
 }  }
   
   typedef struct {
       int64_t offset;
       int count;
       int *total;
       int ret;
       bool done;
   } CoWriteZeroes;
   
   static void coroutine_fn co_write_zeroes_entry(void *opaque)
   {
       CoWriteZeroes *data = opaque;
   
       data->ret = bdrv_co_write_zeroes(bs, data->offset / BDRV_SECTOR_SIZE,
                                        data->count / BDRV_SECTOR_SIZE);
       data->done = true;
       if (data->ret < 0) {
           *data->total = data->ret;
           return;
       }
   
       *data->total = data->count;
   }
   
   static int do_co_write_zeroes(int64_t offset, int count, int *total)
   {
       Coroutine *co;
       CoWriteZeroes data = {
           .offset = offset,
           .count  = count,
           .total  = total,
           .done   = false,
       };
   
       co = qemu_coroutine_create(co_write_zeroes_entry);
       qemu_coroutine_enter(co, &data);
       while (!data.done) {
           qemu_aio_wait();
       }
       if (data.ret < 0) {
           return data.ret;
       } else {
           return 1;
       }
   }
   
 static int do_load_vmstate(char *buf, int64_t offset, int count, int *total)  static int do_load_vmstate(char *buf, int64_t offset, int count, int *total)
 {  {
     *total = bdrv_load_vmstate(bs, (uint8_t *)buf, offset, count);      *total = bdrv_load_vmstate(bs, (uint8_t *)buf, offset, count);
Line 244  static void aio_rw_done(void *opaque, in Line 291  static void aio_rw_done(void *opaque, in
   
 static int do_aio_readv(QEMUIOVector *qiov, int64_t offset, int *total)  static int do_aio_readv(QEMUIOVector *qiov, int64_t offset, int *total)
 {  {
     BlockDriverAIOCB *acb;  
     int async_ret = NOT_DONE;      int async_ret = NOT_DONE;
   
     acb = bdrv_aio_readv(bs, offset >> 9, qiov, qiov->size >> 9,      bdrv_aio_readv(bs, offset >> 9, qiov, qiov->size >> 9,
                          aio_rw_done, &async_ret);                     aio_rw_done, &async_ret);
     if (!acb) {  
         return -EIO;  
     }  
     while (async_ret == NOT_DONE) {      while (async_ret == NOT_DONE) {
         qemu_aio_wait();          main_loop_wait(false);
     }      }
   
     *total = qiov->size;      *total = qiov->size;
Line 262  static int do_aio_readv(QEMUIOVector *qi Line 305  static int do_aio_readv(QEMUIOVector *qi
   
 static int do_aio_writev(QEMUIOVector *qiov, int64_t offset, int *total)  static int do_aio_writev(QEMUIOVector *qiov, int64_t offset, int *total)
 {  {
     BlockDriverAIOCB *acb;  
     int async_ret = NOT_DONE;      int async_ret = NOT_DONE;
   
     acb = bdrv_aio_writev(bs, offset >> 9, qiov, qiov->size >> 9,      bdrv_aio_writev(bs, offset >> 9, qiov, qiov->size >> 9,
                           aio_rw_done, &async_ret);                      aio_rw_done, &async_ret);
     if (!acb) {  
         return -EIO;  
     }  
   
     while (async_ret == NOT_DONE) {      while (async_ret == NOT_DONE) {
         qemu_aio_wait();          main_loop_wait(false);
     }      }
   
     *total = qiov->size;      *total = qiov->size;
Line 315  static int do_aio_multiwrite(BlockReques Line 353  static int do_aio_multiwrite(BlockReques
     }      }
   
     while (async_ret.num_done < num_reqs) {      while (async_ret.num_done < num_reqs) {
         qemu_aio_wait();          main_loop_wait(false);
     }      }
   
     return async_ret.error < 0 ? async_ret.error : 1;      return async_ret.error < 0 ? async_ret.error : 1;
Line 445  static int read_f(int argc, char **argv) Line 483  static int read_f(int argc, char **argv)
     }      }
   
     if ((pattern_count < 0) || (pattern_count + pattern_offset > count))  {      if ((pattern_count < 0) || (pattern_count + pattern_offset > count))  {
         printf("pattern verfication range exceeds end of read data\n");          printf("pattern verification range exceeds end of read data\n");
         return 0;          return 0;
     }      }
   
Line 480  static int read_f(int argc, char **argv) Line 518  static int read_f(int argc, char **argv)
     }      }
   
     if (Pflag) {      if (Pflag) {
         void *cmp_buf = malloc(pattern_count);          void *cmp_buf = g_malloc(pattern_count);
         memset(cmp_buf, pattern, pattern_count);          memset(cmp_buf, pattern, pattern_count);
         if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) {          if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) {
             printf("Pattern verification failed at offset %"              printf("Pattern verification failed at offset %"
                    PRId64 ", %d bytes\n",                     PRId64 ", %d bytes\n",
                    offset + pattern_offset, pattern_count);                     offset + pattern_offset, pattern_count);
         }          }
         free(cmp_buf);          g_free(cmp_buf);
     }      }
   
     if (qflag) {      if (qflag) {
Line 610  static int readv_f(int argc, char **argv Line 648  static int readv_f(int argc, char **argv
     }      }
   
     if (Pflag) {      if (Pflag) {
         void *cmp_buf = malloc(qiov.size);          void *cmp_buf = g_malloc(qiov.size);
         memset(cmp_buf, pattern, qiov.size);          memset(cmp_buf, pattern, qiov.size);
         if (memcmp(buf, cmp_buf, qiov.size)) {          if (memcmp(buf, cmp_buf, qiov.size)) {
             printf("Pattern verification failed at offset %"              printf("Pattern verification failed at offset %"
                    PRId64 ", %zd bytes\n", offset, qiov.size);                     PRId64 ", %zd bytes\n", offset, qiov.size);
         }          }
         free(cmp_buf);          g_free(cmp_buf);
     }      }
   
     if (qflag) {      if (qflag) {
Line 652  static void write_help(void) Line 690  static void write_help(void)
 " -P, -- use different pattern to fill file\n"  " -P, -- use different pattern to fill file\n"
 " -C, -- report statistics in a machine parsable format\n"  " -C, -- report statistics in a machine parsable format\n"
 " -q, -- quiet mode, do not show I/O statistics\n"  " -q, -- quiet mode, do not show I/O statistics\n"
   " -z, -- write zeroes using bdrv_co_write_zeroes\n"
 "\n");  "\n");
 }  }
   
Line 663  static const cmdinfo_t write_cmd = { Line 702  static const cmdinfo_t write_cmd = {
     .cfunc      = write_f,      .cfunc      = write_f,
     .argmin     = 2,      .argmin     = 2,
     .argmax     = -1,      .argmax     = -1,
     .args       = "[-abCpq] [-P pattern ] off len",      .args       = "[-bCpqz] [-P pattern ] off len",
     .oneline    = "writes a number of bytes at a specified offset",      .oneline    = "writes a number of bytes at a specified offset",
     .help       = write_help,      .help       = write_help,
 };  };
Line 671  static const cmdinfo_t write_cmd = { Line 710  static const cmdinfo_t write_cmd = {
 static int write_f(int argc, char **argv)  static int write_f(int argc, char **argv)
 {  {
     struct timeval t1, t2;      struct timeval t1, t2;
     int Cflag = 0, pflag = 0, qflag = 0, bflag = 0;      int Cflag = 0, pflag = 0, qflag = 0, bflag = 0, Pflag = 0, zflag = 0;
     int c, cnt;      int c, cnt;
     char *buf;      char *buf = NULL;
     int64_t offset;      int64_t offset;
     int count;      int count;
     /* Some compilers get confused and warn if this is not initialized.  */      /* Some compilers get confused and warn if this is not initialized.  */
     int total = 0;      int total = 0;
     int pattern = 0xcd;      int pattern = 0xcd;
   
     while ((c = getopt(argc, argv, "bCpP:q")) != EOF) {      while ((c = getopt(argc, argv, "bCpP:qz")) != EOF) {
         switch (c) {          switch (c) {
         case 'b':          case 'b':
             bflag = 1;              bflag = 1;
Line 692  static int write_f(int argc, char **argv Line 731  static int write_f(int argc, char **argv
             pflag = 1;              pflag = 1;
             break;              break;
         case 'P':          case 'P':
               Pflag = 1;
             pattern = parse_pattern(optarg);              pattern = parse_pattern(optarg);
             if (pattern < 0) {              if (pattern < 0) {
                 return 0;                  return 0;
Line 700  static int write_f(int argc, char **argv Line 740  static int write_f(int argc, char **argv
         case 'q':          case 'q':
             qflag = 1;              qflag = 1;
             break;              break;
           case 'z':
               zflag = 1;
               break;
         default:          default:
             return command_usage(&write_cmd);              return command_usage(&write_cmd);
         }          }
Line 709  static int write_f(int argc, char **argv Line 752  static int write_f(int argc, char **argv
         return command_usage(&write_cmd);          return command_usage(&write_cmd);
     }      }
   
     if (bflag && pflag) {      if (bflag + pflag + zflag > 1) {
         printf("-b and -p cannot be specified at the same time\n");          printf("-b, -p, or -z cannot be specified at the same time\n");
           return 0;
       }
   
       if (zflag && Pflag) {
           printf("-z and -P cannot be specified at the same time\n");
         return 0;          return 0;
     }      }
   
Line 741  static int write_f(int argc, char **argv Line 789  static int write_f(int argc, char **argv
         }          }
     }      }
   
     buf = qemu_io_alloc(count, pattern);      if (!zflag) {
           buf = qemu_io_alloc(count, pattern);
       }
   
     gettimeofday(&t1, NULL);      gettimeofday(&t1, NULL);
     if (pflag) {      if (pflag) {
         cnt = do_pwrite(buf, offset, count, &total);          cnt = do_pwrite(buf, offset, count, &total);
     } else if (bflag) {      } else if (bflag) {
         cnt = do_save_vmstate(buf, offset, count, &total);          cnt = do_save_vmstate(buf, offset, count, &total);
       } else if (zflag) {
           cnt = do_co_write_zeroes(offset, count, &total);
     } else {      } else {
         cnt = do_write(buf, offset, count, &total);          cnt = do_write(buf, offset, count, &total);
     }      }
Line 767  static int write_f(int argc, char **argv Line 819  static int write_f(int argc, char **argv
     print_report("wrote", &t2, offset, count, total, cnt, Cflag);      print_report("wrote", &t2, offset, count, total, cnt, Cflag);
   
 out:  out:
     qemu_io_free(buf);      if (!zflag) {
           qemu_io_free(buf);
       }
   
     return 0;      return 0;
 }  }
Line 1072  static void aio_write_done(void *opaque, Line 1126  static void aio_write_done(void *opaque,
                  ctx->qiov.size, 1, ctx->Cflag);                   ctx->qiov.size, 1, ctx->Cflag);
 out:  out:
     qemu_io_free(ctx->buf);      qemu_io_free(ctx->buf);
     free(ctx);      g_free(ctx);
 }  }
   
 static void aio_read_done(void *opaque, int ret)  static void aio_read_done(void *opaque, int ret)
Line 1088  static void aio_read_done(void *opaque,  Line 1142  static void aio_read_done(void *opaque, 
     }      }
   
     if (ctx->Pflag) {      if (ctx->Pflag) {
         void *cmp_buf = malloc(ctx->qiov.size);          void *cmp_buf = g_malloc(ctx->qiov.size);
   
         memset(cmp_buf, ctx->pattern, ctx->qiov.size);          memset(cmp_buf, ctx->pattern, ctx->qiov.size);
         if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {          if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
             printf("Pattern verification failed at offset %"              printf("Pattern verification failed at offset %"
                    PRId64 ", %zd bytes\n", ctx->offset, ctx->qiov.size);                     PRId64 ", %zd bytes\n", ctx->offset, ctx->qiov.size);
         }          }
         free(cmp_buf);          g_free(cmp_buf);
     }      }
   
     if (ctx->qflag) {      if (ctx->qflag) {
Line 1112  static void aio_read_done(void *opaque,  Line 1166  static void aio_read_done(void *opaque, 
                  ctx->qiov.size, 1, ctx->Cflag);                   ctx->qiov.size, 1, ctx->Cflag);
 out:  out:
     qemu_io_free(ctx->buf);      qemu_io_free(ctx->buf);
     free(ctx);      g_free(ctx);
 }  }
   
 static void aio_read_help(void)  static void aio_read_help(void)
Line 1127  static void aio_read_help(void) Line 1181  static void aio_read_help(void)
 " Reads a segment of the currently open file, optionally dumping it to the\n"  " Reads a segment of the currently open file, optionally dumping it to the\n"
 " standard output stream (with -v option) for subsequent inspection.\n"  " standard output stream (with -v option) for subsequent inspection.\n"
 " The read is performed asynchronously and the aio_flush command must be\n"  " The read is performed asynchronously and the aio_flush command must be\n"
 " used to ensure all outstanding aio requests have been completed\n"  " used to ensure all outstanding aio requests have been completed.\n"
 " -C, -- report statistics in a machine parsable format\n"  " -C, -- report statistics in a machine parsable format\n"
 " -P, -- use a pattern to verify read data\n"  " -P, -- use a pattern to verify read data\n"
 " -v, -- dump buffer to standard output\n"  " -v, -- dump buffer to standard output\n"
Line 1150  static const cmdinfo_t aio_read_cmd = { Line 1204  static const cmdinfo_t aio_read_cmd = {
 static int aio_read_f(int argc, char **argv)  static int aio_read_f(int argc, char **argv)
 {  {
     int nr_iov, c;      int nr_iov, c;
     struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx));      struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
     BlockDriverAIOCB *acb;  
   
     while ((c = getopt(argc, argv, "CP:qv")) != EOF) {      while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
         switch (c) {          switch (c) {
Line 1162  static int aio_read_f(int argc, char **a Line 1215  static int aio_read_f(int argc, char **a
             ctx->Pflag = 1;              ctx->Pflag = 1;
             ctx->pattern = parse_pattern(optarg);              ctx->pattern = parse_pattern(optarg);
             if (ctx->pattern < 0) {              if (ctx->pattern < 0) {
                 free(ctx);                  g_free(ctx);
                 return 0;                  return 0;
             }              }
             break;              break;
Line 1173  static int aio_read_f(int argc, char **a Line 1226  static int aio_read_f(int argc, char **a
             ctx->vflag = 1;              ctx->vflag = 1;
             break;              break;
         default:          default:
             free(ctx);              g_free(ctx);
             return command_usage(&aio_read_cmd);              return command_usage(&aio_read_cmd);
         }          }
     }      }
   
     if (optind > argc - 2) {      if (optind > argc - 2) {
         free(ctx);          g_free(ctx);
         return command_usage(&aio_read_cmd);          return command_usage(&aio_read_cmd);
     }      }
   
     ctx->offset = cvtnum(argv[optind]);      ctx->offset = cvtnum(argv[optind]);
     if (ctx->offset < 0) {      if (ctx->offset < 0) {
         printf("non-numeric length argument -- %s\n", argv[optind]);          printf("non-numeric length argument -- %s\n", argv[optind]);
         free(ctx);          g_free(ctx);
         return 0;          return 0;
     }      }
     optind++;      optind++;
Line 1194  static int aio_read_f(int argc, char **a Line 1247  static int aio_read_f(int argc, char **a
     if (ctx->offset & 0x1ff) {      if (ctx->offset & 0x1ff) {
         printf("offset %" PRId64 " is not sector aligned\n",          printf("offset %" PRId64 " is not sector aligned\n",
                ctx->offset);                 ctx->offset);
         free(ctx);          g_free(ctx);
         return 0;          return 0;
     }      }
   
     nr_iov = argc - optind;      nr_iov = argc - optind;
     ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, 0xab);      ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, 0xab);
     if (ctx->buf == NULL) {      if (ctx->buf == NULL) {
         free(ctx);          g_free(ctx);
         return 0;          return 0;
     }      }
   
     gettimeofday(&ctx->t1, NULL);      gettimeofday(&ctx->t1, NULL);
     acb = bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov,      bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov,
                          ctx->qiov.size >> 9, aio_read_done, ctx);                     ctx->qiov.size >> 9, aio_read_done, ctx);
     if (!acb) {  
         free(ctx->buf);  
         free(ctx);  
         return -EIO;  
     }  
   
     return 0;      return 0;
 }  }
   
Line 1230  static void aio_write_help(void) Line 1277  static void aio_write_help(void)
 " Writes into a segment of the currently open file, using a buffer\n"  " Writes into a segment of the currently open file, using a buffer\n"
 " filled with a set pattern (0xcdcdcdcd).\n"  " filled with a set pattern (0xcdcdcdcd).\n"
 " The write is performed asynchronously and the aio_flush command must be\n"  " The write is performed asynchronously and the aio_flush command must be\n"
 " used to ensure all outstanding aio requests have been completed\n"  " used to ensure all outstanding aio requests have been completed.\n"
 " -P, -- use different pattern to fill file\n"  " -P, -- use different pattern to fill file\n"
 " -C, -- report statistics in a machine parsable format\n"  " -C, -- report statistics in a machine parsable format\n"
 " -q, -- quiet mode, do not show I/O statistics\n"  " -q, -- quiet mode, do not show I/O statistics\n"
Line 1253  static int aio_write_f(int argc, char ** Line 1300  static int aio_write_f(int argc, char **
 {  {
     int nr_iov, c;      int nr_iov, c;
     int pattern = 0xcd;      int pattern = 0xcd;
     struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx));      struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
     BlockDriverAIOCB *acb;  
   
     while ((c = getopt(argc, argv, "CqP:")) != EOF) {      while ((c = getopt(argc, argv, "CqP:")) != EOF) {
         switch (c) {          switch (c) {
Line 1267  static int aio_write_f(int argc, char ** Line 1313  static int aio_write_f(int argc, char **
         case 'P':          case 'P':
             pattern = parse_pattern(optarg);              pattern = parse_pattern(optarg);
             if (pattern < 0) {              if (pattern < 0) {
                 free(ctx);                  g_free(ctx);
                 return 0;                  return 0;
             }              }
             break;              break;
         default:          default:
             free(ctx);              g_free(ctx);
             return command_usage(&aio_write_cmd);              return command_usage(&aio_write_cmd);
         }          }
     }      }
   
     if (optind > argc - 2) {      if (optind > argc - 2) {
         free(ctx);          g_free(ctx);
         return command_usage(&aio_write_cmd);          return command_usage(&aio_write_cmd);
     }      }
   
     ctx->offset = cvtnum(argv[optind]);      ctx->offset = cvtnum(argv[optind]);
     if (ctx->offset < 0) {      if (ctx->offset < 0) {
         printf("non-numeric length argument -- %s\n", argv[optind]);          printf("non-numeric length argument -- %s\n", argv[optind]);
         free(ctx);          g_free(ctx);
         return 0;          return 0;
     }      }
     optind++;      optind++;
Line 1293  static int aio_write_f(int argc, char ** Line 1339  static int aio_write_f(int argc, char **
     if (ctx->offset & 0x1ff) {      if (ctx->offset & 0x1ff) {
         printf("offset %" PRId64 " is not sector aligned\n",          printf("offset %" PRId64 " is not sector aligned\n",
                ctx->offset);                 ctx->offset);
         free(ctx);          g_free(ctx);
         return 0;          return 0;
     }      }
   
     nr_iov = argc - optind;      nr_iov = argc - optind;
     ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, pattern);      ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, pattern);
     if (ctx->buf == NULL) {      if (ctx->buf == NULL) {
         free(ctx);          g_free(ctx);
         return 0;          return 0;
     }      }
   
     gettimeofday(&ctx->t1, NULL);      gettimeofday(&ctx->t1, NULL);
     acb = bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,      bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,
                           ctx->qiov.size >> 9, aio_write_done, ctx);                      ctx->qiov.size >> 9, aio_write_done, ctx);
     if (!acb) {  
         free(ctx->buf);  
         free(ctx);  
         return -EIO;  
     }  
   
     return 0;      return 0;
 }  }
   
Line 1520  out: Line 1560  out:
   
 static int alloc_f(int argc, char **argv)  static int alloc_f(int argc, char **argv)
 {  {
     int64_t offset;      int64_t offset, sector_num;
     int nb_sectors, remaining;      int nb_sectors, remaining;
     char s1[64];      char s1[64];
     int num, sum_alloc;      int num, sum_alloc;
Line 1541  static int alloc_f(int argc, char **argv Line 1581  static int alloc_f(int argc, char **argv
   
     remaining = nb_sectors;      remaining = nb_sectors;
     sum_alloc = 0;      sum_alloc = 0;
       sector_num = offset >> 9;
     while (remaining) {      while (remaining) {
         ret = bdrv_is_allocated(bs, offset >> 9, nb_sectors, &num);          ret = bdrv_is_allocated(bs, sector_num, remaining, &num);
           sector_num += num;
         remaining -= num;          remaining -= num;
         if (ret) {          if (ret) {
             sum_alloc += num;              sum_alloc += num;
         }          }
           if (num == 0) {
               nb_sectors -= remaining;
               remaining = 0;
           }
     }      }
   
     cvtstr(offset, s1, sizeof(s1));      cvtstr(offset, s1, sizeof(s1));
Line 1745  static void usage(const char *name) Line 1791  static void usage(const char *name)
 "  -g, --growable       allow file to grow (only applies to protocols)\n"  "  -g, --growable       allow file to grow (only applies to protocols)\n"
 "  -m, --misalign       misalign allocations for O_DIRECT\n"  "  -m, --misalign       misalign allocations for O_DIRECT\n"
 "  -k, --native-aio     use kernel AIO implementation (on Linux only)\n"  "  -k, --native-aio     use kernel AIO implementation (on Linux only)\n"
   "  -t, --cache=MODE     use the given cache mode for the image\n"
   "  -T, --trace FILE     enable trace events listed in the given file\n"
 "  -h, --help           display this help and exit\n"  "  -h, --help           display this help and exit\n"
 "  -V, --version        output version information and exit\n"  "  -V, --version        output version information and exit\n"
 "\n",  "\n",
Line 1756  int main(int argc, char **argv) Line 1804  int main(int argc, char **argv)
 {  {
     int readonly = 0;      int readonly = 0;
     int growable = 0;      int growable = 0;
     const char *sopt = "hVc:rsnmgk";      const char *sopt = "hVc:rsnmgkt:T:";
     const struct option lopt[] = {      const struct option lopt[] = {
         { "help", 0, NULL, 'h' },          { "help", 0, NULL, 'h' },
         { "version", 0, NULL, 'V' },          { "version", 0, NULL, 'V' },
Line 1768  int main(int argc, char **argv) Line 1816  int main(int argc, char **argv)
         { "misalign", 0, NULL, 'm' },          { "misalign", 0, NULL, 'm' },
         { "growable", 0, NULL, 'g' },          { "growable", 0, NULL, 'g' },
         { "native-aio", 0, NULL, 'k' },          { "native-aio", 0, NULL, 'k' },
           { "cache", 1, NULL, 't' },
           { "trace", 1, NULL, 'T' },
         { NULL, 0, NULL, 0 }          { NULL, 0, NULL, 0 }
     };      };
     int c;      int c;
Line 1799  int main(int argc, char **argv) Line 1849  int main(int argc, char **argv)
         case 'k':          case 'k':
             flags |= BDRV_O_NATIVE_AIO;              flags |= BDRV_O_NATIVE_AIO;
             break;              break;
           case 't':
               if (bdrv_parse_cache_flags(optarg, &flags) < 0) {
                   error_report("Invalid cache option: %s", optarg);
                   exit(1);
               }
               break;
           case 'T':
               if (!trace_backend_init(optarg, NULL)) {
                   exit(1); /* error message will have been printed */
               }
               break;
         case 'V':          case 'V':
             printf("%s version %s\n", progname, VERSION);              printf("%s version %s\n", progname, VERSION);
             exit(0);              exit(0);
Line 1818  int main(int argc, char **argv) Line 1879  int main(int argc, char **argv)
   
     bdrv_init();      bdrv_init();
   
       qemu_init_main_loop();
   
     /* initialize commands */      /* initialize commands */
     quit_init();      quit_init();
     help_init();      help_init();
Line 1853  int main(int argc, char **argv) Line 1916  int main(int argc, char **argv)
     command_loop();      command_loop();
   
     /*      /*
      * Make sure all outstanding requests get flushed the program exits.       * Make sure all outstanding requests complete before the program exits.
      */       */
     qemu_aio_flush();      bdrv_drain_all();
   
     if (bs) {      if (bs) {
         bdrv_delete(bs);          bdrv_delete(bs);

Removed from v.1.1.1.6  
changed lines
  Added in v.1.1.1.7


unix.superglobalmegacorp.com