blob: 85d3740b9ca9af1e536f06fef45835b670218bd0 [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"
Benoît Canetc054b3f2012-09-05 13:09:02 +020033#include <getopt.h>
aliguori9230eaf2009-03-28 17:55:19 +000034#include <stdio.h>
bellardea2384d2004-08-01 21:59:26 +000035
bellarde8445332006-06-14 15:32:10 +000036#ifdef _WIN32
37#include <windows.h>
38#endif
39
Anthony Liguoric227f092009-10-01 16:12:16 -050040typedef struct img_cmd_t {
Stuart Brady153859b2009-06-07 00:42:17 +010041 const char *name;
42 int (*handler)(int argc, char **argv);
Anthony Liguoric227f092009-10-01 16:12:16 -050043} img_cmd_t;
Stuart Brady153859b2009-06-07 00:42:17 +010044
aurel32137519c2008-11-30 19:12:49 +000045/* Default to cache=writeback as data integrity is not important for qemu-tcg. */
Stefan Hajnocziadfe0782010-04-13 10:29:35 +010046#define BDRV_O_FLAGS BDRV_O_CACHE_WB
Federico Simoncelli661a0f72011-06-20 12:48:19 -040047#define BDRV_DEFAULT_CACHE "writeback"
aurel32137519c2008-11-30 19:12:49 +000048
bellardea2384d2004-08-01 21:59:26 +000049static void format_print(void *opaque, const char *name)
50{
51 printf(" %s", name);
52}
53
blueswir1d2c639d2009-01-24 18:19:25 +000054/* Please keep in synch with qemu-img.texi */
pbrook3f379ab2007-11-11 03:33:13 +000055static void help(void)
bellardea2384d2004-08-01 21:59:26 +000056{
Paolo Bonzinie00291c2010-02-04 16:49:56 +010057 const char *help_msg =
58 "qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fabrice Bellard\n"
malc3f020d72010-02-08 12:04:56 +030059 "usage: qemu-img command [command options]\n"
60 "QEMU disk image utility\n"
61 "\n"
62 "Command syntax:\n"
Stuart Brady153859b2009-06-07 00:42:17 +010063#define DEF(option, callback, arg_string) \
64 " " arg_string "\n"
65#include "qemu-img-cmds.h"
66#undef DEF
67#undef GEN_DOCS
malc3f020d72010-02-08 12:04:56 +030068 "\n"
69 "Command parameters:\n"
70 " 'filename' is a disk image filename\n"
71 " 'fmt' is the disk image format. It is guessed automatically in most cases\n"
Federico Simoncelli661a0f72011-06-20 12:48:19 -040072 " 'cache' is the cache mode used to write the output disk image, the valid\n"
Liu Yuan80ccf932012-04-20 17:10:56 +080073 " options are: 'none', 'writeback' (default, except for convert), 'writethrough',\n"
74 " 'directsync' and 'unsafe' (default for convert)\n"
malc3f020d72010-02-08 12:04:56 +030075 " 'size' is the disk image size in bytes. Optional suffixes\n"
76 " 'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M)\n"
77 " and T (terabyte, 1024G) are supported. 'b' is ignored.\n"
78 " 'output_filename' is the destination disk image filename\n"
79 " 'output_fmt' is the destination format\n"
80 " 'options' is a comma separated list of format specific options in a\n"
81 " name=value format. Use -o ? for an overview of the options supported by the\n"
82 " used format\n"
83 " '-c' indicates that target image must be compressed (qcow format only)\n"
84 " '-u' enables unsafe rebasing. It is assumed that old and new backing file\n"
85 " match exactly. The image doesn't need a working backing file before\n"
86 " rebasing in this case (useful for renaming the backing file)\n"
87 " '-h' with or without a command shows this help and lists the supported formats\n"
Jes Sorensen6b837bc2011-03-30 14:16:25 +020088 " '-p' show progress of command (only certain commands)\n"
Kevin Wolfa22f1232011-08-26 15:27:13 +020089 " '-S' indicates the consecutive number of bytes that must contain only zeros\n"
90 " for qemu-img to create a sparse image during conversion\n"
Benoît Canetc054b3f2012-09-05 13:09:02 +020091 " '--output' takes the format in which the output must be done (human or json)\n"
malc3f020d72010-02-08 12:04:56 +030092 "\n"
Kevin Wolf4534ff52012-05-11 16:07:02 +020093 "Parameters to check subcommand:\n"
94 " '-r' tries to repair any inconsistencies that are found during the check.\n"
95 " '-r leaks' repairs only cluster leaks, whereas '-r all' fixes all\n"
96 " kinds of errors, with a higher risk of choosing the wrong fix or\n"
Stefan Weil0546b8c2012-08-10 22:03:25 +020097 " hiding corruption that has already occurred.\n"
Kevin Wolf4534ff52012-05-11 16:07:02 +020098 "\n"
malc3f020d72010-02-08 12:04:56 +030099 "Parameters to snapshot subcommand:\n"
100 " 'snapshot' is the name of the snapshot to create, apply or delete\n"
101 " '-a' applies a snapshot (revert disk to saved state)\n"
102 " '-c' creates a snapshot\n"
103 " '-d' deletes a snapshot\n"
Paolo Bonzinie00291c2010-02-04 16:49:56 +0100104 " '-l' lists all snapshots in the given image\n";
105
106 printf("%s\nSupported formats:", help_msg);
bellardea2384d2004-08-01 21:59:26 +0000107 bdrv_iterate_format(format_print, NULL);
108 printf("\n");
109 exit(1);
110}
111
bellardea2384d2004-08-01 21:59:26 +0000112#if defined(WIN32)
113/* XXX: put correct support for win32 */
114static int read_password(char *buf, int buf_size)
115{
116 int c, i;
117 printf("Password: ");
118 fflush(stdout);
119 i = 0;
120 for(;;) {
121 c = getchar();
122 if (c == '\n')
123 break;
124 if (i < (buf_size - 1))
125 buf[i++] = c;
126 }
127 buf[i] = '\0';
128 return 0;
129}
130
131#else
132
133#include <termios.h>
134
135static struct termios oldtty;
136
137static void term_exit(void)
138{
139 tcsetattr (0, TCSANOW, &oldtty);
140}
141
142static void term_init(void)
143{
144 struct termios tty;
145
146 tcgetattr (0, &tty);
147 oldtty = tty;
148
149 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
150 |INLCR|IGNCR|ICRNL|IXON);
151 tty.c_oflag |= OPOST;
152 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
153 tty.c_cflag &= ~(CSIZE|PARENB);
154 tty.c_cflag |= CS8;
155 tty.c_cc[VMIN] = 1;
156 tty.c_cc[VTIME] = 0;
ths3b46e622007-09-17 08:09:54 +0000157
bellardea2384d2004-08-01 21:59:26 +0000158 tcsetattr (0, TCSANOW, &tty);
159
160 atexit(term_exit);
161}
162
pbrook3f379ab2007-11-11 03:33:13 +0000163static int read_password(char *buf, int buf_size)
bellardea2384d2004-08-01 21:59:26 +0000164{
165 uint8_t ch;
166 int i, ret;
167
168 printf("password: ");
169 fflush(stdout);
170 term_init();
171 i = 0;
172 for(;;) {
173 ret = read(0, &ch, 1);
174 if (ret == -1) {
175 if (errno == EAGAIN || errno == EINTR) {
176 continue;
177 } else {
178 ret = -1;
179 break;
180 }
181 } else if (ret == 0) {
182 ret = -1;
183 break;
184 } else {
185 if (ch == '\r') {
186 ret = 0;
187 break;
188 }
189 if (i < (buf_size - 1))
190 buf[i++] = ch;
191 }
192 }
193 term_exit();
194 buf[i] = '\0';
195 printf("\n");
196 return ret;
197}
198#endif
199
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100200static int print_block_option_help(const char *filename, const char *fmt)
201{
202 BlockDriver *drv, *proto_drv;
203 QEMUOptionParameter *create_options = NULL;
204
205 /* Find driver and parse its options */
206 drv = bdrv_find_format(fmt);
207 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100208 error_report("Unknown file format '%s'", fmt);
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100209 return 1;
210 }
211
212 proto_drv = bdrv_find_protocol(filename);
213 if (!proto_drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100214 error_report("Unknown protocol '%s'", filename);
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100215 return 1;
216 }
217
218 create_options = append_option_parameters(create_options,
219 drv->create_options);
220 create_options = append_option_parameters(create_options,
221 proto_drv->create_options);
222 print_option_help(create_options);
223 free_option_parameters(create_options);
224 return 0;
225}
226
bellard75c23802004-08-27 21:28:58 +0000227static BlockDriverState *bdrv_new_open(const char *filename,
Sheng Yang9bc378c2010-01-29 10:15:06 +0800228 const char *fmt,
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +0100229 int flags,
230 bool require_io)
bellard75c23802004-08-27 21:28:58 +0000231{
232 BlockDriverState *bs;
233 BlockDriver *drv;
234 char password[256];
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100235 int ret;
bellard75c23802004-08-27 21:28:58 +0000236
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100237 bs = bdrv_new("image");
Kevin Wolfad717132010-12-16 15:37:41 +0100238
bellard75c23802004-08-27 21:28:58 +0000239 if (fmt) {
240 drv = bdrv_find_format(fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900241 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100242 error_report("Unknown file format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900243 goto fail;
244 }
bellard75c23802004-08-27 21:28:58 +0000245 } else {
246 drv = NULL;
247 }
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100248
249 ret = bdrv_open(bs, filename, flags, drv);
250 if (ret < 0) {
251 error_report("Could not open '%s': %s", filename, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900252 goto fail;
bellard75c23802004-08-27 21:28:58 +0000253 }
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100254
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +0100255 if (bdrv_is_encrypted(bs) && require_io) {
bellard75c23802004-08-27 21:28:58 +0000256 printf("Disk image '%s' is encrypted.\n", filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900257 if (read_password(password, sizeof(password)) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100258 error_report("No password given");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900259 goto fail;
260 }
261 if (bdrv_set_key(bs, password) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100262 error_report("invalid password");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900263 goto fail;
264 }
bellard75c23802004-08-27 21:28:58 +0000265 }
266 return bs;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900267fail:
268 if (bs) {
269 bdrv_delete(bs);
270 }
271 return NULL;
bellard75c23802004-08-27 21:28:58 +0000272}
273
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900274static int add_old_style_options(const char *fmt, QEMUOptionParameter *list,
Jes Sorenseneec77d92010-12-07 17:44:34 +0100275 const char *base_filename,
276 const char *base_fmt)
Kevin Wolfefa84d42009-05-18 16:42:12 +0200277{
Kevin Wolfefa84d42009-05-18 16:42:12 +0200278 if (base_filename) {
279 if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100280 error_report("Backing file not supported for file format '%s'",
281 fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900282 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200283 }
284 }
285 if (base_fmt) {
286 if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100287 error_report("Backing file format not supported for file "
288 "format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900289 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200290 }
291 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900292 return 0;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200293}
294
bellardea2384d2004-08-01 21:59:26 +0000295static int img_create(int argc, char **argv)
296{
Luiz Capitulinoa9300912012-11-30 10:52:06 -0200297 int c;
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100298 uint64_t img_size = -1;
bellardea2384d2004-08-01 21:59:26 +0000299 const char *fmt = "raw";
aliguori9230eaf2009-03-28 17:55:19 +0000300 const char *base_fmt = NULL;
bellardea2384d2004-08-01 21:59:26 +0000301 const char *filename;
302 const char *base_filename = NULL;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200303 char *options = NULL;
Luiz Capitulino9b375252012-11-30 10:52:05 -0200304 Error *local_err = NULL;
ths3b46e622007-09-17 08:09:54 +0000305
bellardea2384d2004-08-01 21:59:26 +0000306 for(;;) {
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200307 c = getopt(argc, argv, "F:b:f:he6o:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100308 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000309 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100310 }
bellardea2384d2004-08-01 21:59:26 +0000311 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100312 case '?':
bellardea2384d2004-08-01 21:59:26 +0000313 case 'h':
314 help();
315 break;
aliguori9230eaf2009-03-28 17:55:19 +0000316 case 'F':
317 base_fmt = optarg;
318 break;
bellardea2384d2004-08-01 21:59:26 +0000319 case 'b':
320 base_filename = optarg;
321 break;
322 case 'f':
323 fmt = optarg;
324 break;
325 case 'e':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200326 error_report("option -e is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100327 "encryption\' instead!");
328 return 1;
thsd8871c52007-10-24 16:11:42 +0000329 case '6':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200330 error_report("option -6 is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100331 "compat6\' instead!");
332 return 1;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200333 case 'o':
334 options = optarg;
335 break;
bellardea2384d2004-08-01 21:59:26 +0000336 }
337 }
aliguori9230eaf2009-03-28 17:55:19 +0000338
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900339 /* Get the filename */
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100340 if (optind >= argc) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900341 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100342 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900343 filename = argv[optind++];
344
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100345 /* Get image size, if specified */
346 if (optind < argc) {
Jes Sorensen70b4f4b2011-01-05 11:41:02 +0100347 int64_t sval;
Markus Armbrustere36b3692011-11-22 09:46:05 +0100348 char *end;
349 sval = strtosz_suffix(argv[optind++], &end, STRTOSZ_DEFSUFFIX_B);
350 if (sval < 0 || *end) {
liguang79443392012-12-17 09:49:23 +0800351 if (sval == -ERANGE) {
352 error_report("Image size must be less than 8 EiB!");
353 } else {
354 error_report("Invalid image size specified! You may use k, M, "
355 "G or T suffixes for ");
356 error_report("kilobytes, megabytes, gigabytes and terabytes.");
357 }
Luiz Capitulinoa9300912012-11-30 10:52:06 -0200358 return 1;
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100359 }
360 img_size = (uint64_t)sval;
361 }
362
Peter Maydellc8057f92012-08-02 13:45:54 +0100363 if (options && is_help_option(options)) {
Luiz Capitulinoa9300912012-11-30 10:52:06 -0200364 return print_block_option_help(filename, fmt);
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100365 }
366
Luiz Capitulino9b375252012-11-30 10:52:05 -0200367 bdrv_img_create(filename, fmt, base_filename, base_fmt,
368 options, img_size, BDRV_O_FLAGS, &local_err);
369 if (error_is_set(&local_err)) {
370 error_report("%s", error_get_pretty(local_err));
371 error_free(local_err);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900372 return 1;
373 }
Luiz Capitulinoa9300912012-11-30 10:52:06 -0200374
bellardea2384d2004-08-01 21:59:26 +0000375 return 0;
376}
377
Kevin Wolfe076f332010-06-29 11:43:13 +0200378/*
379 * Checks an image for consistency. Exit codes:
380 *
381 * 0 - Check completed, image is good
382 * 1 - Check not completed because of internal errors
383 * 2 - Check completed, image is corrupted
384 * 3 - Check completed, image has leaked clusters, but is good otherwise
385 */
aliguori15859692009-04-21 23:11:53 +0000386static int img_check(int argc, char **argv)
387{
388 int c, ret;
389 const char *filename, *fmt;
aliguori15859692009-04-21 23:11:53 +0000390 BlockDriverState *bs;
Kevin Wolfe076f332010-06-29 11:43:13 +0200391 BdrvCheckResult result;
Kevin Wolf4534ff52012-05-11 16:07:02 +0200392 int fix = 0;
Stefan Hajnoczi058f8f12012-08-09 13:05:56 +0100393 int flags = BDRV_O_FLAGS | BDRV_O_CHECK;
aliguori15859692009-04-21 23:11:53 +0000394
395 fmt = NULL;
396 for(;;) {
Kevin Wolf4534ff52012-05-11 16:07:02 +0200397 c = getopt(argc, argv, "f:hr:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100398 if (c == -1) {
aliguori15859692009-04-21 23:11:53 +0000399 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100400 }
aliguori15859692009-04-21 23:11:53 +0000401 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100402 case '?':
aliguori15859692009-04-21 23:11:53 +0000403 case 'h':
404 help();
405 break;
406 case 'f':
407 fmt = optarg;
408 break;
Kevin Wolf4534ff52012-05-11 16:07:02 +0200409 case 'r':
410 flags |= BDRV_O_RDWR;
411
412 if (!strcmp(optarg, "leaks")) {
413 fix = BDRV_FIX_LEAKS;
414 } else if (!strcmp(optarg, "all")) {
415 fix = BDRV_FIX_LEAKS | BDRV_FIX_ERRORS;
416 } else {
417 help();
418 }
419 break;
aliguori15859692009-04-21 23:11:53 +0000420 }
421 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100422 if (optind >= argc) {
aliguori15859692009-04-21 23:11:53 +0000423 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100424 }
aliguori15859692009-04-21 23:11:53 +0000425 filename = argv[optind++];
426
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +0100427 bs = bdrv_new_open(filename, fmt, flags, true);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900428 if (!bs) {
429 return 1;
430 }
Kevin Wolf4534ff52012-05-11 16:07:02 +0200431 ret = bdrv_check(bs, &result, fix);
Kevin Wolfe076f332010-06-29 11:43:13 +0200432
433 if (ret == -ENOTSUP) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100434 error_report("This image format does not support checks");
Kevin Wolfe076f332010-06-29 11:43:13 +0200435 bdrv_delete(bs);
436 return 1;
437 }
438
Kevin Wolfccf34712012-05-11 18:16:54 +0200439 if (result.corruptions_fixed || result.leaks_fixed) {
440 printf("The following inconsistencies were found and repaired:\n\n"
441 " %d leaked clusters\n"
442 " %d corruptions\n\n"
443 "Double checking the fixed image now...\n",
444 result.leaks_fixed,
445 result.corruptions_fixed);
446 ret = bdrv_check(bs, &result, 0);
447 }
448
Kevin Wolfe076f332010-06-29 11:43:13 +0200449 if (!(result.corruptions || result.leaks || result.check_errors)) {
450 printf("No errors were found on the image.\n");
451 } else {
452 if (result.corruptions) {
453 printf("\n%d errors were found on the image.\n"
454 "Data may be corrupted, or further writes to the image "
455 "may corrupt it.\n",
456 result.corruptions);
aliguori15859692009-04-21 23:11:53 +0000457 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200458
459 if (result.leaks) {
460 printf("\n%d leaked clusters were found on the image.\n"
461 "This means waste of disk space, but no harm to data.\n",
462 result.leaks);
463 }
464
465 if (result.check_errors) {
466 printf("\n%d internal errors have occurred during the check.\n",
467 result.check_errors);
468 }
aliguori15859692009-04-21 23:11:53 +0000469 }
470
Dong Xu Wangf8111c22012-03-15 20:13:31 +0800471 if (result.bfi.total_clusters != 0 && result.bfi.allocated_clusters != 0) {
472 printf("%" PRId64 "/%" PRId64 "= %0.2f%% allocated, %0.2f%% fragmented\n",
473 result.bfi.allocated_clusters, result.bfi.total_clusters,
474 result.bfi.allocated_clusters * 100.0 / result.bfi.total_clusters,
475 result.bfi.fragmented_clusters * 100.0 / result.bfi.allocated_clusters);
476 }
477
aliguori15859692009-04-21 23:11:53 +0000478 bdrv_delete(bs);
Kevin Wolfe076f332010-06-29 11:43:13 +0200479
480 if (ret < 0 || result.check_errors) {
481 printf("\nAn error has occurred during the check: %s\n"
482 "The check is not complete and may have missed error.\n",
483 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900484 return 1;
485 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200486
487 if (result.corruptions) {
488 return 2;
489 } else if (result.leaks) {
490 return 3;
491 } else {
492 return 0;
493 }
aliguori15859692009-04-21 23:11:53 +0000494}
495
bellardea2384d2004-08-01 21:59:26 +0000496static int img_commit(int argc, char **argv)
497{
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400498 int c, ret, flags;
499 const char *filename, *fmt, *cache;
bellardea2384d2004-08-01 21:59:26 +0000500 BlockDriverState *bs;
501
502 fmt = NULL;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400503 cache = BDRV_DEFAULT_CACHE;
bellardea2384d2004-08-01 21:59:26 +0000504 for(;;) {
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400505 c = getopt(argc, argv, "f:ht:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100506 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000507 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100508 }
bellardea2384d2004-08-01 21:59:26 +0000509 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100510 case '?':
bellardea2384d2004-08-01 21:59:26 +0000511 case 'h':
512 help();
513 break;
514 case 'f':
515 fmt = optarg;
516 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400517 case 't':
518 cache = optarg;
519 break;
bellardea2384d2004-08-01 21:59:26 +0000520 }
521 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100522 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +0000523 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100524 }
bellardea2384d2004-08-01 21:59:26 +0000525 filename = argv[optind++];
526
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400527 flags = BDRV_O_RDWR;
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +0100528 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400529 if (ret < 0) {
530 error_report("Invalid cache option: %s", cache);
531 return -1;
532 }
533
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +0100534 bs = bdrv_new_open(filename, fmt, flags, true);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900535 if (!bs) {
536 return 1;
537 }
bellardea2384d2004-08-01 21:59:26 +0000538 ret = bdrv_commit(bs);
539 switch(ret) {
540 case 0:
541 printf("Image committed.\n");
542 break;
543 case -ENOENT:
Jes Sorensen15654a62010-12-16 14:31:53 +0100544 error_report("No disk inserted");
bellardea2384d2004-08-01 21:59:26 +0000545 break;
546 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +0100547 error_report("Image is read-only");
bellardea2384d2004-08-01 21:59:26 +0000548 break;
549 case -ENOTSUP:
Jes Sorensen15654a62010-12-16 14:31:53 +0100550 error_report("Image is already committed");
bellardea2384d2004-08-01 21:59:26 +0000551 break;
552 default:
Jes Sorensen15654a62010-12-16 14:31:53 +0100553 error_report("Error while committing image");
bellardea2384d2004-08-01 21:59:26 +0000554 break;
555 }
556
557 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900558 if (ret) {
559 return 1;
560 }
bellardea2384d2004-08-01 21:59:26 +0000561 return 0;
562}
563
Dmitry Konishchevf6a00aa2011-05-18 15:03:59 +0400564/*
thsf58c7b32008-06-05 21:53:49 +0000565 * Returns true iff the first sector pointed to by 'buf' contains at least
566 * a non-NUL byte.
567 *
568 * 'pnum' is set to the number of sectors (including and immediately following
569 * the first one) that are known to be in the same allocated/unallocated state.
570 */
bellardea2384d2004-08-01 21:59:26 +0000571static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
572{
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000573 bool is_zero;
574 int i;
bellardea2384d2004-08-01 21:59:26 +0000575
576 if (n <= 0) {
577 *pnum = 0;
578 return 0;
579 }
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000580 is_zero = buffer_is_zero(buf, 512);
bellardea2384d2004-08-01 21:59:26 +0000581 for(i = 1; i < n; i++) {
582 buf += 512;
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000583 if (is_zero != buffer_is_zero(buf, 512)) {
bellardea2384d2004-08-01 21:59:26 +0000584 break;
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000585 }
bellardea2384d2004-08-01 21:59:26 +0000586 }
587 *pnum = i;
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000588 return !is_zero;
bellardea2384d2004-08-01 21:59:26 +0000589}
590
Kevin Wolf3e85c6f2010-01-12 12:55:18 +0100591/*
Kevin Wolfa22f1232011-08-26 15:27:13 +0200592 * Like is_allocated_sectors, but if the buffer starts with a used sector,
593 * up to 'min' consecutive sectors containing zeros are ignored. This avoids
594 * breaking up write requests for only small sparse areas.
595 */
596static int is_allocated_sectors_min(const uint8_t *buf, int n, int *pnum,
597 int min)
598{
599 int ret;
600 int num_checked, num_used;
601
602 if (n < min) {
603 min = n;
604 }
605
606 ret = is_allocated_sectors(buf, n, pnum);
607 if (!ret) {
608 return ret;
609 }
610
611 num_used = *pnum;
612 buf += BDRV_SECTOR_SIZE * *pnum;
613 n -= *pnum;
614 num_checked = num_used;
615
616 while (n > 0) {
617 ret = is_allocated_sectors(buf, n, pnum);
618
619 buf += BDRV_SECTOR_SIZE * *pnum;
620 n -= *pnum;
621 num_checked += *pnum;
622 if (ret) {
623 num_used = num_checked;
624 } else if (*pnum >= min) {
625 break;
626 }
627 }
628
629 *pnum = num_used;
630 return 1;
631}
632
633/*
Kevin Wolf3e85c6f2010-01-12 12:55:18 +0100634 * Compares two buffers sector by sector. Returns 0 if the first sector of both
635 * buffers matches, non-zero otherwise.
636 *
637 * pnum is set to the number of sectors (including and immediately following
638 * the first one) that are known to have the same comparison result
639 */
640static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
641 int *pnum)
642{
643 int res, i;
644
645 if (n <= 0) {
646 *pnum = 0;
647 return 0;
648 }
649
650 res = !!memcmp(buf1, buf2, 512);
651 for(i = 1; i < n; i++) {
652 buf1 += 512;
653 buf2 += 512;
654
655 if (!!memcmp(buf1, buf2, 512) != res) {
656 break;
657 }
658 }
659
660 *pnum = i;
661 return res;
662}
663
Kevin Wolf80ee15a2009-09-15 12:30:43 +0200664#define IO_BUF_SIZE (2 * 1024 * 1024)
bellardea2384d2004-08-01 21:59:26 +0000665
666static int img_convert(int argc, char **argv)
667{
Jes Sorenseneec77d92010-12-07 17:44:34 +0100668 int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400669 int progress = 0, flags;
670 const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900671 BlockDriver *drv, *proto_drv;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900672 BlockDriverState **bs = NULL, *out_bs = NULL;
ths96b8f132007-12-17 01:35:20 +0000673 int64_t total_sectors, nb_sectors, sector_num, bs_offset;
674 uint64_t bs_sectors;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900675 uint8_t * buf = NULL;
bellardea2384d2004-08-01 21:59:26 +0000676 const uint8_t *buf1;
bellardfaea38e2006-08-05 21:31:00 +0000677 BlockDriverInfo bdi;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900678 QEMUOptionParameter *param = NULL, *create_options = NULL;
Kevin Wolfa18953f2010-10-14 15:46:04 +0200679 QEMUOptionParameter *out_baseimg_param;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200680 char *options = NULL;
edison51ef6722010-09-21 19:58:41 -0700681 const char *snapshot_name = NULL;
Kevin Wolf1f710492012-10-12 14:29:18 +0200682 float local_progress = 0;
Kevin Wolfa22f1232011-08-26 15:27:13 +0200683 int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */
bellardea2384d2004-08-01 21:59:26 +0000684
685 fmt = NULL;
686 out_fmt = "raw";
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400687 cache = "unsafe";
thsf58c7b32008-06-05 21:53:49 +0000688 out_baseimg = NULL;
Jes Sorenseneec77d92010-12-07 17:44:34 +0100689 compress = 0;
bellardea2384d2004-08-01 21:59:26 +0000690 for(;;) {
Kevin Wolfa22f1232011-08-26 15:27:13 +0200691 c = getopt(argc, argv, "f:O:B:s:hce6o:pS:t:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100692 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000693 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100694 }
bellardea2384d2004-08-01 21:59:26 +0000695 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100696 case '?':
bellardea2384d2004-08-01 21:59:26 +0000697 case 'h':
698 help();
699 break;
700 case 'f':
701 fmt = optarg;
702 break;
703 case 'O':
704 out_fmt = optarg;
705 break;
thsf58c7b32008-06-05 21:53:49 +0000706 case 'B':
707 out_baseimg = optarg;
708 break;
bellardea2384d2004-08-01 21:59:26 +0000709 case 'c':
Jes Sorenseneec77d92010-12-07 17:44:34 +0100710 compress = 1;
bellardea2384d2004-08-01 21:59:26 +0000711 break;
712 case 'e':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200713 error_report("option -e is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100714 "encryption\' instead!");
715 return 1;
thsec36ba12007-09-16 21:59:02 +0000716 case '6':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200717 error_report("option -6 is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100718 "compat6\' instead!");
719 return 1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200720 case 'o':
721 options = optarg;
722 break;
edison51ef6722010-09-21 19:58:41 -0700723 case 's':
724 snapshot_name = optarg;
725 break;
Kevin Wolfa22f1232011-08-26 15:27:13 +0200726 case 'S':
727 {
728 int64_t sval;
Markus Armbrustere36b3692011-11-22 09:46:05 +0100729 char *end;
730 sval = strtosz_suffix(optarg, &end, STRTOSZ_DEFSUFFIX_B);
731 if (sval < 0 || *end) {
Kevin Wolfa22f1232011-08-26 15:27:13 +0200732 error_report("Invalid minimum zero buffer size for sparse output specified");
733 return 1;
734 }
735
736 min_sparse = sval / BDRV_SECTOR_SIZE;
737 break;
738 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200739 case 'p':
740 progress = 1;
741 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400742 case 't':
743 cache = optarg;
744 break;
bellardea2384d2004-08-01 21:59:26 +0000745 }
746 }
ths3b46e622007-09-17 08:09:54 +0000747
balrog926c2d22007-10-31 01:11:44 +0000748 bs_n = argc - optind - 1;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100749 if (bs_n < 1) {
750 help();
751 }
balrog926c2d22007-10-31 01:11:44 +0000752
753 out_filename = argv[argc - 1];
thsf58c7b32008-06-05 21:53:49 +0000754
Charles Arnoldfa170c12012-05-11 10:57:54 -0600755 /* Initialize before goto out */
756 qemu_progress_init(progress, 2.0);
757
Peter Maydellc8057f92012-08-02 13:45:54 +0100758 if (options && is_help_option(options)) {
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100759 ret = print_block_option_help(out_filename, out_fmt);
760 goto out;
761 }
762
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900763 if (bs_n > 1 && out_baseimg) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100764 error_report("-B makes no sense when concatenating multiple input "
765 "images");
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100766 ret = -1;
767 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900768 }
Dong Xu Wangf8111c22012-03-15 20:13:31 +0800769
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200770 qemu_progress_print(0, 100);
771
Anthony Liguori7267c092011-08-20 22:09:37 -0500772 bs = g_malloc0(bs_n * sizeof(BlockDriverState *));
balrog926c2d22007-10-31 01:11:44 +0000773
774 total_sectors = 0;
775 for (bs_i = 0; bs_i < bs_n; bs_i++) {
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +0100776 bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS, true);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900777 if (!bs[bs_i]) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100778 error_report("Could not open '%s'", argv[optind + bs_i]);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900779 ret = -1;
780 goto out;
781 }
balrog926c2d22007-10-31 01:11:44 +0000782 bdrv_get_geometry(bs[bs_i], &bs_sectors);
783 total_sectors += bs_sectors;
784 }
bellardea2384d2004-08-01 21:59:26 +0000785
edison51ef6722010-09-21 19:58:41 -0700786 if (snapshot_name != NULL) {
787 if (bs_n > 1) {
Markus Armbruster6daf1942011-06-22 14:03:54 +0200788 error_report("No support for concatenating multiple snapshot");
edison51ef6722010-09-21 19:58:41 -0700789 ret = -1;
790 goto out;
791 }
792 if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
Markus Armbruster6daf1942011-06-22 14:03:54 +0200793 error_report("Failed to load snapshot");
edison51ef6722010-09-21 19:58:41 -0700794 ret = -1;
795 goto out;
796 }
797 }
798
Kevin Wolfefa84d42009-05-18 16:42:12 +0200799 /* Find driver and parse its options */
bellardea2384d2004-08-01 21:59:26 +0000800 drv = bdrv_find_format(out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900801 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100802 error_report("Unknown file format '%s'", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900803 ret = -1;
804 goto out;
805 }
balrog926c2d22007-10-31 01:11:44 +0000806
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900807 proto_drv = bdrv_find_protocol(out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900808 if (!proto_drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100809 error_report("Unknown protocol '%s'", out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900810 ret = -1;
811 goto out;
812 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900813
814 create_options = append_option_parameters(create_options,
815 drv->create_options);
816 create_options = append_option_parameters(create_options,
817 proto_drv->create_options);
Kevin Wolfdb08adf2009-06-04 15:39:38 +0200818
Kevin Wolfefa84d42009-05-18 16:42:12 +0200819 if (options) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900820 param = parse_option_parameters(options, create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200821 if (param == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100822 error_report("Invalid options for file format '%s'.", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900823 ret = -1;
824 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200825 }
826 } else {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900827 param = parse_option_parameters("", create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200828 }
829
830 set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
Jes Sorenseneec77d92010-12-07 17:44:34 +0100831 ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900832 if (ret < 0) {
833 goto out;
834 }
Kevin Wolfefa84d42009-05-18 16:42:12 +0200835
Kevin Wolfa18953f2010-10-14 15:46:04 +0200836 /* Get backing file name if -o backing_file was used */
837 out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
838 if (out_baseimg_param) {
839 out_baseimg = out_baseimg_param->value.s;
840 }
841
Kevin Wolfefa84d42009-05-18 16:42:12 +0200842 /* Check if compression is supported */
Jes Sorenseneec77d92010-12-07 17:44:34 +0100843 if (compress) {
Kevin Wolfefa84d42009-05-18 16:42:12 +0200844 QEMUOptionParameter *encryption =
845 get_option_parameter(param, BLOCK_OPT_ENCRYPT);
Kevin Wolf41521fa2011-10-18 16:19:42 +0200846 QEMUOptionParameter *preallocation =
847 get_option_parameter(param, BLOCK_OPT_PREALLOC);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200848
849 if (!drv->bdrv_write_compressed) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100850 error_report("Compression not supported for this file format");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900851 ret = -1;
852 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200853 }
854
855 if (encryption && encryption->value.n) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100856 error_report("Compression and encryption not supported at "
857 "the same time");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900858 ret = -1;
859 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200860 }
Kevin Wolf41521fa2011-10-18 16:19:42 +0200861
862 if (preallocation && preallocation->value.s
863 && strcmp(preallocation->value.s, "off"))
864 {
865 error_report("Compression and preallocation not supported at "
866 "the same time");
867 ret = -1;
868 goto out;
869 }
Kevin Wolfefa84d42009-05-18 16:42:12 +0200870 }
871
872 /* Create the new image */
873 ret = bdrv_create(drv, out_filename, param);
bellardea2384d2004-08-01 21:59:26 +0000874 if (ret < 0) {
875 if (ret == -ENOTSUP) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100876 error_report("Formatting not supported for file format '%s'",
877 out_fmt);
aurel326e9ea0c2009-04-15 14:42:46 +0000878 } else if (ret == -EFBIG) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100879 error_report("The image size is too large for file format '%s'",
880 out_fmt);
bellardea2384d2004-08-01 21:59:26 +0000881 } else {
Jes Sorensen15654a62010-12-16 14:31:53 +0100882 error_report("%s: error while converting %s: %s",
883 out_filename, out_fmt, strerror(-ret));
bellardea2384d2004-08-01 21:59:26 +0000884 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900885 goto out;
bellardea2384d2004-08-01 21:59:26 +0000886 }
ths3b46e622007-09-17 08:09:54 +0000887
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400888 flags = BDRV_O_RDWR;
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +0100889 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400890 if (ret < 0) {
891 error_report("Invalid cache option: %s", cache);
892 return -1;
893 }
894
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +0100895 out_bs = bdrv_new_open(out_filename, out_fmt, flags, true);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900896 if (!out_bs) {
897 ret = -1;
898 goto out;
899 }
bellardea2384d2004-08-01 21:59:26 +0000900
balrog926c2d22007-10-31 01:11:44 +0000901 bs_i = 0;
902 bs_offset = 0;
903 bdrv_get_geometry(bs[0], &bs_sectors);
Kevin Wolfbb1c0592011-08-08 14:09:12 +0200904 buf = qemu_blockalign(out_bs, IO_BUF_SIZE);
balrog926c2d22007-10-31 01:11:44 +0000905
Jes Sorenseneec77d92010-12-07 17:44:34 +0100906 if (compress) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900907 ret = bdrv_get_info(out_bs, &bdi);
908 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100909 error_report("could not get block driver info");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900910 goto out;
911 }
bellardfaea38e2006-08-05 21:31:00 +0000912 cluster_size = bdi.cluster_size;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900913 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100914 error_report("invalid cluster size");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900915 ret = -1;
916 goto out;
917 }
bellardea2384d2004-08-01 21:59:26 +0000918 cluster_sectors = cluster_size >> 9;
919 sector_num = 0;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200920
921 nb_sectors = total_sectors;
Kevin Wolf1f710492012-10-12 14:29:18 +0200922 if (nb_sectors != 0) {
923 local_progress = (float)100 /
924 (nb_sectors / MIN(nb_sectors, cluster_sectors));
925 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200926
bellardea2384d2004-08-01 21:59:26 +0000927 for(;;) {
balrog926c2d22007-10-31 01:11:44 +0000928 int64_t bs_num;
929 int remainder;
930 uint8_t *buf2;
931
bellardea2384d2004-08-01 21:59:26 +0000932 nb_sectors = total_sectors - sector_num;
933 if (nb_sectors <= 0)
934 break;
935 if (nb_sectors >= cluster_sectors)
936 n = cluster_sectors;
937 else
938 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000939
940 bs_num = sector_num - bs_offset;
941 assert (bs_num >= 0);
942 remainder = n;
943 buf2 = buf;
944 while (remainder > 0) {
945 int nlow;
946 while (bs_num == bs_sectors) {
947 bs_i++;
948 assert (bs_i < bs_n);
949 bs_offset += bs_sectors;
950 bdrv_get_geometry(bs[bs_i], &bs_sectors);
951 bs_num = 0;
Blue Swirl0bfcd592010-05-22 08:02:12 +0000952 /* printf("changing part: sector_num=%" PRId64 ", "
953 "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64
954 "\n", sector_num, bs_i, bs_offset, bs_sectors); */
balrog926c2d22007-10-31 01:11:44 +0000955 }
956 assert (bs_num < bs_sectors);
957
958 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
959
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900960 ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
961 if (ret < 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +0100962 error_report("error while reading sector %" PRId64 ": %s",
963 bs_num, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900964 goto out;
965 }
balrog926c2d22007-10-31 01:11:44 +0000966
967 buf2 += nlow * 512;
968 bs_num += nlow;
969
970 remainder -= nlow;
971 }
972 assert (remainder == 0);
973
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100974 if (n < cluster_sectors) {
bellardea2384d2004-08-01 21:59:26 +0000975 memset(buf + n * 512, 0, cluster_size - n * 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100976 }
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000977 if (!buffer_is_zero(buf, cluster_size)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900978 ret = bdrv_write_compressed(out_bs, sector_num, buf,
979 cluster_sectors);
980 if (ret != 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +0100981 error_report("error while compressing sector %" PRId64
982 ": %s", sector_num, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900983 goto out;
984 }
bellardea2384d2004-08-01 21:59:26 +0000985 }
986 sector_num += n;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200987 qemu_progress_print(local_progress, 100);
bellardea2384d2004-08-01 21:59:26 +0000988 }
bellardfaea38e2006-08-05 21:31:00 +0000989 /* signal EOF to align */
990 bdrv_write_compressed(out_bs, 0, NULL, 0);
bellardea2384d2004-08-01 21:59:26 +0000991 } else {
Kevin Wolff2feebb2010-04-14 17:30:35 +0200992 int has_zero_init = bdrv_has_zero_init(out_bs);
993
thsf58c7b32008-06-05 21:53:49 +0000994 sector_num = 0; // total number of sectors converted so far
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200995 nb_sectors = total_sectors - sector_num;
Kevin Wolf1f710492012-10-12 14:29:18 +0200996 if (nb_sectors != 0) {
997 local_progress = (float)100 /
998 (nb_sectors / MIN(nb_sectors, IO_BUF_SIZE / 512));
999 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001000
bellardea2384d2004-08-01 21:59:26 +00001001 for(;;) {
1002 nb_sectors = total_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001003 if (nb_sectors <= 0) {
bellardea2384d2004-08-01 21:59:26 +00001004 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001005 }
1006 if (nb_sectors >= (IO_BUF_SIZE / 512)) {
bellardea2384d2004-08-01 21:59:26 +00001007 n = (IO_BUF_SIZE / 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001008 } else {
bellardea2384d2004-08-01 21:59:26 +00001009 n = nb_sectors;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001010 }
balrog926c2d22007-10-31 01:11:44 +00001011
1012 while (sector_num - bs_offset >= bs_sectors) {
1013 bs_i ++;
1014 assert (bs_i < bs_n);
1015 bs_offset += bs_sectors;
1016 bdrv_get_geometry(bs[bs_i], &bs_sectors);
Blue Swirl0bfcd592010-05-22 08:02:12 +00001017 /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "
1018 "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",
balrog926c2d22007-10-31 01:11:44 +00001019 sector_num, bs_i, bs_offset, bs_sectors); */
1020 }
1021
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001022 if (n > bs_offset + bs_sectors - sector_num) {
balrog926c2d22007-10-31 01:11:44 +00001023 n = bs_offset + bs_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001024 }
balrog926c2d22007-10-31 01:11:44 +00001025
Kevin Wolff2feebb2010-04-14 17:30:35 +02001026 if (has_zero_init) {
Akkarit Sangpetchd0320442009-07-17 10:02:15 +02001027 /* If the output image is being created as a copy on write image,
1028 assume that sectors which are unallocated in the input image
1029 are present in both the output's and input's base images (no
1030 need to copy them). */
1031 if (out_baseimg) {
1032 if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
1033 n, &n1)) {
1034 sector_num += n1;
1035 continue;
1036 }
1037 /* The next 'n1' sectors are allocated in the input image. Copy
1038 only those as they may be followed by unallocated sectors. */
1039 n = n1;
aliguori93c65b42009-04-05 17:40:43 +00001040 }
aliguori93c65b42009-04-05 17:40:43 +00001041 } else {
1042 n1 = n;
thsf58c7b32008-06-05 21:53:49 +00001043 }
1044
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001045 ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
1046 if (ret < 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +01001047 error_report("error while reading sector %" PRId64 ": %s",
1048 sector_num - bs_offset, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001049 goto out;
1050 }
bellardea2384d2004-08-01 21:59:26 +00001051 /* NOTE: at the same time we convert, we do not write zero
1052 sectors to have a chance to compress the image. Ideally, we
1053 should add a specific call to have the info to go faster */
1054 buf1 = buf;
1055 while (n > 0) {
thsf58c7b32008-06-05 21:53:49 +00001056 /* If the output image is being created as a copy on write image,
1057 copy all sectors even the ones containing only NUL bytes,
aliguori93c65b42009-04-05 17:40:43 +00001058 because they may differ from the sectors in the base image.
1059
1060 If the output is to a host device, we also write out
1061 sectors that are entirely 0, since whatever data was
1062 already there is garbage, not 0s. */
Kevin Wolff2feebb2010-04-14 17:30:35 +02001063 if (!has_zero_init || out_baseimg ||
Kevin Wolfa22f1232011-08-26 15:27:13 +02001064 is_allocated_sectors_min(buf1, n, &n1, min_sparse)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001065 ret = bdrv_write(out_bs, sector_num, buf1, n1);
1066 if (ret < 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +01001067 error_report("error while writing sector %" PRId64
1068 ": %s", sector_num, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001069 goto out;
1070 }
bellardea2384d2004-08-01 21:59:26 +00001071 }
1072 sector_num += n1;
1073 n -= n1;
1074 buf1 += n1 * 512;
1075 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001076 qemu_progress_print(local_progress, 100);
bellardea2384d2004-08-01 21:59:26 +00001077 }
1078 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001079out:
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001080 qemu_progress_end();
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001081 free_option_parameters(create_options);
1082 free_option_parameters(param);
Kevin Wolfbb1c0592011-08-08 14:09:12 +02001083 qemu_vfree(buf);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001084 if (out_bs) {
1085 bdrv_delete(out_bs);
1086 }
Jes Sorensen31ca34b2010-12-06 15:25:36 +01001087 if (bs) {
1088 for (bs_i = 0; bs_i < bs_n; bs_i++) {
1089 if (bs[bs_i]) {
1090 bdrv_delete(bs[bs_i]);
1091 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001092 }
Anthony Liguori7267c092011-08-20 22:09:37 -05001093 g_free(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001094 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001095 if (ret) {
1096 return 1;
1097 }
bellardea2384d2004-08-01 21:59:26 +00001098 return 0;
1099}
1100
bellard57d1a2b2004-08-03 21:15:11 +00001101
bellardfaea38e2006-08-05 21:31:00 +00001102static void dump_snapshots(BlockDriverState *bs)
1103{
1104 QEMUSnapshotInfo *sn_tab, *sn;
1105 int nb_sns, i;
1106 char buf[256];
1107
1108 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1109 if (nb_sns <= 0)
1110 return;
1111 printf("Snapshot list:\n");
1112 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
1113 for(i = 0; i < nb_sns; i++) {
1114 sn = &sn_tab[i];
1115 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
1116 }
Anthony Liguori7267c092011-08-20 22:09:37 -05001117 g_free(sn_tab);
bellardfaea38e2006-08-05 21:31:00 +00001118}
1119
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001120static void dump_json_image_info_list(ImageInfoList *list)
1121{
1122 Error *errp = NULL;
1123 QString *str;
1124 QmpOutputVisitor *ov = qmp_output_visitor_new();
1125 QObject *obj;
1126 visit_type_ImageInfoList(qmp_output_get_visitor(ov),
1127 &list, NULL, &errp);
1128 obj = qmp_output_get_qobject(ov);
1129 str = qobject_to_json_pretty(obj);
1130 assert(str != NULL);
1131 printf("%s\n", qstring_get_str(str));
1132 qobject_decref(obj);
1133 qmp_output_visitor_cleanup(ov);
1134 QDECREF(str);
1135}
1136
Benoît Canetc054b3f2012-09-05 13:09:02 +02001137static void collect_snapshots(BlockDriverState *bs , ImageInfo *info)
bellardea2384d2004-08-01 21:59:26 +00001138{
Benoît Canetc054b3f2012-09-05 13:09:02 +02001139 int i, sn_count;
1140 QEMUSnapshotInfo *sn_tab = NULL;
1141 SnapshotInfoList *info_list, *cur_item = NULL;
1142 sn_count = bdrv_snapshot_list(bs, &sn_tab);
1143
1144 for (i = 0; i < sn_count; i++) {
1145 info->has_snapshots = true;
1146 info_list = g_new0(SnapshotInfoList, 1);
1147
1148 info_list->value = g_new0(SnapshotInfo, 1);
1149 info_list->value->id = g_strdup(sn_tab[i].id_str);
1150 info_list->value->name = g_strdup(sn_tab[i].name);
1151 info_list->value->vm_state_size = sn_tab[i].vm_state_size;
1152 info_list->value->date_sec = sn_tab[i].date_sec;
1153 info_list->value->date_nsec = sn_tab[i].date_nsec;
1154 info_list->value->vm_clock_sec = sn_tab[i].vm_clock_nsec / 1000000000;
1155 info_list->value->vm_clock_nsec = sn_tab[i].vm_clock_nsec % 1000000000;
1156
1157 /* XXX: waiting for the qapi to support qemu-queue.h types */
1158 if (!cur_item) {
1159 info->snapshots = cur_item = info_list;
1160 } else {
1161 cur_item->next = info_list;
1162 cur_item = info_list;
1163 }
1164
1165 }
1166
1167 g_free(sn_tab);
1168}
1169
1170static void dump_json_image_info(ImageInfo *info)
1171{
1172 Error *errp = NULL;
1173 QString *str;
1174 QmpOutputVisitor *ov = qmp_output_visitor_new();
1175 QObject *obj;
1176 visit_type_ImageInfo(qmp_output_get_visitor(ov),
1177 &info, NULL, &errp);
1178 obj = qmp_output_get_qobject(ov);
1179 str = qobject_to_json_pretty(obj);
1180 assert(str != NULL);
1181 printf("%s\n", qstring_get_str(str));
1182 qobject_decref(obj);
1183 qmp_output_visitor_cleanup(ov);
1184 QDECREF(str);
1185}
1186
1187static void collect_image_info(BlockDriverState *bs,
1188 ImageInfo *info,
1189 const char *filename,
1190 const char *fmt)
1191{
ths96b8f132007-12-17 01:35:20 +00001192 uint64_t total_sectors;
bellard93b6b2a2006-08-01 15:51:11 +00001193 char backing_filename[1024];
1194 char backing_filename2[1024];
bellardfaea38e2006-08-05 21:31:00 +00001195 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +00001196
Benoît Canetc054b3f2012-09-05 13:09:02 +02001197 bdrv_get_geometry(bs, &total_sectors);
1198
1199 info->filename = g_strdup(filename);
1200 info->format = g_strdup(bdrv_get_format_name(bs));
1201 info->virtual_size = total_sectors * 512;
1202 info->actual_size = bdrv_get_allocated_file_size(bs);
1203 info->has_actual_size = info->actual_size >= 0;
1204 if (bdrv_is_encrypted(bs)) {
1205 info->encrypted = true;
1206 info->has_encrypted = true;
1207 }
1208 if (bdrv_get_info(bs, &bdi) >= 0) {
1209 if (bdi.cluster_size != 0) {
1210 info->cluster_size = bdi.cluster_size;
1211 info->has_cluster_size = true;
1212 }
1213 info->dirty_flag = bdi.is_dirty;
1214 info->has_dirty_flag = true;
1215 }
1216 bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
1217 if (backing_filename[0] != '\0') {
1218 info->backing_filename = g_strdup(backing_filename);
1219 info->has_backing_filename = true;
1220 bdrv_get_full_backing_filename(bs, backing_filename2,
1221 sizeof(backing_filename2));
1222
1223 if (strcmp(backing_filename, backing_filename2) != 0) {
1224 info->full_backing_filename =
1225 g_strdup(backing_filename2);
1226 info->has_full_backing_filename = true;
1227 }
1228
1229 if (bs->backing_format[0]) {
1230 info->backing_filename_format = g_strdup(bs->backing_format);
1231 info->has_backing_filename_format = true;
1232 }
1233 }
1234}
1235
1236static void dump_human_image_info(ImageInfo *info)
1237{
1238 char size_buf[128], dsize_buf[128];
1239 if (!info->has_actual_size) {
1240 snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
1241 } else {
1242 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
1243 info->actual_size);
1244 }
1245 get_human_readable_size(size_buf, sizeof(size_buf), info->virtual_size);
1246 printf("image: %s\n"
1247 "file format: %s\n"
1248 "virtual size: %s (%" PRId64 " bytes)\n"
1249 "disk size: %s\n",
1250 info->filename, info->format, size_buf,
1251 info->virtual_size,
1252 dsize_buf);
1253
1254 if (info->has_encrypted && info->encrypted) {
1255 printf("encrypted: yes\n");
1256 }
1257
1258 if (info->has_cluster_size) {
1259 printf("cluster_size: %" PRId64 "\n", info->cluster_size);
1260 }
1261
1262 if (info->has_dirty_flag && info->dirty_flag) {
1263 printf("cleanly shut down: no\n");
1264 }
1265
1266 if (info->has_backing_filename) {
1267 printf("backing file: %s", info->backing_filename);
1268 if (info->has_full_backing_filename) {
1269 printf(" (actual path: %s)", info->full_backing_filename);
1270 }
1271 putchar('\n');
1272 if (info->has_backing_filename_format) {
1273 printf("backing file format: %s\n", info->backing_filename_format);
1274 }
1275 }
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001276
1277 if (info->has_snapshots) {
1278 SnapshotInfoList *elem;
1279 char buf[256];
1280
1281 printf("Snapshot list:\n");
1282 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
1283
1284 /* Ideally bdrv_snapshot_dump() would operate on SnapshotInfoList but
1285 * we convert to the block layer's native QEMUSnapshotInfo for now.
1286 */
1287 for (elem = info->snapshots; elem; elem = elem->next) {
1288 QEMUSnapshotInfo sn = {
1289 .vm_state_size = elem->value->vm_state_size,
1290 .date_sec = elem->value->date_sec,
1291 .date_nsec = elem->value->date_nsec,
1292 .vm_clock_nsec = elem->value->vm_clock_sec * 1000000000ULL +
1293 elem->value->vm_clock_nsec,
1294 };
1295
1296 pstrcpy(sn.id_str, sizeof(sn.id_str), elem->value->id);
1297 pstrcpy(sn.name, sizeof(sn.name), elem->value->name);
1298 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), &sn));
1299 }
1300 }
Benoît Canetc054b3f2012-09-05 13:09:02 +02001301}
1302
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001303static void dump_human_image_info_list(ImageInfoList *list)
1304{
1305 ImageInfoList *elem;
1306 bool delim = false;
1307
1308 for (elem = list; elem; elem = elem->next) {
1309 if (delim) {
1310 printf("\n");
1311 }
1312 delim = true;
1313
1314 dump_human_image_info(elem->value);
1315 }
1316}
1317
1318static gboolean str_equal_func(gconstpointer a, gconstpointer b)
1319{
1320 return strcmp(a, b) == 0;
1321}
1322
1323/**
1324 * Open an image file chain and return an ImageInfoList
1325 *
1326 * @filename: topmost image filename
1327 * @fmt: topmost image format (may be NULL to autodetect)
1328 * @chain: true - enumerate entire backing file chain
1329 * false - only topmost image file
1330 *
1331 * Returns a list of ImageInfo objects or NULL if there was an error opening an
1332 * image file. If there was an error a message will have been printed to
1333 * stderr.
1334 */
1335static ImageInfoList *collect_image_info_list(const char *filename,
1336 const char *fmt,
1337 bool chain)
1338{
1339 ImageInfoList *head = NULL;
1340 ImageInfoList **last = &head;
1341 GHashTable *filenames;
1342
1343 filenames = g_hash_table_new_full(g_str_hash, str_equal_func, NULL, NULL);
1344
1345 while (filename) {
1346 BlockDriverState *bs;
1347 ImageInfo *info;
1348 ImageInfoList *elem;
1349
1350 if (g_hash_table_lookup_extended(filenames, filename, NULL, NULL)) {
1351 error_report("Backing file '%s' creates an infinite loop.",
1352 filename);
1353 goto err;
1354 }
1355 g_hash_table_insert(filenames, (gpointer)filename, NULL);
1356
1357 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING,
1358 false);
1359 if (!bs) {
1360 goto err;
1361 }
1362
1363 info = g_new0(ImageInfo, 1);
1364 collect_image_info(bs, info, filename, fmt);
1365 collect_snapshots(bs, info);
1366
1367 elem = g_new0(ImageInfoList, 1);
1368 elem->value = info;
1369 *last = elem;
1370 last = &elem->next;
1371
1372 bdrv_delete(bs);
1373
1374 filename = fmt = NULL;
1375 if (chain) {
1376 if (info->has_full_backing_filename) {
1377 filename = info->full_backing_filename;
1378 } else if (info->has_backing_filename) {
1379 filename = info->backing_filename;
1380 }
1381 if (info->has_backing_filename_format) {
1382 fmt = info->backing_filename_format;
1383 }
1384 }
1385 }
1386 g_hash_table_destroy(filenames);
1387 return head;
1388
1389err:
1390 qapi_free_ImageInfoList(head);
1391 g_hash_table_destroy(filenames);
1392 return NULL;
1393}
1394
1395enum {
1396 OPTION_OUTPUT = 256,
1397 OPTION_BACKING_CHAIN = 257,
1398};
Benoît Canetc054b3f2012-09-05 13:09:02 +02001399
1400typedef enum OutputFormat {
1401 OFORMAT_JSON,
1402 OFORMAT_HUMAN,
1403} OutputFormat;
1404
1405static int img_info(int argc, char **argv)
1406{
1407 int c;
1408 OutputFormat output_format = OFORMAT_HUMAN;
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001409 bool chain = false;
Benoît Canetc054b3f2012-09-05 13:09:02 +02001410 const char *filename, *fmt, *output;
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001411 ImageInfoList *list;
Benoît Canetc054b3f2012-09-05 13:09:02 +02001412
bellardea2384d2004-08-01 21:59:26 +00001413 fmt = NULL;
Benoît Canetc054b3f2012-09-05 13:09:02 +02001414 output = NULL;
bellardea2384d2004-08-01 21:59:26 +00001415 for(;;) {
Benoît Canetc054b3f2012-09-05 13:09:02 +02001416 int option_index = 0;
1417 static const struct option long_options[] = {
1418 {"help", no_argument, 0, 'h'},
1419 {"format", required_argument, 0, 'f'},
1420 {"output", required_argument, 0, OPTION_OUTPUT},
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001421 {"backing-chain", no_argument, 0, OPTION_BACKING_CHAIN},
Benoît Canetc054b3f2012-09-05 13:09:02 +02001422 {0, 0, 0, 0}
1423 };
1424 c = getopt_long(argc, argv, "f:h",
1425 long_options, &option_index);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001426 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +00001427 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001428 }
bellardea2384d2004-08-01 21:59:26 +00001429 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001430 case '?':
bellardea2384d2004-08-01 21:59:26 +00001431 case 'h':
1432 help();
1433 break;
1434 case 'f':
1435 fmt = optarg;
1436 break;
Benoît Canetc054b3f2012-09-05 13:09:02 +02001437 case OPTION_OUTPUT:
1438 output = optarg;
1439 break;
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001440 case OPTION_BACKING_CHAIN:
1441 chain = true;
1442 break;
bellardea2384d2004-08-01 21:59:26 +00001443 }
1444 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001445 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +00001446 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001447 }
bellardea2384d2004-08-01 21:59:26 +00001448 filename = argv[optind++];
1449
Benoît Canetc054b3f2012-09-05 13:09:02 +02001450 if (output && !strcmp(output, "json")) {
1451 output_format = OFORMAT_JSON;
1452 } else if (output && !strcmp(output, "human")) {
1453 output_format = OFORMAT_HUMAN;
1454 } else if (output) {
1455 error_report("--output must be used with human or json as argument.");
1456 return 1;
1457 }
1458
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001459 list = collect_image_info_list(filename, fmt, chain);
1460 if (!list) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001461 return 1;
1462 }
Benoît Canetc054b3f2012-09-05 13:09:02 +02001463
Benoît Canetc054b3f2012-09-05 13:09:02 +02001464 switch (output_format) {
1465 case OFORMAT_HUMAN:
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001466 dump_human_image_info_list(list);
Benoît Canetc054b3f2012-09-05 13:09:02 +02001467 break;
1468 case OFORMAT_JSON:
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001469 if (chain) {
1470 dump_json_image_info_list(list);
1471 } else {
1472 dump_json_image_info(list->value);
1473 }
Benoît Canetc054b3f2012-09-05 13:09:02 +02001474 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001475 }
Benoît Canetc054b3f2012-09-05 13:09:02 +02001476
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001477 qapi_free_ImageInfoList(list);
bellardea2384d2004-08-01 21:59:26 +00001478 return 0;
1479}
1480
aliguorif7b4a942009-01-07 17:40:15 +00001481#define SNAPSHOT_LIST 1
1482#define SNAPSHOT_CREATE 2
1483#define SNAPSHOT_APPLY 3
1484#define SNAPSHOT_DELETE 4
1485
Stuart Brady153859b2009-06-07 00:42:17 +01001486static int img_snapshot(int argc, char **argv)
aliguorif7b4a942009-01-07 17:40:15 +00001487{
1488 BlockDriverState *bs;
1489 QEMUSnapshotInfo sn;
1490 char *filename, *snapshot_name = NULL;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001491 int c, ret = 0, bdrv_oflags;
aliguorif7b4a942009-01-07 17:40:15 +00001492 int action = 0;
1493 qemu_timeval tv;
1494
Kevin Wolf710da702011-01-10 12:33:02 +01001495 bdrv_oflags = BDRV_O_FLAGS | BDRV_O_RDWR;
aliguorif7b4a942009-01-07 17:40:15 +00001496 /* Parse commandline parameters */
1497 for(;;) {
1498 c = getopt(argc, argv, "la:c:d:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001499 if (c == -1) {
aliguorif7b4a942009-01-07 17:40:15 +00001500 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001501 }
aliguorif7b4a942009-01-07 17:40:15 +00001502 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001503 case '?':
aliguorif7b4a942009-01-07 17:40:15 +00001504 case 'h':
1505 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001506 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001507 case 'l':
1508 if (action) {
1509 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001510 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001511 }
1512 action = SNAPSHOT_LIST;
Naphtali Spreif5edb012010-01-17 16:48:13 +02001513 bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
aliguorif7b4a942009-01-07 17:40:15 +00001514 break;
1515 case 'a':
1516 if (action) {
1517 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001518 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001519 }
1520 action = SNAPSHOT_APPLY;
1521 snapshot_name = optarg;
1522 break;
1523 case 'c':
1524 if (action) {
1525 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001526 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001527 }
1528 action = SNAPSHOT_CREATE;
1529 snapshot_name = optarg;
1530 break;
1531 case 'd':
1532 if (action) {
1533 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001534 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001535 }
1536 action = SNAPSHOT_DELETE;
1537 snapshot_name = optarg;
1538 break;
1539 }
1540 }
1541
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001542 if (optind >= argc) {
aliguorif7b4a942009-01-07 17:40:15 +00001543 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001544 }
aliguorif7b4a942009-01-07 17:40:15 +00001545 filename = argv[optind++];
1546
1547 /* Open the image */
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +01001548 bs = bdrv_new_open(filename, NULL, bdrv_oflags, true);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001549 if (!bs) {
1550 return 1;
1551 }
aliguorif7b4a942009-01-07 17:40:15 +00001552
1553 /* Perform the requested action */
1554 switch(action) {
1555 case SNAPSHOT_LIST:
1556 dump_snapshots(bs);
1557 break;
1558
1559 case SNAPSHOT_CREATE:
1560 memset(&sn, 0, sizeof(sn));
1561 pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
1562
1563 qemu_gettimeofday(&tv);
1564 sn.date_sec = tv.tv_sec;
1565 sn.date_nsec = tv.tv_usec * 1000;
1566
1567 ret = bdrv_snapshot_create(bs, &sn);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001568 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001569 error_report("Could not create snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001570 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001571 }
aliguorif7b4a942009-01-07 17:40:15 +00001572 break;
1573
1574 case SNAPSHOT_APPLY:
1575 ret = bdrv_snapshot_goto(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001576 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001577 error_report("Could not apply snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001578 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001579 }
aliguorif7b4a942009-01-07 17:40:15 +00001580 break;
1581
1582 case SNAPSHOT_DELETE:
1583 ret = bdrv_snapshot_delete(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001584 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001585 error_report("Could not delete snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001586 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001587 }
aliguorif7b4a942009-01-07 17:40:15 +00001588 break;
1589 }
1590
1591 /* Cleanup */
1592 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001593 if (ret) {
1594 return 1;
1595 }
Stuart Brady153859b2009-06-07 00:42:17 +01001596 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001597}
1598
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001599static int img_rebase(int argc, char **argv)
1600{
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001601 BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001602 BlockDriver *old_backing_drv, *new_backing_drv;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001603 char *filename;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001604 const char *fmt, *cache, *out_basefmt, *out_baseimg;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001605 int c, flags, ret;
1606 int unsafe = 0;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001607 int progress = 0;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001608
1609 /* Parse commandline parameters */
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001610 fmt = NULL;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001611 cache = BDRV_DEFAULT_CACHE;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001612 out_baseimg = NULL;
1613 out_basefmt = NULL;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001614 for(;;) {
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001615 c = getopt(argc, argv, "uhf:F:b:pt:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001616 if (c == -1) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001617 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001618 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001619 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001620 case '?':
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001621 case 'h':
1622 help();
1623 return 0;
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001624 case 'f':
1625 fmt = optarg;
1626 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001627 case 'F':
1628 out_basefmt = optarg;
1629 break;
1630 case 'b':
1631 out_baseimg = optarg;
1632 break;
1633 case 'u':
1634 unsafe = 1;
1635 break;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001636 case 'p':
1637 progress = 1;
1638 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001639 case 't':
1640 cache = optarg;
1641 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001642 }
1643 }
1644
Anthony Liguori9a9d9db2011-04-13 15:51:47 +01001645 if ((optind >= argc) || (!unsafe && !out_baseimg)) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001646 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001647 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001648 filename = argv[optind++];
1649
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001650 qemu_progress_init(progress, 2.0);
1651 qemu_progress_print(0, 100);
1652
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001653 flags = BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +01001654 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001655 if (ret < 0) {
1656 error_report("Invalid cache option: %s", cache);
1657 return -1;
1658 }
1659
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001660 /*
1661 * Open the images.
1662 *
1663 * Ignore the old backing file for unsafe rebase in case we want to correct
1664 * the reference to a renamed or moved backing file.
1665 */
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +01001666 bs = bdrv_new_open(filename, fmt, flags, true);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001667 if (!bs) {
1668 return 1;
1669 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001670
1671 /* Find the right drivers for the backing files */
1672 old_backing_drv = NULL;
1673 new_backing_drv = NULL;
1674
1675 if (!unsafe && bs->backing_format[0] != '\0') {
1676 old_backing_drv = bdrv_find_format(bs->backing_format);
1677 if (old_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001678 error_report("Invalid format name: '%s'", bs->backing_format);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001679 ret = -1;
1680 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001681 }
1682 }
1683
1684 if (out_basefmt != NULL) {
1685 new_backing_drv = bdrv_find_format(out_basefmt);
1686 if (new_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001687 error_report("Invalid format name: '%s'", out_basefmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001688 ret = -1;
1689 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001690 }
1691 }
1692
1693 /* For safe rebasing we need to compare old and new backing file */
1694 if (unsafe) {
1695 /* Make the compiler happy */
1696 bs_old_backing = NULL;
1697 bs_new_backing = NULL;
1698 } else {
1699 char backing_name[1024];
1700
1701 bs_old_backing = bdrv_new("old_backing");
1702 bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001703 ret = bdrv_open(bs_old_backing, backing_name, BDRV_O_FLAGS,
1704 old_backing_drv);
1705 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001706 error_report("Could not open old backing file '%s'", backing_name);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001707 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001708 }
Alex Bligha6166732012-10-16 13:46:18 +01001709 if (out_baseimg[0]) {
1710 bs_new_backing = bdrv_new("new_backing");
1711 ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS,
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001712 new_backing_drv);
Alex Bligha6166732012-10-16 13:46:18 +01001713 if (ret) {
1714 error_report("Could not open new backing file '%s'",
1715 out_baseimg);
1716 goto out;
1717 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001718 }
1719 }
1720
1721 /*
1722 * Check each unallocated cluster in the COW file. If it is unallocated,
1723 * accesses go to the backing file. We must therefore compare this cluster
1724 * in the old and new backing file, and if they differ we need to copy it
1725 * from the old backing file into the COW file.
1726 *
1727 * If qemu-img crashes during this step, no harm is done. The content of
1728 * the image is the same as the original one at any time.
1729 */
1730 if (!unsafe) {
1731 uint64_t num_sectors;
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01001732 uint64_t old_backing_num_sectors;
Alex Bligha6166732012-10-16 13:46:18 +01001733 uint64_t new_backing_num_sectors = 0;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001734 uint64_t sector;
Kevin Wolfcc60e322010-04-29 14:47:48 +02001735 int n;
TeLeMand6771bf2010-02-08 16:20:00 +08001736 uint8_t * buf_old;
1737 uint8_t * buf_new;
Kevin Wolf1f710492012-10-12 14:29:18 +02001738 float local_progress = 0;
TeLeMand6771bf2010-02-08 16:20:00 +08001739
Kevin Wolfbb1c0592011-08-08 14:09:12 +02001740 buf_old = qemu_blockalign(bs, IO_BUF_SIZE);
1741 buf_new = qemu_blockalign(bs, IO_BUF_SIZE);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001742
1743 bdrv_get_geometry(bs, &num_sectors);
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01001744 bdrv_get_geometry(bs_old_backing, &old_backing_num_sectors);
Alex Bligha6166732012-10-16 13:46:18 +01001745 if (bs_new_backing) {
1746 bdrv_get_geometry(bs_new_backing, &new_backing_num_sectors);
1747 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001748
Kevin Wolf1f710492012-10-12 14:29:18 +02001749 if (num_sectors != 0) {
1750 local_progress = (float)100 /
1751 (num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512));
1752 }
1753
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001754 for (sector = 0; sector < num_sectors; sector += n) {
1755
1756 /* How many sectors can we handle with the next read? */
1757 if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
1758 n = (IO_BUF_SIZE / 512);
1759 } else {
1760 n = num_sectors - sector;
1761 }
1762
1763 /* If the cluster is allocated, we don't need to take action */
Kevin Wolfcc60e322010-04-29 14:47:48 +02001764 ret = bdrv_is_allocated(bs, sector, n, &n);
1765 if (ret) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001766 continue;
1767 }
1768
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01001769 /*
1770 * Read old and new backing file and take into consideration that
1771 * backing files may be smaller than the COW image.
1772 */
1773 if (sector >= old_backing_num_sectors) {
1774 memset(buf_old, 0, n * BDRV_SECTOR_SIZE);
1775 } else {
1776 if (sector + n > old_backing_num_sectors) {
1777 n = old_backing_num_sectors - sector;
1778 }
1779
1780 ret = bdrv_read(bs_old_backing, sector, buf_old, n);
1781 if (ret < 0) {
1782 error_report("error while reading from old backing file");
1783 goto out;
1784 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001785 }
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01001786
Alex Bligha6166732012-10-16 13:46:18 +01001787 if (sector >= new_backing_num_sectors || !bs_new_backing) {
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01001788 memset(buf_new, 0, n * BDRV_SECTOR_SIZE);
1789 } else {
1790 if (sector + n > new_backing_num_sectors) {
1791 n = new_backing_num_sectors - sector;
1792 }
1793
1794 ret = bdrv_read(bs_new_backing, sector, buf_new, n);
1795 if (ret < 0) {
1796 error_report("error while reading from new backing file");
1797 goto out;
1798 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001799 }
1800
1801 /* If they differ, we need to write to the COW file */
1802 uint64_t written = 0;
1803
1804 while (written < n) {
1805 int pnum;
1806
1807 if (compare_sectors(buf_old + written * 512,
Kevin Wolf60b1bd42010-02-17 12:32:59 +01001808 buf_new + written * 512, n - written, &pnum))
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001809 {
1810 ret = bdrv_write(bs, sector + written,
1811 buf_old + written * 512, pnum);
1812 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001813 error_report("Error while writing to COW image: %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001814 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001815 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001816 }
1817 }
1818
1819 written += pnum;
1820 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001821 qemu_progress_print(local_progress, 100);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001822 }
TeLeMand6771bf2010-02-08 16:20:00 +08001823
Kevin Wolfbb1c0592011-08-08 14:09:12 +02001824 qemu_vfree(buf_old);
1825 qemu_vfree(buf_new);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001826 }
1827
1828 /*
1829 * Change the backing file. All clusters that are different from the old
1830 * backing file are overwritten in the COW file now, so the visible content
1831 * doesn't change when we switch the backing file.
1832 */
Alex Bligha6166732012-10-16 13:46:18 +01001833 if (out_baseimg && *out_baseimg) {
1834 ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
1835 } else {
1836 ret = bdrv_change_backing_file(bs, NULL, NULL);
1837 }
1838
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001839 if (ret == -ENOSPC) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001840 error_report("Could not change the backing file to '%s': No "
1841 "space left in the file header", out_baseimg);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001842 } else if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001843 error_report("Could not change the backing file to '%s': %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001844 out_baseimg, strerror(-ret));
1845 }
1846
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001847 qemu_progress_print(100, 0);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001848 /*
1849 * TODO At this point it is possible to check if any clusters that are
1850 * allocated in the COW file are the same in the backing file. If so, they
1851 * could be dropped from the COW file. Don't do this before switching the
1852 * backing file, in case of a crash this would lead to corruption.
1853 */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001854out:
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001855 qemu_progress_end();
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001856 /* Cleanup */
1857 if (!unsafe) {
Kevin Wolfeb863ad2011-03-31 12:39:51 +02001858 if (bs_old_backing != NULL) {
1859 bdrv_delete(bs_old_backing);
1860 }
1861 if (bs_new_backing != NULL) {
1862 bdrv_delete(bs_new_backing);
1863 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001864 }
1865
1866 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001867 if (ret) {
1868 return 1;
1869 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001870 return 0;
1871}
1872
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001873static int img_resize(int argc, char **argv)
1874{
1875 int c, ret, relative;
1876 const char *filename, *fmt, *size;
1877 int64_t n, total_size;
Jes Sorensen2a819982010-12-06 17:08:31 +01001878 BlockDriverState *bs = NULL;
Dong Xu Wang20caf0f2012-08-06 10:18:42 +08001879 QemuOpts *param;
1880 static QemuOptsList resize_options = {
1881 .name = "resize_options",
1882 .head = QTAILQ_HEAD_INITIALIZER(resize_options.head),
1883 .desc = {
1884 {
1885 .name = BLOCK_OPT_SIZE,
1886 .type = QEMU_OPT_SIZE,
1887 .help = "Virtual disk size"
1888 }, {
1889 /* end of list */
1890 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001891 },
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001892 };
1893
Kevin Wolfe80fec72011-04-29 10:58:12 +02001894 /* Remove size from argv manually so that negative numbers are not treated
1895 * as options by getopt. */
1896 if (argc < 3) {
1897 help();
1898 return 1;
1899 }
1900
1901 size = argv[--argc];
1902
1903 /* Parse getopt arguments */
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001904 fmt = NULL;
1905 for(;;) {
1906 c = getopt(argc, argv, "f:h");
1907 if (c == -1) {
1908 break;
1909 }
1910 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001911 case '?':
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001912 case 'h':
1913 help();
1914 break;
1915 case 'f':
1916 fmt = optarg;
1917 break;
1918 }
1919 }
Kevin Wolfe80fec72011-04-29 10:58:12 +02001920 if (optind >= argc) {
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001921 help();
1922 }
1923 filename = argv[optind++];
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001924
1925 /* Choose grow, shrink, or absolute resize mode */
1926 switch (size[0]) {
1927 case '+':
1928 relative = 1;
1929 size++;
1930 break;
1931 case '-':
1932 relative = -1;
1933 size++;
1934 break;
1935 default:
1936 relative = 0;
1937 break;
1938 }
1939
1940 /* Parse size */
Dong Xu Wange478b442012-12-06 14:47:22 +08001941 param = qemu_opts_create_nofail(&resize_options);
Dong Xu Wang20caf0f2012-08-06 10:18:42 +08001942 if (qemu_opt_set(param, BLOCK_OPT_SIZE, size)) {
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001943 /* Error message already printed when size parsing fails */
Jes Sorensen2a819982010-12-06 17:08:31 +01001944 ret = -1;
Dong Xu Wang20caf0f2012-08-06 10:18:42 +08001945 qemu_opts_del(param);
Jes Sorensen2a819982010-12-06 17:08:31 +01001946 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001947 }
Dong Xu Wang20caf0f2012-08-06 10:18:42 +08001948 n = qemu_opt_get_size(param, BLOCK_OPT_SIZE, 0);
1949 qemu_opts_del(param);
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001950
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +01001951 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR, true);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001952 if (!bs) {
Jes Sorensen2a819982010-12-06 17:08:31 +01001953 ret = -1;
1954 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001955 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001956
1957 if (relative) {
1958 total_size = bdrv_getlength(bs) + n * relative;
1959 } else {
1960 total_size = n;
1961 }
1962 if (total_size <= 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001963 error_report("New image size must be positive");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001964 ret = -1;
1965 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001966 }
1967
1968 ret = bdrv_truncate(bs, total_size);
1969 switch (ret) {
1970 case 0:
1971 printf("Image resized.\n");
1972 break;
1973 case -ENOTSUP:
Kevin Wolf259b2172012-03-06 12:44:45 +01001974 error_report("This image does not support resize");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001975 break;
1976 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +01001977 error_report("Image is read-only");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001978 break;
1979 default:
Jes Sorensen15654a62010-12-16 14:31:53 +01001980 error_report("Error resizing image (%d)", -ret);
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001981 break;
1982 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001983out:
Jes Sorensen2a819982010-12-06 17:08:31 +01001984 if (bs) {
1985 bdrv_delete(bs);
1986 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001987 if (ret) {
1988 return 1;
1989 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001990 return 0;
1991}
1992
Anthony Liguoric227f092009-10-01 16:12:16 -05001993static const img_cmd_t img_cmds[] = {
Stuart Brady153859b2009-06-07 00:42:17 +01001994#define DEF(option, callback, arg_string) \
1995 { option, callback },
1996#include "qemu-img-cmds.h"
1997#undef DEF
1998#undef GEN_DOCS
1999 { NULL, NULL, },
2000};
2001
bellardea2384d2004-08-01 21:59:26 +00002002int main(int argc, char **argv)
2003{
Anthony Liguoric227f092009-10-01 16:12:16 -05002004 const img_cmd_t *cmd;
Stuart Brady153859b2009-06-07 00:42:17 +01002005 const char *cmdname;
bellardea2384d2004-08-01 21:59:26 +00002006
Kevin Wolf53f76e52010-12-16 15:10:32 +01002007 error_set_progname(argv[0]);
2008
Paolo Bonzini2592c592012-11-03 18:10:17 +01002009 qemu_init_main_loop();
bellardea2384d2004-08-01 21:59:26 +00002010 bdrv_init();
2011 if (argc < 2)
2012 help();
Stuart Brady153859b2009-06-07 00:42:17 +01002013 cmdname = argv[1];
aurel328f9b1572009-02-09 18:14:31 +00002014 argc--; argv++;
Stuart Brady153859b2009-06-07 00:42:17 +01002015
2016 /* find the command */
2017 for(cmd = img_cmds; cmd->name != NULL; cmd++) {
2018 if (!strcmp(cmdname, cmd->name)) {
2019 return cmd->handler(argc, argv);
2020 }
bellardea2384d2004-08-01 21:59:26 +00002021 }
Stuart Brady153859b2009-06-07 00:42:17 +01002022
2023 /* not found */
2024 help();
bellardea2384d2004-08-01 21:59:26 +00002025 return 0;
2026}