blob: b6b5644cb6afaf7441f950c85ff1e652c79bdbff [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];
Max Reitz34b5d2c2013-09-05 14:45:29 +0200269 Error *local_err = NULL;
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100270 int ret;
bellard75c23802004-08-27 21:28:58 +0000271
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100272 bs = bdrv_new("image");
Kevin Wolfad717132010-12-16 15:37:41 +0100273
bellard75c23802004-08-27 21:28:58 +0000274 if (fmt) {
275 drv = bdrv_find_format(fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900276 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100277 error_report("Unknown file format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900278 goto fail;
279 }
bellard75c23802004-08-27 21:28:58 +0000280 } else {
281 drv = NULL;
282 }
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100283
Max Reitz34b5d2c2013-09-05 14:45:29 +0200284 ret = bdrv_open(bs, filename, NULL, flags, drv, &local_err);
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100285 if (ret < 0) {
Max Reitz34b5d2c2013-09-05 14:45:29 +0200286 error_report("Could not open '%s': %s", filename,
287 error_get_pretty(local_err));
288 error_free(local_err);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900289 goto fail;
bellard75c23802004-08-27 21:28:58 +0000290 }
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100291
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +0100292 if (bdrv_is_encrypted(bs) && require_io) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100293 qprintf(quiet, "Disk image '%s' is encrypted.\n", filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900294 if (read_password(password, sizeof(password)) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100295 error_report("No password given");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900296 goto fail;
297 }
298 if (bdrv_set_key(bs, password) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100299 error_report("invalid password");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900300 goto fail;
301 }
bellard75c23802004-08-27 21:28:58 +0000302 }
303 return bs;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900304fail:
305 if (bs) {
Fam Zheng4f6fd342013-08-23 09:14:47 +0800306 bdrv_unref(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900307 }
308 return NULL;
bellard75c23802004-08-27 21:28:58 +0000309}
310
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900311static int add_old_style_options(const char *fmt, QEMUOptionParameter *list,
Jes Sorenseneec77d92010-12-07 17:44:34 +0100312 const char *base_filename,
313 const char *base_fmt)
Kevin Wolfefa84d42009-05-18 16:42:12 +0200314{
Kevin Wolfefa84d42009-05-18 16:42:12 +0200315 if (base_filename) {
316 if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100317 error_report("Backing file not supported for file format '%s'",
318 fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900319 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200320 }
321 }
322 if (base_fmt) {
323 if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100324 error_report("Backing file format not supported for file "
325 "format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900326 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200327 }
328 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900329 return 0;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200330}
331
bellardea2384d2004-08-01 21:59:26 +0000332static int img_create(int argc, char **argv)
333{
Luiz Capitulinoa9300912012-11-30 10:52:06 -0200334 int c;
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100335 uint64_t img_size = -1;
bellardea2384d2004-08-01 21:59:26 +0000336 const char *fmt = "raw";
aliguori9230eaf2009-03-28 17:55:19 +0000337 const char *base_fmt = NULL;
bellardea2384d2004-08-01 21:59:26 +0000338 const char *filename;
339 const char *base_filename = NULL;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200340 char *options = NULL;
Luiz Capitulino9b375252012-11-30 10:52:05 -0200341 Error *local_err = NULL;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100342 bool quiet = false;
ths3b46e622007-09-17 08:09:54 +0000343
bellardea2384d2004-08-01 21:59:26 +0000344 for(;;) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100345 c = getopt(argc, argv, "F:b:f:he6o:q");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100346 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000347 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100348 }
bellardea2384d2004-08-01 21:59:26 +0000349 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100350 case '?':
bellardea2384d2004-08-01 21:59:26 +0000351 case 'h':
352 help();
353 break;
aliguori9230eaf2009-03-28 17:55:19 +0000354 case 'F':
355 base_fmt = optarg;
356 break;
bellardea2384d2004-08-01 21:59:26 +0000357 case 'b':
358 base_filename = optarg;
359 break;
360 case 'f':
361 fmt = optarg;
362 break;
363 case 'e':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200364 error_report("option -e is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100365 "encryption\' instead!");
366 return 1;
thsd8871c52007-10-24 16:11:42 +0000367 case '6':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200368 error_report("option -6 is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100369 "compat6\' instead!");
370 return 1;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200371 case 'o':
372 options = optarg;
373 break;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100374 case 'q':
375 quiet = true;
376 break;
bellardea2384d2004-08-01 21:59:26 +0000377 }
378 }
aliguori9230eaf2009-03-28 17:55:19 +0000379
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900380 /* Get the filename */
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100381 if (optind >= argc) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900382 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100383 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900384 filename = argv[optind++];
385
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100386 /* Get image size, if specified */
387 if (optind < argc) {
Jes Sorensen70b4f4b2011-01-05 11:41:02 +0100388 int64_t sval;
Markus Armbrustere36b3692011-11-22 09:46:05 +0100389 char *end;
390 sval = strtosz_suffix(argv[optind++], &end, STRTOSZ_DEFSUFFIX_B);
391 if (sval < 0 || *end) {
liguang79443392012-12-17 09:49:23 +0800392 if (sval == -ERANGE) {
393 error_report("Image size must be less than 8 EiB!");
394 } else {
395 error_report("Invalid image size specified! You may use k, M, "
Kevin Wolf5e009842013-06-05 14:19:27 +0200396 "G, T, P or E suffixes for ");
397 error_report("kilobytes, megabytes, gigabytes, terabytes, "
398 "petabytes and exabytes.");
liguang79443392012-12-17 09:49:23 +0800399 }
Luiz Capitulinoa9300912012-11-30 10:52:06 -0200400 return 1;
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100401 }
402 img_size = (uint64_t)sval;
403 }
Kevin Wolffc11eb22013-08-05 10:53:04 +0200404 if (optind != argc) {
405 help();
406 }
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100407
Peter Maydellc8057f92012-08-02 13:45:54 +0100408 if (options && is_help_option(options)) {
Luiz Capitulinoa9300912012-11-30 10:52:06 -0200409 return print_block_option_help(filename, fmt);
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100410 }
411
Luiz Capitulino9b375252012-11-30 10:52:05 -0200412 bdrv_img_create(filename, fmt, base_filename, base_fmt,
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100413 options, img_size, BDRV_O_FLAGS, &local_err, quiet);
Luiz Capitulino9b375252012-11-30 10:52:05 -0200414 if (error_is_set(&local_err)) {
Max Reitzb70d8c22013-09-06 16:51:03 +0200415 error_report("%s: %s", filename, error_get_pretty(local_err));
Luiz Capitulino9b375252012-11-30 10:52:05 -0200416 error_free(local_err);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900417 return 1;
418 }
Luiz Capitulinoa9300912012-11-30 10:52:06 -0200419
bellardea2384d2004-08-01 21:59:26 +0000420 return 0;
421}
422
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100423static void dump_json_image_check(ImageCheck *check, bool quiet)
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500424{
425 Error *errp = NULL;
426 QString *str;
427 QmpOutputVisitor *ov = qmp_output_visitor_new();
428 QObject *obj;
429 visit_type_ImageCheck(qmp_output_get_visitor(ov),
430 &check, NULL, &errp);
431 obj = qmp_output_get_qobject(ov);
432 str = qobject_to_json_pretty(obj);
433 assert(str != NULL);
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100434 qprintf(quiet, "%s\n", qstring_get_str(str));
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500435 qobject_decref(obj);
436 qmp_output_visitor_cleanup(ov);
437 QDECREF(str);
438}
439
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100440static void dump_human_image_check(ImageCheck *check, bool quiet)
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500441{
442 if (!(check->corruptions || check->leaks || check->check_errors)) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100443 qprintf(quiet, "No errors were found on the image.\n");
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500444 } else {
445 if (check->corruptions) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100446 qprintf(quiet, "\n%" PRId64 " errors were found on the image.\n"
447 "Data may be corrupted, or further writes to the image "
448 "may corrupt it.\n",
449 check->corruptions);
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500450 }
451
452 if (check->leaks) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100453 qprintf(quiet,
454 "\n%" PRId64 " leaked clusters were found on the image.\n"
455 "This means waste of disk space, but no harm to data.\n",
456 check->leaks);
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500457 }
458
459 if (check->check_errors) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100460 qprintf(quiet,
461 "\n%" PRId64
462 " internal errors have occurred during the check.\n",
463 check->check_errors);
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500464 }
465 }
466
467 if (check->total_clusters != 0 && check->allocated_clusters != 0) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100468 qprintf(quiet, "%" PRId64 "/%" PRId64 " = %0.2f%% allocated, "
469 "%0.2f%% fragmented, %0.2f%% compressed clusters\n",
470 check->allocated_clusters, check->total_clusters,
471 check->allocated_clusters * 100.0 / check->total_clusters,
472 check->fragmented_clusters * 100.0 / check->allocated_clusters,
473 check->compressed_clusters * 100.0 /
474 check->allocated_clusters);
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500475 }
476
477 if (check->image_end_offset) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100478 qprintf(quiet,
479 "Image end offset: %" PRId64 "\n", check->image_end_offset);
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500480 }
481}
482
483static int collect_image_check(BlockDriverState *bs,
484 ImageCheck *check,
485 const char *filename,
486 const char *fmt,
487 int fix)
488{
489 int ret;
490 BdrvCheckResult result;
491
492 ret = bdrv_check(bs, &result, fix);
493 if (ret < 0) {
494 return ret;
495 }
496
497 check->filename = g_strdup(filename);
498 check->format = g_strdup(bdrv_get_format_name(bs));
499 check->check_errors = result.check_errors;
500 check->corruptions = result.corruptions;
501 check->has_corruptions = result.corruptions != 0;
502 check->leaks = result.leaks;
503 check->has_leaks = result.leaks != 0;
504 check->corruptions_fixed = result.corruptions_fixed;
505 check->has_corruptions_fixed = result.corruptions != 0;
506 check->leaks_fixed = result.leaks_fixed;
507 check->has_leaks_fixed = result.leaks != 0;
508 check->image_end_offset = result.image_end_offset;
509 check->has_image_end_offset = result.image_end_offset != 0;
510 check->total_clusters = result.bfi.total_clusters;
511 check->has_total_clusters = result.bfi.total_clusters != 0;
512 check->allocated_clusters = result.bfi.allocated_clusters;
513 check->has_allocated_clusters = result.bfi.allocated_clusters != 0;
514 check->fragmented_clusters = result.bfi.fragmented_clusters;
515 check->has_fragmented_clusters = result.bfi.fragmented_clusters != 0;
Stefan Hajnoczie6439d72013-02-07 17:15:04 +0100516 check->compressed_clusters = result.bfi.compressed_clusters;
517 check->has_compressed_clusters = result.bfi.compressed_clusters != 0;
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500518
519 return 0;
520}
521
Kevin Wolfe076f332010-06-29 11:43:13 +0200522/*
523 * Checks an image for consistency. Exit codes:
524 *
525 * 0 - Check completed, image is good
526 * 1 - Check not completed because of internal errors
527 * 2 - Check completed, image is corrupted
528 * 3 - Check completed, image has leaked clusters, but is good otherwise
529 */
aliguori15859692009-04-21 23:11:53 +0000530static int img_check(int argc, char **argv)
531{
532 int c, ret;
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500533 OutputFormat output_format = OFORMAT_HUMAN;
534 const char *filename, *fmt, *output;
aliguori15859692009-04-21 23:11:53 +0000535 BlockDriverState *bs;
Kevin Wolf4534ff52012-05-11 16:07:02 +0200536 int fix = 0;
Stefan Hajnoczi058f8f12012-08-09 13:05:56 +0100537 int flags = BDRV_O_FLAGS | BDRV_O_CHECK;
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500538 ImageCheck *check;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100539 bool quiet = false;
aliguori15859692009-04-21 23:11:53 +0000540
541 fmt = NULL;
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500542 output = NULL;
aliguori15859692009-04-21 23:11:53 +0000543 for(;;) {
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500544 int option_index = 0;
545 static const struct option long_options[] = {
546 {"help", no_argument, 0, 'h'},
547 {"format", required_argument, 0, 'f'},
548 {"repair", no_argument, 0, 'r'},
549 {"output", required_argument, 0, OPTION_OUTPUT},
550 {0, 0, 0, 0}
551 };
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100552 c = getopt_long(argc, argv, "f:hr:q",
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500553 long_options, &option_index);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100554 if (c == -1) {
aliguori15859692009-04-21 23:11:53 +0000555 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100556 }
aliguori15859692009-04-21 23:11:53 +0000557 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100558 case '?':
aliguori15859692009-04-21 23:11:53 +0000559 case 'h':
560 help();
561 break;
562 case 'f':
563 fmt = optarg;
564 break;
Kevin Wolf4534ff52012-05-11 16:07:02 +0200565 case 'r':
566 flags |= BDRV_O_RDWR;
567
568 if (!strcmp(optarg, "leaks")) {
569 fix = BDRV_FIX_LEAKS;
570 } else if (!strcmp(optarg, "all")) {
571 fix = BDRV_FIX_LEAKS | BDRV_FIX_ERRORS;
572 } else {
573 help();
574 }
575 break;
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500576 case OPTION_OUTPUT:
577 output = optarg;
578 break;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100579 case 'q':
580 quiet = true;
581 break;
aliguori15859692009-04-21 23:11:53 +0000582 }
583 }
Kevin Wolffc11eb22013-08-05 10:53:04 +0200584 if (optind != argc - 1) {
aliguori15859692009-04-21 23:11:53 +0000585 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100586 }
aliguori15859692009-04-21 23:11:53 +0000587 filename = argv[optind++];
588
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500589 if (output && !strcmp(output, "json")) {
590 output_format = OFORMAT_JSON;
591 } else if (output && !strcmp(output, "human")) {
592 output_format = OFORMAT_HUMAN;
593 } else if (output) {
594 error_report("--output must be used with human or json as argument.");
595 return 1;
596 }
597
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100598 bs = bdrv_new_open(filename, fmt, flags, true, quiet);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900599 if (!bs) {
600 return 1;
601 }
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500602
603 check = g_new0(ImageCheck, 1);
604 ret = collect_image_check(bs, check, filename, fmt, fix);
Kevin Wolfe076f332010-06-29 11:43:13 +0200605
606 if (ret == -ENOTSUP) {
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500607 if (output_format == OFORMAT_HUMAN) {
608 error_report("This image format does not support checks");
609 }
Peter Lievenfefddf92013-10-24 08:53:34 +0200610 ret = 63;
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500611 goto fail;
Kevin Wolfe076f332010-06-29 11:43:13 +0200612 }
613
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500614 if (check->corruptions_fixed || check->leaks_fixed) {
615 int corruptions_fixed, leaks_fixed;
616
617 leaks_fixed = check->leaks_fixed;
618 corruptions_fixed = check->corruptions_fixed;
619
620 if (output_format == OFORMAT_HUMAN) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100621 qprintf(quiet,
622 "The following inconsistencies were found and repaired:\n\n"
623 " %" PRId64 " leaked clusters\n"
624 " %" PRId64 " corruptions\n\n"
625 "Double checking the fixed image now...\n",
626 check->leaks_fixed,
627 check->corruptions_fixed);
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500628 }
629
630 ret = collect_image_check(bs, check, filename, fmt, 0);
631
632 check->leaks_fixed = leaks_fixed;
633 check->corruptions_fixed = corruptions_fixed;
Kevin Wolfccf34712012-05-11 18:16:54 +0200634 }
635
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500636 switch (output_format) {
637 case OFORMAT_HUMAN:
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100638 dump_human_image_check(check, quiet);
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500639 break;
640 case OFORMAT_JSON:
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100641 dump_json_image_check(check, quiet);
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500642 break;
643 }
644
645 if (ret || check->check_errors) {
646 ret = 1;
647 goto fail;
648 }
649
650 if (check->corruptions) {
651 ret = 2;
652 } else if (check->leaks) {
653 ret = 3;
Kevin Wolfe076f332010-06-29 11:43:13 +0200654 } else {
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500655 ret = 0;
aliguori15859692009-04-21 23:11:53 +0000656 }
657
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500658fail:
659 qapi_free_ImageCheck(check);
Fam Zheng4f6fd342013-08-23 09:14:47 +0800660 bdrv_unref(bs);
Kevin Wolfe076f332010-06-29 11:43:13 +0200661
Federico Simoncelli8599ea42013-01-28 06:59:47 -0500662 return ret;
aliguori15859692009-04-21 23:11:53 +0000663}
664
bellardea2384d2004-08-01 21:59:26 +0000665static int img_commit(int argc, char **argv)
666{
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400667 int c, ret, flags;
668 const char *filename, *fmt, *cache;
bellardea2384d2004-08-01 21:59:26 +0000669 BlockDriverState *bs;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100670 bool quiet = false;
bellardea2384d2004-08-01 21:59:26 +0000671
672 fmt = NULL;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400673 cache = BDRV_DEFAULT_CACHE;
bellardea2384d2004-08-01 21:59:26 +0000674 for(;;) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100675 c = getopt(argc, argv, "f:ht:q");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100676 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000677 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100678 }
bellardea2384d2004-08-01 21:59:26 +0000679 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100680 case '?':
bellardea2384d2004-08-01 21:59:26 +0000681 case 'h':
682 help();
683 break;
684 case 'f':
685 fmt = optarg;
686 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400687 case 't':
688 cache = optarg;
689 break;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100690 case 'q':
691 quiet = true;
692 break;
bellardea2384d2004-08-01 21:59:26 +0000693 }
694 }
Kevin Wolffc11eb22013-08-05 10:53:04 +0200695 if (optind != argc - 1) {
bellardea2384d2004-08-01 21:59:26 +0000696 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100697 }
bellardea2384d2004-08-01 21:59:26 +0000698 filename = argv[optind++];
699
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400700 flags = BDRV_O_RDWR;
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +0100701 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400702 if (ret < 0) {
703 error_report("Invalid cache option: %s", cache);
704 return -1;
705 }
706
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100707 bs = bdrv_new_open(filename, fmt, flags, true, quiet);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900708 if (!bs) {
709 return 1;
710 }
bellardea2384d2004-08-01 21:59:26 +0000711 ret = bdrv_commit(bs);
712 switch(ret) {
713 case 0:
Miroslav Rezaninaf382d432013-02-13 09:09:40 +0100714 qprintf(quiet, "Image committed.\n");
bellardea2384d2004-08-01 21:59:26 +0000715 break;
716 case -ENOENT:
Jes Sorensen15654a62010-12-16 14:31:53 +0100717 error_report("No disk inserted");
bellardea2384d2004-08-01 21:59:26 +0000718 break;
719 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +0100720 error_report("Image is read-only");
bellardea2384d2004-08-01 21:59:26 +0000721 break;
722 case -ENOTSUP:
Jes Sorensen15654a62010-12-16 14:31:53 +0100723 error_report("Image is already committed");
bellardea2384d2004-08-01 21:59:26 +0000724 break;
725 default:
Jes Sorensen15654a62010-12-16 14:31:53 +0100726 error_report("Error while committing image");
bellardea2384d2004-08-01 21:59:26 +0000727 break;
728 }
729
Fam Zheng4f6fd342013-08-23 09:14:47 +0800730 bdrv_unref(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900731 if (ret) {
732 return 1;
733 }
bellardea2384d2004-08-01 21:59:26 +0000734 return 0;
735}
736
Dmitry Konishchevf6a00aa2011-05-18 15:03:59 +0400737/*
thsf58c7b32008-06-05 21:53:49 +0000738 * Returns true iff the first sector pointed to by 'buf' contains at least
739 * a non-NUL byte.
740 *
741 * 'pnum' is set to the number of sectors (including and immediately following
742 * the first one) that are known to be in the same allocated/unallocated state.
743 */
bellardea2384d2004-08-01 21:59:26 +0000744static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
745{
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000746 bool is_zero;
747 int i;
bellardea2384d2004-08-01 21:59:26 +0000748
749 if (n <= 0) {
750 *pnum = 0;
751 return 0;
752 }
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000753 is_zero = buffer_is_zero(buf, 512);
bellardea2384d2004-08-01 21:59:26 +0000754 for(i = 1; i < n; i++) {
755 buf += 512;
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000756 if (is_zero != buffer_is_zero(buf, 512)) {
bellardea2384d2004-08-01 21:59:26 +0000757 break;
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000758 }
bellardea2384d2004-08-01 21:59:26 +0000759 }
760 *pnum = i;
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000761 return !is_zero;
bellardea2384d2004-08-01 21:59:26 +0000762}
763
Kevin Wolf3e85c6f2010-01-12 12:55:18 +0100764/*
Kevin Wolfa22f1232011-08-26 15:27:13 +0200765 * Like is_allocated_sectors, but if the buffer starts with a used sector,
766 * up to 'min' consecutive sectors containing zeros are ignored. This avoids
767 * breaking up write requests for only small sparse areas.
768 */
769static int is_allocated_sectors_min(const uint8_t *buf, int n, int *pnum,
770 int min)
771{
772 int ret;
773 int num_checked, num_used;
774
775 if (n < min) {
776 min = n;
777 }
778
779 ret = is_allocated_sectors(buf, n, pnum);
780 if (!ret) {
781 return ret;
782 }
783
784 num_used = *pnum;
785 buf += BDRV_SECTOR_SIZE * *pnum;
786 n -= *pnum;
787 num_checked = num_used;
788
789 while (n > 0) {
790 ret = is_allocated_sectors(buf, n, pnum);
791
792 buf += BDRV_SECTOR_SIZE * *pnum;
793 n -= *pnum;
794 num_checked += *pnum;
795 if (ret) {
796 num_used = num_checked;
797 } else if (*pnum >= min) {
798 break;
799 }
800 }
801
802 *pnum = num_used;
803 return 1;
804}
805
806/*
Kevin Wolf3e85c6f2010-01-12 12:55:18 +0100807 * Compares two buffers sector by sector. Returns 0 if the first sector of both
808 * buffers matches, non-zero otherwise.
809 *
810 * pnum is set to the number of sectors (including and immediately following
811 * the first one) that are known to have the same comparison result
812 */
813static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
814 int *pnum)
815{
816 int res, i;
817
818 if (n <= 0) {
819 *pnum = 0;
820 return 0;
821 }
822
823 res = !!memcmp(buf1, buf2, 512);
824 for(i = 1; i < n; i++) {
825 buf1 += 512;
826 buf2 += 512;
827
828 if (!!memcmp(buf1, buf2, 512) != res) {
829 break;
830 }
831 }
832
833 *pnum = i;
834 return res;
835}
836
Kevin Wolf80ee15a2009-09-15 12:30:43 +0200837#define IO_BUF_SIZE (2 * 1024 * 1024)
bellardea2384d2004-08-01 21:59:26 +0000838
Miroslav Rezaninad14ed182013-02-13 09:09:41 +0100839static int64_t sectors_to_bytes(int64_t sectors)
840{
841 return sectors << BDRV_SECTOR_BITS;
842}
843
844static int64_t sectors_to_process(int64_t total, int64_t from)
845{
846 return MIN(total - from, IO_BUF_SIZE >> BDRV_SECTOR_BITS);
847}
848
849/*
850 * Check if passed sectors are empty (not allocated or contain only 0 bytes)
851 *
852 * Returns 0 in case sectors are filled with 0, 1 if sectors contain non-zero
853 * data and negative value on error.
854 *
855 * @param bs: Driver used for accessing file
856 * @param sect_num: Number of first sector to check
857 * @param sect_count: Number of sectors to check
858 * @param filename: Name of disk file we are checking (logging purpose)
859 * @param buffer: Allocated buffer for storing read data
860 * @param quiet: Flag for quiet mode
861 */
862static int check_empty_sectors(BlockDriverState *bs, int64_t sect_num,
863 int sect_count, const char *filename,
864 uint8_t *buffer, bool quiet)
865{
866 int pnum, ret = 0;
867 ret = bdrv_read(bs, sect_num, buffer, sect_count);
868 if (ret < 0) {
869 error_report("Error while reading offset %" PRId64 " of %s: %s",
870 sectors_to_bytes(sect_num), filename, strerror(-ret));
871 return ret;
872 }
873 ret = is_allocated_sectors(buffer, sect_count, &pnum);
874 if (ret || pnum != sect_count) {
875 qprintf(quiet, "Content mismatch at offset %" PRId64 "!\n",
876 sectors_to_bytes(ret ? sect_num : sect_num + pnum));
877 return 1;
878 }
879
880 return 0;
881}
882
883/*
884 * Compares two images. Exit codes:
885 *
886 * 0 - Images are identical
887 * 1 - Images differ
888 * >1 - Error occurred
889 */
890static int img_compare(int argc, char **argv)
891{
892 const char *fmt1 = NULL, *fmt2 = NULL, *filename1, *filename2;
893 BlockDriverState *bs1, *bs2;
894 int64_t total_sectors1, total_sectors2;
895 uint8_t *buf1 = NULL, *buf2 = NULL;
896 int pnum1, pnum2;
897 int allocated1, allocated2;
898 int ret = 0; /* return value - 0 Ident, 1 Different, >1 Error */
899 bool progress = false, quiet = false, strict = false;
900 int64_t total_sectors;
901 int64_t sector_num = 0;
902 int64_t nb_sectors;
903 int c, pnum;
904 uint64_t bs_sectors;
905 uint64_t progress_base;
906
907 for (;;) {
908 c = getopt(argc, argv, "hpf:F:sq");
909 if (c == -1) {
910 break;
911 }
912 switch (c) {
913 case '?':
914 case 'h':
915 help();
916 break;
917 case 'f':
918 fmt1 = optarg;
919 break;
920 case 'F':
921 fmt2 = optarg;
922 break;
923 case 'p':
924 progress = true;
925 break;
926 case 'q':
927 quiet = true;
928 break;
929 case 's':
930 strict = true;
931 break;
932 }
933 }
934
935 /* Progress is not shown in Quiet mode */
936 if (quiet) {
937 progress = false;
938 }
939
940
Kevin Wolffc11eb22013-08-05 10:53:04 +0200941 if (optind != argc - 2) {
Miroslav Rezaninad14ed182013-02-13 09:09:41 +0100942 help();
943 }
944 filename1 = argv[optind++];
945 filename2 = argv[optind++];
946
947 /* Initialize before goto out */
948 qemu_progress_init(progress, 2.0);
949
950 bs1 = bdrv_new_open(filename1, fmt1, BDRV_O_FLAGS, true, quiet);
951 if (!bs1) {
952 error_report("Can't open file %s", filename1);
953 ret = 2;
954 goto out3;
955 }
956
957 bs2 = bdrv_new_open(filename2, fmt2, BDRV_O_FLAGS, true, quiet);
958 if (!bs2) {
959 error_report("Can't open file %s", filename2);
960 ret = 2;
961 goto out2;
962 }
963
964 buf1 = qemu_blockalign(bs1, IO_BUF_SIZE);
965 buf2 = qemu_blockalign(bs2, IO_BUF_SIZE);
966 bdrv_get_geometry(bs1, &bs_sectors);
967 total_sectors1 = bs_sectors;
968 bdrv_get_geometry(bs2, &bs_sectors);
969 total_sectors2 = bs_sectors;
970 total_sectors = MIN(total_sectors1, total_sectors2);
971 progress_base = MAX(total_sectors1, total_sectors2);
972
973 qemu_progress_print(0, 100);
974
975 if (strict && total_sectors1 != total_sectors2) {
976 ret = 1;
977 qprintf(quiet, "Strict mode: Image size mismatch!\n");
978 goto out;
979 }
980
981 for (;;) {
982 nb_sectors = sectors_to_process(total_sectors, sector_num);
983 if (nb_sectors <= 0) {
984 break;
985 }
986 allocated1 = bdrv_is_allocated_above(bs1, NULL, sector_num, nb_sectors,
987 &pnum1);
988 if (allocated1 < 0) {
989 ret = 3;
990 error_report("Sector allocation test failed for %s", filename1);
991 goto out;
992 }
993
994 allocated2 = bdrv_is_allocated_above(bs2, NULL, sector_num, nb_sectors,
995 &pnum2);
996 if (allocated2 < 0) {
997 ret = 3;
998 error_report("Sector allocation test failed for %s", filename2);
999 goto out;
1000 }
1001 nb_sectors = MIN(pnum1, pnum2);
1002
1003 if (allocated1 == allocated2) {
1004 if (allocated1) {
1005 ret = bdrv_read(bs1, sector_num, buf1, nb_sectors);
1006 if (ret < 0) {
1007 error_report("Error while reading offset %" PRId64 " of %s:"
1008 " %s", sectors_to_bytes(sector_num), filename1,
1009 strerror(-ret));
1010 ret = 4;
1011 goto out;
1012 }
1013 ret = bdrv_read(bs2, sector_num, buf2, nb_sectors);
1014 if (ret < 0) {
1015 error_report("Error while reading offset %" PRId64
1016 " of %s: %s", sectors_to_bytes(sector_num),
1017 filename2, strerror(-ret));
1018 ret = 4;
1019 goto out;
1020 }
1021 ret = compare_sectors(buf1, buf2, nb_sectors, &pnum);
1022 if (ret || pnum != nb_sectors) {
Miroslav Rezaninad14ed182013-02-13 09:09:41 +01001023 qprintf(quiet, "Content mismatch at offset %" PRId64 "!\n",
1024 sectors_to_bytes(
1025 ret ? sector_num : sector_num + pnum));
Fam Zheng36452f12013-11-13 20:26:49 +08001026 ret = 1;
Miroslav Rezaninad14ed182013-02-13 09:09:41 +01001027 goto out;
1028 }
1029 }
1030 } else {
1031 if (strict) {
1032 ret = 1;
1033 qprintf(quiet, "Strict mode: Offset %" PRId64
1034 " allocation mismatch!\n",
1035 sectors_to_bytes(sector_num));
1036 goto out;
1037 }
1038
1039 if (allocated1) {
1040 ret = check_empty_sectors(bs1, sector_num, nb_sectors,
1041 filename1, buf1, quiet);
1042 } else {
1043 ret = check_empty_sectors(bs2, sector_num, nb_sectors,
1044 filename2, buf1, quiet);
1045 }
1046 if (ret) {
1047 if (ret < 0) {
Miroslav Rezaninad14ed182013-02-13 09:09:41 +01001048 error_report("Error while reading offset %" PRId64 ": %s",
1049 sectors_to_bytes(sector_num), strerror(-ret));
Fam Zheng36452f12013-11-13 20:26:49 +08001050 ret = 4;
Miroslav Rezaninad14ed182013-02-13 09:09:41 +01001051 }
1052 goto out;
1053 }
1054 }
1055 sector_num += nb_sectors;
1056 qemu_progress_print(((float) nb_sectors / progress_base)*100, 100);
1057 }
1058
1059 if (total_sectors1 != total_sectors2) {
1060 BlockDriverState *bs_over;
1061 int64_t total_sectors_over;
1062 const char *filename_over;
1063
1064 qprintf(quiet, "Warning: Image size mismatch!\n");
1065 if (total_sectors1 > total_sectors2) {
1066 total_sectors_over = total_sectors1;
1067 bs_over = bs1;
1068 filename_over = filename1;
1069 } else {
1070 total_sectors_over = total_sectors2;
1071 bs_over = bs2;
1072 filename_over = filename2;
1073 }
1074
1075 for (;;) {
1076 nb_sectors = sectors_to_process(total_sectors_over, sector_num);
1077 if (nb_sectors <= 0) {
1078 break;
1079 }
1080 ret = bdrv_is_allocated_above(bs_over, NULL, sector_num,
1081 nb_sectors, &pnum);
1082 if (ret < 0) {
1083 ret = 3;
1084 error_report("Sector allocation test failed for %s",
1085 filename_over);
1086 goto out;
1087
1088 }
1089 nb_sectors = pnum;
1090 if (ret) {
1091 ret = check_empty_sectors(bs_over, sector_num, nb_sectors,
1092 filename_over, buf1, quiet);
1093 if (ret) {
1094 if (ret < 0) {
Miroslav Rezaninad14ed182013-02-13 09:09:41 +01001095 error_report("Error while reading offset %" PRId64
1096 " of %s: %s", sectors_to_bytes(sector_num),
1097 filename_over, strerror(-ret));
Fam Zheng36452f12013-11-13 20:26:49 +08001098 ret = 4;
Miroslav Rezaninad14ed182013-02-13 09:09:41 +01001099 }
1100 goto out;
1101 }
1102 }
1103 sector_num += nb_sectors;
1104 qemu_progress_print(((float) nb_sectors / progress_base)*100, 100);
1105 }
1106 }
1107
1108 qprintf(quiet, "Images are identical.\n");
1109 ret = 0;
1110
1111out:
Fam Zheng4f6fd342013-08-23 09:14:47 +08001112 bdrv_unref(bs2);
Miroslav Rezaninad14ed182013-02-13 09:09:41 +01001113 qemu_vfree(buf1);
1114 qemu_vfree(buf2);
1115out2:
Fam Zheng4f6fd342013-08-23 09:14:47 +08001116 bdrv_unref(bs1);
Miroslav Rezaninad14ed182013-02-13 09:09:41 +01001117out3:
1118 qemu_progress_end();
1119 return ret;
1120}
1121
bellardea2384d2004-08-01 21:59:26 +00001122static int img_convert(int argc, char **argv)
1123{
Alexandre Derumierb2e10492013-09-02 19:07:24 +01001124 int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size,
1125 cluster_sectors, skip_create;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001126 int progress = 0, flags;
1127 const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +09001128 BlockDriver *drv, *proto_drv;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001129 BlockDriverState **bs = NULL, *out_bs = NULL;
ths96b8f132007-12-17 01:35:20 +00001130 int64_t total_sectors, nb_sectors, sector_num, bs_offset;
1131 uint64_t bs_sectors;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001132 uint8_t * buf = NULL;
bellardea2384d2004-08-01 21:59:26 +00001133 const uint8_t *buf1;
bellardfaea38e2006-08-05 21:31:00 +00001134 BlockDriverInfo bdi;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +09001135 QEMUOptionParameter *param = NULL, *create_options = NULL;
Kevin Wolfa18953f2010-10-14 15:46:04 +02001136 QEMUOptionParameter *out_baseimg_param;
Kevin Wolfefa84d42009-05-18 16:42:12 +02001137 char *options = NULL;
edison51ef6722010-09-21 19:58:41 -07001138 const char *snapshot_name = NULL;
Kevin Wolf1f710492012-10-12 14:29:18 +02001139 float local_progress = 0;
Kevin Wolfa22f1232011-08-26 15:27:13 +02001140 int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01001141 bool quiet = false;
Max Reitzcc84d902013-09-06 17:14:26 +02001142 Error *local_err = NULL;
bellardea2384d2004-08-01 21:59:26 +00001143
1144 fmt = NULL;
1145 out_fmt = "raw";
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001146 cache = "unsafe";
thsf58c7b32008-06-05 21:53:49 +00001147 out_baseimg = NULL;
Jes Sorenseneec77d92010-12-07 17:44:34 +01001148 compress = 0;
Alexandre Derumierb2e10492013-09-02 19:07:24 +01001149 skip_create = 0;
bellardea2384d2004-08-01 21:59:26 +00001150 for(;;) {
Alexandre Derumierb2e10492013-09-02 19:07:24 +01001151 c = getopt(argc, argv, "f:O:B:s:hce6o:pS:t:qn");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001152 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +00001153 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001154 }
bellardea2384d2004-08-01 21:59:26 +00001155 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001156 case '?':
bellardea2384d2004-08-01 21:59:26 +00001157 case 'h':
1158 help();
1159 break;
1160 case 'f':
1161 fmt = optarg;
1162 break;
1163 case 'O':
1164 out_fmt = optarg;
1165 break;
thsf58c7b32008-06-05 21:53:49 +00001166 case 'B':
1167 out_baseimg = optarg;
1168 break;
bellardea2384d2004-08-01 21:59:26 +00001169 case 'c':
Jes Sorenseneec77d92010-12-07 17:44:34 +01001170 compress = 1;
bellardea2384d2004-08-01 21:59:26 +00001171 break;
1172 case 'e':
Markus Armbruster9d42e152011-06-22 14:03:55 +02001173 error_report("option -e is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +01001174 "encryption\' instead!");
1175 return 1;
thsec36ba12007-09-16 21:59:02 +00001176 case '6':
Markus Armbruster9d42e152011-06-22 14:03:55 +02001177 error_report("option -6 is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +01001178 "compat6\' instead!");
1179 return 1;
Kevin Wolfefa84d42009-05-18 16:42:12 +02001180 case 'o':
1181 options = optarg;
1182 break;
edison51ef6722010-09-21 19:58:41 -07001183 case 's':
1184 snapshot_name = optarg;
1185 break;
Kevin Wolfa22f1232011-08-26 15:27:13 +02001186 case 'S':
1187 {
1188 int64_t sval;
Markus Armbrustere36b3692011-11-22 09:46:05 +01001189 char *end;
1190 sval = strtosz_suffix(optarg, &end, STRTOSZ_DEFSUFFIX_B);
1191 if (sval < 0 || *end) {
Kevin Wolfa22f1232011-08-26 15:27:13 +02001192 error_report("Invalid minimum zero buffer size for sparse output specified");
1193 return 1;
1194 }
1195
1196 min_sparse = sval / BDRV_SECTOR_SIZE;
1197 break;
1198 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001199 case 'p':
1200 progress = 1;
1201 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001202 case 't':
1203 cache = optarg;
1204 break;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01001205 case 'q':
1206 quiet = true;
1207 break;
Alexandre Derumierb2e10492013-09-02 19:07:24 +01001208 case 'n':
1209 skip_create = 1;
1210 break;
bellardea2384d2004-08-01 21:59:26 +00001211 }
1212 }
ths3b46e622007-09-17 08:09:54 +00001213
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01001214 if (quiet) {
1215 progress = 0;
1216 }
1217
balrog926c2d22007-10-31 01:11:44 +00001218 bs_n = argc - optind - 1;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001219 if (bs_n < 1) {
1220 help();
1221 }
balrog926c2d22007-10-31 01:11:44 +00001222
1223 out_filename = argv[argc - 1];
thsf58c7b32008-06-05 21:53:49 +00001224
Charles Arnoldfa170c12012-05-11 10:57:54 -06001225 /* Initialize before goto out */
1226 qemu_progress_init(progress, 2.0);
1227
Peter Maydellc8057f92012-08-02 13:45:54 +01001228 if (options && is_help_option(options)) {
Jes Sorensen4ac8aac2010-12-06 15:25:38 +01001229 ret = print_block_option_help(out_filename, out_fmt);
1230 goto out;
1231 }
1232
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001233 if (bs_n > 1 && out_baseimg) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001234 error_report("-B makes no sense when concatenating multiple input "
1235 "images");
Jes Sorensen31ca34b2010-12-06 15:25:36 +01001236 ret = -1;
1237 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001238 }
Dong Xu Wangf8111c22012-03-15 20:13:31 +08001239
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001240 qemu_progress_print(0, 100);
1241
Anthony Liguori7267c092011-08-20 22:09:37 -05001242 bs = g_malloc0(bs_n * sizeof(BlockDriverState *));
balrog926c2d22007-10-31 01:11:44 +00001243
1244 total_sectors = 0;
1245 for (bs_i = 0; bs_i < bs_n; bs_i++) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01001246 bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS, true,
1247 quiet);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001248 if (!bs[bs_i]) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001249 error_report("Could not open '%s'", argv[optind + bs_i]);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001250 ret = -1;
1251 goto out;
1252 }
balrog926c2d22007-10-31 01:11:44 +00001253 bdrv_get_geometry(bs[bs_i], &bs_sectors);
1254 total_sectors += bs_sectors;
1255 }
bellardea2384d2004-08-01 21:59:26 +00001256
edison51ef6722010-09-21 19:58:41 -07001257 if (snapshot_name != NULL) {
1258 if (bs_n > 1) {
Markus Armbruster6daf1942011-06-22 14:03:54 +02001259 error_report("No support for concatenating multiple snapshot");
edison51ef6722010-09-21 19:58:41 -07001260 ret = -1;
1261 goto out;
1262 }
1263 if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
Markus Armbruster6daf1942011-06-22 14:03:54 +02001264 error_report("Failed to load snapshot");
edison51ef6722010-09-21 19:58:41 -07001265 ret = -1;
1266 goto out;
1267 }
1268 }
1269
Kevin Wolfefa84d42009-05-18 16:42:12 +02001270 /* Find driver and parse its options */
bellardea2384d2004-08-01 21:59:26 +00001271 drv = bdrv_find_format(out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001272 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001273 error_report("Unknown file format '%s'", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001274 ret = -1;
1275 goto out;
1276 }
balrog926c2d22007-10-31 01:11:44 +00001277
Kevin Wolf98289622013-07-10 15:47:39 +02001278 proto_drv = bdrv_find_protocol(out_filename, true);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001279 if (!proto_drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001280 error_report("Unknown protocol '%s'", out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001281 ret = -1;
1282 goto out;
1283 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +09001284
1285 create_options = append_option_parameters(create_options,
1286 drv->create_options);
1287 create_options = append_option_parameters(create_options,
1288 proto_drv->create_options);
Kevin Wolfdb08adf2009-06-04 15:39:38 +02001289
Kevin Wolfefa84d42009-05-18 16:42:12 +02001290 if (options) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +09001291 param = parse_option_parameters(options, create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +02001292 if (param == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001293 error_report("Invalid options for file format '%s'.", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001294 ret = -1;
1295 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +02001296 }
1297 } else {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +09001298 param = parse_option_parameters("", create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +02001299 }
1300
1301 set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
Jes Sorenseneec77d92010-12-07 17:44:34 +01001302 ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001303 if (ret < 0) {
1304 goto out;
1305 }
Kevin Wolfefa84d42009-05-18 16:42:12 +02001306
Kevin Wolfa18953f2010-10-14 15:46:04 +02001307 /* Get backing file name if -o backing_file was used */
1308 out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
1309 if (out_baseimg_param) {
1310 out_baseimg = out_baseimg_param->value.s;
1311 }
1312
Kevin Wolfefa84d42009-05-18 16:42:12 +02001313 /* Check if compression is supported */
Jes Sorenseneec77d92010-12-07 17:44:34 +01001314 if (compress) {
Kevin Wolfefa84d42009-05-18 16:42:12 +02001315 QEMUOptionParameter *encryption =
1316 get_option_parameter(param, BLOCK_OPT_ENCRYPT);
Kevin Wolf41521fa2011-10-18 16:19:42 +02001317 QEMUOptionParameter *preallocation =
1318 get_option_parameter(param, BLOCK_OPT_PREALLOC);
Kevin Wolfefa84d42009-05-18 16:42:12 +02001319
1320 if (!drv->bdrv_write_compressed) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001321 error_report("Compression not supported for this file format");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001322 ret = -1;
1323 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +02001324 }
1325
1326 if (encryption && encryption->value.n) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001327 error_report("Compression and encryption not supported at "
1328 "the same time");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001329 ret = -1;
1330 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +02001331 }
Kevin Wolf41521fa2011-10-18 16:19:42 +02001332
1333 if (preallocation && preallocation->value.s
1334 && strcmp(preallocation->value.s, "off"))
1335 {
1336 error_report("Compression and preallocation not supported at "
1337 "the same time");
1338 ret = -1;
1339 goto out;
1340 }
Kevin Wolfefa84d42009-05-18 16:42:12 +02001341 }
1342
Alexandre Derumierb2e10492013-09-02 19:07:24 +01001343 if (!skip_create) {
1344 /* Create the new image */
Max Reitzcc84d902013-09-06 17:14:26 +02001345 ret = bdrv_create(drv, out_filename, param, &local_err);
Alexandre Derumierb2e10492013-09-02 19:07:24 +01001346 if (ret < 0) {
Max Reitzcc84d902013-09-06 17:14:26 +02001347 error_report("%s: error while converting %s: %s",
1348 out_filename, out_fmt, error_get_pretty(local_err));
1349 error_free(local_err);
Alexandre Derumierb2e10492013-09-02 19:07:24 +01001350 goto out;
bellardea2384d2004-08-01 21:59:26 +00001351 }
1352 }
ths3b46e622007-09-17 08:09:54 +00001353
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001354 flags = BDRV_O_RDWR;
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +01001355 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001356 if (ret < 0) {
1357 error_report("Invalid cache option: %s", cache);
1358 return -1;
1359 }
1360
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01001361 out_bs = bdrv_new_open(out_filename, out_fmt, flags, true, quiet);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001362 if (!out_bs) {
1363 ret = -1;
1364 goto out;
1365 }
bellardea2384d2004-08-01 21:59:26 +00001366
balrog926c2d22007-10-31 01:11:44 +00001367 bs_i = 0;
1368 bs_offset = 0;
1369 bdrv_get_geometry(bs[0], &bs_sectors);
Kevin Wolfbb1c0592011-08-08 14:09:12 +02001370 buf = qemu_blockalign(out_bs, IO_BUF_SIZE);
balrog926c2d22007-10-31 01:11:44 +00001371
Alexandre Derumierb2e10492013-09-02 19:07:24 +01001372 if (skip_create) {
1373 int64_t output_length = bdrv_getlength(out_bs);
1374 if (output_length < 0) {
1375 error_report("unable to get output image length: %s\n",
1376 strerror(-output_length));
1377 ret = -1;
1378 goto out;
1379 } else if (output_length < total_sectors << BDRV_SECTOR_BITS) {
1380 error_report("output file is smaller than input file");
1381 ret = -1;
1382 goto out;
1383 }
1384 }
1385
Jes Sorenseneec77d92010-12-07 17:44:34 +01001386 if (compress) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001387 ret = bdrv_get_info(out_bs, &bdi);
1388 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001389 error_report("could not get block driver info");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001390 goto out;
1391 }
bellardfaea38e2006-08-05 21:31:00 +00001392 cluster_size = bdi.cluster_size;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001393 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001394 error_report("invalid cluster size");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001395 ret = -1;
1396 goto out;
1397 }
bellardea2384d2004-08-01 21:59:26 +00001398 cluster_sectors = cluster_size >> 9;
1399 sector_num = 0;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001400
1401 nb_sectors = total_sectors;
Kevin Wolf1f710492012-10-12 14:29:18 +02001402 if (nb_sectors != 0) {
1403 local_progress = (float)100 /
1404 (nb_sectors / MIN(nb_sectors, cluster_sectors));
1405 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001406
bellardea2384d2004-08-01 21:59:26 +00001407 for(;;) {
balrog926c2d22007-10-31 01:11:44 +00001408 int64_t bs_num;
1409 int remainder;
1410 uint8_t *buf2;
1411
bellardea2384d2004-08-01 21:59:26 +00001412 nb_sectors = total_sectors - sector_num;
1413 if (nb_sectors <= 0)
1414 break;
1415 if (nb_sectors >= cluster_sectors)
1416 n = cluster_sectors;
1417 else
1418 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +00001419
1420 bs_num = sector_num - bs_offset;
1421 assert (bs_num >= 0);
1422 remainder = n;
1423 buf2 = buf;
1424 while (remainder > 0) {
1425 int nlow;
1426 while (bs_num == bs_sectors) {
1427 bs_i++;
1428 assert (bs_i < bs_n);
1429 bs_offset += bs_sectors;
1430 bdrv_get_geometry(bs[bs_i], &bs_sectors);
1431 bs_num = 0;
Blue Swirl0bfcd592010-05-22 08:02:12 +00001432 /* printf("changing part: sector_num=%" PRId64 ", "
1433 "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64
1434 "\n", sector_num, bs_i, bs_offset, bs_sectors); */
balrog926c2d22007-10-31 01:11:44 +00001435 }
1436 assert (bs_num < bs_sectors);
1437
1438 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
1439
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001440 ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
1441 if (ret < 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +01001442 error_report("error while reading sector %" PRId64 ": %s",
1443 bs_num, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001444 goto out;
1445 }
balrog926c2d22007-10-31 01:11:44 +00001446
1447 buf2 += nlow * 512;
1448 bs_num += nlow;
1449
1450 remainder -= nlow;
1451 }
1452 assert (remainder == 0);
1453
Stefan Hajnoczi54f106d2013-04-15 17:17:33 +02001454 if (!buffer_is_zero(buf, n * BDRV_SECTOR_SIZE)) {
1455 ret = bdrv_write_compressed(out_bs, sector_num, buf, n);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001456 if (ret != 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +01001457 error_report("error while compressing sector %" PRId64
1458 ": %s", sector_num, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001459 goto out;
1460 }
bellardea2384d2004-08-01 21:59:26 +00001461 }
1462 sector_num += n;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001463 qemu_progress_print(local_progress, 100);
bellardea2384d2004-08-01 21:59:26 +00001464 }
bellardfaea38e2006-08-05 21:31:00 +00001465 /* signal EOF to align */
1466 bdrv_write_compressed(out_bs, 0, NULL, 0);
bellardea2384d2004-08-01 21:59:26 +00001467 } else {
Kevin Wolff2feebb2010-04-14 17:30:35 +02001468 int has_zero_init = bdrv_has_zero_init(out_bs);
1469
thsf58c7b32008-06-05 21:53:49 +00001470 sector_num = 0; // total number of sectors converted so far
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001471 nb_sectors = total_sectors - sector_num;
Kevin Wolf1f710492012-10-12 14:29:18 +02001472 if (nb_sectors != 0) {
1473 local_progress = (float)100 /
1474 (nb_sectors / MIN(nb_sectors, IO_BUF_SIZE / 512));
1475 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001476
bellardea2384d2004-08-01 21:59:26 +00001477 for(;;) {
1478 nb_sectors = total_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001479 if (nb_sectors <= 0) {
bellardea2384d2004-08-01 21:59:26 +00001480 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001481 }
1482 if (nb_sectors >= (IO_BUF_SIZE / 512)) {
bellardea2384d2004-08-01 21:59:26 +00001483 n = (IO_BUF_SIZE / 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001484 } else {
bellardea2384d2004-08-01 21:59:26 +00001485 n = nb_sectors;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001486 }
balrog926c2d22007-10-31 01:11:44 +00001487
1488 while (sector_num - bs_offset >= bs_sectors) {
1489 bs_i ++;
1490 assert (bs_i < bs_n);
1491 bs_offset += bs_sectors;
1492 bdrv_get_geometry(bs[bs_i], &bs_sectors);
Blue Swirl0bfcd592010-05-22 08:02:12 +00001493 /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "
1494 "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",
balrog926c2d22007-10-31 01:11:44 +00001495 sector_num, bs_i, bs_offset, bs_sectors); */
1496 }
1497
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001498 if (n > bs_offset + bs_sectors - sector_num) {
balrog926c2d22007-10-31 01:11:44 +00001499 n = bs_offset + bs_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001500 }
balrog926c2d22007-10-31 01:11:44 +00001501
Paolo Bonzinie4a86f82013-09-04 19:00:26 +02001502 /* If the output image is being created as a copy on write image,
1503 assume that sectors which are unallocated in the input image
1504 are present in both the output's and input's base images (no
1505 need to copy them). */
1506 if (out_baseimg) {
1507 ret = bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
1508 n, &n1);
1509 if (ret < 0) {
1510 error_report("error while reading metadata for sector "
1511 "%" PRId64 ": %s",
1512 sector_num - bs_offset, strerror(-ret));
1513 goto out;
aliguori93c65b42009-04-05 17:40:43 +00001514 }
Paolo Bonzinie4a86f82013-09-04 19:00:26 +02001515 if (!ret) {
1516 sector_num += n1;
1517 continue;
1518 }
1519 /* The next 'n1' sectors are allocated in the input image. Copy
1520 only those as they may be followed by unallocated sectors. */
1521 n = n1;
aliguori93c65b42009-04-05 17:40:43 +00001522 } else {
1523 n1 = n;
thsf58c7b32008-06-05 21:53:49 +00001524 }
1525
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001526 ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
1527 if (ret < 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +01001528 error_report("error while reading sector %" PRId64 ": %s",
1529 sector_num - bs_offset, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001530 goto out;
1531 }
bellardea2384d2004-08-01 21:59:26 +00001532 /* NOTE: at the same time we convert, we do not write zero
1533 sectors to have a chance to compress the image. Ideally, we
1534 should add a specific call to have the info to go faster */
1535 buf1 = buf;
1536 while (n > 0) {
Paolo Bonzini11212d82013-09-04 19:00:27 +02001537 if (!has_zero_init ||
Kevin Wolfa22f1232011-08-26 15:27:13 +02001538 is_allocated_sectors_min(buf1, n, &n1, min_sparse)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001539 ret = bdrv_write(out_bs, sector_num, buf1, n1);
1540 if (ret < 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +01001541 error_report("error while writing sector %" PRId64
1542 ": %s", sector_num, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001543 goto out;
1544 }
bellardea2384d2004-08-01 21:59:26 +00001545 }
1546 sector_num += n1;
1547 n -= n1;
1548 buf1 += n1 * 512;
1549 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001550 qemu_progress_print(local_progress, 100);
bellardea2384d2004-08-01 21:59:26 +00001551 }
1552 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001553out:
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001554 qemu_progress_end();
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001555 free_option_parameters(create_options);
1556 free_option_parameters(param);
Kevin Wolfbb1c0592011-08-08 14:09:12 +02001557 qemu_vfree(buf);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001558 if (out_bs) {
Fam Zheng4f6fd342013-08-23 09:14:47 +08001559 bdrv_unref(out_bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001560 }
Jes Sorensen31ca34b2010-12-06 15:25:36 +01001561 if (bs) {
1562 for (bs_i = 0; bs_i < bs_n; bs_i++) {
1563 if (bs[bs_i]) {
Fam Zheng4f6fd342013-08-23 09:14:47 +08001564 bdrv_unref(bs[bs_i]);
Jes Sorensen31ca34b2010-12-06 15:25:36 +01001565 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001566 }
Anthony Liguori7267c092011-08-20 22:09:37 -05001567 g_free(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001568 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001569 if (ret) {
1570 return 1;
1571 }
bellardea2384d2004-08-01 21:59:26 +00001572 return 0;
1573}
1574
bellard57d1a2b2004-08-03 21:15:11 +00001575
bellardfaea38e2006-08-05 21:31:00 +00001576static void dump_snapshots(BlockDriverState *bs)
1577{
1578 QEMUSnapshotInfo *sn_tab, *sn;
1579 int nb_sns, i;
bellardfaea38e2006-08-05 21:31:00 +00001580
1581 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1582 if (nb_sns <= 0)
1583 return;
1584 printf("Snapshot list:\n");
Wenchao Xia5b917042013-05-25 11:09:45 +08001585 bdrv_snapshot_dump(fprintf, stdout, NULL);
1586 printf("\n");
bellardfaea38e2006-08-05 21:31:00 +00001587 for(i = 0; i < nb_sns; i++) {
1588 sn = &sn_tab[i];
Wenchao Xia5b917042013-05-25 11:09:45 +08001589 bdrv_snapshot_dump(fprintf, stdout, sn);
1590 printf("\n");
bellardfaea38e2006-08-05 21:31:00 +00001591 }
Anthony Liguori7267c092011-08-20 22:09:37 -05001592 g_free(sn_tab);
bellardfaea38e2006-08-05 21:31:00 +00001593}
1594
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001595static void dump_json_image_info_list(ImageInfoList *list)
1596{
1597 Error *errp = NULL;
1598 QString *str;
1599 QmpOutputVisitor *ov = qmp_output_visitor_new();
1600 QObject *obj;
1601 visit_type_ImageInfoList(qmp_output_get_visitor(ov),
1602 &list, NULL, &errp);
1603 obj = qmp_output_get_qobject(ov);
1604 str = qobject_to_json_pretty(obj);
1605 assert(str != NULL);
1606 printf("%s\n", qstring_get_str(str));
1607 qobject_decref(obj);
1608 qmp_output_visitor_cleanup(ov);
1609 QDECREF(str);
1610}
1611
Benoît Canetc054b3f2012-09-05 13:09:02 +02001612static void dump_json_image_info(ImageInfo *info)
1613{
1614 Error *errp = NULL;
1615 QString *str;
1616 QmpOutputVisitor *ov = qmp_output_visitor_new();
1617 QObject *obj;
1618 visit_type_ImageInfo(qmp_output_get_visitor(ov),
1619 &info, NULL, &errp);
1620 obj = qmp_output_get_qobject(ov);
1621 str = qobject_to_json_pretty(obj);
1622 assert(str != NULL);
1623 printf("%s\n", qstring_get_str(str));
1624 qobject_decref(obj);
1625 qmp_output_visitor_cleanup(ov);
1626 QDECREF(str);
1627}
1628
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001629static void dump_human_image_info_list(ImageInfoList *list)
1630{
1631 ImageInfoList *elem;
1632 bool delim = false;
1633
1634 for (elem = list; elem; elem = elem->next) {
1635 if (delim) {
1636 printf("\n");
1637 }
1638 delim = true;
1639
Wenchao Xia5b917042013-05-25 11:09:45 +08001640 bdrv_image_info_dump(fprintf, stdout, elem->value);
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001641 }
1642}
1643
1644static gboolean str_equal_func(gconstpointer a, gconstpointer b)
1645{
1646 return strcmp(a, b) == 0;
1647}
1648
1649/**
1650 * Open an image file chain and return an ImageInfoList
1651 *
1652 * @filename: topmost image filename
1653 * @fmt: topmost image format (may be NULL to autodetect)
1654 * @chain: true - enumerate entire backing file chain
1655 * false - only topmost image file
1656 *
1657 * Returns a list of ImageInfo objects or NULL if there was an error opening an
1658 * image file. If there was an error a message will have been printed to
1659 * stderr.
1660 */
1661static ImageInfoList *collect_image_info_list(const char *filename,
1662 const char *fmt,
1663 bool chain)
1664{
1665 ImageInfoList *head = NULL;
1666 ImageInfoList **last = &head;
1667 GHashTable *filenames;
Wenchao Xia43526ec2013-06-06 12:27:58 +08001668 Error *err = NULL;
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001669
1670 filenames = g_hash_table_new_full(g_str_hash, str_equal_func, NULL, NULL);
1671
1672 while (filename) {
1673 BlockDriverState *bs;
1674 ImageInfo *info;
1675 ImageInfoList *elem;
1676
1677 if (g_hash_table_lookup_extended(filenames, filename, NULL, NULL)) {
1678 error_report("Backing file '%s' creates an infinite loop.",
1679 filename);
1680 goto err;
1681 }
1682 g_hash_table_insert(filenames, (gpointer)filename, NULL);
1683
1684 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING,
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01001685 false, false);
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001686 if (!bs) {
1687 goto err;
1688 }
1689
Wenchao Xia43526ec2013-06-06 12:27:58 +08001690 bdrv_query_image_info(bs, &info, &err);
1691 if (error_is_set(&err)) {
1692 error_report("%s", error_get_pretty(err));
1693 error_free(err);
1694 goto err;
Wenchao Xiafb0ed452013-06-06 12:27:57 +08001695 }
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001696
1697 elem = g_new0(ImageInfoList, 1);
1698 elem->value = info;
1699 *last = elem;
1700 last = &elem->next;
1701
Fam Zheng4f6fd342013-08-23 09:14:47 +08001702 bdrv_unref(bs);
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001703
1704 filename = fmt = NULL;
1705 if (chain) {
1706 if (info->has_full_backing_filename) {
1707 filename = info->full_backing_filename;
1708 } else if (info->has_backing_filename) {
1709 filename = info->backing_filename;
1710 }
1711 if (info->has_backing_filename_format) {
1712 fmt = info->backing_filename_format;
1713 }
1714 }
1715 }
1716 g_hash_table_destroy(filenames);
1717 return head;
1718
1719err:
1720 qapi_free_ImageInfoList(head);
1721 g_hash_table_destroy(filenames);
1722 return NULL;
1723}
1724
Benoît Canetc054b3f2012-09-05 13:09:02 +02001725static int img_info(int argc, char **argv)
1726{
1727 int c;
1728 OutputFormat output_format = OFORMAT_HUMAN;
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001729 bool chain = false;
Benoît Canetc054b3f2012-09-05 13:09:02 +02001730 const char *filename, *fmt, *output;
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001731 ImageInfoList *list;
Benoît Canetc054b3f2012-09-05 13:09:02 +02001732
bellardea2384d2004-08-01 21:59:26 +00001733 fmt = NULL;
Benoît Canetc054b3f2012-09-05 13:09:02 +02001734 output = NULL;
bellardea2384d2004-08-01 21:59:26 +00001735 for(;;) {
Benoît Canetc054b3f2012-09-05 13:09:02 +02001736 int option_index = 0;
1737 static const struct option long_options[] = {
1738 {"help", no_argument, 0, 'h'},
1739 {"format", required_argument, 0, 'f'},
1740 {"output", required_argument, 0, OPTION_OUTPUT},
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001741 {"backing-chain", no_argument, 0, OPTION_BACKING_CHAIN},
Benoît Canetc054b3f2012-09-05 13:09:02 +02001742 {0, 0, 0, 0}
1743 };
1744 c = getopt_long(argc, argv, "f:h",
1745 long_options, &option_index);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001746 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +00001747 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001748 }
bellardea2384d2004-08-01 21:59:26 +00001749 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001750 case '?':
bellardea2384d2004-08-01 21:59:26 +00001751 case 'h':
1752 help();
1753 break;
1754 case 'f':
1755 fmt = optarg;
1756 break;
Benoît Canetc054b3f2012-09-05 13:09:02 +02001757 case OPTION_OUTPUT:
1758 output = optarg;
1759 break;
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001760 case OPTION_BACKING_CHAIN:
1761 chain = true;
1762 break;
bellardea2384d2004-08-01 21:59:26 +00001763 }
1764 }
Kevin Wolffc11eb22013-08-05 10:53:04 +02001765 if (optind != argc - 1) {
bellardea2384d2004-08-01 21:59:26 +00001766 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001767 }
bellardea2384d2004-08-01 21:59:26 +00001768 filename = argv[optind++];
1769
Benoît Canetc054b3f2012-09-05 13:09:02 +02001770 if (output && !strcmp(output, "json")) {
1771 output_format = OFORMAT_JSON;
1772 } else if (output && !strcmp(output, "human")) {
1773 output_format = OFORMAT_HUMAN;
1774 } else if (output) {
1775 error_report("--output must be used with human or json as argument.");
1776 return 1;
1777 }
1778
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001779 list = collect_image_info_list(filename, fmt, chain);
1780 if (!list) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001781 return 1;
1782 }
Benoît Canetc054b3f2012-09-05 13:09:02 +02001783
Benoît Canetc054b3f2012-09-05 13:09:02 +02001784 switch (output_format) {
1785 case OFORMAT_HUMAN:
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001786 dump_human_image_info_list(list);
Benoît Canetc054b3f2012-09-05 13:09:02 +02001787 break;
1788 case OFORMAT_JSON:
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001789 if (chain) {
1790 dump_json_image_info_list(list);
1791 } else {
1792 dump_json_image_info(list->value);
1793 }
Benoît Canetc054b3f2012-09-05 13:09:02 +02001794 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001795 }
Benoît Canetc054b3f2012-09-05 13:09:02 +02001796
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001797 qapi_free_ImageInfoList(list);
bellardea2384d2004-08-01 21:59:26 +00001798 return 0;
1799}
1800
Paolo Bonzini4c93a13b2013-09-04 19:00:33 +02001801
1802typedef struct MapEntry {
1803 int flags;
1804 int depth;
1805 int64_t start;
1806 int64_t length;
1807 int64_t offset;
1808 BlockDriverState *bs;
1809} MapEntry;
1810
1811static void dump_map_entry(OutputFormat output_format, MapEntry *e,
1812 MapEntry *next)
1813{
1814 switch (output_format) {
1815 case OFORMAT_HUMAN:
1816 if ((e->flags & BDRV_BLOCK_DATA) &&
1817 !(e->flags & BDRV_BLOCK_OFFSET_VALID)) {
1818 error_report("File contains external, encrypted or compressed clusters.");
1819 exit(1);
1820 }
1821 if ((e->flags & (BDRV_BLOCK_DATA|BDRV_BLOCK_ZERO)) == BDRV_BLOCK_DATA) {
1822 printf("%#-16"PRIx64"%#-16"PRIx64"%#-16"PRIx64"%s\n",
1823 e->start, e->length, e->offset, e->bs->filename);
1824 }
1825 /* This format ignores the distinction between 0, ZERO and ZERO|DATA.
1826 * Modify the flags here to allow more coalescing.
1827 */
1828 if (next &&
1829 (next->flags & (BDRV_BLOCK_DATA|BDRV_BLOCK_ZERO)) != BDRV_BLOCK_DATA) {
1830 next->flags &= ~BDRV_BLOCK_DATA;
1831 next->flags |= BDRV_BLOCK_ZERO;
1832 }
1833 break;
1834 case OFORMAT_JSON:
1835 printf("%s{ \"start\": %"PRId64", \"length\": %"PRId64", \"depth\": %d,"
1836 " \"zero\": %s, \"data\": %s",
1837 (e->start == 0 ? "[" : ",\n"),
1838 e->start, e->length, e->depth,
1839 (e->flags & BDRV_BLOCK_ZERO) ? "true" : "false",
1840 (e->flags & BDRV_BLOCK_DATA) ? "true" : "false");
1841 if (e->flags & BDRV_BLOCK_OFFSET_VALID) {
Paolo Bonzinic745bfb2013-09-11 18:47:52 +02001842 printf(", \"offset\": %"PRId64"", e->offset);
Paolo Bonzini4c93a13b2013-09-04 19:00:33 +02001843 }
1844 putchar('}');
1845
1846 if (!next) {
1847 printf("]\n");
1848 }
1849 break;
1850 }
1851}
1852
1853static int get_block_status(BlockDriverState *bs, int64_t sector_num,
1854 int nb_sectors, MapEntry *e)
1855{
1856 int64_t ret;
1857 int depth;
1858
1859 /* As an optimization, we could cache the current range of unallocated
1860 * clusters in each file of the chain, and avoid querying the same
1861 * range repeatedly.
1862 */
1863
1864 depth = 0;
1865 for (;;) {
1866 ret = bdrv_get_block_status(bs, sector_num, nb_sectors, &nb_sectors);
1867 if (ret < 0) {
1868 return ret;
1869 }
1870 assert(nb_sectors);
1871 if (ret & (BDRV_BLOCK_ZERO|BDRV_BLOCK_DATA)) {
1872 break;
1873 }
1874 bs = bs->backing_hd;
1875 if (bs == NULL) {
1876 ret = 0;
1877 break;
1878 }
1879
1880 depth++;
1881 }
1882
1883 e->start = sector_num * BDRV_SECTOR_SIZE;
1884 e->length = nb_sectors * BDRV_SECTOR_SIZE;
1885 e->flags = ret & ~BDRV_BLOCK_OFFSET_MASK;
1886 e->offset = ret & BDRV_BLOCK_OFFSET_MASK;
1887 e->depth = depth;
1888 e->bs = bs;
1889 return 0;
1890}
1891
1892static int img_map(int argc, char **argv)
1893{
1894 int c;
1895 OutputFormat output_format = OFORMAT_HUMAN;
1896 BlockDriverState *bs;
1897 const char *filename, *fmt, *output;
1898 int64_t length;
1899 MapEntry curr = { .length = 0 }, next;
1900 int ret = 0;
1901
1902 fmt = NULL;
1903 output = NULL;
1904 for (;;) {
1905 int option_index = 0;
1906 static const struct option long_options[] = {
1907 {"help", no_argument, 0, 'h'},
1908 {"format", required_argument, 0, 'f'},
1909 {"output", required_argument, 0, OPTION_OUTPUT},
1910 {0, 0, 0, 0}
1911 };
1912 c = getopt_long(argc, argv, "f:h",
1913 long_options, &option_index);
1914 if (c == -1) {
1915 break;
1916 }
1917 switch (c) {
1918 case '?':
1919 case 'h':
1920 help();
1921 break;
1922 case 'f':
1923 fmt = optarg;
1924 break;
1925 case OPTION_OUTPUT:
1926 output = optarg;
1927 break;
1928 }
1929 }
1930 if (optind >= argc) {
1931 help();
1932 }
1933 filename = argv[optind++];
1934
1935 if (output && !strcmp(output, "json")) {
1936 output_format = OFORMAT_JSON;
1937 } else if (output && !strcmp(output, "human")) {
1938 output_format = OFORMAT_HUMAN;
1939 } else if (output) {
1940 error_report("--output must be used with human or json as argument.");
1941 return 1;
1942 }
1943
1944 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS, true, false);
1945 if (!bs) {
1946 return 1;
1947 }
1948
1949 if (output_format == OFORMAT_HUMAN) {
1950 printf("%-16s%-16s%-16s%s\n", "Offset", "Length", "Mapped to", "File");
1951 }
1952
1953 length = bdrv_getlength(bs);
1954 while (curr.start + curr.length < length) {
1955 int64_t nsectors_left;
1956 int64_t sector_num;
1957 int n;
1958
1959 sector_num = (curr.start + curr.length) >> BDRV_SECTOR_BITS;
1960
1961 /* Probe up to 1 GiB at a time. */
1962 nsectors_left = DIV_ROUND_UP(length, BDRV_SECTOR_SIZE) - sector_num;
1963 n = MIN(1 << (30 - BDRV_SECTOR_BITS), nsectors_left);
1964 ret = get_block_status(bs, sector_num, n, &next);
1965
1966 if (ret < 0) {
1967 error_report("Could not read file metadata: %s", strerror(-ret));
1968 goto out;
1969 }
1970
1971 if (curr.length != 0 && curr.flags == next.flags &&
1972 curr.depth == next.depth &&
1973 ((curr.flags & BDRV_BLOCK_OFFSET_VALID) == 0 ||
1974 curr.offset + curr.length == next.offset)) {
1975 curr.length += next.length;
1976 continue;
1977 }
1978
1979 if (curr.length > 0) {
1980 dump_map_entry(output_format, &curr, &next);
1981 }
1982 curr = next;
1983 }
1984
1985 dump_map_entry(output_format, &curr, NULL);
1986
1987out:
1988 bdrv_unref(bs);
1989 return ret < 0;
1990}
1991
aliguorif7b4a942009-01-07 17:40:15 +00001992#define SNAPSHOT_LIST 1
1993#define SNAPSHOT_CREATE 2
1994#define SNAPSHOT_APPLY 3
1995#define SNAPSHOT_DELETE 4
1996
Stuart Brady153859b2009-06-07 00:42:17 +01001997static int img_snapshot(int argc, char **argv)
aliguorif7b4a942009-01-07 17:40:15 +00001998{
1999 BlockDriverState *bs;
2000 QEMUSnapshotInfo sn;
2001 char *filename, *snapshot_name = NULL;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002002 int c, ret = 0, bdrv_oflags;
aliguorif7b4a942009-01-07 17:40:15 +00002003 int action = 0;
2004 qemu_timeval tv;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002005 bool quiet = false;
Wenchao Xiaa89d89d2013-09-11 14:04:33 +08002006 Error *err = NULL;
aliguorif7b4a942009-01-07 17:40:15 +00002007
Kevin Wolf710da702011-01-10 12:33:02 +01002008 bdrv_oflags = BDRV_O_FLAGS | BDRV_O_RDWR;
aliguorif7b4a942009-01-07 17:40:15 +00002009 /* Parse commandline parameters */
2010 for(;;) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002011 c = getopt(argc, argv, "la:c:d:hq");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01002012 if (c == -1) {
aliguorif7b4a942009-01-07 17:40:15 +00002013 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01002014 }
aliguorif7b4a942009-01-07 17:40:15 +00002015 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01002016 case '?':
aliguorif7b4a942009-01-07 17:40:15 +00002017 case 'h':
2018 help();
Stuart Brady153859b2009-06-07 00:42:17 +01002019 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00002020 case 'l':
2021 if (action) {
2022 help();
Stuart Brady153859b2009-06-07 00:42:17 +01002023 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00002024 }
2025 action = SNAPSHOT_LIST;
Naphtali Spreif5edb012010-01-17 16:48:13 +02002026 bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
aliguorif7b4a942009-01-07 17:40:15 +00002027 break;
2028 case 'a':
2029 if (action) {
2030 help();
Stuart Brady153859b2009-06-07 00:42:17 +01002031 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00002032 }
2033 action = SNAPSHOT_APPLY;
2034 snapshot_name = optarg;
2035 break;
2036 case 'c':
2037 if (action) {
2038 help();
Stuart Brady153859b2009-06-07 00:42:17 +01002039 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00002040 }
2041 action = SNAPSHOT_CREATE;
2042 snapshot_name = optarg;
2043 break;
2044 case 'd':
2045 if (action) {
2046 help();
Stuart Brady153859b2009-06-07 00:42:17 +01002047 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00002048 }
2049 action = SNAPSHOT_DELETE;
2050 snapshot_name = optarg;
2051 break;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002052 case 'q':
2053 quiet = true;
2054 break;
aliguorif7b4a942009-01-07 17:40:15 +00002055 }
2056 }
2057
Kevin Wolffc11eb22013-08-05 10:53:04 +02002058 if (optind != argc - 1) {
aliguorif7b4a942009-01-07 17:40:15 +00002059 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01002060 }
aliguorif7b4a942009-01-07 17:40:15 +00002061 filename = argv[optind++];
2062
2063 /* Open the image */
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002064 bs = bdrv_new_open(filename, NULL, bdrv_oflags, true, quiet);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002065 if (!bs) {
2066 return 1;
2067 }
aliguorif7b4a942009-01-07 17:40:15 +00002068
2069 /* Perform the requested action */
2070 switch(action) {
2071 case SNAPSHOT_LIST:
2072 dump_snapshots(bs);
2073 break;
2074
2075 case SNAPSHOT_CREATE:
2076 memset(&sn, 0, sizeof(sn));
2077 pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
2078
2079 qemu_gettimeofday(&tv);
2080 sn.date_sec = tv.tv_sec;
2081 sn.date_nsec = tv.tv_usec * 1000;
2082
2083 ret = bdrv_snapshot_create(bs, &sn);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01002084 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01002085 error_report("Could not create snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00002086 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01002087 }
aliguorif7b4a942009-01-07 17:40:15 +00002088 break;
2089
2090 case SNAPSHOT_APPLY:
2091 ret = bdrv_snapshot_goto(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01002092 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01002093 error_report("Could not apply snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00002094 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01002095 }
aliguorif7b4a942009-01-07 17:40:15 +00002096 break;
2097
2098 case SNAPSHOT_DELETE:
Wenchao Xiaa89d89d2013-09-11 14:04:33 +08002099 bdrv_snapshot_delete_by_id_or_name(bs, snapshot_name, &err);
2100 if (error_is_set(&err)) {
2101 error_report("Could not delete snapshot '%s': (%s)",
2102 snapshot_name, error_get_pretty(err));
2103 error_free(err);
2104 ret = 1;
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;
Max Reitz34b5d2c2013-09-05 14:45:29 +02002127 Error *local_err = NULL;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002128
2129 /* Parse commandline parameters */
Kevin Wolfe53dbee2010-03-02 12:14:31 +01002130 fmt = NULL;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04002131 cache = BDRV_DEFAULT_CACHE;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002132 out_baseimg = NULL;
2133 out_basefmt = NULL;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002134 for(;;) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002135 c = getopt(argc, argv, "uhf:F:b:pt:q");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01002136 if (c == -1) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002137 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01002138 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002139 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01002140 case '?':
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002141 case 'h':
2142 help();
2143 return 0;
Kevin Wolfe53dbee2010-03-02 12:14:31 +01002144 case 'f':
2145 fmt = optarg;
2146 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002147 case 'F':
2148 out_basefmt = optarg;
2149 break;
2150 case 'b':
2151 out_baseimg = optarg;
2152 break;
2153 case 'u':
2154 unsafe = 1;
2155 break;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02002156 case 'p':
2157 progress = 1;
2158 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04002159 case 't':
2160 cache = optarg;
2161 break;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002162 case 'q':
2163 quiet = true;
2164 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002165 }
2166 }
2167
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002168 if (quiet) {
2169 progress = 0;
2170 }
2171
Kevin Wolffc11eb22013-08-05 10:53:04 +02002172 if ((optind != argc - 1) || (!unsafe && !out_baseimg)) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002173 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01002174 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002175 filename = argv[optind++];
2176
Jes Sorensen6b837bc2011-03-30 14:16:25 +02002177 qemu_progress_init(progress, 2.0);
2178 qemu_progress_print(0, 100);
2179
Federico Simoncelli661a0f72011-06-20 12:48:19 -04002180 flags = BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +01002181 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -04002182 if (ret < 0) {
2183 error_report("Invalid cache option: %s", cache);
2184 return -1;
2185 }
2186
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002187 /*
2188 * Open the images.
2189 *
2190 * Ignore the old backing file for unsafe rebase in case we want to correct
2191 * the reference to a renamed or moved backing file.
2192 */
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002193 bs = bdrv_new_open(filename, fmt, flags, true, quiet);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002194 if (!bs) {
2195 return 1;
2196 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002197
2198 /* Find the right drivers for the backing files */
2199 old_backing_drv = NULL;
2200 new_backing_drv = NULL;
2201
2202 if (!unsafe && bs->backing_format[0] != '\0') {
2203 old_backing_drv = bdrv_find_format(bs->backing_format);
2204 if (old_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01002205 error_report("Invalid format name: '%s'", bs->backing_format);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002206 ret = -1;
2207 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002208 }
2209 }
2210
2211 if (out_basefmt != NULL) {
2212 new_backing_drv = bdrv_find_format(out_basefmt);
2213 if (new_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01002214 error_report("Invalid format name: '%s'", out_basefmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002215 ret = -1;
2216 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002217 }
2218 }
2219
2220 /* For safe rebasing we need to compare old and new backing file */
2221 if (unsafe) {
2222 /* Make the compiler happy */
2223 bs_old_backing = NULL;
2224 bs_new_backing = NULL;
2225 } else {
2226 char backing_name[1024];
2227
2228 bs_old_backing = bdrv_new("old_backing");
2229 bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
Kevin Wolfde9c0ce2013-03-15 10:35:02 +01002230 ret = bdrv_open(bs_old_backing, backing_name, NULL, BDRV_O_FLAGS,
Max Reitz34b5d2c2013-09-05 14:45:29 +02002231 old_backing_drv, &local_err);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002232 if (ret) {
Max Reitz34b5d2c2013-09-05 14:45:29 +02002233 error_report("Could not open old backing file '%s': %s",
2234 backing_name, error_get_pretty(local_err));
2235 error_free(local_err);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002236 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002237 }
Alex Bligha6166732012-10-16 13:46:18 +01002238 if (out_baseimg[0]) {
2239 bs_new_backing = bdrv_new("new_backing");
Kevin Wolfde9c0ce2013-03-15 10:35:02 +01002240 ret = bdrv_open(bs_new_backing, out_baseimg, NULL, BDRV_O_FLAGS,
Max Reitz34b5d2c2013-09-05 14:45:29 +02002241 new_backing_drv, &local_err);
Alex Bligha6166732012-10-16 13:46:18 +01002242 if (ret) {
Max Reitz34b5d2c2013-09-05 14:45:29 +02002243 error_report("Could not open new backing file '%s': %s",
2244 out_baseimg, error_get_pretty(local_err));
2245 error_free(local_err);
Alex Bligha6166732012-10-16 13:46:18 +01002246 goto out;
2247 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002248 }
2249 }
2250
2251 /*
2252 * Check each unallocated cluster in the COW file. If it is unallocated,
2253 * accesses go to the backing file. We must therefore compare this cluster
2254 * in the old and new backing file, and if they differ we need to copy it
2255 * from the old backing file into the COW file.
2256 *
2257 * If qemu-img crashes during this step, no harm is done. The content of
2258 * the image is the same as the original one at any time.
2259 */
2260 if (!unsafe) {
2261 uint64_t num_sectors;
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01002262 uint64_t old_backing_num_sectors;
Alex Bligha6166732012-10-16 13:46:18 +01002263 uint64_t new_backing_num_sectors = 0;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002264 uint64_t sector;
Kevin Wolfcc60e322010-04-29 14:47:48 +02002265 int n;
TeLeMand6771bf2010-02-08 16:20:00 +08002266 uint8_t * buf_old;
2267 uint8_t * buf_new;
Kevin Wolf1f710492012-10-12 14:29:18 +02002268 float local_progress = 0;
TeLeMand6771bf2010-02-08 16:20:00 +08002269
Kevin Wolfbb1c0592011-08-08 14:09:12 +02002270 buf_old = qemu_blockalign(bs, IO_BUF_SIZE);
2271 buf_new = qemu_blockalign(bs, IO_BUF_SIZE);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002272
2273 bdrv_get_geometry(bs, &num_sectors);
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01002274 bdrv_get_geometry(bs_old_backing, &old_backing_num_sectors);
Alex Bligha6166732012-10-16 13:46:18 +01002275 if (bs_new_backing) {
2276 bdrv_get_geometry(bs_new_backing, &new_backing_num_sectors);
2277 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002278
Kevin Wolf1f710492012-10-12 14:29:18 +02002279 if (num_sectors != 0) {
2280 local_progress = (float)100 /
2281 (num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512));
2282 }
2283
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002284 for (sector = 0; sector < num_sectors; sector += n) {
2285
2286 /* How many sectors can we handle with the next read? */
2287 if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
2288 n = (IO_BUF_SIZE / 512);
2289 } else {
2290 n = num_sectors - sector;
2291 }
2292
2293 /* If the cluster is allocated, we don't need to take action */
Kevin Wolfcc60e322010-04-29 14:47:48 +02002294 ret = bdrv_is_allocated(bs, sector, n, &n);
Paolo Bonzinid6636402013-09-04 19:00:25 +02002295 if (ret < 0) {
2296 error_report("error while reading image metadata: %s",
2297 strerror(-ret));
2298 goto out;
2299 }
Kevin Wolfcc60e322010-04-29 14:47:48 +02002300 if (ret) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002301 continue;
2302 }
2303
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01002304 /*
2305 * Read old and new backing file and take into consideration that
2306 * backing files may be smaller than the COW image.
2307 */
2308 if (sector >= old_backing_num_sectors) {
2309 memset(buf_old, 0, n * BDRV_SECTOR_SIZE);
2310 } else {
2311 if (sector + n > old_backing_num_sectors) {
2312 n = old_backing_num_sectors - sector;
2313 }
2314
2315 ret = bdrv_read(bs_old_backing, sector, buf_old, n);
2316 if (ret < 0) {
2317 error_report("error while reading from old backing file");
2318 goto out;
2319 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002320 }
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01002321
Alex Bligha6166732012-10-16 13:46:18 +01002322 if (sector >= new_backing_num_sectors || !bs_new_backing) {
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01002323 memset(buf_new, 0, n * BDRV_SECTOR_SIZE);
2324 } else {
2325 if (sector + n > new_backing_num_sectors) {
2326 n = new_backing_num_sectors - sector;
2327 }
2328
2329 ret = bdrv_read(bs_new_backing, sector, buf_new, n);
2330 if (ret < 0) {
2331 error_report("error while reading from new backing file");
2332 goto out;
2333 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002334 }
2335
2336 /* If they differ, we need to write to the COW file */
2337 uint64_t written = 0;
2338
2339 while (written < n) {
2340 int pnum;
2341
2342 if (compare_sectors(buf_old + written * 512,
Kevin Wolf60b1bd42010-02-17 12:32:59 +01002343 buf_new + written * 512, n - written, &pnum))
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002344 {
2345 ret = bdrv_write(bs, sector + written,
2346 buf_old + written * 512, pnum);
2347 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01002348 error_report("Error while writing to COW image: %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002349 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002350 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002351 }
2352 }
2353
2354 written += pnum;
2355 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02002356 qemu_progress_print(local_progress, 100);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002357 }
TeLeMand6771bf2010-02-08 16:20:00 +08002358
Kevin Wolfbb1c0592011-08-08 14:09:12 +02002359 qemu_vfree(buf_old);
2360 qemu_vfree(buf_new);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002361 }
2362
2363 /*
2364 * Change the backing file. All clusters that are different from the old
2365 * backing file are overwritten in the COW file now, so the visible content
2366 * doesn't change when we switch the backing file.
2367 */
Alex Bligha6166732012-10-16 13:46:18 +01002368 if (out_baseimg && *out_baseimg) {
2369 ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
2370 } else {
2371 ret = bdrv_change_backing_file(bs, NULL, NULL);
2372 }
2373
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002374 if (ret == -ENOSPC) {
Jes Sorensen15654a62010-12-16 14:31:53 +01002375 error_report("Could not change the backing file to '%s': No "
2376 "space left in the file header", out_baseimg);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002377 } else if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01002378 error_report("Could not change the backing file to '%s': %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002379 out_baseimg, strerror(-ret));
2380 }
2381
Jes Sorensen6b837bc2011-03-30 14:16:25 +02002382 qemu_progress_print(100, 0);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002383 /*
2384 * TODO At this point it is possible to check if any clusters that are
2385 * allocated in the COW file are the same in the backing file. If so, they
2386 * could be dropped from the COW file. Don't do this before switching the
2387 * backing file, in case of a crash this would lead to corruption.
2388 */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002389out:
Jes Sorensen6b837bc2011-03-30 14:16:25 +02002390 qemu_progress_end();
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002391 /* Cleanup */
2392 if (!unsafe) {
Kevin Wolfeb863ad2011-03-31 12:39:51 +02002393 if (bs_old_backing != NULL) {
Fam Zheng4f6fd342013-08-23 09:14:47 +08002394 bdrv_unref(bs_old_backing);
Kevin Wolfeb863ad2011-03-31 12:39:51 +02002395 }
2396 if (bs_new_backing != NULL) {
Fam Zheng4f6fd342013-08-23 09:14:47 +08002397 bdrv_unref(bs_new_backing);
Kevin Wolfeb863ad2011-03-31 12:39:51 +02002398 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002399 }
2400
Fam Zheng4f6fd342013-08-23 09:14:47 +08002401 bdrv_unref(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002402 if (ret) {
2403 return 1;
2404 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01002405 return 0;
2406}
2407
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002408static int img_resize(int argc, char **argv)
2409{
2410 int c, ret, relative;
2411 const char *filename, *fmt, *size;
2412 int64_t n, total_size;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002413 bool quiet = false;
Jes Sorensen2a819982010-12-06 17:08:31 +01002414 BlockDriverState *bs = NULL;
Dong Xu Wang20caf0f2012-08-06 10:18:42 +08002415 QemuOpts *param;
2416 static QemuOptsList resize_options = {
2417 .name = "resize_options",
2418 .head = QTAILQ_HEAD_INITIALIZER(resize_options.head),
2419 .desc = {
2420 {
2421 .name = BLOCK_OPT_SIZE,
2422 .type = QEMU_OPT_SIZE,
2423 .help = "Virtual disk size"
2424 }, {
2425 /* end of list */
2426 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002427 },
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002428 };
2429
Kevin Wolfe80fec72011-04-29 10:58:12 +02002430 /* Remove size from argv manually so that negative numbers are not treated
2431 * as options by getopt. */
2432 if (argc < 3) {
2433 help();
2434 return 1;
2435 }
2436
2437 size = argv[--argc];
2438
2439 /* Parse getopt arguments */
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002440 fmt = NULL;
2441 for(;;) {
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002442 c = getopt(argc, argv, "f:hq");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002443 if (c == -1) {
2444 break;
2445 }
2446 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01002447 case '?':
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002448 case 'h':
2449 help();
2450 break;
2451 case 'f':
2452 fmt = optarg;
2453 break;
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002454 case 'q':
2455 quiet = true;
2456 break;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002457 }
2458 }
Kevin Wolffc11eb22013-08-05 10:53:04 +02002459 if (optind != argc - 1) {
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002460 help();
2461 }
2462 filename = argv[optind++];
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002463
2464 /* Choose grow, shrink, or absolute resize mode */
2465 switch (size[0]) {
2466 case '+':
2467 relative = 1;
2468 size++;
2469 break;
2470 case '-':
2471 relative = -1;
2472 size++;
2473 break;
2474 default:
2475 relative = 0;
2476 break;
2477 }
2478
2479 /* Parse size */
Dong Xu Wange478b442012-12-06 14:47:22 +08002480 param = qemu_opts_create_nofail(&resize_options);
Dong Xu Wang20caf0f2012-08-06 10:18:42 +08002481 if (qemu_opt_set(param, BLOCK_OPT_SIZE, size)) {
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002482 /* Error message already printed when size parsing fails */
Jes Sorensen2a819982010-12-06 17:08:31 +01002483 ret = -1;
Dong Xu Wang20caf0f2012-08-06 10:18:42 +08002484 qemu_opts_del(param);
Jes Sorensen2a819982010-12-06 17:08:31 +01002485 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002486 }
Dong Xu Wang20caf0f2012-08-06 10:18:42 +08002487 n = qemu_opt_get_size(param, BLOCK_OPT_SIZE, 0);
2488 qemu_opts_del(param);
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002489
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002490 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR, true, quiet);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002491 if (!bs) {
Jes Sorensen2a819982010-12-06 17:08:31 +01002492 ret = -1;
2493 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002494 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002495
2496 if (relative) {
2497 total_size = bdrv_getlength(bs) + n * relative;
2498 } else {
2499 total_size = n;
2500 }
2501 if (total_size <= 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01002502 error_report("New image size must be positive");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002503 ret = -1;
2504 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002505 }
2506
2507 ret = bdrv_truncate(bs, total_size);
2508 switch (ret) {
2509 case 0:
Miroslav Rezaninaf382d432013-02-13 09:09:40 +01002510 qprintf(quiet, "Image resized.\n");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002511 break;
2512 case -ENOTSUP:
Kevin Wolf259b2172012-03-06 12:44:45 +01002513 error_report("This image does not support resize");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002514 break;
2515 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +01002516 error_report("Image is read-only");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002517 break;
2518 default:
Jes Sorensen15654a62010-12-16 14:31:53 +01002519 error_report("Error resizing image (%d)", -ret);
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002520 break;
2521 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002522out:
Jes Sorensen2a819982010-12-06 17:08:31 +01002523 if (bs) {
Fam Zheng4f6fd342013-08-23 09:14:47 +08002524 bdrv_unref(bs);
Jes Sorensen2a819982010-12-06 17:08:31 +01002525 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09002526 if (ret) {
2527 return 1;
2528 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01002529 return 0;
2530}
2531
Max Reitz6f176b42013-09-03 10:09:50 +02002532static int img_amend(int argc, char **argv)
2533{
2534 int c, ret = 0;
2535 char *options = NULL;
2536 QEMUOptionParameter *create_options = NULL, *options_param = NULL;
2537 const char *fmt = NULL, *filename;
2538 bool quiet = false;
2539 BlockDriverState *bs = NULL;
2540
2541 for (;;) {
2542 c = getopt(argc, argv, "hqf:o:");
2543 if (c == -1) {
2544 break;
2545 }
2546
2547 switch (c) {
2548 case 'h':
2549 case '?':
2550 help();
2551 break;
2552 case 'o':
2553 options = optarg;
2554 break;
2555 case 'f':
2556 fmt = optarg;
2557 break;
2558 case 'q':
2559 quiet = true;
2560 break;
2561 }
2562 }
2563
2564 if (optind != argc - 1) {
2565 help();
2566 }
2567
2568 if (!options) {
2569 help();
2570 }
2571
2572 filename = argv[argc - 1];
2573
2574 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR, true, quiet);
2575 if (!bs) {
2576 error_report("Could not open image '%s'", filename);
2577 ret = -1;
2578 goto out;
2579 }
2580
2581 fmt = bs->drv->format_name;
2582
2583 if (is_help_option(options)) {
2584 ret = print_block_option_help(filename, fmt);
2585 goto out;
2586 }
2587
2588 create_options = append_option_parameters(create_options,
2589 bs->drv->create_options);
2590 options_param = parse_option_parameters(options, create_options,
2591 options_param);
2592 if (options_param == NULL) {
2593 error_report("Invalid options for file format '%s'", fmt);
2594 ret = -1;
2595 goto out;
2596 }
2597
2598 ret = bdrv_amend_options(bs, options_param);
2599 if (ret < 0) {
2600 error_report("Error while amending options: %s", strerror(-ret));
2601 goto out;
2602 }
2603
2604out:
2605 if (bs) {
2606 bdrv_unref(bs);
2607 }
2608 free_option_parameters(create_options);
2609 free_option_parameters(options_param);
2610 if (ret) {
2611 return 1;
2612 }
2613 return 0;
2614}
2615
Anthony Liguoric227f092009-10-01 16:12:16 -05002616static const img_cmd_t img_cmds[] = {
Stuart Brady153859b2009-06-07 00:42:17 +01002617#define DEF(option, callback, arg_string) \
2618 { option, callback },
2619#include "qemu-img-cmds.h"
2620#undef DEF
2621#undef GEN_DOCS
2622 { NULL, NULL, },
2623};
2624
bellardea2384d2004-08-01 21:59:26 +00002625int main(int argc, char **argv)
2626{
Anthony Liguoric227f092009-10-01 16:12:16 -05002627 const img_cmd_t *cmd;
Stuart Brady153859b2009-06-07 00:42:17 +01002628 const char *cmdname;
bellardea2384d2004-08-01 21:59:26 +00002629
MORITA Kazutaka526eda12013-07-23 17:30:11 +09002630#ifdef CONFIG_POSIX
2631 signal(SIGPIPE, SIG_IGN);
2632#endif
2633
Kevin Wolf53f76e52010-12-16 15:10:32 +01002634 error_set_progname(argv[0]);
2635
Paolo Bonzini2592c592012-11-03 18:10:17 +01002636 qemu_init_main_loop();
bellardea2384d2004-08-01 21:59:26 +00002637 bdrv_init();
2638 if (argc < 2)
2639 help();
Stuart Brady153859b2009-06-07 00:42:17 +01002640 cmdname = argv[1];
aurel328f9b1572009-02-09 18:14:31 +00002641 argc--; argv++;
Stuart Brady153859b2009-06-07 00:42:17 +01002642
2643 /* find the command */
2644 for(cmd = img_cmds; cmd->name != NULL; cmd++) {
2645 if (!strcmp(cmdname, cmd->name)) {
2646 return cmd->handler(argc, argv);
2647 }
bellardea2384d2004-08-01 21:59:26 +00002648 }
Stuart Brady153859b2009-06-07 00:42:17 +01002649
2650 /* not found */
2651 help();
bellardea2384d2004-08-01 21:59:26 +00002652 return 0;
2653}