Commit 9ea2ea7146042d54fc3d17d0269ae865cbf55dcf

Authored by Kevin Wolf
Committed by Anthony Liguori
1 parent 0e7e1989

Convert qemu-img create to new bdrv_create

This patch changes qemu-img to actually use the new bdrv_create interface. It
translates the old-style qemu-img options which have been bdrv_create2
parameters or flags so far to option structures. As the generic approach, it
introduces an -o option which accepts any parameter the driver knows.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Showing 1 changed file with 87 additions and 46 deletions
qemu-img.c
@@ -22,6 +22,7 @@ @@ -22,6 +22,7 @@
22 * THE SOFTWARE. 22 * THE SOFTWARE.
23 */ 23 */
24 #include "qemu-common.h" 24 #include "qemu-common.h"
  25 +#include "qemu-option.h"
25 #include "osdep.h" 26 #include "osdep.h"
26 #include "block_int.h" 27 #include "block_int.h"
27 #include <stdio.h> 28 #include <stdio.h>
@@ -221,14 +222,13 @@ static int img_create(int argc, char **argv) @@ -221,14 +222,13 @@ static int img_create(int argc, char **argv)
221 const char *base_fmt = NULL; 222 const char *base_fmt = NULL;
222 const char *filename; 223 const char *filename;
223 const char *base_filename = NULL; 224 const char *base_filename = NULL;
224 - uint64_t size;  
225 - double sizef;  
226 - const char *p;  
227 BlockDriver *drv; 225 BlockDriver *drv;
  226 + QEMUOptionParameter *param = NULL;
  227 + char *options = NULL;
228 228
229 flags = 0; 229 flags = 0;
230 for(;;) { 230 for(;;) {
231 - c = getopt(argc, argv, "F:b:f:he6"); 231 + c = getopt(argc, argv, "F:b:f:he6o:");
232 if (c == -1) 232 if (c == -1)
233 break; 233 break;
234 switch(c) { 234 switch(c) {
@@ -250,59 +250,100 @@ static int img_create(int argc, char **argv) @@ -250,59 +250,100 @@ static int img_create(int argc, char **argv)
250 case '6': 250 case '6':
251 flags |= BLOCK_FLAG_COMPAT6; 251 flags |= BLOCK_FLAG_COMPAT6;
252 break; 252 break;
  253 + case 'o':
  254 + options = optarg;
  255 + break;
253 } 256 }
254 } 257 }
255 if (optind >= argc) 258 if (optind >= argc)
256 help(); 259 help();
257 filename = argv[optind++]; 260 filename = argv[optind++];
258 - size = 0;  
259 - if (base_filename) {  
260 - BlockDriverState *bs;  
261 - BlockDriver *base_drv = NULL;  
262 261
263 - if (base_fmt) {  
264 - base_drv = bdrv_find_format(base_fmt);  
265 - if (base_drv == NULL)  
266 - error("Unknown basefile format '%s'", base_fmt);  
267 - } 262 + /* Find driver and parse its options */
  263 + drv = bdrv_find_format(fmt);
  264 + if (!drv)
  265 + error("Unknown file format '%s'", fmt);
268 266
269 - bs = bdrv_new_open(base_filename, base_fmt);  
270 - bdrv_get_geometry(bs, &size);  
271 - size *= 512;  
272 - bdrv_delete(bs); 267 + if (options) {
  268 + param = parse_option_parameters(options, drv->create_options, param);
  269 + if (param == NULL) {
  270 + error("Invalid options for file format '%s'.", fmt);
  271 + }
273 } else { 272 } else {
274 - if (optind >= argc)  
275 - help();  
276 - p = argv[optind];  
277 - sizef = strtod(p, (char **)&p);  
278 - if (*p == 'M') {  
279 - size = (uint64_t)(sizef * 1024 * 1024);  
280 - } else if (*p == 'G') {  
281 - size = (uint64_t)(sizef * 1024 * 1024 * 1024);  
282 - } else if (*p == 'k' || *p == 'K' || *p == '\0') {  
283 - size = (uint64_t)(sizef * 1024);  
284 - } else {  
285 - help(); 273 + param = parse_option_parameters("", drv->create_options, param);
  274 + }
  275 +
  276 + /* Add size to parameters */
  277 + if (optind < argc) {
  278 + set_option_parameter(param, BLOCK_OPT_SIZE, argv[optind++]);
  279 + }
  280 +
  281 + /* Add old-style options to parameters */
  282 + if (flags & BLOCK_FLAG_ENCRYPT) {
  283 + if (set_option_parameter(param, BLOCK_OPT_ENCRYPT, "on")) {
  284 + error("Encryption not supported for file format '%s'", fmt);
286 } 285 }
287 } 286 }
288 - drv = bdrv_find_format(fmt);  
289 - if (!drv)  
290 - error("Unknown file format '%s'", fmt);  
291 - printf("Formatting '%s', fmt=%s",  
292 - filename, fmt);  
293 - if (flags & BLOCK_FLAG_ENCRYPT)  
294 - printf(", encrypted");  
295 - if (flags & BLOCK_FLAG_COMPAT6)  
296 - printf(", compatibility level=6"); 287 + if (flags & BLOCK_FLAG_COMPAT6) {
  288 + if (set_option_parameter(param, BLOCK_OPT_COMPAT6, "on")) {
  289 + error("VMDK version 6 not supported for file format '%s'", fmt);
  290 + }
  291 + }
  292 +
