#include "osdep.h"
#include "block_int.h"
#include <assert.h>
+#include <stdio.h>
#ifdef _WIN32
-#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
/* Default to cache=writeback as data integrity is not important for qemu-tcg. */
#define BRDV_O_FLAGS BDRV_O_CACHE_WB
-static void noreturn error(const char *fmt, ...)
+static void QEMU_NORETURN error(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
"QEMU disk image utility\n"
"\n"
"Command syntax:\n"
- " create [-e] [-6] [-b base_image] [-f fmt] filename [size]\n"
+ " create [-e] [-6] [-F fmt] [-b base_image] [-f fmt] filename [size]\n"
" commit [-f fmt] filename\n"
" convert [-c] [-e] [-6] [-f fmt] [-O output_fmt] [-B output_base_image] filename [filename2 [...]] output_filename\n"
" info [-f fmt] filename\n"
" differ\n"
" 'fmt' is the disk image format. It is guessed automatically in most cases\n"
" 'size' is the disk image size in kilobytes. Optional suffixes\n"
- " 'M' (megabyte, 1024 * 1024) and 'G' (gigabyte, 1024 * 1024 * 1024) are"
- " supported any @code{k} or @code{K} is ignored\n"
+ " 'M' (megabyte, 1024 * 1024) and 'G' (gigabyte, 1024 * 1024 * 1024) are\n"
+ " supported any 'k' or 'K' is ignored\n"
" 'output_filename' is the destination disk image filename\n"
" 'output_fmt' is the destination format\n"
" '-c' indicates that target image must be compressed (qcow format only)\n"
{
int c, ret, flags;
const char *fmt = "raw";
+ const char *base_fmt = NULL;
const char *filename;
const char *base_filename = NULL;
uint64_t size;
+ double sizef;
const char *p;
BlockDriver *drv;
flags = 0;
for(;;) {
- c = getopt(argc, argv, "b:f:he6");
+ c = getopt(argc, argv, "F:b:f:he6");
if (c == -1)
break;
switch(c) {
case 'h':
help();
break;
+ case 'F':
+ base_fmt = optarg;
+ break;
case 'b':
base_filename = optarg;
break;
size = 0;
if (base_filename) {
BlockDriverState *bs;
- bs = bdrv_new_open(base_filename, NULL);
+ BlockDriver *base_drv = NULL;
+
+ if (base_fmt) {
+ base_drv = bdrv_find_format(base_fmt);
+ if (base_drv == NULL)
+ error("Unknown basefile format '%s'", base_fmt);
+ }
+
+ bs = bdrv_new_open(base_filename, base_fmt);
bdrv_get_geometry(bs, &size);
size *= 512;
bdrv_delete(bs);
if (optind >= argc)
help();
p = argv[optind];
- size = strtoul(p, (char **)&p, 0);
+ sizef = strtod(p, (char **)&p);
if (*p == 'M') {
- size *= 1024 * 1024;
+ size = (uint64_t)(sizef * 1024 * 1024);
} else if (*p == 'G') {
- size *= 1024 * 1024 * 1024;
+ size = (uint64_t)(sizef * 1024 * 1024 * 1024);
} else if (*p == 'k' || *p == 'K' || *p == '\0') {
- size *= 1024;
+ size = (uint64_t)(sizef * 1024);
} else {
help();
}
if (base_filename) {
printf(", backing_file=%s",
base_filename);
+ if (base_fmt)
+ printf(", backing_fmt=%s",
+ base_fmt);
}
printf(", size=%" PRIu64 " kB\n", size / 1024);
- ret = bdrv_create(drv, filename, size / 512, base_filename, flags);
+ ret = bdrv_create2(drv, filename, size / 512, base_filename, base_fmt, flags);
if (ret < 0) {
if (ret == -ENOTSUP) {
error("Formatting or formatting option not supported for file format '%s'", fmt);
if (bdrv_get_info(bs, &bdi) >= 0) {
if (bdi.cluster_size != 0)
printf("cluster_size: %d\n", bdi.cluster_size);
- if (bdi.highest_alloc)
- printf("highest_alloc: %" PRId64 "\n", bdi.highest_alloc);
- if (bdi.num_free_bytes)
- printf("num_free_bytes: %" PRId64 "\n", bdi.num_free_bytes);
}
bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
if (backing_filename[0] != '\0') {
if (argc < 2)
help();
cmd = argv[1];
- optind++;
+ argc--; argv++;
if (!strcmp(cmd, "create")) {
img_create(argc, argv);
} else if (!strcmp(cmd, "commit")) {