Skip to content

Commit 0c8c489

Browse files
lizhenguikevmw
authored andcommitted
qemu-img: add support for rate limit in qemu-img convert
add support for rate limit in qemu-img convert. Signed-off-by: Zhengui <[email protected]> Message-Id: <[email protected]> Reviewed-by: Alberto Garcia <[email protected]> Signed-off-by: Kevin Wolf <[email protected]>
1 parent a0441b6 commit 0c8c489

File tree

3 files changed

+33
-4
lines changed

3 files changed

+33
-4
lines changed

docs/tools/qemu-img.rst

+5-1
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,10 @@ Parameters to convert subcommand:
188188
allocated target image depending on the host support for getting allocation
189189
information.
190190

191+
.. option:: -r
192+
193+
Rate limit for the convert process
194+
191195
.. option:: --salvage
192196

193197
Try to ignore I/O errors when reading. Unless in quiet mode (``-q``), errors
@@ -410,7 +414,7 @@ Command description:
410414
4
411415
Error on reading data
412416

413-
.. option:: convert [--object OBJECTDEF] [--image-opts] [--target-image-opts] [--target-is-zero] [--bitmaps] [-U] [-C] [-c] [-p] [-q] [-n] [-f FMT] [-t CACHE] [-T SRC_CACHE] [-O OUTPUT_FMT] [-B BACKING_FILE] [-o OPTIONS] [-l SNAPSHOT_PARAM] [-S SPARSE_SIZE] [-m NUM_COROUTINES] [-W] FILENAME [FILENAME2 [...]] OUTPUT_FILENAME
417+
.. option:: convert [--object OBJECTDEF] [--image-opts] [--target-image-opts] [--target-is-zero] [--bitmaps] [-U] [-C] [-c] [-p] [-q] [-n] [-f FMT] [-t CACHE] [-T SRC_CACHE] [-O OUTPUT_FMT] [-B BACKING_FILE] [-o OPTIONS] [-l SNAPSHOT_PARAM] [-S SPARSE_SIZE] [-r RATE_LIMIT] [-m NUM_COROUTINES] [-W] FILENAME [FILENAME2 [...]] OUTPUT_FILENAME
414418

415419
Convert the disk image *FILENAME* or a snapshot *SNAPSHOT_PARAM*
416420
to disk image *OUTPUT_FILENAME* using format *OUTPUT_FMT*. It can

qemu-img-cmds.hx

+2-2
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ SRST
4646
ERST
4747

4848
DEF("convert", img_convert,
49-
"convert [--object objectdef] [--image-opts] [--target-image-opts] [--target-is-zero] [--bitmaps] [-U] [-C] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-B backing_file] [-o options] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] [--salvage] filename [filename2 [...]] output_filename")
49+
"convert [--object objectdef] [--image-opts] [--target-image-opts] [--target-is-zero] [--bitmaps] [-U] [-C] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-B backing_file] [-o options] [-l snapshot_param] [-S sparse_size] [-r rate_limit] [-m num_coroutines] [-W] [--salvage] filename [filename2 [...]] output_filename")
5050
SRST
51-
.. option:: convert [--object OBJECTDEF] [--image-opts] [--target-image-opts] [--target-is-zero] [--bitmaps] [-U] [-C] [-c] [-p] [-q] [-n] [-f FMT] [-t CACHE] [-T SRC_CACHE] [-O OUTPUT_FMT] [-B BACKING_FILE] [-o OPTIONS] [-l SNAPSHOT_PARAM] [-S SPARSE_SIZE] [-m NUM_COROUTINES] [-W] [--salvage] FILENAME [FILENAME2 [...]] OUTPUT_FILENAME
51+
.. option:: convert [--object OBJECTDEF] [--image-opts] [--target-image-opts] [--target-is-zero] [--bitmaps] [-U] [-C] [-c] [-p] [-q] [-n] [-f FMT] [-t CACHE] [-T SRC_CACHE] [-O OUTPUT_FMT] [-B BACKING_FILE] [-o OPTIONS] [-l SNAPSHOT_PARAM] [-S SPARSE_SIZE] [-r RATE_LIMIT] [-m NUM_COROUTINES] [-W] [--salvage] FILENAME [FILENAME2 [...]] OUTPUT_FILENAME
5252
ERST
5353

