From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46854) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WYJd0-0006Rt-Rr for qemu-devel@nongnu.org; Thu, 10 Apr 2014 14:23:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WYJcu-0005st-MA for qemu-devel@nongnu.org; Thu, 10 Apr 2014 14:23:10 -0400 Received: from mx1.redhat.com ([209.132.183.28]:26632) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WYJRo-0001yb-4q for qemu-devel@nongnu.org; Thu, 10 Apr 2014 14:11:36 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s3AIBZJx022622 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 10 Apr 2014 14:11:35 -0400 From: Max Reitz Date: Thu, 10 Apr 2014 20:11:06 +0200 Message-Id: <1397153468-16498-4-git-send-email-mreitz@redhat.com> In-Reply-To: <1397153468-16498-1-git-send-email-mreitz@redhat.com> References: <1397153468-16498-1-git-send-email-mreitz@redhat.com> Subject: [Qemu-devel] [PATCH v3 3/5] qemu-img: Enable progress output for commit List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Kevin Wolf , Fam Zheng , Stefan Hajnoczi , Max Reitz Implement progress output for the commit command by querying the progress of the block job. Signed-off-by: Max Reitz --- qemu-img-cmds.hx | 4 ++-- qemu-img.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- qemu-img.texi | 2 +- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx index d029609..8bc55cd 100644 --- a/qemu-img-cmds.hx +++ b/qemu-img-cmds.hx @@ -22,9 +22,9 @@ STEXI ETEXI DEF("commit", img_commit, - "commit [-q] [-f fmt] [-t cache] filename") + "commit [-q] [-f fmt] [-t cache] [-p] filename") STEXI -@item commit [-q] [-f @var{fmt}] [-t @var{cache}] @var{filename} +@item commit [-q] [-f @var{fmt}] [-t @var{cache}] [-p] @var{filename} ETEXI DEF("compare", img_compare, diff --git a/qemu-img.c b/qemu-img.c index 026742a..0c22b20 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -686,6 +686,9 @@ fail: struct CommonBlockJobCBInfo { Error **errp; bool done; + /* If the blockjob works on several sectors at once, this field has to + * contain that granularity in bytes */ + uint64_t granularity; }; static void common_block_job_cb(void *opaque, int ret) @@ -702,12 +705,34 @@ static void common_block_job_cb(void *opaque, int ret) static void run_block_job(BlockJob *job, struct CommonBlockJobCBInfo *cbi) { BlockJobInfo *info; + uint64_t mod_offset = 0; do { aio_poll(qemu_get_aio_context(), true); info = block_job_query(job); + if (info->offset) { + if (!mod_offset) { + /* Some block jobs (at least "commit") will only work on a + * subset of the image file and therefore basically skip many + * sectors at the start (processing them apparently + * instantaneously). These sectors should be ignored when + * calculating the progress. + * If the blockjob processes several sectors at once, the first + * progress report is likely to come after one such sector group + * (whose size is cbi->granularity), therefore subtract it from + * the current offset in order to obtain a more probable + * starting offset. */ + mod_offset = info->offset > cbi->granularity + ? info->offset - cbi->granularity + : 0; + } + + qemu_progress_print((float)(info->offset - mod_offset) / + (info->len - mod_offset) * 100.f, 0); + } + if (!info->busy && info->offset < info->len) { block_job_resume(job); } @@ -728,13 +753,13 @@ static int img_commit(int argc, char **argv) int c, ret, flags; const char *filename, *fmt, *cache; BlockDriverState *bs, *base_bs; - bool quiet = false; + bool progress = false, quiet = false; Error *local_err = NULL; fmt = NULL; cache = BDRV_DEFAULT_CACHE; for(;;) { - c = getopt(argc, argv, "f:ht:q"); + c = getopt(argc, argv, "f:ht:qp"); if (c == -1) { break; } @@ -749,11 +774,20 @@ static int img_commit(int argc, char **argv) case 't': cache = optarg; break; + case 'p': + progress = true; + break; case 'q': quiet = true; break; } } + + /* Progress is not shown in Quiet mode */ + if (quiet) { + progress = false; + } + if (optind != argc - 1) { help(); } @@ -771,6 +805,9 @@ static int img_commit(int argc, char **argv) return 1; } + qemu_progress_init(progress, 1.f); + qemu_progress_print(0.f, 100); + /* This is different from QMP, which by default uses the deepest file in the * backing chain (i.e., the very base); however, the traditional behavior of * qemu-img commit is using the immediate backing file. */ @@ -782,6 +819,7 @@ static int img_commit(int argc, char **argv) struct CommonBlockJobCBInfo cbi = { .errp = &local_err, + .granularity = COMMIT_BUF_SECTORS << BDRV_SECTOR_BITS, }; commit_active_start(bs, base_bs, 0, COMMIT_BUF_SECTORS << BDRV_SECTOR_BITS, @@ -794,6 +832,8 @@ static int img_commit(int argc, char **argv) run_block_job(bs->job, &cbi); done: + qemu_progress_end(); + bdrv_unref(bs); if (local_err) { diff --git a/qemu-img.texi b/qemu-img.texi index f84590e..1a9c08f 100644 --- a/qemu-img.texi +++ b/qemu-img.texi @@ -140,7 +140,7 @@ this case. @var{backing_file} will never be modified unless you use the The size can also be specified using the @var{size} option with @code{-o}, it doesn't need to be specified separately in this case. -@item commit [-f @var{fmt}] [-t @var{cache}] @var{filename} +@item commit [-q] [-f @var{fmt}] [-t @var{cache}] [-p] @var{filename} Commit the changes recorded in @var{filename} in its base image or backing file. If the backing file is smaller than the snapshot, then the backing file will be -- 1.9.1