blob: 0cf6be228033119d36d1f549aacc69432ece043e [file] [log] [blame]
bellardea2384d2004-08-01 21:59:26 +00001/*
bellardfb43f4d2006-08-07 21:34:46 +00002 * QEMU disk image utility
ths5fafdf22007-09-16 21:08:06 +00003 *
bellard68d0f702008-01-06 17:21:48 +00004 * Copyright (c) 2003-2008 Fabrice Bellard
ths5fafdf22007-09-16 21:08:06 +00005 *
bellardea2384d2004-08-01 21:59:26 +00006 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
Benoît Canetc054b3f2012-09-05 13:09:02 +020024#include "qapi-visit.h"
25#include "qapi/qmp-output-visitor.h"
Paolo Bonzini7b1b5d12012-12-17 18:19:43 +010026#include "qapi/qmp/qjson.h"
pbrookfaf07962007-11-11 02:51:17 +000027#include "qemu-common.h"
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010028#include "qemu/option.h"
29#include "qemu/error-report.h"
30#include "qemu/osdep.h"
Paolo Bonzini9c17d612012-12-17 18:20:04 +010031#include "sysemu/sysemu.h"
Paolo Bonzini737e1502012-12-17 18:19:44 +010032#include "block/block_int.h"
Wenchao Xiaf364ec62013-05-25 11:09:44 +080033#include "block/qapi.h"
Benoît Canetc054b3f2012-09-05 13:09:02 +020034#include <getopt.h>
aliguori9230eaf2009-03-28 17:55:19 +000035#include <stdio.h>
Miroslav Rezaninaf382d432013-02-13 09:09:40 +010036#include <stdarg.h>
bellardea2384d2004-08-01 21:59:26 +000037
bellarde8445332006-06-14 15:32:10 +000038#ifdef _WIN32
39#include <windows.h>
40#endif
41
Anthony Liguoric227f092009-10-01 16:12:16 -050042typedef struct img_cmd_t {
Stuart Brady153859b2009-06-07 00:42:17 +010043 const char *name;
44 int (*handler)(int argc, char **argv);
Anthony Liguoric227f092009-10-01 16:12:16 -050045} img_cmd_t;
Stuart Brady153859b2009-06-07 00:42:17 +010046
Federico Simoncelli8599ea42013-01-28 06:59:47 -050047enum {
48 OPTION_OUTPUT = 256,
49 OPTION_BACKING_CHAIN = 257,
50};
51
52typedef enum OutputFormat {
53 OFORMAT_JSON,
54 OFORMAT_HUMAN,
55} OutputFormat;
56
aurel32137519c2008-11-30 19:12:49 +000057/* Default to cache=writeback as data integrity is not important for qemu-tcg. */
Stefan Hajnocziadfe0782010-04-13 10:29:35 +010058#define BDRV_O_FLAGS BDRV_O_CACHE_WB
Federico Simoncelli661a0f72011-06-20 12:48:19 -040059#define BDRV_DEFAULT_CACHE "writeback"
aurel32137519c2008-11-30 19:12:49 +000060
bellardea2384d2004-08-01 21:59:26 +000061static void format_print(void *opaque, const char *name)
62{
63 printf(" %s", name);
64}
65
blueswir1d2c639d2009-01-24 18:19:25 +000066/* Please keep in synch with qemu-img.texi */
pbrook3f379ab2007-11-11 03:33:13 +000067static void help(void)
bellardea2384d2004-08-01 21:59:26 +000068{
Paolo Bonzinie00291c2010-02-04 16:49:56 +010069 const char *help_msg =
70 "qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fabrice Bellard\n"
malc3f020d72010-02-08 12:04:56 +030071 "usage: qemu-img command [command options]\n"
72 "QEMU disk image utility\n"
73 "\n"
74 "Command syntax:\n"
Stuart Brady153859b2009-06-07 00:42:17 +010075#define DEF(option, callback, arg_string) \
76 " " arg_string "\n"
77#include "qemu-img-cmds.h"
78#undef DEF
79#undef GEN_DOCS
malc3f020d72010-02-08 12:04:56 +030080 "\n"
81 "Command parameters:\n"
82 " 'filename' is a disk image filename\n"
83 " 'fmt' is the disk image format. It is guessed automatically in most cases\n"
Federico Simoncelli661a0f72011-06-20 12:48:19 -040084 " 'cache' is the cache mode used to write the output disk image, the valid\n"
Liu Yuan80ccf932012-04-20 17:10:56 +080085 " options are: 'none', 'writeback' (default, except for convert), 'writethrough',\n"
86 " 'directsync' and 'unsafe' (default for convert)\n"
malc3f020d72010-02-08 12:04:56 +030087 " 'size' is the disk image size in bytes. Optional suffixes\n"
Kevin Wolf5e009842013-06-05 14:19:27 +020088 " 'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M),\n"
89 " 'T' (terabyte, 1024G), 'P' (petabyte, 1024T) and 'E' (exabyte, 1024P) are\n"
90 " supported. 'b' is ignored.\n"
malc3f020d72010-02-08 12:04:56 +030091 " 'output_filename' is the destination disk image filename\n"
92 " 'output_fmt' is the destination format\n"
93 " 'options' is a comma separated list of format specific options in a\n"
94 " name=value format. Use -o ? for an overview of the options supported by the\n"
95 " used format\n"
96 " '-c' indicates that target image must be compressed (qcow format only)\n"
97 " '-u' enables unsafe rebasing. It is assumed that old and new backing file\n"
98 " match exactly. The image doesn't need a working backing file before\n"
99 " rebasing in this case (useful for renaming the backing file)\n"
100 " '-h' with or without a command shows this help and lists the supported formats\n"
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200101 " '-p' show progress of command (only certain commands)\n"
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100102 " '-q' use Quiet mode - do not print any output (except errors)\n"
Kevin Wolfa22f1232011-08-26 15:27:13 +0200103 " '-S' indicates the consecutive number of bytes that must contain only zeros\n"
104 " for qemu-img to create a sparse image during conversion\n"
Benoît Canetc054b3f2012-09-05 13:09:02 +0200105 " '--output' takes the format in which the output must be done (human or json)\n"
Alexandre Derumierb2e10492013-09-02 19:07:24 +0100106 " '-n' skips the target volume creation (useful if the volume is created\n"
107 " prior to running qemu-img)\n"
malc3f020d72010-02-08 12:04:56 +0300108 "\n"
Kevin Wolf4534ff52012-05-11 16:07:02 +0200109 "Parameters to check subcommand:\n"
110 " '-r' tries to repair any inconsistencies that are found during the check.\n"
111 " '-r leaks' repairs only cluster leaks, whereas '-r all' fixes all\n"
112 " kinds of errors, with a higher risk of choosing the wrong fix or\n"
Stefan Weil0546b8c2012-08-10 22:03:25 +0200113 " hiding corruption that has already occurred.\n"
Kevin Wolf4534ff52012-05-11 16:07:02 +0200114 "\n"
malc3f020d72010-02-08 12:04:56 +0300115 "Parameters to snapshot subcommand:\n"
116 " 'snapshot' is the name of the snapshot to create, apply or delete\n"
117 " '-a' applies a snapshot (revert disk to saved state)\n"
118 " '-c' creates a snapshot\n"
119 " '-d' deletes a snapshot\n"
Miroslav Rezaninad14ed182013-02-13 09:09:41 +0100120 " '-l' lists all snapshots in the given image\n"
121 "\n"
122 "Parameters to compare subcommand:\n"
123 " '-f' first image format\n"
124 " '-F' second image format\n"
125 " '-s' run in Strict mode - fail on different image size or sector allocation\n";
Paolo Bonzinie00291c2010-02-04 16:49:56 +0100126
127 printf("%s\nSupported formats:", help_msg);
bellardea2384d2004-08-01 21:59:26 +0000128 bdrv_iterate_format(format_print, NULL);
129 printf("\n");
130 exit(1);
131}
132
Stefan Weil7c30f652013-06-16 17:01:05 +0200133static int GCC_FMT_ATTR(2, 3) qprintf(bool quiet, const char *fmt, ...)
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100134{
135 int ret = 0;
136 if (!quiet) {
137 va_list args;
138 va_start(args, fmt);
139 ret = vprintf(fmt, args);
140 va_end(args);
141 }
142 return ret;
143}
144
bellardea2384d2004-08-01 21:59:26 +0000145#if defined(WIN32)
146/* XXX: put correct support for win32 */
147static int read_password(char *buf, int buf_size)
148{
149 int c, i;
150 printf("Password: ");
151 fflush(stdout);
152 i = 0;
153 for(;;) {
154 c = getchar();
155 if (c == '\n')
156 break;
157 if (i < (buf_size - 1))
158 buf[i++] = c;
159 }
160 buf[i] = '\0';
161 return 0;
162}
163
164#else
165
166#include <termios.h>
167
168static struct termios oldtty;
169
170static void term_exit(void)
171{
172 tcsetattr (0, TCSANOW, &oldtty);
173}
174
175static void term_init(void)
176{
177 struct termios tty;
178
179 tcgetattr (0, &tty);
180 oldtty = tty;
181
182 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
183 |INLCR|IGNCR|ICRNL|IXON);
184 tty.c_oflag |= OPOST;
185 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
186 tty.c_cflag &= ~(CSIZE|PARENB);
187 tty.c_cflag |= CS8;
188 tty.c_cc[VMIN] = 1;
189 tty.c_cc[VTIME] = 0;
ths3b46e622007-09-17 08:09:54 +0000190
bellardea2384d2004-08-01 21:59:26 +0000191 tcsetattr (0, TCSANOW, &tty);
192
193 atexit(term_exit);
194}
195
pbrook3f379ab2007-11-11 03:33:13 +0000196static int read_password(char *buf, int buf_size)
bellardea2384d2004-08-01 21:59:26 +0000197{
198 uint8_t ch;
199 int i, ret;
200
201 printf("password: ");
202 fflush(stdout);
203 term_init();
204 i = 0;
205 for(;;) {
206 ret = read(0, &ch, 1);
207 if (ret == -1) {
208 if (errno == EAGAIN || errno == EINTR) {
209 continue;
210 } else {
211 ret = -1;
212 break;
213 }
214 } else if (ret == 0) {
215 ret = -1;
216 break;
217 } else {
218 if (ch == '\r') {
219 ret = 0;
220 break;
221 }
222 if (i < (buf_size - 1))
223 buf[i++] = ch;
224 }
225 }
226 term_exit();
227 buf[i] = '\0';
228 printf("\n");
229 return ret;
230}
231#endif
232
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100233static int print_block_option_help(const char *filename, const char *fmt)
234{
235 BlockDriver *drv, *proto_drv;
236 QEMUOptionParameter *create_options = NULL;
237
238 /* Find driver and parse its options */
239 drv = bdrv_find_format(fmt);
240 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100241 error_report("Unknown file format '%s'", fmt);
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100242 return 1;
243 }
244
Kevin Wolf98289622013-07-10 15:47:39 +0200245 proto_drv = bdrv_find_protocol(filename, true);
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100246 if (!proto_drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100247 error_report("Unknown protocol '%s'", filename);
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100248 return 1;
249 }
250
251 create_options = append_option_parameters(create_options,
252 drv->create_options);
253 create_options = append_option_parameters(create_options,
254 proto_drv->create_options);
255 print_option_help(create_options);
256 free_option_parameters(create_options);
257 return 0;
258}
259
bellard75c23802004-08-27 21:28:58 +0000260static BlockDriverState *bdrv_new_open(const char *filename,
Sheng Yang9bc378c2010-01-29 10:15:06 +0800261 const char *fmt,
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +0100262 int flags,
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100263 bool require_io,
264 bool quiet)
bellard75c23802004-08-27 21:28:58 +0000265{
266 BlockDriverState *bs;
267 BlockDriver *drv;
268 char password[256];
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100269 int ret;
bellard75c23802004-08-27 21:28:58 +0000270
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100271 bs = bdrv_new("image");
Kevin Wolfad717132010-12-16 15:37:41 +0100272
bellard75c23802004-08-27 21:28:58 +0000273 if (fmt) {
274 drv = bdrv_find_format(fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900275 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100276 error_report("Unknown file format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900277 goto fail;
278 }
bellard75c23802004-08-27 21:28:58 +0000279 } else {
280 drv = NULL;
281 }
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100282
Kevin Wolfde9c0ce2013-03-15 10:35:02 +0100283 ret = bdrv_open(bs, filename, NULL, flags, drv);
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100284 if (ret < 0) {
285 error_report("Could not open '%s': %s", filename, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900286 goto fail;
bellard75c23802004-08-27 21:28:58 +0000287 }
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100288
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +0100289 if (bdrv_is_encrypted(bs) && require_io) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100290 qprintf(quiet, "Disk image '%s' is encrypted.\n", filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900291 if (read_password(password, sizeof(password)) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100292 error_report("No password given");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900293 goto fail;
294 }
295 if (bdrv_set_key(bs, password) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100296 error_report("invalid password");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900297 goto fail;
298 }
bellard75c23802004-08-27 21:28:58 +0000299 }
300 return bs;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900301fail:
302 if (bs) {
Fam Zheng4f6fd342013-08-23 09:14:47 +0800303 bdrv_unref(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900304 }
305 return NULL;
bellard75c23802004-08-27 21:28:58 +0000306}
307
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900308static int add_old_style_options(const char *fmt, QEMUOptionParameter *list,
Jes Sorenseneec77d92010-12-07 17:44:34 +0100309 const char *base_filename,
310 const char *base_fmt)
Kevin Wolfefa84d42009-05-18 16:42:12 +0200311{
Kevin Wolfefa84d42009-05-18 16:42:12 +0200312 if (base_filename) {
313 if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100314 error_report("Backing file not supported for file format '%s'",
315 fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900316 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200317 }
318 }
319 if (base_fmt) {
320 if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100321 error_report("Backing file format not supported for file "
322 "format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900323 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200324 }
325 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900326 return 0;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200327}
328
bellardea2384d2004-08-01 21:59:26 +0000329static int img_create(int argc, char **argv)
330{
Luiz Capitulinoa9300912012-11-30 10:52:06 -0200331 int c;
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100332 uint64_t img_size = -1;
bellardea2384d2004-08-01 21:59:26 +0000333 const char *fmt = "raw";
aliguori9230eaf2009-03-28 17:55:19 +0000334 const char *base_fmt = NULL;
bellardea2384d2004-08-01 21:59:26 +0000335 const char *filename;
336 const char *base_filename = NULL;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200337 char *options = NULL;
Luiz Capitulino9b375252012-11-30 10:52:05 -0200338 Error *local_err = NULL;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100339 bool quiet = false;
ths3b46e622007-09-17 08:09:54 +0000340
bellardea2384d2004-08-01 21:59:26 +0000341 for(;;) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100342 c = getopt(argc, argv, "F:b:f:he6o:q");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100343 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000344 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100345 }
bellardea2384d2004-08-01 21:59:26 +0000346 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100347 case '?':
bellardea2384d2004-08-01 21:59:26 +0000348 case 'h':
349 help();
350 break;
aliguori9230eaf2009-03-28 17:55:19 +0000351 case 'F':
352 base_fmt = optarg;
353 break;
bellardea2384d2004-08-01 21:59:26 +0000354 case 'b':
355 base_filename = optarg;
356 break;
357 case 'f':
358 fmt = optarg;
359 break;
360 case 'e':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200361 error_report("option -e is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100362 "encryption\' instead!");
363 return 1;
thsd8871c52007-10-24 16:11:42 +0000364 case '6':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200365 error_report("option -6 is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100366 "compat6\' instead!");
367 return 1;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200368 case 'o':
369 options = optarg;
370 break;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100371 case 'q':
372 quiet = true;
373 break;
bellardea2384d2004-08-01 21:59:26 +0000374 }
375 }
aliguori9230eaf2009-03-28 17:55:19 +0000376
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900377 /* Get the filename */
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100378 if (optind >= argc) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900379 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100380 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900381 filename = argv[optind++];
382
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100383 /* Get image size, if specified */
384 if (optind < argc) {
Jes Sorensen70b4f4b2011-01-05 11:41:02 +0100385 int64_t sval;
Markus Armbrustere36b3692011-11-22 09:46:05 +0100386 char *end;
387 sval = strtosz_suffix(argv[optind++], &end, STRTOSZ_DEFSUFFIX_B);
388 if (sval < 0 || *end) {
liguang79443392012-12-17 09:49:23 +0800389 if (sval == -ERANGE) {
390 error_report("Image size must be less than 8 EiB!");
391 } else {
392 error_report("Invalid image size specified! You may use k, M, "
Kevin Wolf5e009842013-06-05 14:19:27 +0200393 "G, T, P or E suffixes for ");
394 error_report("kilobytes, megabytes, gigabytes, terabytes, "
395 "petabytes and exabytes.");
liguang79443392012-12-17 09:49:23 +0800396 }
Luiz Capitulinoa9300912012-11-30 10:52:06 -0200397 return 1;
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100398 }
399 img_size = (uint64_t)sval;
400 }
Kevin Wolffc11eb22013-08-05 10:53:04 +0200401 if (optind != argc) {
402 help();
403 }
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100404
Peter Maydellc8057f92012-08-02 13:45:54 +0100405 if (options && is_help_option(options)) {
Luiz Capitulinoa9300912012-11-30 10:52:06 -0200406 return print_block_option_help(filename, fmt);
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100407 }
408
Luiz Capitulino9b375252012-11-30 10:52:05 -0200409 bdrv_img_create(filename, fmt, base_filename, base_fmt,
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100410 options, img_size, BDRV_O_FLAGS, &local_err, quiet);
Luiz Capitulino9b375252012-11-30 10:52:05 -0200411 if (error_is_set(&local_err)) {
412 error_report("%s", error_get_pretty(local_err));
413 error_free(local_err);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900414 return 1;
415 }
Luiz Capitulinoa9300912012-11-30 10:52:06 -0200416
bellardea2384d2004-08-01 21:59:26 +0000417 return 0;
418}
419
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100420static void dump_json_image_check(ImageCheck *check, bool quiet)
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500421{
422 Error *errp = NULL;
423 QString *str;
424 QmpOutputVisitor *ov = qmp_output_visitor_new();
425 QObject *obj;
426 visit_type_ImageCheck(qmp_output_get_visitor(ov),
427 &check, NULL, &errp);
428 obj = qmp_output_get_qobject(ov);
429 str = qobject_to_json_pretty(obj);
430 assert(str != NULL);
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100431 qprintf(quiet, "%s\n", qstring_get_str(str));
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500432 qobject_decref(obj);
433 qmp_output_visitor_cleanup(ov);
434 QDECREF(str);
435}
436
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100437static void dump_human_image_check(ImageCheck *check, bool quiet)
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500438{
439 if (!(check->corruptions || check->leaks || check->check_errors)) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100440 qprintf(quiet, "No errors were found on the image.\n");
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500441 } else {
442 if (check->corruptions) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100443 qprintf(quiet, "\n%" PRId64 " errors were found on the image.\n"
444 "Data may be corrupted, or further writes to the image "
445 "may corrupt it.\n",
446 check->corruptions);
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500447 }
448
449 if (check->leaks) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100450 qprintf(quiet,
451 "\n%" PRId64 " leaked clusters were found on the image.\n"
452 "This means waste of disk space, but no harm to data.\n",
453 check->leaks);
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500454 }
455
456 if (check->check_errors) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100457 qprintf(quiet,
458 "\n%" PRId64
459 " internal errors have occurred during the check.\n",
460 check->check_errors);
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500461 }
462 }
463
464 if (check->total_clusters != 0 && check->allocated_clusters != 0) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100465 qprintf(quiet, "%" PRId64 "/%" PRId64 " = %0.2f%% allocated, "
466 "%0.2f%% fragmented, %0.2f%% compressed clusters\n",
467 check->allocated_clusters, check->total_clusters,
468 check->allocated_clusters * 100.0 / check->total_clusters,
469 check->fragmented_clusters * 100.0 / check->allocated_clusters,
470 check->compressed_clusters * 100.0 /
471 check->allocated_clusters);
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500472 }
473
474 if (check->image_end_offset) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100475 qprintf(quiet,
476 "Image end offset: %" PRId64 "\n", check->image_end_offset);
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500477 }
478}
479
480static int collect_image_check(BlockDriverState *bs,
481 ImageCheck *check,
482 const char *filename,
483 const char *fmt,
484 int fix)
485{
486 int ret;
487 BdrvCheckResult result;
488
489 ret = bdrv_check(bs, &result, fix);
490 if (ret < 0) {
491 return ret;
492 }
493
494 check->filename = g_strdup(filename);
495 check->format = g_strdup(bdrv_get_format_name(bs));
496 check->check_errors = result.check_errors;
497 check->corruptions = result.corruptions;
498 check->has_corruptions = result.corruptions != 0;
499 check->leaks = result.leaks;
500 check->has_leaks = result.leaks != 0;
501 check->corruptions_fixed = result.corruptions_fixed;
502 check->has_corruptions_fixed = result.corruptions != 0;
503 check->leaks_fixed = result.leaks_fixed;
504 check->has_leaks_fixed = result.leaks != 0;
505 check->image_end_offset = result.image_end_offset;
506 check->has_image_end_offset = result.image_end_offset != 0;
507 check->total_clusters = result.bfi.total_clusters;
508 check->has_total_clusters = result.bfi.total_clusters != 0;
509 check->allocated_clusters = result.bfi.allocated_clusters;
510 check->has_allocated_clusters = result.bfi.allocated_clusters != 0;
511 check->fragmented_clusters = result.bfi.fragmented_clusters;
512 check->has_fragmented_clusters = result.bfi.fragmented_clusters != 0;
Stefan Hajnoczie6439d72013-02-07 17:15:04 +0100513 check->compressed_clusters = result.bfi.compressed_clusters;
514 check->has_compressed_clusters = result.bfi.compressed_clusters != 0;
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500515
516 return 0;
517}
518
Kevin Wolfe076f332010-06-29 11:43:13 +0200519/*
520 * Checks an image for consistency. Exit codes:
521 *
522 * 0 - Check completed, image is good
523 * 1 - Check not completed because of internal errors
524 * 2 - Check completed, image is corrupted
525 * 3 - Check completed, image has leaked clusters, but is good otherwise
526 */
aliguori15859692009-04-21 23:11:53 +0000527static int img_check(int argc, char **argv)
528{
529 int c, ret;
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500530 OutputFormat output_format = OFORMAT_HUMAN;
531 const char *filename, *fmt, *output;
aliguori15859692009-04-21 23:11:53 +0000532 BlockDriverState *bs;
Kevin Wolf4534ff52012-05-11 16:07:02 +0200533 int fix = 0;
Stefan Hajnoczi058f8f12012-08-09 13:05:56 +0100534 int flags = BDRV_O_FLAGS | BDRV_O_CHECK;
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500535 ImageCheck *check;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100536 bool quiet = false;
aliguori15859692009-04-21 23:11:53 +0000537
538 fmt = NULL;
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500539 output = NULL;
aliguori15859692009-04-21 23:11:53 +0000540 for(;;) {
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500541 int option_index = 0;
542 static const struct option long_options[] = {
543 {"help", no_argument, 0, 'h'},
544 {"format", required_argument, 0, 'f'},
545 {"repair", no_argument, 0, 'r'},
546 {"output", required_argument, 0, OPTION_OUTPUT},
547 {0, 0, 0, 0}
548 };
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100549 c = getopt_long(argc, argv, "f:hr:q",
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500550 long_options, &option_index);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100551 if (c == -1) {
aliguori15859692009-04-21 23:11:53 +0000552 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100553 }
aliguori15859692009-04-21 23:11:53 +0000554 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100555 case '?':
aliguori15859692009-04-21 23:11:53 +0000556 case 'h':
557 help();
558 break;
559 case 'f':
560 fmt = optarg;
561 break;
Kevin Wolf4534ff52012-05-11 16:07:02 +0200562 case 'r':
563 flags |= BDRV_O_RDWR;
564
565 if (!strcmp(optarg, "leaks")) {
566 fix = BDRV_FIX_LEAKS;
567 } else if (!strcmp(optarg, "all")) {
568 fix = BDRV_FIX_LEAKS | BDRV_FIX_ERRORS;
569 } else {
570 help();
571 }
572 break;
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500573 case OPTION_OUTPUT:
574 output = optarg;
575 break;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100576 case 'q':
577 quiet = true;
578 break;
aliguori15859692009-04-21 23:11:53 +0000579 }
580 }
Kevin Wolffc11eb22013-08-05 10:53:04 +0200581 if (optind != argc - 1) {
aliguori15859692009-04-21 23:11:53 +0000582 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100583 }
aliguori15859692009-04-21 23:11:53 +0000584 filename = argv[optind++];
585
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500586 if (output && !strcmp(output, "json")) {
587 output_format = OFORMAT_JSON;
588 } else if (output && !strcmp(output, "human")) {
589 output_format = OFORMAT_HUMAN;
590 } else if (output) {
591 error_report("--output must be used with human or json as argument.");
592 return 1;
593 }
594
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100595 bs = bdrv_new_open(filename, fmt, flags, true, quiet);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900596 if (!bs) {
597 return 1;
598 }
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500599
600 check = g_new0(ImageCheck, 1);
601 ret = collect_image_check(bs, check, filename, fmt, fix);
Kevin Wolfe076f332010-06-29 11:43:13 +0200602
603 if (ret == -ENOTSUP) {
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500604 if (output_format == OFORMAT_HUMAN) {
605 error_report("This image format does not support checks");
606 }
607 ret = 1;
608 goto fail;
Kevin Wolfe076f332010-06-29 11:43:13 +0200609 }
610
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500611 if (check->corruptions_fixed || check->leaks_fixed) {
612 int corruptions_fixed, leaks_fixed;
613
614 leaks_fixed = check->leaks_fixed;
615 corruptions_fixed = check->corruptions_fixed;
616
617 if (output_format == OFORMAT_HUMAN) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100618 qprintf(quiet,
619 "The following inconsistencies were found and repaired:\n\n"
620 " %" PRId64 " leaked clusters\n"
621 " %" PRId64 " corruptions\n\n"
622 "Double checking the fixed image now...\n",
623 check->leaks_fixed,
624 check->corruptions_fixed);
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500625 }
626
627 ret = collect_image_check(bs, check, filename, fmt, 0);
628
629 check->leaks_fixed = leaks_fixed;
630 check->corruptions_fixed = corruptions_fixed;
Kevin Wolfccf34712012-05-11 18:16:54 +0200631 }
632
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500633 switch (output_format) {
634 case OFORMAT_HUMAN:
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100635 dump_human_image_check(check, quiet);
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500636 break;
637 case OFORMAT_JSON:
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100638 dump_json_image_check(check, quiet);
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500639 break;
640 }
641
642 if (ret || check->check_errors) {
643 ret = 1;
644 goto fail;
645 }
646
647 if (check->corruptions) {
648 ret = 2;
649 } else if (check->leaks) {
650 ret = 3;
Kevin Wolfe076f332010-06-29 11:43:13 +0200651 } else {
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500652 ret = 0;
aliguori15859692009-04-21 23:11:53 +0000653 }
654
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500655fail:
656 qapi_free_ImageCheck(check);
Fam Zheng4f6fd342013-08-23 09:14:47 +0800657 bdrv_unref(bs);
Kevin Wolfe076f332010-06-29 11:43:13 +0200658
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500659 return ret;
aliguori15859692009-04-21 23:11:53 +0000660}
661
bellardea2384d2004-08-01 21:59:26 +0000662static int img_commit(int argc, char **argv)
663{
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400664 int c, ret, flags;
665 const char *filename, *fmt, *cache;
bellardea2384d2004-08-01 21:59:26 +0000666 BlockDriverState *bs;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100667 bool quiet = false;
bellardea2384d2004-08-01 21:59:26 +0000668
669 fmt = NULL;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400670 cache = BDRV_DEFAULT_CACHE;
bellardea2384d2004-08-01 21:59:26 +0000671 for(;;) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100672 c = getopt(argc, argv, "f:ht:q");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100673 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000674 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100675 }
bellardea2384d2004-08-01 21:59:26 +0000676 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100677 case '?':
bellardea2384d2004-08-01 21:59:26 +0000678 case 'h':
679 help();
680 break;
681 case 'f':
682 fmt = optarg;
683 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400684 case 't':
685 cache = optarg;
686 break;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100687 case 'q':
688 quiet = true;
689 break;
bellardea2384d2004-08-01 21:59:26 +0000690 }
691 }
Kevin Wolffc11eb22013-08-05 10:53:04 +0200692 if (optind != argc - 1) {
bellardea2384d2004-08-01 21:59:26 +0000693 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100694 }
bellardea2384d2004-08-01 21:59:26 +0000695 filename = argv[optind++];
696
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400697 flags = BDRV_O_RDWR;
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +0100698 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400699 if (ret < 0) {
700 error_report("Invalid cache option: %s", cache);
701 return -1;
702 }
703
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100704 bs = bdrv_new_open(filename, fmt, flags, true, quiet);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900705 if (!bs) {
706 return 1;
707 }
bellardea2384d2004-08-01 21:59:26 +0000708 ret = bdrv_commit(bs);
709 switch(ret) {
710 case 0:
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100711 qprintf(quiet, "Image committed.\n");
bellardea2384d2004-08-01 21:59:26 +0000712 break;
713 case -ENOENT:
Jes Sorensen15654a62010-12-16 14:31:53 +0100714 error_report("No disk inserted");
bellardea2384d2004-08-01 21:59:26 +0000715 break;
716 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +0100717 error_report("Image is read-only");
bellardea2384d2004-08-01 21:59:26 +0000718 break;
719 case -ENOTSUP:
Jes Sorensen15654a62010-12-16 14:31:53 +0100720 error_report("Image is already committed");
bellardea2384d2004-08-01 21:59:26 +0000721 break;
722 default:
Jes Sorensen15654a62010-12-16 14:31:53 +0100723 error_report("Error while committing image");
bellardea2384d2004-08-01 21:59:26 +0000724 break;
725 }
726
Fam Zheng4f6fd342013-08-23 09:14:47 +0800727 bdrv_unref(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900728 if (ret) {
729 return 1;
730 }
bellardea2384d2004-08-01 21:59:26 +0000731 return 0;
732}
733
Dmitry Konishchevf6a00aa2011-05-18 15:03:59 +0400734/*
thsf58c7b32008-06-05 21:53:49 +0000735 * Returns true iff the first sector pointed to by 'buf' contains at least
736 * a non-NUL byte.
737 *
738 * 'pnum' is set to the number of sectors (including and immediately following
739 * the first one) that are known to be in the same allocated/unallocated state.
740 */
bellardea2384d2004-08-01 21:59:26 +0000741static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
742{
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000743 bool is_zero;
744 int i;
bellardea2384d2004-08-01 21:59:26 +0000745
746 if (n <= 0) {
747 *pnum = 0;
748 return 0;
749 }
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000750 is_zero = buffer_is_zero(buf, 512);
bellardea2384d2004-08-01 21:59:26 +0000751 for(i = 1; i < n; i++) {
752 buf += 512;
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000753 if (is_zero != buffer_is_zero(buf, 512)) {
bellardea2384d2004-08-01 21:59:26 +0000754 break;
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000755 }
bellardea2384d2004-08-01 21:59:26 +0000756 }
757 *pnum = i;
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000758 return !is_zero;
bellardea2384d2004-08-01 21:59:26 +0000759}
760
Kevin Wolf3e85c6f2010-01-12 12:55:18 +0100761/*
Kevin Wolfa22f1232011-08-26 15:27:13 +0200762 * Like is_allocated_sectors, but if the buffer starts with a used sector,
763 * up to 'min' consecutive sectors containing zeros are ignored. This avoids
764 * breaking up write requests for only small sparse areas.
765 */
766static int is_allocated_sectors_min(const uint8_t *buf, int n, int *pnum,
767 int min)
768{
769 int ret;
770 int num_checked, num_used;
771
772 if (n < min) {
773 min = n;
774 }
775
776 ret = is_allocated_sectors(buf, n, pnum);
777 if (!ret) {
778 return ret;
779 }
780
781 num_used = *pnum;
782 buf += BDRV_SECTOR_SIZE * *pnum;
783 n -= *pnum;
784 num_checked = num_used;
785
786 while (n > 0) {
787 ret = is_allocated_sectors(buf, n, pnum);
788
789 buf += BDRV_SECTOR_SIZE * *pnum;
790 n -= *pnum;
791 num_checked += *pnum;
792 if (ret) {
793 num_used = num_checked;
794 } else if (*pnum >= min) {
795 break;
796 }
797 }
798
799 *pnum = num_used;
800 return 1;
801}
802
803/*
Kevin Wolf3e85c6f2010-01-12 12:55:18 +0100804 * Compares two buffers sector by sector. Returns 0 if the first sector of both
805 * buffers matches, non-zero otherwise.
806 *
807 * pnum is set to the number of sectors (including and immediately following
808 * the first one) that are known to have the same comparison result
809 */
810static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
811 int *pnum)
812{
813 int res, i;
814
815 if (n <= 0) {
816 *pnum = 0;
817 return 0;
818 }
819
820 res = !!memcmp(buf1, buf2, 512);
821 for(i = 1; i < n; i++) {
822 buf1 += 512;
823 buf2 += 512;
824
825 if (!!memcmp(buf1, buf2, 512) != res) {
826 break;
827 }
828 }
829
830 *pnum = i;
831 return res;
832}
833
Kevin Wolf80ee15a2009-09-15 12:30:43 +0200834#define IO_BUF_SIZE (2 * 1024 * 1024)
bellardea2384d2004-08-01 21:59:26 +0000835
Miroslav Rezaninad14ed182013-02-13 09:09:41 +0100836static int64_t sectors_to_bytes(int64_t sectors)
837{
838 return sectors << BDRV_SECTOR_BITS;
839}
840
841static int64_t sectors_to_process(int64_t total, int64_t from)
842{
843 return MIN(total - from, IO_BUF_SIZE >> BDRV_SECTOR_BITS);
844}
845
846/*
847 * Check if passed sectors are empty (not allocated or contain only 0 bytes)
848 *
849 * Returns 0 in case sectors are filled with 0, 1 if sectors contain non-zero
850 * data and negative value on error.
851 *
852 * @param bs: Driver used for accessing file
853 * @param sect_num: Number of first sector to check
854 * @param sect_count: Number of sectors to check
855 * @param filename: Name of disk file we are checking (logging purpose)
856 * @param buffer: Allocated buffer for storing read data
857 * @param quiet: Flag for quiet mode
858 */
859static int check_empty_sectors(BlockDriverState *bs, int64_t sect_num,
860 int sect_count, const char *filename,
861 uint8_t *buffer, bool quiet)
862{
863 int pnum, ret = 0;
864 ret = bdrv_read(bs, sect_num, buffer, sect_count);
865 if (ret < 0) {
866 error_report("Error while reading offset %" PRId64 " of %s: %s",
867 sectors_to_bytes(sect_num), filename, strerror(-ret));
868 return ret;
869 }
870 ret = is_allocated_sectors(buffer, sect_count, &pnum);
871 if (ret || pnum != sect_count) {
872 qprintf(quiet, "Content mismatch at offset %" PRId64 "!\n",
873 sectors_to_bytes(ret ? sect_num : sect_num + pnum));
874 return 1;
875 }
876
877 return 0;
878}
879
880/*
881 * Compares two images. Exit codes:
882 *
883 * 0 - Images are identical
884 * 1 - Images differ
885 * >1 - Error occurred
886 */
887static int img_compare(int argc, char **argv)
888{
889 const char *fmt1 = NULL, *fmt2 = NULL, *filename1, *filename2;
890 BlockDriverState *bs1, *bs2;
891 int64_t total_sectors1, total_sectors2;
892 uint8_t *buf1 = NULL, *buf2 = NULL;
893 int pnum1, pnum2;
894 int allocated1, allocated2;
895 int ret = 0; /* return value - 0 Ident, 1 Different, >1 Error */
896 bool progress = false, quiet = false, strict = false;
897 int64_t total_sectors;
898 int64_t sector_num = 0;
899 int64_t nb_sectors;
900 int c, pnum;
901 uint64_t bs_sectors;
902 uint64_t progress_base;
903
904 for (;;) {
905 c = getopt(argc, argv, "hpf:F:sq");
906 if (c == -1) {
907 break;
908 }
909 switch (c) {
910 case '?':
911 case 'h':
912 help();
913 break;
914 case 'f':
915 fmt1 = optarg;
916 break;
917 case 'F':
918 fmt2 = optarg;
919 break;
920 case 'p':
921 progress = true;
922 break;
923 case 'q':
924 quiet = true;
925 break;
926 case 's':
927 strict = true;
928 break;
929 }
930 }
931
932 /* Progress is not shown in Quiet mode */
933 if (quiet) {
934 progress = false;
935 }
936
937
Kevin Wolffc11eb22013-08-05 10:53:04 +0200938 if (optind != argc - 2) {
Miroslav Rezaninad14ed182013-02-13 09:09:41 +0100939 help();
940 }
941 filename1 = argv[optind++];
942 filename2 = argv[optind++];
943
944 /* Initialize before goto out */
945 qemu_progress_init(progress, 2.0);
946
947 bs1 = bdrv_new_open(filename1, fmt1, BDRV_O_FLAGS, true, quiet);
948 if (!bs1) {
949 error_report("Can't open file %s", filename1);
950 ret = 2;
951 goto out3;
952 }
953
954 bs2 = bdrv_new_open(filename2, fmt2, BDRV_O_FLAGS, true, quiet);
955 if (!bs2) {
956 error_report("Can't open file %s", filename2);
957 ret = 2;
958 goto out2;
959 }
960
961 buf1 = qemu_blockalign(bs1, IO_BUF_SIZE);
962 buf2 = qemu_blockalign(bs2, IO_BUF_SIZE);
963 bdrv_get_geometry(bs1, &bs_sectors);
964 total_sectors1 = bs_sectors;
965 bdrv_get_geometry(bs2, &bs_sectors);
966 total_sectors2 = bs_sectors;
967 total_sectors = MIN(total_sectors1, total_sectors2);
968 progress_base = MAX(total_sectors1, total_sectors2);
969
970 qemu_progress_print(0, 100);
971
972 if (strict && total_sectors1 != total_sectors2) {
973 ret = 1;
974 qprintf(quiet, "Strict mode: Image size mismatch!\n");
975 goto out;
976 }
977
978 for (;;) {
979 nb_sectors = sectors_to_process(total_sectors, sector_num);
980 if (nb_sectors <= 0) {
981 break;
982 }
983 allocated1 = bdrv_is_allocated_above(bs1, NULL, sector_num, nb_sectors,
984 &pnum1);
985 if (allocated1 < 0) {
986 ret = 3;
987 error_report("Sector allocation test failed for %s", filename1);
988 goto out;
989 }
990
991 allocated2 = bdrv_is_allocated_above(bs2, NULL, sector_num, nb_sectors,
992 &pnum2);
993 if (allocated2 < 0) {
994 ret = 3;
995 error_report("Sector allocation test failed for %s", filename2);
996 goto out;
997 }
998 nb_sectors = MIN(pnum1, pnum2);
999
1000 if (allocated1 == allocated2) {
1001 if (allocated1) {
1002 ret = bdrv_read(bs1, sector_num, buf1, nb_sectors);
1003 if (ret < 0) {
1004 error_report("Error while reading offset %" PRId64 " of %s:"
1005 " %s", sectors_to_bytes(sector_num), filename1,
1006 strerror(-ret));
1007 ret = 4;
1008 goto out;
1009 }
1010 ret = bdrv_read(bs2, sector_num, buf2, nb_sectors);
1011 if (ret < 0) {
1012 error_report("Error while reading offset %" PRId64
1013 " of %s: %s", sectors_to_bytes(sector_num),
1014 filename2, strerror(-ret));
1015 ret = 4;
1016 goto out;
1017 }
1018 ret = compare_sectors(buf1, buf2, nb_sectors, &pnum);
1019 if (ret || pnum != nb_sectors) {
1020 ret = 1;
1021 qprintf(quiet, "Content mismatch at offset %" PRId64 "!\n",
1022 sectors_to_bytes(
1023 ret ? sector_num : sector_num + pnum));
1024 goto out;
1025 }
1026 }
1027 } else {
1028 if (strict) {
1029 ret = 1;
1030 qprintf(quiet, "Strict mode: Offset %" PRId64
1031 " allocation mismatch!\n",
1032 sectors_to_bytes(sector_num));
1033 goto out;
1034 }
1035
1036 if (allocated1) {
1037 ret = check_empty_sectors(bs1, sector_num, nb_sectors,
1038 filename1, buf1, quiet);
1039 } else {
1040 ret = check_empty_sectors(bs2, sector_num, nb_sectors,
1041 filename2, buf1, quiet);
1042 }
1043 if (ret) {
1044 if (ret < 0) {
1045 ret = 4;
1046 error_report("Error while reading offset %" PRId64 ": %s",
1047 sectors_to_bytes(sector_num), strerror(-ret));
1048 }
1049 goto out;
1050 }
1051 }
1052 sector_num += nb_sectors;
1053 qemu_progress_print(((float) nb_sectors / progress_base)*100, 100);
1054 }
1055
1056 if (total_sectors1 != total_sectors2) {
1057 BlockDriverState *bs_over;
1058 int64_t total_sectors_over;
1059 const char *filename_over;
1060
1061 qprintf(quiet, "Warning: Image size mismatch!\n");
1062 if (total_sectors1 > total_sectors2) {
1063 total_sectors_over = total_sectors1;
1064 bs_over = bs1;
1065 filename_over = filename1;
1066 } else {
1067 total_sectors_over = total_sectors2;
1068 bs_over = bs2;
1069 filename_over = filename2;
1070 }
1071
1072 for (;;) {
1073 nb_sectors = sectors_to_process(total_sectors_over, sector_num);
1074 if (nb_sectors <= 0) {
1075 break;
1076 }
1077 ret = bdrv_is_allocated_above(bs_over, NULL, sector_num,
1078 nb_sectors, &pnum);
1079 if (ret < 0) {
1080 ret = 3;
1081 error_report("Sector allocation test failed for %s",
1082 filename_over);
1083 goto out;
1084
1085 }
1086 nb_sectors = pnum;
1087 if (ret) {
1088 ret = check_empty_sectors(bs_over, sector_num, nb_sectors,
1089 filename_over, buf1, quiet);
1090 if (ret) {
1091 if (ret < 0) {
1092 ret = 4;
1093 error_report("Error while reading offset %" PRId64
1094 " of %s: %s", sectors_to_bytes(sector_num),
1095 filename_over, strerror(-ret));
1096 }
1097 goto out;
1098 }
1099 }
1100 sector_num += nb_sectors;
1101 qemu_progress_print(((float) nb_sectors / progress_base)*100, 100);
1102 }
1103 }
1104
1105 qprintf(quiet, "Images are identical.\n");
1106 ret = 0;
1107
1108out:
Fam Zheng4f6fd342013-08-23 09:14:47 +08001109 bdrv_unref(bs2);
Miroslav Rezaninad14ed182013-02-13 09:09:41 +01001110 qemu_vfree(buf1);
1111 qemu_vfree(buf2);
1112out2:
Fam Zheng4f6fd342013-08-23 09:14:47 +08001113 bdrv_unref(bs1);
Miroslav Rezaninad14ed182013-02-13 09:09:41 +01001114out3:
1115 qemu_progress_end();
1116 return ret;
1117}
1118
bellardea2384d2004-08-01 21:59:26 +00001119static int img_convert(int argc, char **argv)
1120{
Alexandre Derumierb2e10492013-09-02 19:07:24 +01001121 int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size,
1122 cluster_sectors, skip_create;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001123 int progress = 0, flags;
1124 const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +09001125 BlockDriver *drv, *proto_drv;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001126 BlockDriverState **bs = NULL, *out_bs = NULL;
ths96b8f132007-12-17 01:35:20 +00001127 int64_t total_sectors, nb_sectors, sector_num, bs_offset;
1128 uint64_t bs_sectors;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001129 uint8_t * buf = NULL;
bellardea2384d2004-08-01 21:59:26 +00001130 const uint8_t *buf1;
bellardfaea38e2006-08-05 21:31:00 +00001131 BlockDriverInfo bdi;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +09001132 QEMUOptionParameter *param = NULL, *create_options = NULL;
Kevin Wolfa18953f2010-10-14 15:46:04 +02001133 QEMUOptionParameter *out_baseimg_param;
Kevin Wolfefa84d42009-05-18 16:42:12 +02001134 char *options = NULL;
edison51ef6722010-09-21 19:58:41 -07001135 const char *snapshot_name = NULL;
Kevin Wolf1f710492012-10-12 14:29:18 +02001136 float local_progress = 0;
Kevin Wolfa22f1232011-08-26 15:27:13 +02001137 int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01001138 bool quiet = false;
bellardea2384d2004-08-01 21:59:26 +00001139
1140 fmt = NULL;
1141 out_fmt = "raw";
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001142 cache = "unsafe";
thsf58c7b32008-06-05 21:53:49 +00001143 out_baseimg = NULL;
Jes Sorenseneec77d92010-12-07 17:44:34 +01001144 compress = 0;
Alexandre Derumierb2e10492013-09-02 19:07:24 +01001145 skip_create = 0;
bellardea2384d2004-08-01 21:59:26 +00001146 for(;;) {
Alexandre Derumierb2e10492013-09-02 19:07:24 +01001147 c = getopt(argc, argv, "f:O:B:s:hce6o:pS:t:qn");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001148 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +00001149 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001150 }
bellardea2384d2004-08-01 21:59:26 +00001151 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001152 case '?':
bellardea2384d2004-08-01 21:59:26 +00001153 case 'h':
1154 help();
1155 break;
1156 case 'f':
1157 fmt = optarg;
1158 break;
1159 case 'O':
1160 out_fmt = optarg;
1161 break;
thsf58c7b32008-06-05 21:53:49 +00001162 case 'B':
1163 out_baseimg = optarg;
1164 break;
bellardea2384d2004-08-01 21:59:26 +00001165 case 'c':
Jes Sorenseneec77d92010-12-07 17:44:34 +01001166 compress = 1;
bellardea2384d2004-08-01 21:59:26 +00001167 break;
1168 case 'e':
Markus Armbruster9d42e152011-06-22 14:03:55 +02001169 error_report("option -e is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +01001170 "encryption\' instead!");
1171 return 1;
thsec36ba12007-09-16 21:59:02 +00001172 case '6':
Markus Armbruster9d42e152011-06-22 14:03:55 +02001173 error_report("option -6 is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +01001174 "compat6\' instead!");
1175 return 1;
Kevin Wolfefa84d42009-05-18 16:42:12 +02001176 case 'o':
1177 options = optarg;
1178 break;
edison51ef6722010-09-21 19:58:41 -07001179 case 's':
1180 snapshot_name = optarg;
1181 break;
Kevin Wolfa22f1232011-08-26 15:27:13 +02001182 case 'S':
1183 {
1184 int64_t sval;
Markus Armbrustere36b3692011-11-22 09:46:05 +01001185 char *end;
1186 sval = strtosz_suffix(optarg, &end, STRTOSZ_DEFSUFFIX_B);
1187 if (sval < 0 || *end) {
Kevin Wolfa22f1232011-08-26 15:27:13 +02001188 error_report("Invalid minimum zero buffer size for sparse output specified");
1189 return 1;
1190 }
1191
1192 min_sparse = sval / BDRV_SECTOR_SIZE;
1193 break;
1194 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001195 case 'p':
1196 progress = 1;
1197 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001198 case 't':
1199 cache = optarg;
1200 break;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01001201 case 'q':
1202 quiet = true;
1203 break;
Alexandre Derumierb2e10492013-09-02 19:07:24 +01001204 case 'n':
1205 skip_create = 1;
1206 break;
bellardea2384d2004-08-01 21:59:26 +00001207 }
1208 }
ths3b46e622007-09-17 08:09:54 +00001209
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01001210 if (quiet) {
1211 progress = 0;
1212 }
1213
balrog926c2d22007-10-31 01:11:44 +00001214 bs_n = argc - optind - 1;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001215 if (bs_n < 1) {
1216 help();
1217 }
balrog926c2d22007-10-31 01:11:44 +00001218
1219 out_filename = argv[argc - 1];
thsf58c7b32008-06-05 21:53:49 +00001220
Charles Arnoldfa170c12012-05-11 10:57:54 -06001221 /* Initialize before goto out */
1222 qemu_progress_init(progress, 2.0);
1223
Peter Maydellc8057f92012-08-02 13:45:54 +01001224 if (options && is_help_option(options)) {
Jes Sorensen4ac8aac2010-12-06 15:25:38 +01001225 ret = print_block_option_help(out_filename, out_fmt);
1226 goto out;
1227 }
1228
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001229 if (bs_n > 1 && out_baseimg) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001230 error_report("-B makes no sense when concatenating multiple input "
1231 "images");
Jes Sorensen31ca34b2010-12-06 15:25:36 +01001232 ret = -1;
1233 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001234 }
Dong Xu Wangf8111c22012-03-15 20:13:31 +08001235
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001236 qemu_progress_print(0, 100);
1237
Anthony Liguori7267c092011-08-20 22:09:37 -05001238 bs = g_malloc0(bs_n * sizeof(BlockDriverState *));
balrog926c2d22007-10-31 01:11:44 +00001239
1240 total_sectors = 0;
1241 for (bs_i = 0; bs_i < bs_n; bs_i++) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01001242 bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS, true,
1243 quiet);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001244 if (!bs[bs_i]) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001245 error_report("Could not open '%s'", argv[optind + bs_i]);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001246 ret = -1;
1247 goto out;
1248 }
balrog926c2d22007-10-31 01:11:44 +00001249 bdrv_get_geometry(bs[bs_i], &bs_sectors);
1250 total_sectors += bs_sectors;
1251 }
bellardea2384d2004-08-01 21:59:26 +00001252
edison51ef6722010-09-21 19:58:41 -07001253 if (snapshot_name != NULL) {
1254 if (bs_n > 1) {
Markus Armbruster6daf1942011-06-22 14:03:54 +02001255 error_report("No support for concatenating multiple snapshot");
edison51ef6722010-09-21 19:58:41 -07001256 ret = -1;
1257 goto out;
1258 }
1259 if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
Markus Armbruster6daf1942011-06-22 14:03:54 +02001260 error_report("Failed to load snapshot");
edison51ef6722010-09-21 19:58:41 -07001261 ret = -1;
1262 goto out;
1263 }
1264 }
1265
Kevin Wolfefa84d42009-05-18 16:42:12 +02001266 /* Find driver and parse its options */
bellardea2384d2004-08-01 21:59:26 +00001267 drv = bdrv_find_format(out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001268 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001269 error_report("Unknown file format '%s'", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001270 ret = -1;
1271 goto out;
1272 }
balrog926c2d22007-10-31 01:11:44 +00001273
Kevin Wolf98289622013-07-10 15:47:39 +02001274 proto_drv = bdrv_find_protocol(out_filename, true);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001275 if (!proto_drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001276 error_report("Unknown protocol '%s'", out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001277 ret = -1;
1278 goto out;
1279 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +09001280
1281 create_options = append_option_parameters(create_options,
1282 drv->create_options);
1283 create_options = append_option_parameters(create_options,
1284 proto_drv->create_options);
Kevin Wolfdb08adf2009-06-04 15:39:38 +02001285
Kevin Wolfefa84d42009-05-18 16:42:12 +02001286 if (options) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +09001287 param = parse_option_parameters(options, create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +02001288 if (param == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001289 error_report("Invalid options for file format '%s'.", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001290 ret = -1;
1291 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +02001292 }
1293 } else {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +09001294 param = parse_option_parameters("", create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +02001295 }
1296
1297 set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
Jes Sorenseneec77d92010-12-07 17:44:34 +01001298 ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001299 if (ret < 0) {
1300 goto out;
1301 }
Kevin Wolfefa84d42009-05-18 16:42:12 +02001302
Kevin Wolfa18953f2010-10-14 15:46:04 +02001303 /* Get backing file name if -o backing_file was used */
1304 out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
1305 if (out_baseimg_param) {
1306 out_baseimg = out_baseimg_param->value.s;
1307 }
1308
Kevin Wolfefa84d42009-05-18 16:42:12 +02001309 /* Check if compression is supported */
Jes Sorenseneec77d92010-12-07 17:44:34 +01001310 if (compress) {
Kevin Wolfefa84d42009-05-18 16:42:12 +02001311 QEMUOptionParameter *encryption =
1312 get_option_parameter(param, BLOCK_OPT_ENCRYPT);
Kevin Wolf41521fa2011-10-18 16:19:42 +02001313 QEMUOptionParameter *preallocation =
1314 get_option_parameter(param, BLOCK_OPT_PREALLOC);
Kevin Wolfefa84d42009-05-18 16:42:12 +02001315
1316 if (!drv->bdrv_write_compressed) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001317 error_report("Compression not supported for this file format");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001318 ret = -1;
1319 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +02001320 }
1321
1322 if (encryption && encryption->value.n) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001323 error_report("Compression and encryption not supported at "
1324 "the same time");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001325 ret = -1;
1326 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +02001327 }
Kevin Wolf41521fa2011-10-18 16:19:42 +02001328
1329 if (preallocation && preallocation->value.s
1330 && strcmp(preallocation->value.s, "off"))
1331 {
1332 error_report("Compression and preallocation not supported at "
1333 "the same time");
1334 ret = -1;
1335 goto out;
1336 }
Kevin Wolfefa84d42009-05-18 16:42:12 +02001337 }
1338
Alexandre Derumierb2e10492013-09-02 19:07:24 +01001339 if (!skip_create) {
1340 /* Create the new image */
1341 ret = bdrv_create(drv, out_filename, param);
1342 if (ret < 0) {
1343 if (ret == -ENOTSUP) {
1344 error_report("Formatting not supported for file format '%s'",
1345 out_fmt);
1346 } else if (ret == -EFBIG) {
1347 error_report("The image size is too large for file format '%s'",
1348 out_fmt);
1349 } else {
1350 error_report("%s: error while converting %s: %s",
1351 out_filename, out_fmt, strerror(-ret));
1352 }
1353 goto out;
bellardea2384d2004-08-01 21:59:26 +00001354 }
1355 }
ths3b46e622007-09-17 08:09:54 +00001356
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001357 flags = BDRV_O_RDWR;
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +01001358 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001359 if (ret < 0) {
1360 error_report("Invalid cache option: %s", cache);
1361 return -1;
1362 }
1363
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01001364 out_bs = bdrv_new_open(out_filename, out_fmt, flags, true, quiet);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001365 if (!out_bs) {
1366 ret = -1;
1367 goto out;
1368 }
bellardea2384d2004-08-01 21:59:26 +00001369
balrog926c2d22007-10-31 01:11:44 +00001370 bs_i = 0;
1371 bs_offset = 0;
1372 bdrv_get_geometry(bs[0], &bs_sectors);
Kevin Wolfbb1c0592011-08-08 14:09:12 +02001373 buf = qemu_blockalign(out_bs, IO_BUF_SIZE);
balrog926c2d22007-10-31 01:11:44 +00001374
Alexandre Derumierb2e10492013-09-02 19:07:24 +01001375 if (skip_create) {
1376 int64_t output_length = bdrv_getlength(out_bs);
1377 if (output_length < 0) {
1378 error_report("unable to get output image length: %s\n",
1379 strerror(-output_length));
1380 ret = -1;
1381 goto out;
1382 } else if (output_length < total_sectors << BDRV_SECTOR_BITS) {
1383 error_report("output file is smaller than input file");
1384 ret = -1;
1385 goto out;
1386 }
1387 }
1388
Jes Sorenseneec77d92010-12-07 17:44:34 +01001389 if (compress) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001390 ret = bdrv_get_info(out_bs, &bdi);
1391 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001392 error_report("could not get block driver info");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001393 goto out;
1394 }
bellardfaea38e2006-08-05 21:31:00 +00001395 cluster_size = bdi.cluster_size;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001396 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001397 error_report("invalid cluster size");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001398 ret = -1;
1399 goto out;
1400 }
bellardea2384d2004-08-01 21:59:26 +00001401 cluster_sectors = cluster_size >> 9;
1402 sector_num = 0;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001403
1404 nb_sectors = total_sectors;
Kevin Wolf1f710492012-10-12 14:29:18 +02001405 if (nb_sectors != 0) {
1406 local_progress = (float)100 /
1407 (nb_sectors / MIN(nb_sectors, cluster_sectors));
1408 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001409
bellardea2384d2004-08-01 21:59:26 +00001410 for(;;) {
balrog926c2d22007-10-31 01:11:44 +00001411 int64_t bs_num;
1412 int remainder;
1413 uint8_t *buf2;
1414
bellardea2384d2004-08-01 21:59:26 +00001415 nb_sectors = total_sectors - sector_num;
1416 if (nb_sectors <= 0)
1417 break;
1418 if (nb_sectors >= cluster_sectors)
1419 n = cluster_sectors;
1420 else
1421 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +00001422
1423 bs_num = sector_num - bs_offset;
1424 assert (bs_num >= 0);
1425 remainder = n;
1426 buf2 = buf;
1427 while (remainder > 0) {
1428 int nlow;
1429 while (bs_num == bs_sectors) {
1430 bs_i++;
1431 assert (bs_i < bs_n);
1432 bs_offset += bs_sectors;
1433 bdrv_get_geometry(bs[bs_i], &bs_sectors);
1434 bs_num = 0;
Blue Swirl0bfcd592010-05-22 08:02:12 +00001435 /* printf("changing part: sector_num=%" PRId64 ", "
1436 "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64
1437 "\n", sector_num, bs_i, bs_offset, bs_sectors); */
balrog926c2d22007-10-31 01:11:44 +00001438 }
1439 assert (bs_num < bs_sectors);
1440
1441 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
1442
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001443 ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
1444 if (ret < 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +01001445 error_report("error while reading sector %" PRId64 ": %s",
1446 bs_num, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001447 goto out;
1448 }
balrog926c2d22007-10-31 01:11:44 +00001449
1450 buf2 += nlow * 512;
1451 bs_num += nlow;
1452
1453 remainder -= nlow;
1454 }
1455 assert (remainder == 0);
1456
Stefan Hajnoczi54f106d2013-04-15 17:17:33 +02001457 if (!buffer_is_zero(buf, n * BDRV_SECTOR_SIZE)) {
1458 ret = bdrv_write_compressed(out_bs, sector_num, buf, n);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001459 if (ret != 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +01001460 error_report("error while compressing sector %" PRId64
1461 ": %s", sector_num, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001462 goto out;
1463 }
bellardea2384d2004-08-01 21:59:26 +00001464 }
1465 sector_num += n;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001466 qemu_progress_print(local_progress, 100);
bellardea2384d2004-08-01 21:59:26 +00001467 }
bellardfaea38e2006-08-05 21:31:00 +00001468 /* signal EOF to align */
1469 bdrv_write_compressed(out_bs, 0, NULL, 0);
bellardea2384d2004-08-01 21:59:26 +00001470 } else {
Kevin Wolff2feebb2010-04-14 17:30:35 +02001471 int has_zero_init = bdrv_has_zero_init(out_bs);
1472
thsf58c7b32008-06-05 21:53:49 +00001473 sector_num = 0; // total number of sectors converted so far
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001474 nb_sectors = total_sectors - sector_num;
Kevin Wolf1f710492012-10-12 14:29:18 +02001475 if (nb_sectors != 0) {
1476 local_progress = (float)100 /
1477 (nb_sectors / MIN(nb_sectors, IO_BUF_SIZE / 512));
1478 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001479
bellardea2384d2004-08-01 21:59:26 +00001480 for(;;) {
1481 nb_sectors = total_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001482 if (nb_sectors <= 0) {
bellardea2384d2004-08-01 21:59:26 +00001483 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001484 }
1485 if (nb_sectors >= (IO_BUF_SIZE / 512)) {
bellardea2384d2004-08-01 21:59:26 +00001486 n = (IO_BUF_SIZE / 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001487 } else {
bellardea2384d2004-08-01 21:59:26 +00001488 n = nb_sectors;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001489 }
balrog926c2d22007-10-31 01:11:44 +00001490
1491 while (sector_num - bs_offset >= bs_sectors) {
1492 bs_i ++;
1493 assert (bs_i < bs_n);
1494 bs_offset += bs_sectors;
1495 bdrv_get_geometry(bs[bs_i], &bs_sectors);
Blue Swirl0bfcd592010-05-22 08:02:12 +00001496 /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "
1497 "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",
balrog926c2d22007-10-31 01:11:44 +00001498 sector_num, bs_i, bs_offset, bs_sectors); */
1499 }
1500
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001501 if (n > bs_offset + bs_sectors - sector_num) {
balrog926c2d22007-10-31 01:11:44 +00001502 n = bs_offset + bs_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001503 }
balrog926c2d22007-10-31 01:11:44 +00001504
Paolo Bonzinie4a86f82013-09-04 19:00:26 +02001505 /* If the output image is being created as a copy on write image,
1506 assume that sectors which are unallocated in the input image
1507 are present in both the output's and input's base images (no
1508 need to copy them). */
1509 if (out_baseimg) {
1510 ret = bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
1511 n, &n1);
1512 if (ret < 0) {
1513 error_report("error while reading metadata for sector "
1514 "%" PRId64 ": %s",
1515 sector_num - bs_offset, strerror(-ret));
1516 goto out;
aliguori93c65b42009-04-05 17:40:43 +00001517 }
Paolo Bonzinie4a86f82013-09-04 19:00:26 +02001518 if (!ret) {
1519 sector_num += n1;
1520 continue;
1521 }
1522 /* The next 'n1' sectors are allocated in the input image. Copy
1523 only those as they may be followed by unallocated sectors. */
1524 n = n1;
aliguori93c65b42009-04-05 17:40:43 +00001525 } else {
1526 n1 = n;
thsf58c7b32008-06-05 21:53:49 +00001527 }
1528
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001529 ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
1530 if (ret < 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +01001531 error_report("error while reading sector %" PRId64 ": %s",
1532 sector_num - bs_offset, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001533 goto out;
1534 }
bellardea2384d2004-08-01 21:59:26 +00001535 /* NOTE: at the same time we convert, we do not write zero
1536 sectors to have a chance to compress the image. Ideally, we
1537 should add a specific call to have the info to go faster */
1538 buf1 = buf;
1539 while (n > 0) {
Paolo Bonzini11212d82013-09-04 19:00:27 +02001540 if (!has_zero_init ||
Kevin Wolfa22f1232011-08-26 15:27:13 +02001541 is_allocated_sectors_min(buf1, n, &n1, min_sparse)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001542 ret = bdrv_write(out_bs, sector_num, buf1, n1);
1543 if (ret < 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +01001544 error_report("error while writing sector %" PRId64
1545 ": %s", sector_num, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001546 goto out;
1547 }
bellardea2384d2004-08-01 21:59:26 +00001548 }
1549 sector_num += n1;
1550 n -= n1;
1551 buf1 += n1 * 512;
1552 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001553 qemu_progress_print(local_progress, 100);
bellardea2384d2004-08-01 21:59:26 +00001554 }
1555 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001556out:
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001557 qemu_progress_end();
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001558 free_option_parameters(create_options);
1559 free_option_parameters(param);
Kevin Wolfbb1c0592011-08-08 14:09:12 +02001560 qemu_vfree(buf);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001561 if (out_bs) {
Fam Zheng4f6fd342013-08-23 09:14:47 +08001562 bdrv_unref(out_bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001563 }
Jes Sorensen31ca34b2010-12-06 15:25:36 +01001564 if (bs) {
1565 for (bs_i = 0; bs_i < bs_n; bs_i++) {
1566 if (bs[bs_i]) {
Fam Zheng4f6fd342013-08-23 09:14:47 +08001567 bdrv_unref(bs[bs_i]);
Jes Sorensen31ca34b2010-12-06 15:25:36 +01001568 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001569 }
Anthony Liguori7267c092011-08-20 22:09:37 -05001570 g_free(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001571 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001572 if (ret) {
1573 return 1;
1574 }
bellardea2384d2004-08-01 21:59:26 +00001575 return 0;
1576}
1577
bellard57d1a2b2004-08-03 21:15:11 +00001578
bellardfaea38e2006-08-05 21:31:00 +00001579static void dump_snapshots(BlockDriverState *bs)
1580{
1581 QEMUSnapshotInfo *sn_tab, *sn;
1582 int nb_sns, i;
bellardfaea38e2006-08-05 21:31:00 +00001583
1584 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1585 if (nb_sns <= 0)
1586 return;
1587 printf("Snapshot list:\n");
Wenchao Xia5b917042013-05-25 11:09:45 +08001588 bdrv_snapshot_dump(fprintf, stdout, NULL);
1589 printf("\n");
bellardfaea38e2006-08-05 21:31:00 +00001590 for(i = 0; i < nb_sns; i++) {
1591 sn = &sn_tab[i];
Wenchao Xia5b917042013-05-25 11:09:45 +08001592 bdrv_snapshot_dump(fprintf, stdout, sn);
1593 printf("\n");
bellardfaea38e2006-08-05 21:31:00 +00001594 }
Anthony Liguori7267c092011-08-20 22:09:37 -05001595 g_free(sn_tab);
bellardfaea38e2006-08-05 21:31:00 +00001596}
1597
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001598static void dump_json_image_info_list(ImageInfoList *list)
1599{
1600 Error *errp = NULL;
1601 QString *str;
1602 QmpOutputVisitor *ov = qmp_output_visitor_new();
1603 QObject *obj;
1604 visit_type_ImageInfoList(qmp_output_get_visitor(ov),
1605 &list, NULL, &errp);
1606 obj = qmp_output_get_qobject(ov);
1607 str = qobject_to_json_pretty(obj);
1608 assert(str != NULL);
1609 printf("%s\n", qstring_get_str(str));
1610 qobject_decref(obj);
1611 qmp_output_visitor_cleanup(ov);
1612 QDECREF(str);
1613}
1614
Benoît Canetc054b3f2012-09-05 13:09:02 +02001615static void dump_json_image_info(ImageInfo *info)
1616{
1617 Error *errp = NULL;
1618 QString *str;
1619 QmpOutputVisitor *ov = qmp_output_visitor_new();
1620 QObject *obj;
1621 visit_type_ImageInfo(qmp_output_get_visitor(ov),
1622 &info, NULL, &errp);
1623 obj = qmp_output_get_qobject(ov);
1624 str = qobject_to_json_pretty(obj);
1625 assert(str != NULL);
1626 printf("%s\n", qstring_get_str(str));
1627 qobject_decref(obj);
1628 qmp_output_visitor_cleanup(ov);
1629 QDECREF(str);
1630}
1631
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001632static void dump_human_image_info_list(ImageInfoList *list)
1633{
1634 ImageInfoList *elem;
1635 bool delim = false;
1636
1637 for (elem = list; elem; elem = elem->next) {
1638 if (delim) {
1639 printf("\n");
1640 }
1641 delim = true;
1642
Wenchao Xia5b917042013-05-25 11:09:45 +08001643 bdrv_image_info_dump(fprintf, stdout, elem->value);
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001644 }
1645}
1646
1647static gboolean str_equal_func(gconstpointer a, gconstpointer b)
1648{
1649 return strcmp(a, b) == 0;
1650}
1651
1652/**
1653 * Open an image file chain and return an ImageInfoList
1654 *
1655 * @filename: topmost image filename
1656 * @fmt: topmost image format (may be NULL to autodetect)
1657 * @chain: true - enumerate entire backing file chain
1658 * false - only topmost image file
1659 *
1660 * Returns a list of ImageInfo objects or NULL if there was an error opening an
1661 * image file. If there was an error a message will have been printed to
1662 * stderr.
1663 */
1664static ImageInfoList *collect_image_info_list(const char *filename,
1665 const char *fmt,
1666 bool chain)
1667{
1668 ImageInfoList *head = NULL;
1669 ImageInfoList **last = &head;
1670 GHashTable *filenames;
Wenchao Xia43526ec2013-06-06 12:27:58 +08001671 Error *err = NULL;
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001672
1673 filenames = g_hash_table_new_full(g_str_hash, str_equal_func, NULL, NULL);
1674
1675 while (filename) {
1676 BlockDriverState *bs;
1677 ImageInfo *info;
1678 ImageInfoList *elem;
1679
1680 if (g_hash_table_lookup_extended(filenames, filename, NULL, NULL)) {
1681 error_report("Backing file '%s' creates an infinite loop.",
1682 filename);
1683 goto err;
1684 }
1685 g_hash_table_insert(filenames, (gpointer)filename, NULL);
1686
1687 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING,
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01001688 false, false);
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001689 if (!bs) {
1690 goto err;
1691 }
1692
Wenchao Xia43526ec2013-06-06 12:27:58 +08001693 bdrv_query_image_info(bs, &info, &err);
1694 if (error_is_set(&err)) {
1695 error_report("%s", error_get_pretty(err));
1696 error_free(err);
1697 goto err;
Wenchao Xiafb0ed452013-06-06 12:27:57 +08001698 }
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001699
1700 elem = g_new0(ImageInfoList, 1);
1701 elem->value = info;
1702 *last = elem;
1703 last = &elem->next;
1704
Fam Zheng4f6fd342013-08-23 09:14:47 +08001705 bdrv_unref(bs);
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001706
1707 filename = fmt = NULL;
1708 if (chain) {
1709 if (info->has_full_backing_filename) {
1710 filename = info->full_backing_filename;
1711 } else if (info->has_backing_filename) {
1712 filename = info->backing_filename;
1713 }
1714 if (info->has_backing_filename_format) {
1715 fmt = info->backing_filename_format;
1716 }
1717 }
1718 }
1719 g_hash_table_destroy(filenames);
1720 return head;
1721
1722err:
1723 qapi_free_ImageInfoList(head);
1724 g_hash_table_destroy(filenames);
1725 return NULL;
1726}
1727
Benoît Canetc054b3f2012-09-05 13:09:02 +02001728static int img_info(int argc, char **argv)
1729{
1730 int c;
1731 OutputFormat output_format = OFORMAT_HUMAN;
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001732 bool chain = false;
Benoît Canetc054b3f2012-09-05 13:09:02 +02001733 const char *filename, *fmt, *output;
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001734 ImageInfoList *list;
Benoît Canetc054b3f2012-09-05 13:09:02 +02001735
bellardea2384d2004-08-01 21:59:26 +00001736 fmt = NULL;
Benoît Canetc054b3f2012-09-05 13:09:02 +02001737 output = NULL;
bellardea2384d2004-08-01 21:59:26 +00001738 for(;;) {
Benoît Canetc054b3f2012-09-05 13:09:02 +02001739 int option_index = 0;
1740 static const struct option long_options[] = {
1741 {"help", no_argument, 0, 'h'},
1742 {"format", required_argument, 0, 'f'},
1743 {"output", required_argument, 0, OPTION_OUTPUT},
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001744 {"backing-chain", no_argument, 0, OPTION_BACKING_CHAIN},
Benoît Canetc054b3f2012-09-05 13:09:02 +02001745 {0, 0, 0, 0}
1746 };
1747 c = getopt_long(argc, argv, "f:h",
1748 long_options, &option_index);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001749 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +00001750 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001751 }
bellardea2384d2004-08-01 21:59:26 +00001752 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001753 case '?':
bellardea2384d2004-08-01 21:59:26 +00001754 case 'h':
1755 help();
1756 break;
1757 case 'f':
1758 fmt = optarg;
1759 break;
Benoît Canetc054b3f2012-09-05 13:09:02 +02001760 case OPTION_OUTPUT:
1761 output = optarg;
1762 break;
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001763 case OPTION_BACKING_CHAIN:
1764 chain = true;
1765 break;
bellardea2384d2004-08-01 21:59:26 +00001766 }
1767 }
Kevin Wolffc11eb22013-08-05 10:53:04 +02001768 if (optind != argc - 1) {
bellardea2384d2004-08-01 21:59:26 +00001769 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001770 }
bellardea2384d2004-08-01 21:59:26 +00001771 filename = argv[optind++];
1772
Benoît Canetc054b3f2012-09-05 13:09:02 +02001773 if (output && !strcmp(output, "json")) {
1774 output_format = OFORMAT_JSON;
1775 } else if (output && !strcmp(output, "human")) {
1776 output_format = OFORMAT_HUMAN;
1777 } else if (output) {
1778 error_report("--output must be used with human or json as argument.");
1779 return 1;
1780 }
1781
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001782 list = collect_image_info_list(filename, fmt, chain);
1783 if (!list) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001784 return 1;
1785 }
Benoît Canetc054b3f2012-09-05 13:09:02 +02001786
Benoît Canetc054b3f2012-09-05 13:09:02 +02001787 switch (output_format) {
1788 case OFORMAT_HUMAN:
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001789 dump_human_image_info_list(list);
Benoît Canetc054b3f2012-09-05 13:09:02 +02001790 break;
1791 case OFORMAT_JSON:
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001792 if (chain) {
1793 dump_json_image_info_list(list);
1794 } else {
1795 dump_json_image_info(list->value);
1796 }
Benoît Canetc054b3f2012-09-05 13:09:02 +02001797 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001798 }
Benoît Canetc054b3f2012-09-05 13:09:02 +02001799
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001800 qapi_free_ImageInfoList(list);
bellardea2384d2004-08-01 21:59:26 +00001801 return 0;
1802}
1803
Paolo Bonzini4c93a13b2013-09-04 19:00:33 +02001804
1805typedef struct MapEntry {
1806 int flags;
1807 int depth;
1808 int64_t start;
1809 int64_t length;
1810 int64_t offset;
1811 BlockDriverState *bs;
1812} MapEntry;
1813
1814static void dump_map_entry(OutputFormat output_format, MapEntry *e,
1815 MapEntry *next)
1816{
1817 switch (output_format) {
1818 case OFORMAT_HUMAN:
1819 if ((e->flags & BDRV_BLOCK_DATA) &&
1820 !(e->flags & BDRV_BLOCK_OFFSET_VALID)) {
1821 error_report("File contains external, encrypted or compressed clusters.");
1822 exit(1);
1823 }
1824 if ((e->flags & (BDRV_BLOCK_DATA|BDRV_BLOCK_ZERO)) == BDRV_BLOCK_DATA) {
1825 printf("%#-16"PRIx64"%#-16"PRIx64"%#-16"PRIx64"%s\n",
1826 e->start, e->length, e->offset, e->bs->filename);
1827 }
1828 /* This format ignores the distinction between 0, ZERO and ZERO|DATA.
1829 * Modify the flags here to allow more coalescing.
1830 */
1831 if (next &&
1832 (next->flags & (BDRV_BLOCK_DATA|BDRV_BLOCK_ZERO)) != BDRV_BLOCK_DATA) {
1833 next->flags &= ~BDRV_BLOCK_DATA;
1834 next->flags |= BDRV_BLOCK_ZERO;
1835 }
1836 break;
1837 case OFORMAT_JSON:
1838 printf("%s{ \"start\": %"PRId64", \"length\": %"PRId64", \"depth\": %d,"
1839 " \"zero\": %s, \"data\": %s",
1840 (e->start == 0 ? "[" : ",\n"),
1841 e->start, e->length, e->depth,
1842 (e->flags & BDRV_BLOCK_ZERO) ? "true" : "false",
1843 (e->flags & BDRV_BLOCK_DATA) ? "true" : "false");
1844 if (e->flags & BDRV_BLOCK_OFFSET_VALID) {
1845 printf(", 'offset': %"PRId64"", e->offset);
1846 }
1847 putchar('}');
1848
1849 if (!next) {
1850 printf("]\n");
1851 }
1852 break;
1853 }
1854}
1855
1856static int get_block_status(BlockDriverState *bs, int64_t sector_num,
1857 int nb_sectors, MapEntry *e)
1858{
1859 int64_t ret;
1860 int depth;
1861
1862 /* As an optimization, we could cache the current range of unallocated
1863 * clusters in each file of the chain, and avoid querying the same
1864 * range repeatedly.
1865 */
1866
1867 depth = 0;
1868 for (;;) {
1869 ret = bdrv_get_block_status(bs, sector_num, nb_sectors, &nb_sectors);
1870 if (ret < 0) {
1871 return ret;
1872 }
1873 assert(nb_sectors);
1874 if (ret & (BDRV_BLOCK_ZERO|BDRV_BLOCK_DATA)) {
1875 break;
1876 }
1877 bs = bs->backing_hd;
1878 if (bs == NULL) {
1879 ret = 0;
1880 break;
1881 }
1882
1883 depth++;
1884 }
1885
1886 e->start = sector_num * BDRV_SECTOR_SIZE;
1887 e->length = nb_sectors * BDRV_SECTOR_SIZE;
1888 e->flags = ret & ~BDRV_BLOCK_OFFSET_MASK;
1889 e->offset = ret & BDRV_BLOCK_OFFSET_MASK;
1890 e->depth = depth;
1891 e->bs = bs;
1892 return 0;
1893}
1894
1895static int img_map(int argc, char **argv)
1896{
1897 int c;
1898 OutputFormat output_format = OFORMAT_HUMAN;
1899 BlockDriverState *bs;
1900 const char *filename, *fmt, *output;
1901 int64_t length;
1902 MapEntry curr = { .length = 0 }, next;
1903 int ret = 0;
1904
1905 fmt = NULL;
1906 output = NULL;
1907 for (;;) {
1908 int option_index = 0;
1909 static const struct option long_options[] = {
1910 {"help", no_argument, 0, 'h'},
1911 {"format", required_argument, 0, 'f'},
1912 {"output", required_argument, 0, OPTION_OUTPUT},
1913 {0, 0, 0, 0}
1914 };
1915 c = getopt_long(argc, argv, "f:h",
1916 long_options, &option_index);
1917 if (c == -1) {
1918 break;
1919 }
1920 switch (c) {
1921 case '?':
1922 case 'h':
1923 help();
1924 break;
1925 case 'f':
1926 fmt = optarg;
1927 break;
1928 case OPTION_OUTPUT:
1929 output = optarg;
1930 break;
1931 }
1932 }
1933 if (optind >= argc) {
1934 help();
1935 }
1936 filename = argv[optind++];
1937
1938 if (output && !strcmp(output, "json")) {
1939 output_format = OFORMAT_JSON;
1940 } else if (output && !strcmp(output, "human")) {
1941 output_format = OFORMAT_HUMAN;
1942 } else if (output) {
1943 error_report("--output must be used with human or json as argument.");
1944 return 1;
1945 }
1946
1947 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS, true, false);
1948 if (!bs) {
1949 return 1;
1950 }
1951
1952 if (output_format == OFORMAT_HUMAN) {
1953 printf("%-16s%-16s%-16s%s\n", "Offset", "Length", "Mapped to", "File");
1954 }
1955
1956 length = bdrv_getlength(bs);
1957 while (curr.start + curr.length < length) {
1958 int64_t nsectors_left;
1959 int64_t sector_num;
1960 int n;
1961
1962 sector_num = (curr.start + curr.length) >> BDRV_SECTOR_BITS;
1963
1964 /* Probe up to 1 GiB at a time. */
1965 nsectors_left = DIV_ROUND_UP(length, BDRV_SECTOR_SIZE) - sector_num;
1966 n = MIN(1 << (30 - BDRV_SECTOR_BITS), nsectors_left);
1967 ret = get_block_status(bs, sector_num, n, &next);
1968
1969 if (ret < 0) {
1970 error_report("Could not read file metadata: %s", strerror(-ret));
1971 goto out;
1972 }
1973
1974 if (curr.length != 0 && curr.flags == next.flags &&
1975 curr.depth == next.depth &&
1976 ((curr.flags & BDRV_BLOCK_OFFSET_VALID) == 0 ||
1977 curr.offset + curr.length == next.offset)) {
1978 curr.length += next.length;
1979 continue;
1980 }
1981
1982 if (curr.length > 0) {
1983 dump_map_entry(output_format, &curr, &next);
1984 }
1985 curr = next;
1986 }
1987
1988 dump_map_entry(output_format, &curr, NULL);
1989
1990out:
1991 bdrv_unref(bs);
1992 return ret < 0;
1993}
1994
aliguorif7b4a942009-01-07 17:40:15 +00001995#define SNAPSHOT_LIST 1
1996#define SNAPSHOT_CREATE 2
1997#define SNAPSHOT_APPLY 3
1998#define SNAPSHOT_DELETE 4
1999
Stuart Brady153859b2009-06-07 00:42:17 +01002000static int img_snapshot(int argc, char **argv)
aliguorif7b4a942009-01-07 17:40:15 +00002001{
2002 BlockDriverState *bs;
2003 QEMUSnapshotInfo sn;
2004 char *filename, *snapshot_name = NULL;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002005 int c, ret = 0, bdrv_oflags;
aliguorif7b4a942009-01-07 17:40:15 +00002006 int action = 0;
2007 qemu_timeval tv;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002008 bool quiet = false;
aliguorif7b4a942009-01-07 17:40:15 +00002009
Kevin Wolf710da702011-01-10 12:33:02 +01002010 bdrv_oflags = BDRV_O_FLAGS | BDRV_O_RDWR;
aliguorif7b4a942009-01-07 17:40:15 +00002011 /* Parse commandline parameters */
2012 for(;;) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002013 c = getopt(argc, argv, "la:c:d:hq");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01002014 if (c == -1) {
aliguorif7b4a942009-01-07 17:40:15 +00002015 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01002016 }
aliguorif7b4a942009-01-07 17:40:15 +00002017 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01002018 case '?':
aliguorif7b4a942009-01-07 17:40:15 +00002019 case 'h':
2020 help();
Stuart Brady153859b2009-06-07 00:42:17 +01002021 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00002022 case 'l':
2023 if (action) {
2024 help();
Stuart Brady153859b2009-06-07 00:42:17 +01002025 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00002026 }
2027 action = SNAPSHOT_LIST;
Naphtali Spreif5edb012010-01-17 16:48:13 +02002028 bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
aliguorif7b4a942009-01-07 17:40:15 +00002029 break;
2030 case 'a':
2031 if (action) {
2032 help();
Stuart Brady153859b2009-06-07 00:42:17 +01002033 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00002034 }
2035 action = SNAPSHOT_APPLY;
2036 snapshot_name = optarg;
2037 break;
2038 case 'c':
2039 if (action) {
2040 help();
Stuart Brady153859b2009-06-07 00:42:17 +01002041 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00002042 }
2043 action = SNAPSHOT_CREATE;
2044 snapshot_name = optarg;
2045 break;
2046 case 'd':
2047 if (action) {
2048 help();
Stuart Brady153859b2009-06-07 00:42:17 +01002049 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00002050 }
2051 action = SNAPSHOT_DELETE;
2052 snapshot_name = optarg;
2053 break;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002054 case 'q':
2055 quiet = true;
2056 break;
aliguorif7b4a942009-01-07 17:40:15 +00002057 }
2058 }
2059
Kevin Wolffc11eb22013-08-05 10:53:04 +02002060 if (optind != argc - 1) {
aliguorif7b4a942009-01-07 17:40:15 +00002061 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01002062 }
aliguorif7b4a942009-01-07 17:40:15 +00002063 filename = argv[optind++];
2064
2065 /* Open the image */
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002066 bs = bdrv_new_open(filename, NULL, bdrv_oflags, true, quiet);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002067 if (!bs) {
2068 return 1;
2069 }
aliguorif7b4a942009-01-07 17:40:15 +00002070
2071 /* Perform the requested action */
2072 switch(action) {
2073 case SNAPSHOT_LIST:
2074 dump_snapshots(bs);
2075 break;
2076
2077 case SNAPSHOT_CREATE:
2078 memset(&sn, 0, sizeof(sn));
2079 pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
2080
2081 qemu_gettimeofday(&tv);
2082 sn.date_sec = tv.tv_sec;
2083 sn.date_nsec = tv.tv_usec * 1000;
2084
2085 ret = bdrv_snapshot_create(bs, &sn);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01002086 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01002087 error_report("Could not create snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00002088 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01002089 }
aliguorif7b4a942009-01-07 17:40:15 +00002090 break;
2091
2092 case SNAPSHOT_APPLY:
2093 ret = bdrv_snapshot_goto(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01002094 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01002095 error_report("Could not apply snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00002096 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01002097 }
aliguorif7b4a942009-01-07 17:40:15 +00002098 break;
2099
2100 case SNAPSHOT_DELETE:
2101 ret = bdrv_snapshot_delete(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01002102 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01002103 error_report("Could not delete snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00002104 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01002105 }
aliguorif7b4a942009-01-07 17:40:15 +00002106 break;
2107 }
2108
2109 /* Cleanup */
Fam Zheng4f6fd342013-08-23 09:14:47 +08002110 bdrv_unref(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002111 if (ret) {
2112 return 1;
2113 }
Stuart Brady153859b2009-06-07 00:42:17 +01002114 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00002115}
2116
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002117static int img_rebase(int argc, char **argv)
2118{
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002119 BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
Stefan Hajnoczif163d072010-04-13 10:29:34 +01002120 BlockDriver *old_backing_drv, *new_backing_drv;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002121 char *filename;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04002122 const char *fmt, *cache, *out_basefmt, *out_baseimg;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002123 int c, flags, ret;
2124 int unsafe = 0;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02002125 int progress = 0;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002126 bool quiet = false;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002127
2128 /* Parse commandline parameters */
Kevin Wolfe53dbee2010-03-02 12:14:31 +01002129 fmt = NULL;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04002130 cache = BDRV_DEFAULT_CACHE;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002131 out_baseimg = NULL;
2132 out_basefmt = NULL;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002133 for(;;) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002134 c = getopt(argc, argv, "uhf:F:b:pt:q");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01002135 if (c == -1) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002136 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01002137 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002138 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01002139 case '?':
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002140 case 'h':
2141 help();
2142 return 0;
Kevin Wolfe53dbee2010-03-02 12:14:31 +01002143 case 'f':
2144 fmt = optarg;
2145 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002146 case 'F':
2147 out_basefmt = optarg;
2148 break;
2149 case 'b':
2150 out_baseimg = optarg;
2151 break;
2152 case 'u':
2153 unsafe = 1;
2154 break;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02002155 case 'p':
2156 progress = 1;
2157 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04002158 case 't':
2159 cache = optarg;
2160 break;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002161 case 'q':
2162 quiet = true;
2163 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002164 }
2165 }
2166
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002167 if (quiet) {
2168 progress = 0;
2169 }
2170
Kevin Wolffc11eb22013-08-05 10:53:04 +02002171 if ((optind != argc - 1) || (!unsafe && !out_baseimg)) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002172 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01002173 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002174 filename = argv[optind++];
2175
Jes Sorensen6b837bc2011-03-30 14:16:25 +02002176 qemu_progress_init(progress, 2.0);
2177 qemu_progress_print(0, 100);
2178
Federico Simoncelli661a0f72011-06-20 12:48:19 -04002179 flags = BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +01002180 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -04002181 if (ret < 0) {
2182 error_report("Invalid cache option: %s", cache);
2183 return -1;
2184 }
2185
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002186 /*
2187 * Open the images.
2188 *
2189 * Ignore the old backing file for unsafe rebase in case we want to correct
2190 * the reference to a renamed or moved backing file.
2191 */
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002192 bs = bdrv_new_open(filename, fmt, flags, true, quiet);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002193 if (!bs) {
2194 return 1;
2195 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002196
2197 /* Find the right drivers for the backing files */
2198 old_backing_drv = NULL;
2199 new_backing_drv = NULL;
2200
2201 if (!unsafe && bs->backing_format[0] != '\0') {
2202 old_backing_drv = bdrv_find_format(bs->backing_format);
2203 if (old_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01002204 error_report("Invalid format name: '%s'", bs->backing_format);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002205 ret = -1;
2206 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002207 }
2208 }
2209
2210 if (out_basefmt != NULL) {
2211 new_backing_drv = bdrv_find_format(out_basefmt);
2212 if (new_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01002213 error_report("Invalid format name: '%s'", out_basefmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002214 ret = -1;
2215 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002216 }
2217 }
2218
2219 /* For safe rebasing we need to compare old and new backing file */
2220 if (unsafe) {
2221 /* Make the compiler happy */
2222 bs_old_backing = NULL;
2223 bs_new_backing = NULL;
2224 } else {
2225 char backing_name[1024];
2226
2227 bs_old_backing = bdrv_new("old_backing");
2228 bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
Kevin Wolfde9c0ce2013-03-15 10:35:02 +01002229 ret = bdrv_open(bs_old_backing, backing_name, NULL, BDRV_O_FLAGS,
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002230 old_backing_drv);
2231 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01002232 error_report("Could not open old backing file '%s'", backing_name);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002233 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002234 }
Alex Bligha6166732012-10-16 13:46:18 +01002235 if (out_baseimg[0]) {
2236 bs_new_backing = bdrv_new("new_backing");
Kevin Wolfde9c0ce2013-03-15 10:35:02 +01002237 ret = bdrv_open(bs_new_backing, out_baseimg, NULL, BDRV_O_FLAGS,
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002238 new_backing_drv);
Alex Bligha6166732012-10-16 13:46:18 +01002239 if (ret) {
2240 error_report("Could not open new backing file '%s'",
2241 out_baseimg);
2242 goto out;
2243 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002244 }
2245 }
2246
2247 /*
2248 * Check each unallocated cluster in the COW file. If it is unallocated,
2249 * accesses go to the backing file. We must therefore compare this cluster
2250 * in the old and new backing file, and if they differ we need to copy it
2251 * from the old backing file into the COW file.
2252 *
2253 * If qemu-img crashes during this step, no harm is done. The content of
2254 * the image is the same as the original one at any time.
2255 */
2256 if (!unsafe) {
2257 uint64_t num_sectors;
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01002258 uint64_t old_backing_num_sectors;
Alex Bligha6166732012-10-16 13:46:18 +01002259 uint64_t new_backing_num_sectors = 0;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002260 uint64_t sector;
Kevin Wolfcc60e322010-04-29 14:47:48 +02002261 int n;
TeLeMand6771bf2010-02-08 16:20:00 +08002262 uint8_t * buf_old;
2263 uint8_t * buf_new;
Kevin Wolf1f710492012-10-12 14:29:18 +02002264 float local_progress = 0;
TeLeMand6771bf2010-02-08 16:20:00 +08002265
Kevin Wolfbb1c0592011-08-08 14:09:12 +02002266 buf_old = qemu_blockalign(bs, IO_BUF_SIZE);
2267 buf_new = qemu_blockalign(bs, IO_BUF_SIZE);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002268
2269 bdrv_get_geometry(bs, &num_sectors);
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01002270 bdrv_get_geometry(bs_old_backing, &old_backing_num_sectors);
Alex Bligha6166732012-10-16 13:46:18 +01002271 if (bs_new_backing) {
2272 bdrv_get_geometry(bs_new_backing, &new_backing_num_sectors);
2273 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002274
Kevin Wolf1f710492012-10-12 14:29:18 +02002275 if (num_sectors != 0) {
2276 local_progress = (float)100 /
2277 (num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512));
2278 }
2279
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002280 for (sector = 0; sector < num_sectors; sector += n) {
2281
2282 /* How many sectors can we handle with the next read? */
2283 if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
2284 n = (IO_BUF_SIZE / 512);
2285 } else {
2286 n = num_sectors - sector;
2287 }
2288
2289 /* If the cluster is allocated, we don't need to take action */
Kevin Wolfcc60e322010-04-29 14:47:48 +02002290 ret = bdrv_is_allocated(bs, sector, n, &n);
Paolo Bonzinid6636402013-09-04 19:00:25 +02002291 if (ret < 0) {
2292 error_report("error while reading image metadata: %s",
2293 strerror(-ret));
2294 goto out;
2295 }
Kevin Wolfcc60e322010-04-29 14:47:48 +02002296 if (ret) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002297 continue;
2298 }
2299
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01002300 /*
2301 * Read old and new backing file and take into consideration that
2302 * backing files may be smaller than the COW image.
2303 */
2304 if (sector >= old_backing_num_sectors) {
2305 memset(buf_old, 0, n * BDRV_SECTOR_SIZE);
2306 } else {
2307 if (sector + n > old_backing_num_sectors) {
2308 n = old_backing_num_sectors - sector;
2309 }
2310
2311 ret = bdrv_read(bs_old_backing, sector, buf_old, n);
2312 if (ret < 0) {
2313 error_report("error while reading from old backing file");
2314 goto out;
2315 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002316 }
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01002317
Alex Bligha6166732012-10-16 13:46:18 +01002318 if (sector >= new_backing_num_sectors || !bs_new_backing) {
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01002319 memset(buf_new, 0, n * BDRV_SECTOR_SIZE);
2320 } else {
2321 if (sector + n > new_backing_num_sectors) {
2322 n = new_backing_num_sectors - sector;
2323 }
2324
2325 ret = bdrv_read(bs_new_backing, sector, buf_new, n);
2326 if (ret < 0) {
2327 error_report("error while reading from new backing file");
2328 goto out;
2329 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002330 }
2331
2332 /* If they differ, we need to write to the COW file */
2333 uint64_t written = 0;
2334
2335 while (written < n) {
2336 int pnum;
2337
2338 if (compare_sectors(buf_old + written * 512,
Kevin Wolf60b1bd42010-02-17 12:32:59 +01002339 buf_new + written * 512, n - written, &pnum))
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002340 {
2341 ret = bdrv_write(bs, sector + written,
2342 buf_old + written * 512, pnum);
2343 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01002344 error_report("Error while writing to COW image: %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002345 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002346 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002347 }
2348 }
2349
2350 written += pnum;
2351 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02002352 qemu_progress_print(local_progress, 100);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002353 }
TeLeMand6771bf2010-02-08 16:20:00 +08002354
Kevin Wolfbb1c0592011-08-08 14:09:12 +02002355 qemu_vfree(buf_old);
2356 qemu_vfree(buf_new);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002357 }
2358
2359 /*
2360 * Change the backing file. All clusters that are different from the old
2361 * backing file are overwritten in the COW file now, so the visible content
2362 * doesn't change when we switch the backing file.
2363 */
Alex Bligha6166732012-10-16 13:46:18 +01002364 if (out_baseimg && *out_baseimg) {
2365 ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
2366 } else {
2367 ret = bdrv_change_backing_file(bs, NULL, NULL);
2368 }
2369
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002370 if (ret == -ENOSPC) {
Jes Sorensen15654a62010-12-16 14:31:53 +01002371 error_report("Could not change the backing file to '%s': No "
2372 "space left in the file header", out_baseimg);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002373 } else if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01002374 error_report("Could not change the backing file to '%s': %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002375 out_baseimg, strerror(-ret));
2376 }
2377
Jes Sorensen6b837bc2011-03-30 14:16:25 +02002378 qemu_progress_print(100, 0);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002379 /*
2380 * TODO At this point it is possible to check if any clusters that are
2381 * allocated in the COW file are the same in the backing file. If so, they
2382 * could be dropped from the COW file. Don't do this before switching the
2383 * backing file, in case of a crash this would lead to corruption.
2384 */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002385out:
Jes Sorensen6b837bc2011-03-30 14:16:25 +02002386 qemu_progress_end();
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002387 /* Cleanup */
2388 if (!unsafe) {
Kevin Wolfeb863ad2011-03-31 12:39:51 +02002389 if (bs_old_backing != NULL) {
Fam Zheng4f6fd342013-08-23 09:14:47 +08002390 bdrv_unref(bs_old_backing);
Kevin Wolfeb863ad2011-03-31 12:39:51 +02002391 }
2392 if (bs_new_backing != NULL) {
Fam Zheng4f6fd342013-08-23 09:14:47 +08002393 bdrv_unref(bs_new_backing);
Kevin Wolfeb863ad2011-03-31 12:39:51 +02002394 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002395 }
2396
Fam Zheng4f6fd342013-08-23 09:14:47 +08002397 bdrv_unref(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002398 if (ret) {
2399 return 1;
2400 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002401 return 0;
2402}
2403
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002404static int img_resize(int argc, char **argv)
2405{
2406 int c, ret, relative;
2407 const char *filename, *fmt, *size;
2408 int64_t n, total_size;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002409 bool quiet = false;
Jes Sorensen2a819982010-12-06 17:08:31 +01002410 BlockDriverState *bs = NULL;
Dong Xu Wang20caf0f2012-08-06 10:18:42 +08002411 QemuOpts *param;
2412 static QemuOptsList resize_options = {
2413 .name = "resize_options",
2414 .head = QTAILQ_HEAD_INITIALIZER(resize_options.head),
2415 .desc = {
2416 {
2417 .name = BLOCK_OPT_SIZE,
2418 .type = QEMU_OPT_SIZE,
2419 .help = "Virtual disk size"
2420 }, {
2421 /* end of list */
2422 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002423 },
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002424 };
2425
Kevin Wolfe80fec72011-04-29 10:58:12 +02002426 /* Remove size from argv manually so that negative numbers are not treated
2427 * as options by getopt. */
2428 if (argc < 3) {
2429 help();
2430 return 1;
2431 }
2432
2433 size = argv[--argc];
2434
2435 /* Parse getopt arguments */
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002436 fmt = NULL;
2437 for(;;) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002438 c = getopt(argc, argv, "f:hq");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002439 if (c == -1) {
2440 break;
2441 }
2442 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01002443 case '?':
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002444 case 'h':
2445 help();
2446 break;
2447 case 'f':
2448 fmt = optarg;
2449 break;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002450 case 'q':
2451 quiet = true;
2452 break;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002453 }
2454 }
Kevin Wolffc11eb22013-08-05 10:53:04 +02002455 if (optind != argc - 1) {
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002456 help();
2457 }
2458 filename = argv[optind++];
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002459
2460 /* Choose grow, shrink, or absolute resize mode */
2461 switch (size[0]) {
2462 case '+':
2463 relative = 1;
2464 size++;
2465 break;
2466 case '-':
2467 relative = -1;
2468 size++;
2469 break;
2470 default:
2471 relative = 0;
2472 break;
2473 }
2474
2475 /* Parse size */
Dong Xu Wange478b442012-12-06 14:47:22 +08002476 param = qemu_opts_create_nofail(&resize_options);
Dong Xu Wang20caf0f2012-08-06 10:18:42 +08002477 if (qemu_opt_set(param, BLOCK_OPT_SIZE, size)) {
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002478 /* Error message already printed when size parsing fails */
Jes Sorensen2a819982010-12-06 17:08:31 +01002479 ret = -1;
Dong Xu Wang20caf0f2012-08-06 10:18:42 +08002480 qemu_opts_del(param);
Jes Sorensen2a819982010-12-06 17:08:31 +01002481 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002482 }
Dong Xu Wang20caf0f2012-08-06 10:18:42 +08002483 n = qemu_opt_get_size(param, BLOCK_OPT_SIZE, 0);
2484 qemu_opts_del(param);
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002485
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002486 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR, true, quiet);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002487 if (!bs) {
Jes Sorensen2a819982010-12-06 17:08:31 +01002488 ret = -1;
2489 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002490 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002491
2492 if (relative) {
2493 total_size = bdrv_getlength(bs) + n * relative;
2494 } else {
2495 total_size = n;
2496 }
2497 if (total_size <= 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01002498 error_report("New image size must be positive");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002499 ret = -1;
2500 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002501 }
2502
2503 ret = bdrv_truncate(bs, total_size);
2504 switch (ret) {
2505 case 0:
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002506 qprintf(quiet, "Image resized.\n");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002507 break;
2508 case -ENOTSUP:
Kevin Wolf259b2172012-03-06 12:44:45 +01002509 error_report("This image does not support resize");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002510 break;
2511 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +01002512 error_report("Image is read-only");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002513 break;
2514 default:
Jes Sorensen15654a62010-12-16 14:31:53 +01002515 error_report("Error resizing image (%d)", -ret);
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002516 break;
2517 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002518out:
Jes Sorensen2a819982010-12-06 17:08:31 +01002519 if (bs) {
Fam Zheng4f6fd342013-08-23 09:14:47 +08002520 bdrv_unref(bs);
Jes Sorensen2a819982010-12-06 17:08:31 +01002521 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002522 if (ret) {
2523 return 1;
2524 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002525 return 0;
2526}
2527
Max Reitz6f176b42013-09-03 10:09:50 +02002528static int img_amend(int argc, char **argv)
2529{
2530 int c, ret = 0;
2531 char *options = NULL;
2532 QEMUOptionParameter *create_options = NULL, *options_param = NULL;
2533 const char *fmt = NULL, *filename;
2534 bool quiet = false;
2535 BlockDriverState *bs = NULL;
2536
2537 for (;;) {
2538 c = getopt(argc, argv, "hqf:o:");
2539 if (c == -1) {
2540 break;
2541 }
2542
2543 switch (c) {
2544 case 'h':
2545 case '?':
2546 help();
2547 break;
2548 case 'o':
2549 options = optarg;
2550 break;
2551 case 'f':
2552 fmt = optarg;
2553 break;
2554 case 'q':
2555 quiet = true;
2556 break;
2557 }
2558 }
2559
2560 if (optind != argc - 1) {
2561 help();
2562 }
2563
2564 if (!options) {
2565 help();
2566 }
2567
2568 filename = argv[argc - 1];
2569
2570 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR, true, quiet);
2571 if (!bs) {
2572 error_report("Could not open image '%s'", filename);
2573 ret = -1;
2574 goto out;
2575 }
2576
2577 fmt = bs->drv->format_name;
2578
2579 if (is_help_option(options)) {
2580 ret = print_block_option_help(filename, fmt);
2581 goto out;
2582 }
2583
2584 create_options = append_option_parameters(create_options,
2585 bs->drv->create_options);
2586 options_param = parse_option_parameters(options, create_options,
2587 options_param);
2588 if (options_param == NULL) {
2589 error_report("Invalid options for file format '%s'", fmt);
2590 ret = -1;
2591 goto out;
2592 }
2593
2594 ret = bdrv_amend_options(bs, options_param);
2595 if (ret < 0) {
2596 error_report("Error while amending options: %s", strerror(-ret));
2597 goto out;
2598 }
2599
2600out:
2601 if (bs) {
2602 bdrv_unref(bs);
2603 }
2604 free_option_parameters(create_options);
2605 free_option_parameters(options_param);
2606 if (ret) {
2607 return 1;
2608 }
2609 return 0;
2610}
2611
Anthony Liguoric227f092009-10-01 16:12:16 -05002612static const img_cmd_t img_cmds[] = {
Stuart Brady153859b2009-06-07 00:42:17 +01002613#define DEF(option, callback, arg_string) \
2614 { option, callback },
2615#include "qemu-img-cmds.h"
2616#undef DEF
2617#undef GEN_DOCS
2618 { NULL, NULL, },
2619};
2620
bellardea2384d2004-08-01 21:59:26 +00002621int main(int argc, char **argv)
2622{
Anthony Liguoric227f092009-10-01 16:12:16 -05002623 const img_cmd_t *cmd;
Stuart Brady153859b2009-06-07 00:42:17 +01002624 const char *cmdname;
bellardea2384d2004-08-01 21:59:26 +00002625
MORITA Kazutaka526eda12013-07-23 17:30:11 +09002626#ifdef CONFIG_POSIX
2627 signal(SIGPIPE, SIG_IGN);
2628#endif
2629
Kevin Wolf53f76e52010-12-16 15:10:32 +01002630 error_set_progname(argv[0]);
2631
Paolo Bonzini2592c592012-11-03 18:10:17 +01002632 qemu_init_main_loop();
bellardea2384d2004-08-01 21:59:26 +00002633 bdrv_init();
2634 if (argc < 2)
2635 help();
Stuart Brady153859b2009-06-07 00:42:17 +01002636 cmdname = argv[1];
aurel328f9b1572009-02-09 18:14:31 +00002637 argc--; argv++;
Stuart Brady153859b2009-06-07 00:42:17 +01002638
2639 /* find the command */
2640 for(cmd = img_cmds; cmd->name != NULL; cmd++) {
2641 if (!strcmp(cmdname, cmd->name)) {
2642 return cmd->handler(argc, argv);
2643 }
bellardea2384d2004-08-01 21:59:26 +00002644 }
Stuart Brady153859b2009-06-07 00:42:17 +01002645
2646 /* not found */
2647 help();
bellardea2384d2004-08-01 21:59:26 +00002648 return 0;
2649}