5454
DEF("create", img_create,

qemu-img.c

+26-1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
#include "block/qapi.h"
5151
#include "crypto/init.h"
5252
#include "trace/control.h"
53+
#include "qemu/throttle.h"
54+
#include "block/throttle-groups.h"
5355

5456
#define QEMU_IMG_VERSION "qemu-img version " QEMU_FULL_VERSION \
5557
"\n" QEMU_COPYRIGHT "\n"
@@ -1669,6 +1671,7 @@ enum ImgConvertBlockStatus {
16691671
};
16701672

16711673
#define MAX_COROUTINES 16
1674+
#define CONVERT_THROTTLE_GROUP "img_convert"
16721675

16731676
typedef struct ImgConvertState {
16741677
BlockBackend **src;
@@ -2184,6 +2187,17 @@ static int convert_copy_bitmaps(BlockDriverState *src, BlockDriverState *dst)
21842187

21852188
#define MAX_BUF_SECTORS 32768
21862189

2190+
static void set_rate_limit(BlockBackend *blk, int64_t rate_limit)
2191+
{
2192+
ThrottleConfig cfg;
2193+
2194+
throttle_config_init(&cfg);
2195+
cfg.buckets[THROTTLE_BPS_WRITE].avg = rate_limit;
2196+
2197+
blk_io_limits_enable(blk, CONVERT_THROTTLE_GROUP);
2198+
blk_set_io_limits(blk, &cfg);
2199+
}
2200+
21872201
static int img_convert(int argc, char **argv)
21882202
{
21892203
int c, bs_i, flags, src_flags = 0;
@@ -2204,6 +2218,7 @@ static int img_convert(int argc, char **argv)
22042218
bool force_share = false;
22052219
bool explict_min_sparse = false;
22062220
bool bitmaps = false;
2221+
int64_t rate_limit = 0;
22072222

22082223
ImgConvertState s = (ImgConvertState) {
22092224
/* Need at least 4k of zeros for sparse detection */
@@ -2226,7 +2241,7 @@ static int img_convert(int argc, char **argv)
22262241
{"bitmaps", no_argument, 0, OPTION_BITMAPS},
22272242
{0, 0, 0, 0}
22282243
};
2229-
c = getopt_long(argc, argv, ":hf:O:B:Cco:l:S:pt:T:qnm:WU",
2244+
c = getopt_long(argc, argv, ":hf:O:B:Cco:l:S:pt:T:qnm:WUr:",
22302245
long_options, NULL);
22312246
if (c == -1) {
22322247
break;
@@ -2323,6 +2338,12 @@ static int img_convert(int argc, char **argv)
23232338
case 'U':
23242339
force_share = true;
23252340
break;
2341+
case 'r':
2342+
rate_limit = cvtnum("rate limit", optarg);
2343+
if (rate_limit < 0) {
2344+
goto fail_getopt;
2345+
}
2346+
break;
23262347
case OPTION_OBJECT: {
23272348
QemuOpts *object_opts;
23282349
object_opts = qemu_opts_parse_noisily(&qemu_object_opts,
@@ -2712,6 +2733,10 @@ static int img_convert(int argc, char **argv)
27122733
s.cluster_sectors = bdi.cluster_size / BDRV_SECTOR_SIZE;
27132734
}
27142735

2736+
if (rate_limit) {
2737+
set_rate_limit(s.target, rate_limit);
2738+
}
2739+
27152740
ret = convert_do_copy(&s);
27162741

27172742
/* Now copy the bitmaps */

0 commit comments

Comments
 (0)