50
50
#include "block/qapi.h"
51
51
#include "crypto/init.h"
52
52
#include "trace/control.h"
53
+ #include "qemu/throttle.h"
54
+ #include "block/throttle-groups.h"
53
55
54
56
#define QEMU_IMG_VERSION "qemu-img version " QEMU_FULL_VERSION \
55
57
"\n" QEMU_COPYRIGHT "\n"
@@ -1669,6 +1671,7 @@ enum ImgConvertBlockStatus {
1669
1671
};
1670
1672
1671
1673
#define MAX_COROUTINES 16
1674
+ #define CONVERT_THROTTLE_GROUP "img_convert"
1672
1675
1673
1676
typedef struct ImgConvertState {
1674
1677
BlockBackend * * src ;
@@ -2184,6 +2187,17 @@ static int convert_copy_bitmaps(BlockDriverState *src, BlockDriverState *dst)
2184
2187
2185
2188
#define MAX_BUF_SECTORS 32768
2186
2189
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
+
2187
2201
static int img_convert (int argc , char * * argv )
2188
2202
{
2189
2203
int c , bs_i , flags , src_flags = 0 ;
@@ -2204,6 +2218,7 @@ static int img_convert(int argc, char **argv)
2204
2218
bool force_share = false;
2205
2219
bool explict_min_sparse = false;
2206
2220
bool bitmaps = false;
2221
+ int64_t rate_limit = 0 ;
2207
2222
2208
2223
ImgConvertState s = (ImgConvertState ) {
2209
2224
/* Need at least 4k of zeros for sparse detection */
@@ -2226,7 +2241,7 @@ static int img_convert(int argc, char **argv)
2226
2241
{"bitmaps" , no_argument , 0 , OPTION_BITMAPS },
2227
2242
{0 , 0 , 0 , 0 }
2228
2243
};
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: " ,
2230
2245
long_options , NULL );
2231
2246
if (c == -1 ) {
2232
2247
break ;
@@ -2323,6 +2338,12 @@ static int img_convert(int argc, char **argv)
2323
2338
case 'U' :
2324
2339
force_share = true;
2325
2340
break ;
2341
+ case 'r' :
2342
+ rate_limit = cvtnum ("rate limit" , optarg );
2343
+ if (rate_limit < 0 ) {
2344
+ goto fail_getopt ;
2345
+ }
2346
+ break ;
2326
2347
case OPTION_OBJECT : {
2327
2348
QemuOpts * object_opts ;
2328
2349
object_opts = qemu_opts_parse_noisily (& qemu_object_opts ,
@@ -2712,6 +2733,10 @@ static int img_convert(int argc, char **argv)
2712
2733
s .cluster_sectors = bdi .cluster_size / BDRV_SECTOR_SIZE ;
2713
2734
}
2714
2735
2736
+ if (rate_limit ) {
2737
+ set_rate_limit (s .target , rate_limit );
2738
+ }
2739
+
2715
2740
ret = convert_do_copy (& s );
2716
2741
2717
2742
/* Now copy the bitmaps */
0 commit comments