diff options
Diffstat (limited to 'qemu-img.c')
-rw-r--r-- | qemu-img.c | 61 |
1 files changed, 54 insertions, 7 deletions
diff --git a/qemu-img.c b/qemu-img.c index 7e3cc4cbd5..e8251234b1 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -77,6 +77,7 @@ static void help(void) " match exactly. The image doesn't need a working backing file before\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" + " '-p' show progress of command (only certain commands)\n" "\n" "Parameters to snapshot subcommand:\n" " 'snapshot' is the name of the snapshot to create, apply or delete\n" @@ -567,6 +568,7 @@ static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n, static int img_convert(int argc, char **argv) { int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors; + int progress = 0; const char *fmt, *out_fmt, *out_baseimg, *out_filename; BlockDriver *drv, *proto_drv; BlockDriverState **bs = NULL, *out_bs = NULL; @@ -579,13 +581,14 @@ static int img_convert(int argc, char **argv) QEMUOptionParameter *out_baseimg_param; char *options = NULL; const char *snapshot_name = NULL; + float local_progress; fmt = NULL; out_fmt = "raw"; out_baseimg = NULL; compress = 0; for(;;) { - c = getopt(argc, argv, "f:O:B:s:hce6o:"); + c = getopt(argc, argv, "f:O:B:s:hce6o:p"); if (c == -1) { break; } @@ -620,6 +623,9 @@ static int img_convert(int argc, char **argv) case 's': snapshot_name = optarg; break; + case 'p': + progress = 1; + break; } } @@ -642,6 +648,9 @@ static int img_convert(int argc, char **argv) goto out; } + qemu_progress_init(progress, 2.0); + qemu_progress_print(0, 100); + bs = qemu_mallocz(bs_n * sizeof(BlockDriverState *)); total_sectors = 0; @@ -773,6 +782,11 @@ static int img_convert(int argc, char **argv) } cluster_sectors = cluster_size >> 9; sector_num = 0; + + nb_sectors = total_sectors; + local_progress = (float)100 / + (nb_sectors / MIN(nb_sectors, (cluster_sectors))); + for(;;) { int64_t bs_num; int remainder; @@ -832,6 +846,7 @@ static int img_convert(int argc, char **argv) } } sector_num += n; + qemu_progress_print(local_progress, 100); } /* signal EOF to align */ bdrv_write_compressed(out_bs, 0, NULL, 0); @@ -839,6 +854,10 @@ static int img_convert(int argc, char **argv) int has_zero_init = bdrv_has_zero_init(out_bs); 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(;;) { nb_sectors = total_sectors - sector_num; if (nb_sectors <= 0) { @@ -912,9 +931,11 @@ static int img_convert(int argc, char **argv) n -= n1; buf1 += n1 * 512; } + qemu_progress_print(local_progress, 100); } } out: + qemu_progress_end(); free_option_parameters(create_options); free_option_parameters(param); qemu_free(buf); @@ -1184,6 +1205,7 @@ static int img_rebase(int argc, char **argv) const char *fmt, *out_basefmt, *out_baseimg; int c, flags, ret; int unsafe = 0; + int progress = 0; /* Parse commandline parameters */ fmt = NULL; @@ -1191,7 +1213,7 @@ static int img_rebase(int argc, char **argv) out_basefmt = NULL; for(;;) { - c = getopt(argc, argv, "uhf:F:b:"); + c = getopt(argc, argv, "uhf:F:b:p"); if (c == -1) { break; } @@ -1212,14 +1234,20 @@ static int img_rebase(int argc, char **argv) case 'u': unsafe = 1; break; + case 'p': + progress = 1; + break; } } - if ((optind >= argc) || !out_baseimg) { + if ((optind >= argc) || (!unsafe && !out_baseimg)) { help(); } filename = argv[optind++]; + qemu_progress_init(progress, 2.0); + qemu_progress_print(0, 100); + /* * Open the images. * @@ -1295,12 +1323,15 @@ static int img_rebase(int argc, char **argv) int n; uint8_t * buf_old; uint8_t * buf_new; + float local_progress; buf_old = qemu_malloc(IO_BUF_SIZE); buf_new = qemu_malloc(IO_BUF_SIZE); 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) { /* How many sectors can we handle with the next read? */ @@ -1348,6 +1379,7 @@ static int img_rebase(int argc, char **argv) written += pnum; } + qemu_progress_print(local_progress, 100); } qemu_free(buf_old); @@ -1368,6 +1400,7 @@ static int img_rebase(int argc, char **argv) out_baseimg, strerror(-ret)); } + qemu_progress_print(100, 0); /* * 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 @@ -1375,10 +1408,15 @@ static int img_rebase(int argc, char **argv) * backing file, in case of a crash this would lead to corruption. */ out: + qemu_progress_end(); /* Cleanup */ if (!unsafe) { - bdrv_delete(bs_old_backing); - bdrv_delete(bs_new_backing); + if (bs_old_backing != NULL) { + bdrv_delete(bs_old_backing); + } + if (bs_new_backing != NULL) { + bdrv_delete(bs_new_backing); + } } bdrv_delete(bs); @@ -1404,6 +1442,16 @@ static int img_resize(int argc, char **argv) { 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; for(;;) { c = getopt(argc, argv, "f:h"); @@ -1420,11 +1468,10 @@ static int img_resize(int argc, char **argv) break; } } - if (optind + 1 >= argc) { + if (optind >= argc) { help(); } filename = argv[optind++]; - size = argv[optind++]; /* Choose grow, shrink, or absolute resize mode */ switch (size[0]) { |