@ -60,6 +60,7 @@ enum {
OPTION_PATTERN = 260 ,
OPTION_FLUSH_INTERVAL = 261 ,
OPTION_NO_DRAIN = 262 ,
OPTION_TARGET_IMAGE_OPTS = 263 ,
} ;
typedef enum OutputFormat {
@ -1913,10 +1914,10 @@ static int convert_do_copy(ImgConvertState *s)
static int img_convert ( int argc , char * * argv )
{
int c , bs_i , flags , src_flags = 0 ;
const char * fmt = NULL , * out_fmt = " raw " , * cache = " unsafe " ,
const char * fmt = NULL , * out_fmt = NULL , * cache = " unsafe " ,
* src_cache = BDRV_DEFAULT_CACHE , * out_baseimg = NULL ,
* out_filename , * out_baseimg_param , * snapshot_name = NULL ;
BlockDriver * drv , * proto_drv ;
BlockDriver * drv = NULL , * proto_drv = NULL ;
BlockDriverInfo bdi ;
BlockDriverState * out_bs ;
QemuOpts * opts = NULL , * sn_opts = NULL ;
@ -1924,7 +1925,7 @@ static int img_convert(int argc, char **argv)
char * options = NULL ;
Error * local_err = NULL ;
bool writethrough , src_writethrough , quiet = false , image_opts = false ,
skip_create = false , progress = false ;
skip_create = false , progress = false , tgt_image_opts = false ;
int64_t ret = - EINVAL ;
bool force_share = false ;
@ -1942,6 +1943,7 @@ static int img_convert(int argc, char **argv)
{ " object " , required_argument , 0 , OPTION_OBJECT } ,
{ " image-opts " , no_argument , 0 , OPTION_IMAGE_OPTS } ,
{ " force-share " , no_argument , 0 , ' U ' } ,
{ " target-image-opts " , no_argument , 0 , OPTION_TARGET_IMAGE_OPTS } ,
{ 0 , 0 , 0 , 0 }
} ;
c = getopt_long ( argc , argv , " :hf:O:B:ce6o:s:l:S:pt:T:qnm:WU " ,
@ -2062,9 +2064,16 @@ static int img_convert(int argc, char **argv)
case OPTION_IMAGE_OPTS :
image_opts = true ;
break ;
case OPTION_TARGET_IMAGE_OPTS :
tgt_image_opts = true ;
break ;
}
}
if ( ! out_fmt & & ! tgt_image_opts ) {
out_fmt = " raw " ;
}
if ( qemu_opts_foreach ( & qemu_object_opts ,
user_creatable_add_opts_foreach ,
NULL , NULL ) ) {
@ -2076,12 +2085,22 @@ static int img_convert(int argc, char **argv)
goto fail_getopt ;
}
if ( tgt_image_opts & & ! skip_create ) {
error_report ( " --target-image-opts requires use of -n flag " ) ;
goto fail_getopt ;
}
s . src_num = argc - optind - 1 ;
out_filename = s . src_num > = 1 ? argv [ argc - 1 ] : NULL ;
if ( options & & has_help_option ( options ) ) {
ret = print_block_option_help ( out_filename , out_fmt ) ;
goto fail_getopt ;
if ( out_fmt ) {
ret = print_block_option_help ( out_filename , out_fmt ) ;
goto fail_getopt ;
} else {
error_report ( " Option help requires a format be specified " ) ;
goto fail_getopt ;
}
}
if ( s . src_num < 1 ) {
@ -2146,22 +2165,22 @@ static int img_convert(int argc, char **argv)
goto out ;
}
/* Find driver and parse its options */
drv = bdrv_find_format ( out_fmt ) ;
if ( ! drv ) {
error_report ( " Unknown file format '%s' " , out_fmt ) ;
ret = - 1 ;
goto out ;
}
if ( ! skip_create ) {
/* Find driver and parse its options */
drv = bdrv_find_format ( out_fmt ) ;
if ( ! drv ) {
error_report ( " Unknown file format '%s' " , out_fmt ) ;
ret = - 1 ;
goto out ;
}
proto_drv = bdrv_find_protocol ( out_filename , true , & local_err ) ;
if ( ! proto_drv ) {
error_report_err ( local_err ) ;
ret = - 1 ;
goto out ;
}
proto_drv = bdrv_find_protocol ( out_filename , true , & local_err ) ;
if ( ! proto_drv ) {
error_report_err ( local_err ) ;
ret = - 1 ;
goto out ;
}
if ( ! skip_create ) {
if ( ! drv - > create_opts ) {
error_report ( " Format driver '%s' does not support image creation " ,
drv - > format_name ) ;
@ -2218,7 +2237,7 @@ static int img_convert(int argc, char **argv)
const char * preallocation =
qemu_opt_get ( opts , BLOCK_OPT_PREALLOC ) ;
if ( ! drv - > bdrv_co_pwritev_compressed ) {
if ( drv & & ! drv - > bdrv_co_pwritev_compressed ) {
error_report ( " Compression not supported for this file format " ) ;
ret = - 1 ;
goto out ;
@ -2258,19 +2277,30 @@ static int img_convert(int argc, char **argv)
goto out ;
}
/* XXX we should allow --image-opts to trigger use of
* img_open ( ) here , but then we have trouble with
* the bdrv_create ( ) call which takes different params .
* Not critical right now , so fix can wait . . .
*/
s . target = img_open_file ( out_filename , out_fmt , flags , writethrough , quiet ,
false ) ;
if ( skip_create ) {
s . target = img_open ( tgt_image_opts , out_filename , out_fmt ,
flags , writethrough , quiet , false ) ;
} else {
/* TODO ultimately we should allow --target-image-opts
* to be used even when - n is not given .
* That has to wait for bdrv_create to be improved
* to allow filenames in option syntax
*/
s . target = img_open_file ( out_filename , out_fmt , flags ,
writethrough , quiet , false ) ;
}
if ( ! s . target ) {
ret = - 1 ;
goto out ;
}
out_bs = blk_bs ( s . target ) ;
if ( s . compressed & & ! out_bs - > drv - > bdrv_co_pwritev_compressed ) {
error_report ( " Compression not supported for this file format " ) ;
ret = - 1 ;
goto out ;
}
/* increase bufsectors from the default 4096 (2M) if opt_transfer
* or discard_alignment of the out_bs is greater . Limit to 32768 ( 16 MB )
* as maximum . */