297 if (base_filename) { 293 if (base_filename) {
298 - printf(", backing_file=%s",  
299 - base_filename);  
300 - if (base_fmt)  
301 - printf(", backing_fmt=%s",  
302 - base_fmt);  
303 - }  
304 - printf(", size=%" PRIu64 " kB\n", size / 1024);  
305 - ret = bdrv_create2(drv, filename, size / 512, base_filename, base_fmt, flags); 294 + if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE, base_filename)) {
  295 + error("Backing file not supported for file format '%s'", fmt);
  296 + }
  297 + }
  298 + if (base_fmt) {
  299 + if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, base_fmt)) {
  300 + error("Backing file format not supported for file format '%s'", fmt);
  301 + }
  302 + }
  303 +
  304 + // The size for the image must always be specified, with one exception:
  305 + // If we are using a backing file, we can obtain the size from there
  306 + if (get_option_parameter(param, BLOCK_OPT_SIZE)->value.n == 0) {
  307 +
  308 + QEMUOptionParameter *backing_file =
  309 + get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
  310 + QEMUOptionParameter *backing_fmt =
  311 + get_option_parameter(param, BLOCK_OPT_BACKING_FMT);
  312 +
  313 + if (backing_file && backing_file->value.s) {
  314 + BlockDriverState *bs;
  315 + uint64_t size;
  316 + const char *fmt = NULL;
  317 + char buf[32];
  318 +
  319 + if (backing_fmt && backing_fmt->value.s) {
  320 + if (bdrv_find_format(backing_fmt->value.s)) {
  321 + fmt = backing_fmt->value.s;
  322 + } else {
  323 + error("Unknown backing file format '%s'",
  324 + backing_fmt->value.s);
  325 + }
  326 + }
  327 +
  328 + bs = bdrv_new_open(backing_file->value.s, fmt);
  329 + bdrv_get_geometry(bs, &size);
  330 + size *= 512;
  331 + bdrv_delete(bs);
  332 +
  333 + snprintf(buf, sizeof(buf), "%" PRId64, size);
  334 + set_option_parameter(param, BLOCK_OPT_SIZE, buf);
  335 + } else {
  336 + error("Image creation needs a size parameter");
  337 + }
  338 + }
  339 +
  340 + printf("Formatting '%s', fmt=%s ", filename, fmt);
  341 + print_option_parameters(param);
  342 + puts("");
  343 +
  344 + ret = bdrv_create(drv, filename, param);
  345 + free_option_parameters(param);
  346 +
306 if (ret < 0) { 347 if (ret < 0) {
307 if (ret == -ENOTSUP) { 348 if (ret == -ENOTSUP) {
308 error("Formatting or formatting option not supported for file format '%s'", fmt); 349 error("Formatting or formatting option not supported for file format '%s'", fmt);