aboutsummaryrefslogtreecommitdiff
path: root/qemu-img.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu-img.c')
-rw-r--r--qemu-img.c61
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]) {