blob: a13bc788cf6e6b1bc7b9c430ece29e049a8f638b [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"
Kevin Wolf9ea2ea72009-05-18 16:42:11 +020028#include "qemu-option.h"
Kevin Wolf53f76e52010-12-16 15:10:32 +010029#include "qemu-error.h"
aliguorif7b4a942009-01-07 17:40:15 +000030#include "osdep.h"
Jes Sorensendc786bc2010-10-26 10:39:23 +020031#include "sysemu.h"
thsec36ba12007-09-16 21:59:02 +000032#include "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) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100351 error_report("Invalid image size specified! You may use k, M, G or "
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100352 "T suffixes for ");
Jes Sorensen15654a62010-12-16 14:31:53 +0100353 error_report("kilobytes, megabytes, gigabytes and terabytes.");
Luiz Capitulinoa9300912012-11-30 10:52:06 -0200354 return 1;
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100355 }
356 img_size = (uint64_t)sval;
357 }
358
Peter Maydellc8057f92012-08-02 13:45:54 +0100359 if (options && is_help_option(options)) {
Luiz Capitulinoa9300912012-11-30 10:52:06 -0200360 return print_block_option_help(filename, fmt);
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100361 }
362
Luiz Capitulino9b375252012-11-30 10:52:05 -0200363 bdrv_img_create(filename, fmt, base_filename, base_fmt,
364 options, img_size, BDRV_O_FLAGS, &local_err);
365 if (error_is_set(&local_err)) {
366 error_report("%s", error_get_pretty(local_err));
367 error_free(local_err);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900368 return 1;
369 }
Luiz Capitulinoa9300912012-11-30 10:52:06 -0200370
bellardea2384d2004-08-01 21:59:26 +0000371 return 0;
372}
373
Kevin Wolfe076f332010-06-29 11:43:13 +0200374/*
375 * Checks an image for consistency. Exit codes:
376 *
377 * 0 - Check completed, image is good
378 * 1 - Check not completed because of internal errors
379 * 2 - Check completed, image is corrupted
380 * 3 - Check completed, image has leaked clusters, but is good otherwise
381 */
aliguori15859692009-04-21 23:11:53 +0000382static int img_check(int argc, char **argv)
383{
384 int c, ret;
385 const char *filename, *fmt;
aliguori15859692009-04-21 23:11:53 +0000386 BlockDriverState *bs;
Kevin Wolfe076f332010-06-29 11:43:13 +0200387 BdrvCheckResult result;
Kevin Wolf4534ff52012-05-11 16:07:02 +0200388 int fix = 0;
Stefan Hajnoczi058f8f12012-08-09 13:05:56 +0100389 int flags = BDRV_O_FLAGS | BDRV_O_CHECK;
aliguori15859692009-04-21 23:11:53 +0000390
391 fmt = NULL;
392 for(;;) {
Kevin Wolf4534ff52012-05-11 16:07:02 +0200393 c = getopt(argc, argv, "f:hr:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100394 if (c == -1) {
aliguori15859692009-04-21 23:11:53 +0000395 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100396 }
aliguori15859692009-04-21 23:11:53 +0000397 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100398 case '?':
aliguori15859692009-04-21 23:11:53 +0000399 case 'h':
400 help();
401 break;
402 case 'f':
403 fmt = optarg;
404 break;
Kevin Wolf4534ff52012-05-11 16:07:02 +0200405 case 'r':
406 flags |= BDRV_O_RDWR;
407
408 if (!strcmp(optarg, "leaks")) {
409 fix = BDRV_FIX_LEAKS;
410 } else if (!strcmp(optarg, "all")) {
411 fix = BDRV_FIX_LEAKS | BDRV_FIX_ERRORS;
412 } else {
413 help();
414 }
415 break;
aliguori15859692009-04-21 23:11:53 +0000416 }
417 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100418 if (optind >= argc) {
aliguori15859692009-04-21 23:11:53 +0000419 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100420 }
aliguori15859692009-04-21 23:11:53 +0000421 filename = argv[optind++];
422
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +0100423 bs = bdrv_new_open(filename, fmt, flags, true);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900424 if (!bs) {
425 return 1;
426 }
Kevin Wolf4534ff52012-05-11 16:07:02 +0200427 ret = bdrv_check(bs, &result, fix);
Kevin Wolfe076f332010-06-29 11:43:13 +0200428
429 if (ret == -ENOTSUP) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100430 error_report("This image format does not support checks");
Kevin Wolfe076f332010-06-29 11:43:13 +0200431 bdrv_delete(bs);
432 return 1;
433 }
434
Kevin Wolfccf34712012-05-11 18:16:54 +0200435 if (result.corruptions_fixed || result.leaks_fixed) {
436 printf("The following inconsistencies were found and repaired:\n\n"
437 " %d leaked clusters\n"
438 " %d corruptions\n\n"
439 "Double checking the fixed image now...\n",
440 result.leaks_fixed,
441 result.corruptions_fixed);
442 ret = bdrv_check(bs, &result, 0);
443 }
444
Kevin Wolfe076f332010-06-29 11:43:13 +0200445 if (!(result.corruptions || result.leaks || result.check_errors)) {
446 printf("No errors were found on the image.\n");
447 } else {
448 if (result.corruptions) {
449 printf("\n%d errors were found on the image.\n"
450 "Data may be corrupted, or further writes to the image "
451 "may corrupt it.\n",
452 result.corruptions);
aliguori15859692009-04-21 23:11:53 +0000453 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200454
455 if (result.leaks) {
456 printf("\n%d leaked clusters were found on the image.\n"
457 "This means waste of disk space, but no harm to data.\n",
458 result.leaks);
459 }
460
461 if (result.check_errors) {
462 printf("\n%d internal errors have occurred during the check.\n",
463 result.check_errors);
464 }
aliguori15859692009-04-21 23:11:53 +0000465 }
466
Dong Xu Wangf8111c22012-03-15 20:13:31 +0800467 if (result.bfi.total_clusters != 0 && result.bfi.allocated_clusters != 0) {
468 printf("%" PRId64 "/%" PRId64 "= %0.2f%% allocated, %0.2f%% fragmented\n",
469 result.bfi.allocated_clusters, result.bfi.total_clusters,
470 result.bfi.allocated_clusters * 100.0 / result.bfi.total_clusters,
471 result.bfi.fragmented_clusters * 100.0 / result.bfi.allocated_clusters);
472 }
473
aliguori15859692009-04-21 23:11:53 +0000474 bdrv_delete(bs);
Kevin Wolfe076f332010-06-29 11:43:13 +0200475
476 if (ret < 0 || result.check_errors) {
477 printf("\nAn error has occurred during the check: %s\n"
478 "The check is not complete and may have missed error.\n",
479 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900480 return 1;
481 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200482
483 if (result.corruptions) {
484 return 2;
485 } else if (result.leaks) {
486 return 3;
487 } else {
488 return 0;
489 }
aliguori15859692009-04-21 23:11:53 +0000490}
491
bellardea2384d2004-08-01 21:59:26 +0000492static int img_commit(int argc, char **argv)
493{
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400494 int c, ret, flags;
495 const char *filename, *fmt, *cache;
bellardea2384d2004-08-01 21:59:26 +0000496 BlockDriverState *bs;
497
498 fmt = NULL;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400499 cache = BDRV_DEFAULT_CACHE;
bellardea2384d2004-08-01 21:59:26 +0000500 for(;;) {
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400501 c = getopt(argc, argv, "f:ht:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100502 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000503 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100504 }
bellardea2384d2004-08-01 21:59:26 +0000505 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100506 case '?':
bellardea2384d2004-08-01 21:59:26 +0000507 case 'h':
508 help();
509 break;
510 case 'f':
511 fmt = optarg;
512 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400513 case 't':
514 cache = optarg;
515 break;
bellardea2384d2004-08-01 21:59:26 +0000516 }
517 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100518 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +0000519 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100520 }
bellardea2384d2004-08-01 21:59:26 +0000521 filename = argv[optind++];
522
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400523 flags = BDRV_O_RDWR;
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +0100524 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400525 if (ret < 0) {
526 error_report("Invalid cache option: %s", cache);
527 return -1;
528 }
529
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +0100530 bs = bdrv_new_open(filename, fmt, flags, true);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900531 if (!bs) {
532 return 1;
533 }
bellardea2384d2004-08-01 21:59:26 +0000534 ret = bdrv_commit(bs);
535 switch(ret) {
536 case 0:
537 printf("Image committed.\n");
538 break;
539 case -ENOENT:
Jes Sorensen15654a62010-12-16 14:31:53 +0100540 error_report("No disk inserted");
bellardea2384d2004-08-01 21:59:26 +0000541 break;
542 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +0100543 error_report("Image is read-only");
bellardea2384d2004-08-01 21:59:26 +0000544 break;
545 case -ENOTSUP:
Jes Sorensen15654a62010-12-16 14:31:53 +0100546 error_report("Image is already committed");
bellardea2384d2004-08-01 21:59:26 +0000547 break;
548 default:
Jes Sorensen15654a62010-12-16 14:31:53 +0100549 error_report("Error while committing image");
bellardea2384d2004-08-01 21:59:26 +0000550 break;
551 }
552
553 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900554 if (ret) {
555 return 1;
556 }
bellardea2384d2004-08-01 21:59:26 +0000557 return 0;
558}
559
Dmitry Konishchevf6a00aa2011-05-18 15:03:59 +0400560/*
thsf58c7b32008-06-05 21:53:49 +0000561 * Returns true iff the first sector pointed to by 'buf' contains at least
562 * a non-NUL byte.
563 *
564 * 'pnum' is set to the number of sectors (including and immediately following
565 * the first one) that are known to be in the same allocated/unallocated state.
566 */
bellardea2384d2004-08-01 21:59:26 +0000567static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
568{
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000569 bool is_zero;
570 int i;
bellardea2384d2004-08-01 21:59:26 +0000571
572 if (n <= 0) {
573 *pnum = 0;
574 return 0;
575 }
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000576 is_zero = buffer_is_zero(buf, 512);
bellardea2384d2004-08-01 21:59:26 +0000577 for(i = 1; i < n; i++) {
578 buf += 512;
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000579 if (is_zero != buffer_is_zero(buf, 512)) {
bellardea2384d2004-08-01 21:59:26 +0000580 break;
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000581 }
bellardea2384d2004-08-01 21:59:26 +0000582 }
583 *pnum = i;
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000584 return !is_zero;
bellardea2384d2004-08-01 21:59:26 +0000585}
586
Kevin Wolf3e85c6f2010-01-12 12:55:18 +0100587/*
Kevin Wolfa22f1232011-08-26 15:27:13 +0200588 * Like is_allocated_sectors, but if the buffer starts with a used sector,
589 * up to 'min' consecutive sectors containing zeros are ignored. This avoids
590 * breaking up write requests for only small sparse areas.
591 */
592static int is_allocated_sectors_min(const uint8_t *buf, int n, int *pnum,
593 int min)
594{
595 int ret;
596 int num_checked, num_used;
597
598 if (n < min) {
599 min = n;
600 }
601
602 ret = is_allocated_sectors(buf, n, pnum);
603 if (!ret) {
604 return ret;
605 }
606
607 num_used = *pnum;
608 buf += BDRV_SECTOR_SIZE * *pnum;
609 n -= *pnum;
610 num_checked = num_used;
611
612 while (n > 0) {
613 ret = is_allocated_sectors(buf, n, pnum);
614
615 buf += BDRV_SECTOR_SIZE * *pnum;
616 n -= *pnum;
617 num_checked += *pnum;
618 if (ret) {
619 num_used = num_checked;
620 } else if (*pnum >= min) {
621 break;
622 }
623 }
624
625 *pnum = num_used;
626 return 1;
627}
628
629/*
Kevin Wolf3e85c6f2010-01-12 12:55:18 +0100630 * Compares two buffers sector by sector. Returns 0 if the first sector of both
631 * buffers matches, non-zero otherwise.
632 *
633 * pnum is set to the number of sectors (including and immediately following
634 * the first one) that are known to have the same comparison result
635 */
636static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
637 int *pnum)
638{
639 int res, i;
640
641 if (n <= 0) {
642 *pnum = 0;
643 return 0;
644 }
645
646 res = !!memcmp(buf1, buf2, 512);
647 for(i = 1; i < n; i++) {
648 buf1 += 512;
649 buf2 += 512;
650
651 if (!!memcmp(buf1, buf2, 512) != res) {
652 break;
653 }
654 }
655
656 *pnum = i;
657 return res;
658}
659
Kevin Wolf80ee15a2009-09-15 12:30:43 +0200660#define IO_BUF_SIZE (2 * 1024 * 1024)
bellardea2384d2004-08-01 21:59:26 +0000661
662static int img_convert(int argc, char **argv)
663{
Jes Sorenseneec77d92010-12-07 17:44:34 +0100664 int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400665 int progress = 0, flags;
666 const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900667 BlockDriver *drv, *proto_drv;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900668 BlockDriverState **bs = NULL, *out_bs = NULL;
ths96b8f132007-12-17 01:35:20 +0000669 int64_t total_sectors, nb_sectors, sector_num, bs_offset;
670 uint64_t bs_sectors;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900671 uint8_t * buf = NULL;
bellardea2384d2004-08-01 21:59:26 +0000672 const uint8_t *buf1;
bellardfaea38e2006-08-05 21:31:00 +0000673 BlockDriverInfo bdi;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900674 QEMUOptionParameter *param = NULL, *create_options = NULL;
Kevin Wolfa18953f2010-10-14 15:46:04 +0200675 QEMUOptionParameter *out_baseimg_param;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200676 char *options = NULL;
edison51ef6722010-09-21 19:58:41 -0700677 const char *snapshot_name = NULL;
Kevin Wolf1f710492012-10-12 14:29:18 +0200678 float local_progress = 0;
Kevin Wolfa22f1232011-08-26 15:27:13 +0200679 int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */
bellardea2384d2004-08-01 21:59:26 +0000680
681 fmt = NULL;
682 out_fmt = "raw";
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400683 cache = "unsafe";
thsf58c7b32008-06-05 21:53:49 +0000684 out_baseimg = NULL;
Jes Sorenseneec77d92010-12-07 17:44:34 +0100685 compress = 0;
bellardea2384d2004-08-01 21:59:26 +0000686 for(;;) {
Kevin Wolfa22f1232011-08-26 15:27:13 +0200687 c = getopt(argc, argv, "f:O:B:s:hce6o:pS:t:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100688 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000689 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100690 }
bellardea2384d2004-08-01 21:59:26 +0000691 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100692 case '?':
bellardea2384d2004-08-01 21:59:26 +0000693 case 'h':
694 help();
695 break;
696 case 'f':
697 fmt = optarg;
698 break;
699 case 'O':
700 out_fmt = optarg;
701 break;
thsf58c7b32008-06-05 21:53:49 +0000702 case 'B':
703 out_baseimg = optarg;
704 break;
bellardea2384d2004-08-01 21:59:26 +0000705 case 'c':
Jes Sorenseneec77d92010-12-07 17:44:34 +0100706 compress = 1;
bellardea2384d2004-08-01 21:59:26 +0000707 break;
708 case 'e':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200709 error_report("option -e is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100710 "encryption\' instead!");
711 return 1;
thsec36ba12007-09-16 21:59:02 +0000712 case '6':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200713 error_report("option -6 is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100714 "compat6\' instead!");
715 return 1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200716 case 'o':
717 options = optarg;
718 break;
edison51ef6722010-09-21 19:58:41 -0700719 case 's':
720 snapshot_name = optarg;
721 break;
Kevin Wolfa22f1232011-08-26 15:27:13 +0200722 case 'S':
723 {
724 int64_t sval;
Markus Armbrustere36b3692011-11-22 09:46:05 +0100725 char *end;
726 sval = strtosz_suffix(optarg, &end, STRTOSZ_DEFSUFFIX_B);
727 if (sval < 0 || *end) {
Kevin Wolfa22f1232011-08-26 15:27:13 +0200728 error_report("Invalid minimum zero buffer size for sparse output specified");
729 return 1;
730 }
731
732 min_sparse = sval / BDRV_SECTOR_SIZE;
733 break;
734 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200735 case 'p':
736 progress = 1;
737 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400738 case 't':
739 cache = optarg;
740 break;
bellardea2384d2004-08-01 21:59:26 +0000741 }
742 }
ths3b46e622007-09-17 08:09:54 +0000743
balrog926c2d22007-10-31 01:11:44 +0000744 bs_n = argc - optind - 1;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100745 if (bs_n < 1) {
746 help();
747 }
balrog926c2d22007-10-31 01:11:44 +0000748
749 out_filename = argv[argc - 1];
thsf58c7b32008-06-05 21:53:49 +0000750
Charles Arnoldfa170c12012-05-11 10:57:54 -0600751 /* Initialize before goto out */
752 qemu_progress_init(progress, 2.0);
753
Peter Maydellc8057f92012-08-02 13:45:54 +0100754 if (options && is_help_option(options)) {
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100755 ret = print_block_option_help(out_filename, out_fmt);
756 goto out;
757 }
758
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900759 if (bs_n > 1 && out_baseimg) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100760 error_report("-B makes no sense when concatenating multiple input "
761 "images");
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100762 ret = -1;
763 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900764 }
Dong Xu Wangf8111c22012-03-15 20:13:31 +0800765
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200766 qemu_progress_print(0, 100);
767
Anthony Liguori7267c092011-08-20 22:09:37 -0500768 bs = g_malloc0(bs_n * sizeof(BlockDriverState *));
balrog926c2d22007-10-31 01:11:44 +0000769
770 total_sectors = 0;
771 for (bs_i = 0; bs_i < bs_n; bs_i++) {
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +0100772 bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS, true);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900773 if (!bs[bs_i]) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100774 error_report("Could not open '%s'", argv[optind + bs_i]);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900775 ret = -1;
776 goto out;
777 }
balrog926c2d22007-10-31 01:11:44 +0000778 bdrv_get_geometry(bs[bs_i], &bs_sectors);
779 total_sectors += bs_sectors;
780 }
bellardea2384d2004-08-01 21:59:26 +0000781
edison51ef6722010-09-21 19:58:41 -0700782 if (snapshot_name != NULL) {
783 if (bs_n > 1) {
Markus Armbruster6daf1942011-06-22 14:03:54 +0200784 error_report("No support for concatenating multiple snapshot");
edison51ef6722010-09-21 19:58:41 -0700785 ret = -1;
786 goto out;
787 }
788 if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
Markus Armbruster6daf1942011-06-22 14:03:54 +0200789 error_report("Failed to load snapshot");
edison51ef6722010-09-21 19:58:41 -0700790 ret = -1;
791 goto out;
792 }
793 }
794
Kevin Wolfefa84d42009-05-18 16:42:12 +0200795 /* Find driver and parse its options */
bellardea2384d2004-08-01 21:59:26 +0000796 drv = bdrv_find_format(out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900797 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100798 error_report("Unknown file format '%s'", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900799 ret = -1;
800 goto out;
801 }
balrog926c2d22007-10-31 01:11:44 +0000802
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900803 proto_drv = bdrv_find_protocol(out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900804 if (!proto_drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100805 error_report("Unknown protocol '%s'", out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900806 ret = -1;
807 goto out;
808 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900809
810 create_options = append_option_parameters(create_options,
811 drv->create_options);
812 create_options = append_option_parameters(create_options,
813 proto_drv->create_options);
Kevin Wolfdb08adf2009-06-04 15:39:38 +0200814
Kevin Wolfefa84d42009-05-18 16:42:12 +0200815 if (options) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900816 param = parse_option_parameters(options, create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200817 if (param == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100818 error_report("Invalid options for file format '%s'.", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900819 ret = -1;
820 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200821 }
822 } else {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900823 param = parse_option_parameters("", create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200824 }
825
826 set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
Jes Sorenseneec77d92010-12-07 17:44:34 +0100827 ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900828 if (ret < 0) {
829 goto out;
830 }
Kevin Wolfefa84d42009-05-18 16:42:12 +0200831
Kevin Wolfa18953f2010-10-14 15:46:04 +0200832 /* Get backing file name if -o backing_file was used */
833 out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
834 if (out_baseimg_param) {
835 out_baseimg = out_baseimg_param->value.s;
836 }
837
Kevin Wolfefa84d42009-05-18 16:42:12 +0200838 /* Check if compression is supported */
Jes Sorenseneec77d92010-12-07 17:44:34 +0100839 if (compress) {
Kevin Wolfefa84d42009-05-18 16:42:12 +0200840 QEMUOptionParameter *encryption =
841 get_option_parameter(param, BLOCK_OPT_ENCRYPT);
Kevin Wolf41521fa2011-10-18 16:19:42 +0200842 QEMUOptionParameter *preallocation =
843 get_option_parameter(param, BLOCK_OPT_PREALLOC);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200844
845 if (!drv->bdrv_write_compressed) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100846 error_report("Compression not supported for this file format");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900847 ret = -1;
848 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200849 }
850
851 if (encryption && encryption->value.n) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100852 error_report("Compression and encryption not supported at "
853 "the same time");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900854 ret = -1;
855 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200856 }
Kevin Wolf41521fa2011-10-18 16:19:42 +0200857
858 if (preallocation && preallocation->value.s
859 && strcmp(preallocation->value.s, "off"))
860 {
861 error_report("Compression and preallocation not supported at "
862 "the same time");
863 ret = -1;
864 goto out;
865 }
Kevin Wolfefa84d42009-05-18 16:42:12 +0200866 }
867
868 /* Create the new image */
869 ret = bdrv_create(drv, out_filename, param);
bellardea2384d2004-08-01 21:59:26 +0000870 if (ret < 0) {
871 if (ret == -ENOTSUP) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100872 error_report("Formatting not supported for file format '%s'",
873 out_fmt);
aurel326e9ea0c2009-04-15 14:42:46 +0000874 } else if (ret == -EFBIG) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100875 error_report("The image size is too large for file format '%s'",
876 out_fmt);
bellardea2384d2004-08-01 21:59:26 +0000877 } else {
Jes Sorensen15654a62010-12-16 14:31:53 +0100878 error_report("%s: error while converting %s: %s",
879 out_filename, out_fmt, strerror(-ret));
bellardea2384d2004-08-01 21:59:26 +0000880 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900881 goto out;
bellardea2384d2004-08-01 21:59:26 +0000882 }
ths3b46e622007-09-17 08:09:54 +0000883
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400884 flags = BDRV_O_RDWR;
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +0100885 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400886 if (ret < 0) {
887 error_report("Invalid cache option: %s", cache);
888 return -1;
889 }
890
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +0100891 out_bs = bdrv_new_open(out_filename, out_fmt, flags, true);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900892 if (!out_bs) {
893 ret = -1;
894 goto out;
895 }
bellardea2384d2004-08-01 21:59:26 +0000896
balrog926c2d22007-10-31 01:11:44 +0000897 bs_i = 0;
898 bs_offset = 0;
899 bdrv_get_geometry(bs[0], &bs_sectors);
Kevin Wolfbb1c0592011-08-08 14:09:12 +0200900 buf = qemu_blockalign(out_bs, IO_BUF_SIZE);
balrog926c2d22007-10-31 01:11:44 +0000901
Jes Sorenseneec77d92010-12-07 17:44:34 +0100902 if (compress) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900903 ret = bdrv_get_info(out_bs, &bdi);
904 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100905 error_report("could not get block driver info");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900906 goto out;
907 }
bellardfaea38e2006-08-05 21:31:00 +0000908 cluster_size = bdi.cluster_size;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900909 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100910 error_report("invalid cluster size");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900911 ret = -1;
912 goto out;
913 }
bellardea2384d2004-08-01 21:59:26 +0000914 cluster_sectors = cluster_size >> 9;
915 sector_num = 0;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200916
917 nb_sectors = total_sectors;
Kevin Wolf1f710492012-10-12 14:29:18 +0200918 if (nb_sectors != 0) {
919 local_progress = (float)100 /
920 (nb_sectors / MIN(nb_sectors, cluster_sectors));
921 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200922
bellardea2384d2004-08-01 21:59:26 +0000923 for(;;) {
balrog926c2d22007-10-31 01:11:44 +0000924 int64_t bs_num;
925 int remainder;
926 uint8_t *buf2;
927
bellardea2384d2004-08-01 21:59:26 +0000928 nb_sectors = total_sectors - sector_num;
929 if (nb_sectors <= 0)
930 break;
931 if (nb_sectors >= cluster_sectors)
932 n = cluster_sectors;
933 else
934 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000935
936 bs_num = sector_num - bs_offset;
937 assert (bs_num >= 0);
938 remainder = n;
939 buf2 = buf;
940 while (remainder > 0) {
941 int nlow;
942 while (bs_num == bs_sectors) {
943 bs_i++;
944 assert (bs_i < bs_n);
945 bs_offset += bs_sectors;
946 bdrv_get_geometry(bs[bs_i], &bs_sectors);
947 bs_num = 0;
Blue Swirl0bfcd592010-05-22 08:02:12 +0000948 /* printf("changing part: sector_num=%" PRId64 ", "
949 "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64
950 "\n", sector_num, bs_i, bs_offset, bs_sectors); */
balrog926c2d22007-10-31 01:11:44 +0000951 }
952 assert (bs_num < bs_sectors);
953
954 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
955
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900956 ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
957 if (ret < 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +0100958 error_report("error while reading sector %" PRId64 ": %s",
959 bs_num, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900960 goto out;
961 }
balrog926c2d22007-10-31 01:11:44 +0000962
963 buf2 += nlow * 512;
964 bs_num += nlow;
965
966 remainder -= nlow;
967 }
968 assert (remainder == 0);
969
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100970 if (n < cluster_sectors) {
bellardea2384d2004-08-01 21:59:26 +0000971 memset(buf + n * 512, 0, cluster_size - n * 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100972 }
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000973 if (!buffer_is_zero(buf, cluster_size)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900974 ret = bdrv_write_compressed(out_bs, sector_num, buf,
975 cluster_sectors);
976 if (ret != 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +0100977 error_report("error while compressing sector %" PRId64
978 ": %s", sector_num, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900979 goto out;
980 }
bellardea2384d2004-08-01 21:59:26 +0000981 }
982 sector_num += n;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200983 qemu_progress_print(local_progress, 100);
bellardea2384d2004-08-01 21:59:26 +0000984 }
bellardfaea38e2006-08-05 21:31:00 +0000985 /* signal EOF to align */
986 bdrv_write_compressed(out_bs, 0, NULL, 0);
bellardea2384d2004-08-01 21:59:26 +0000987 } else {
Kevin Wolff2feebb2010-04-14 17:30:35 +0200988 int has_zero_init = bdrv_has_zero_init(out_bs);
989
thsf58c7b32008-06-05 21:53:49 +0000990 sector_num = 0; // total number of sectors converted so far
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200991 nb_sectors = total_sectors - sector_num;
Kevin Wolf1f710492012-10-12 14:29:18 +0200992 if (nb_sectors != 0) {
993 local_progress = (float)100 /
994 (nb_sectors / MIN(nb_sectors, IO_BUF_SIZE / 512));
995 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200996
bellardea2384d2004-08-01 21:59:26 +0000997 for(;;) {
998 nb_sectors = total_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100999 if (nb_sectors <= 0) {
bellardea2384d2004-08-01 21:59:26 +00001000 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001001 }
1002 if (nb_sectors >= (IO_BUF_SIZE / 512)) {
bellardea2384d2004-08-01 21:59:26 +00001003 n = (IO_BUF_SIZE / 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001004 } else {
bellardea2384d2004-08-01 21:59:26 +00001005 n = nb_sectors;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001006 }
balrog926c2d22007-10-31 01:11:44 +00001007
1008 while (sector_num - bs_offset >= bs_sectors) {
1009 bs_i ++;
1010 assert (bs_i < bs_n);
1011 bs_offset += bs_sectors;
1012 bdrv_get_geometry(bs[bs_i], &bs_sectors);
Blue Swirl0bfcd592010-05-22 08:02:12 +00001013 /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "
1014 "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",
balrog926c2d22007-10-31 01:11:44 +00001015 sector_num, bs_i, bs_offset, bs_sectors); */
1016 }
1017
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001018 if (n > bs_offset + bs_sectors - sector_num) {
balrog926c2d22007-10-31 01:11:44 +00001019 n = bs_offset + bs_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001020 }
balrog926c2d22007-10-31 01:11:44 +00001021
Kevin Wolff2feebb2010-04-14 17:30:35 +02001022 if (has_zero_init) {
Akkarit Sangpetchd0320442009-07-17 10:02:15 +02001023 /* If the output image is being created as a copy on write image,
1024 assume that sectors which are unallocated in the input image
1025 are present in both the output's and input's base images (no
1026 need to copy them). */
1027 if (out_baseimg) {
1028 if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
1029 n, &n1)) {
1030 sector_num += n1;
1031 continue;
1032 }
1033 /* The next 'n1' sectors are allocated in the input image. Copy
1034 only those as they may be followed by unallocated sectors. */
1035 n = n1;
aliguori93c65b42009-04-05 17:40:43 +00001036 }
aliguori93c65b42009-04-05 17:40:43 +00001037 } else {
1038 n1 = n;
thsf58c7b32008-06-05 21:53:49 +00001039 }
1040
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001041 ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
1042 if (ret < 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +01001043 error_report("error while reading sector %" PRId64 ": %s",
1044 sector_num - bs_offset, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001045 goto out;
1046 }
bellardea2384d2004-08-01 21:59:26 +00001047 /* NOTE: at the same time we convert, we do not write zero
1048 sectors to have a chance to compress the image. Ideally, we
1049 should add a specific call to have the info to go faster */
1050 buf1 = buf;
1051 while (n > 0) {
thsf58c7b32008-06-05 21:53:49 +00001052 /* If the output image is being created as a copy on write image,
1053 copy all sectors even the ones containing only NUL bytes,
aliguori93c65b42009-04-05 17:40:43 +00001054 because they may differ from the sectors in the base image.
1055
1056 If the output is to a host device, we also write out
1057 sectors that are entirely 0, since whatever data was
1058 already there is garbage, not 0s. */
Kevin Wolff2feebb2010-04-14 17:30:35 +02001059 if (!has_zero_init || out_baseimg ||
Kevin Wolfa22f1232011-08-26 15:27:13 +02001060 is_allocated_sectors_min(buf1, n, &n1, min_sparse)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001061 ret = bdrv_write(out_bs, sector_num, buf1, n1);
1062 if (ret < 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +01001063 error_report("error while writing sector %" PRId64
1064 ": %s", sector_num, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001065 goto out;
1066 }
bellardea2384d2004-08-01 21:59:26 +00001067 }
1068 sector_num += n1;
1069 n -= n1;
1070 buf1 += n1 * 512;
1071 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001072 qemu_progress_print(local_progress, 100);
bellardea2384d2004-08-01 21:59:26 +00001073 }
1074 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001075out:
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001076 qemu_progress_end();
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001077 free_option_parameters(create_options);
1078 free_option_parameters(param);
Kevin Wolfbb1c0592011-08-08 14:09:12 +02001079 qemu_vfree(buf);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001080 if (out_bs) {
1081 bdrv_delete(out_bs);
1082 }
Jes Sorensen31ca34b2010-12-06 15:25:36 +01001083 if (bs) {
1084 for (bs_i = 0; bs_i < bs_n; bs_i++) {
1085 if (bs[bs_i]) {
1086 bdrv_delete(bs[bs_i]);
1087 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001088 }
Anthony Liguori7267c092011-08-20 22:09:37 -05001089 g_free(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001090 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001091 if (ret) {
1092 return 1;
1093 }
bellardea2384d2004-08-01 21:59:26 +00001094 return 0;
1095}
1096
bellard57d1a2b2004-08-03 21:15:11 +00001097
bellardfaea38e2006-08-05 21:31:00 +00001098static void dump_snapshots(BlockDriverState *bs)
1099{
1100 QEMUSnapshotInfo *sn_tab, *sn;
1101 int nb_sns, i;
1102 char buf[256];
1103
1104 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1105 if (nb_sns <= 0)
1106 return;
1107 printf("Snapshot list:\n");
1108 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
1109 for(i = 0; i < nb_sns; i++) {
1110 sn = &sn_tab[i];
1111 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
1112 }
Anthony Liguori7267c092011-08-20 22:09:37 -05001113 g_free(sn_tab);
bellardfaea38e2006-08-05 21:31:00 +00001114}
1115
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001116static void dump_json_image_info_list(ImageInfoList *list)
1117{
1118 Error *errp = NULL;
1119 QString *str;
1120 QmpOutputVisitor *ov = qmp_output_visitor_new();
1121 QObject *obj;
1122 visit_type_ImageInfoList(qmp_output_get_visitor(ov),
1123 &list, NULL, &errp);
1124 obj = qmp_output_get_qobject(ov);
1125 str = qobject_to_json_pretty(obj);
1126 assert(str != NULL);
1127 printf("%s\n", qstring_get_str(str));
1128 qobject_decref(obj);
1129 qmp_output_visitor_cleanup(ov);
1130 QDECREF(str);
1131}
1132
Benoît Canetc054b3f2012-09-05 13:09:02 +02001133static void collect_snapshots(BlockDriverState *bs , ImageInfo *info)
bellardea2384d2004-08-01 21:59:26 +00001134{
Benoît Canetc054b3f2012-09-05 13:09:02 +02001135 int i, sn_count;
1136 QEMUSnapshotInfo *sn_tab = NULL;
1137 SnapshotInfoList *info_list, *cur_item = NULL;
1138 sn_count = bdrv_snapshot_list(bs, &sn_tab);
1139
1140 for (i = 0; i < sn_count; i++) {
1141 info->has_snapshots = true;
1142 info_list = g_new0(SnapshotInfoList, 1);
1143
1144 info_list->value = g_new0(SnapshotInfo, 1);
1145 info_list->value->id = g_strdup(sn_tab[i].id_str);
1146 info_list->value->name = g_strdup(sn_tab[i].name);
1147 info_list->value->vm_state_size = sn_tab[i].vm_state_size;
1148 info_list->value->date_sec = sn_tab[i].date_sec;
1149 info_list->value->date_nsec = sn_tab[i].date_nsec;
1150 info_list->value->vm_clock_sec = sn_tab[i].vm_clock_nsec / 1000000000;
1151 info_list->value->vm_clock_nsec = sn_tab[i].vm_clock_nsec % 1000000000;
1152
1153 /* XXX: waiting for the qapi to support qemu-queue.h types */
1154 if (!cur_item) {
1155 info->snapshots = cur_item = info_list;
1156 } else {
1157 cur_item->next = info_list;
1158 cur_item = info_list;
1159 }
1160
1161 }
1162
1163 g_free(sn_tab);
1164}
1165
1166static void dump_json_image_info(ImageInfo *info)
1167{
1168 Error *errp = NULL;
1169 QString *str;
1170 QmpOutputVisitor *ov = qmp_output_visitor_new();
1171 QObject *obj;
1172 visit_type_ImageInfo(qmp_output_get_visitor(ov),
1173 &info, NULL, &errp);
1174 obj = qmp_output_get_qobject(ov);
1175 str = qobject_to_json_pretty(obj);
1176 assert(str != NULL);
1177 printf("%s\n", qstring_get_str(str));
1178 qobject_decref(obj);
1179 qmp_output_visitor_cleanup(ov);
1180 QDECREF(str);
1181}
1182
1183static void collect_image_info(BlockDriverState *bs,
1184 ImageInfo *info,
1185 const char *filename,
1186 const char *fmt)
1187{
ths96b8f132007-12-17 01:35:20 +00001188 uint64_t total_sectors;
bellard93b6b2a2006-08-01 15:51:11 +00001189 char backing_filename[1024];
1190 char backing_filename2[1024];
bellardfaea38e2006-08-05 21:31:00 +00001191 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +00001192
Benoît Canetc054b3f2012-09-05 13:09:02 +02001193 bdrv_get_geometry(bs, &total_sectors);
1194
1195 info->filename = g_strdup(filename);
1196 info->format = g_strdup(bdrv_get_format_name(bs));
1197 info->virtual_size = total_sectors * 512;
1198 info->actual_size = bdrv_get_allocated_file_size(bs);
1199 info->has_actual_size = info->actual_size >= 0;
1200 if (bdrv_is_encrypted(bs)) {
1201 info->encrypted = true;
1202 info->has_encrypted = true;
1203 }
1204 if (bdrv_get_info(bs, &bdi) >= 0) {
1205 if (bdi.cluster_size != 0) {
1206 info->cluster_size = bdi.cluster_size;
1207 info->has_cluster_size = true;
1208 }
1209 info->dirty_flag = bdi.is_dirty;
1210 info->has_dirty_flag = true;
1211 }
1212 bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
1213 if (backing_filename[0] != '\0') {
1214 info->backing_filename = g_strdup(backing_filename);
1215 info->has_backing_filename = true;
1216 bdrv_get_full_backing_filename(bs, backing_filename2,
1217 sizeof(backing_filename2));
1218
1219 if (strcmp(backing_filename, backing_filename2) != 0) {
1220 info->full_backing_filename =
1221 g_strdup(backing_filename2);
1222 info->has_full_backing_filename = true;
1223 }
1224
1225 if (bs->backing_format[0]) {
1226 info->backing_filename_format = g_strdup(bs->backing_format);
1227 info->has_backing_filename_format = true;
1228 }
1229 }
1230}
1231
1232static void dump_human_image_info(ImageInfo *info)
1233{
1234 char size_buf[128], dsize_buf[128];
1235 if (!info->has_actual_size) {
1236 snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
1237 } else {
1238 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
1239 info->actual_size);
1240 }
1241 get_human_readable_size(size_buf, sizeof(size_buf), info->virtual_size);
1242 printf("image: %s\n"
1243 "file format: %s\n"
1244 "virtual size: %s (%" PRId64 " bytes)\n"
1245 "disk size: %s\n",
1246 info->filename, info->format, size_buf,
1247 info->virtual_size,
1248 dsize_buf);
1249
1250 if (info->has_encrypted && info->encrypted) {
1251 printf("encrypted: yes\n");
1252 }
1253
1254 if (info->has_cluster_size) {
1255 printf("cluster_size: %" PRId64 "\n", info->cluster_size);
1256 }
1257
1258 if (info->has_dirty_flag && info->dirty_flag) {
1259 printf("cleanly shut down: no\n");
1260 }
1261
1262 if (info->has_backing_filename) {
1263 printf("backing file: %s", info->backing_filename);
1264 if (info->has_full_backing_filename) {
1265 printf(" (actual path: %s)", info->full_backing_filename);
1266 }
1267 putchar('\n');
1268 if (info->has_backing_filename_format) {
1269 printf("backing file format: %s\n", info->backing_filename_format);
1270 }
1271 }
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001272
1273 if (info->has_snapshots) {
1274 SnapshotInfoList *elem;
1275 char buf[256];
1276
1277 printf("Snapshot list:\n");
1278 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
1279
1280 /* Ideally bdrv_snapshot_dump() would operate on SnapshotInfoList but
1281 * we convert to the block layer's native QEMUSnapshotInfo for now.
1282 */
1283 for (elem = info->snapshots; elem; elem = elem->next) {
1284 QEMUSnapshotInfo sn = {
1285 .vm_state_size = elem->value->vm_state_size,
1286 .date_sec = elem->value->date_sec,
1287 .date_nsec = elem->value->date_nsec,
1288 .vm_clock_nsec = elem->value->vm_clock_sec * 1000000000ULL +
1289 elem->value->vm_clock_nsec,
1290 };
1291
1292 pstrcpy(sn.id_str, sizeof(sn.id_str), elem->value->id);
1293 pstrcpy(sn.name, sizeof(sn.name), elem->value->name);
1294 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), &sn));
1295 }
1296 }
Benoît Canetc054b3f2012-09-05 13:09:02 +02001297}
1298
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001299static void dump_human_image_info_list(ImageInfoList *list)
1300{
1301 ImageInfoList *elem;
1302 bool delim = false;
1303
1304 for (elem = list; elem; elem = elem->next) {
1305 if (delim) {
1306 printf("\n");
1307 }
1308 delim = true;
1309
1310 dump_human_image_info(elem->value);
1311 }
1312}
1313
1314static gboolean str_equal_func(gconstpointer a, gconstpointer b)
1315{
1316 return strcmp(a, b) == 0;
1317}
1318
1319/**
1320 * Open an image file chain and return an ImageInfoList
1321 *
1322 * @filename: topmost image filename
1323 * @fmt: topmost image format (may be NULL to autodetect)
1324 * @chain: true - enumerate entire backing file chain
1325 * false - only topmost image file
1326 *
1327 * Returns a list of ImageInfo objects or NULL if there was an error opening an
1328 * image file. If there was an error a message will have been printed to
1329 * stderr.
1330 */
1331static ImageInfoList *collect_image_info_list(const char *filename,
1332 const char *fmt,
1333 bool chain)
1334{
1335 ImageInfoList *head = NULL;
1336 ImageInfoList **last = &head;
1337 GHashTable *filenames;
1338
1339 filenames = g_hash_table_new_full(g_str_hash, str_equal_func, NULL, NULL);
1340
1341 while (filename) {
1342 BlockDriverState *bs;
1343 ImageInfo *info;
1344 ImageInfoList *elem;
1345
1346 if (g_hash_table_lookup_extended(filenames, filename, NULL, NULL)) {
1347 error_report("Backing file '%s' creates an infinite loop.",
1348 filename);
1349 goto err;
1350 }
1351 g_hash_table_insert(filenames, (gpointer)filename, NULL);
1352
1353 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING,
1354 false);
1355 if (!bs) {
1356 goto err;
1357 }
1358
1359 info = g_new0(ImageInfo, 1);
1360 collect_image_info(bs, info, filename, fmt);
1361 collect_snapshots(bs, info);
1362
1363 elem = g_new0(ImageInfoList, 1);
1364 elem->value = info;
1365 *last = elem;
1366 last = &elem->next;
1367
1368 bdrv_delete(bs);
1369
1370 filename = fmt = NULL;
1371 if (chain) {
1372 if (info->has_full_backing_filename) {
1373 filename = info->full_backing_filename;
1374 } else if (info->has_backing_filename) {
1375 filename = info->backing_filename;
1376 }
1377 if (info->has_backing_filename_format) {
1378 fmt = info->backing_filename_format;
1379 }
1380 }
1381 }
1382 g_hash_table_destroy(filenames);
1383 return head;
1384
1385err:
1386 qapi_free_ImageInfoList(head);
1387 g_hash_table_destroy(filenames);
1388 return NULL;
1389}
1390
1391enum {
1392 OPTION_OUTPUT = 256,
1393 OPTION_BACKING_CHAIN = 257,
1394};
Benoît Canetc054b3f2012-09-05 13:09:02 +02001395
1396typedef enum OutputFormat {
1397 OFORMAT_JSON,
1398 OFORMAT_HUMAN,
1399} OutputFormat;
1400
1401static int img_info(int argc, char **argv)
1402{
1403 int c;
1404 OutputFormat output_format = OFORMAT_HUMAN;
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001405 bool chain = false;
Benoît Canetc054b3f2012-09-05 13:09:02 +02001406 const char *filename, *fmt, *output;
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001407 ImageInfoList *list;
Benoît Canetc054b3f2012-09-05 13:09:02 +02001408
bellardea2384d2004-08-01 21:59:26 +00001409 fmt = NULL;
Benoît Canetc054b3f2012-09-05 13:09:02 +02001410 output = NULL;
bellardea2384d2004-08-01 21:59:26 +00001411 for(;;) {
Benoît Canetc054b3f2012-09-05 13:09:02 +02001412 int option_index = 0;
1413 static const struct option long_options[] = {
1414 {"help", no_argument, 0, 'h'},
1415 {"format", required_argument, 0, 'f'},
1416 {"output", required_argument, 0, OPTION_OUTPUT},
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001417 {"backing-chain", no_argument, 0, OPTION_BACKING_CHAIN},
Benoît Canetc054b3f2012-09-05 13:09:02 +02001418 {0, 0, 0, 0}
1419 };
1420 c = getopt_long(argc, argv, "f:h",
1421 long_options, &option_index);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001422 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +00001423 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001424 }
bellardea2384d2004-08-01 21:59:26 +00001425 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001426 case '?':
bellardea2384d2004-08-01 21:59:26 +00001427 case 'h':
1428 help();
1429 break;
1430 case 'f':
1431 fmt = optarg;
1432 break;
Benoît Canetc054b3f2012-09-05 13:09:02 +02001433 case OPTION_OUTPUT:
1434 output = optarg;
1435 break;
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001436 case OPTION_BACKING_CHAIN:
1437 chain = true;
1438 break;
bellardea2384d2004-08-01 21:59:26 +00001439 }
1440 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001441 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +00001442 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001443 }
bellardea2384d2004-08-01 21:59:26 +00001444 filename = argv[optind++];
1445
Benoît Canetc054b3f2012-09-05 13:09:02 +02001446 if (output && !strcmp(output, "json")) {
1447 output_format = OFORMAT_JSON;
1448 } else if (output && !strcmp(output, "human")) {
1449 output_format = OFORMAT_HUMAN;
1450 } else if (output) {
1451 error_report("--output must be used with human or json as argument.");
1452 return 1;
1453 }
1454
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001455 list = collect_image_info_list(filename, fmt, chain);
1456 if (!list) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001457 return 1;
1458 }
Benoît Canetc054b3f2012-09-05 13:09:02 +02001459
Benoît Canetc054b3f2012-09-05 13:09:02 +02001460 switch (output_format) {
1461 case OFORMAT_HUMAN:
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001462 dump_human_image_info_list(list);
Benoît Canetc054b3f2012-09-05 13:09:02 +02001463 break;
1464 case OFORMAT_JSON:
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001465 if (chain) {
1466 dump_json_image_info_list(list);
1467 } else {
1468 dump_json_image_info(list->value);
1469 }
Benoît Canetc054b3f2012-09-05 13:09:02 +02001470 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001471 }
Benoît Canetc054b3f2012-09-05 13:09:02 +02001472
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001473 qapi_free_ImageInfoList(list);
bellardea2384d2004-08-01 21:59:26 +00001474 return 0;
1475}
1476
aliguorif7b4a942009-01-07 17:40:15 +00001477#define SNAPSHOT_LIST 1
1478#define SNAPSHOT_CREATE 2
1479#define SNAPSHOT_APPLY 3
1480#define SNAPSHOT_DELETE 4
1481
Stuart Brady153859b2009-06-07 00:42:17 +01001482static int img_snapshot(int argc, char **argv)
aliguorif7b4a942009-01-07 17:40:15 +00001483{
1484 BlockDriverState *bs;
1485 QEMUSnapshotInfo sn;
1486 char *filename, *snapshot_name = NULL;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001487 int c, ret = 0, bdrv_oflags;
aliguorif7b4a942009-01-07 17:40:15 +00001488 int action = 0;
1489 qemu_timeval tv;
1490
Kevin Wolf710da702011-01-10 12:33:02 +01001491 bdrv_oflags = BDRV_O_FLAGS | BDRV_O_RDWR;
aliguorif7b4a942009-01-07 17:40:15 +00001492 /* Parse commandline parameters */
1493 for(;;) {
1494 c = getopt(argc, argv, "la:c:d:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001495 if (c == -1) {
aliguorif7b4a942009-01-07 17:40:15 +00001496 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001497 }
aliguorif7b4a942009-01-07 17:40:15 +00001498 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001499 case '?':
aliguorif7b4a942009-01-07 17:40:15 +00001500 case 'h':
1501 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001502 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001503 case 'l':
1504 if (action) {
1505 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001506 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001507 }
1508 action = SNAPSHOT_LIST;
Naphtali Spreif5edb012010-01-17 16:48:13 +02001509 bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
aliguorif7b4a942009-01-07 17:40:15 +00001510 break;
1511 case 'a':
1512 if (action) {
1513 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001514 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001515 }
1516 action = SNAPSHOT_APPLY;
1517 snapshot_name = optarg;
1518 break;
1519 case 'c':
1520 if (action) {
1521 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001522 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001523 }
1524 action = SNAPSHOT_CREATE;
1525 snapshot_name = optarg;
1526 break;
1527 case 'd':
1528 if (action) {
1529 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001530 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001531 }
1532 action = SNAPSHOT_DELETE;
1533 snapshot_name = optarg;
1534 break;
1535 }
1536 }
1537
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001538 if (optind >= argc) {
aliguorif7b4a942009-01-07 17:40:15 +00001539 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001540 }
aliguorif7b4a942009-01-07 17:40:15 +00001541 filename = argv[optind++];
1542
1543 /* Open the image */
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +01001544 bs = bdrv_new_open(filename, NULL, bdrv_oflags, true);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001545 if (!bs) {
1546 return 1;
1547 }
aliguorif7b4a942009-01-07 17:40:15 +00001548
1549 /* Perform the requested action */
1550 switch(action) {
1551 case SNAPSHOT_LIST:
1552 dump_snapshots(bs);
1553 break;
1554
1555 case SNAPSHOT_CREATE:
1556 memset(&sn, 0, sizeof(sn));
1557 pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
1558
1559 qemu_gettimeofday(&tv);
1560 sn.date_sec = tv.tv_sec;
1561 sn.date_nsec = tv.tv_usec * 1000;
1562
1563 ret = bdrv_snapshot_create(bs, &sn);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001564 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001565 error_report("Could not create snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001566 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001567 }
aliguorif7b4a942009-01-07 17:40:15 +00001568 break;
1569
1570 case SNAPSHOT_APPLY:
1571 ret = bdrv_snapshot_goto(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001572 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001573 error_report("Could not apply snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001574 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001575 }
aliguorif7b4a942009-01-07 17:40:15 +00001576 break;
1577
1578 case SNAPSHOT_DELETE:
1579 ret = bdrv_snapshot_delete(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001580 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001581 error_report("Could not delete snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001582 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001583 }
aliguorif7b4a942009-01-07 17:40:15 +00001584 break;
1585 }
1586
1587 /* Cleanup */
1588 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001589 if (ret) {
1590 return 1;
1591 }
Stuart Brady153859b2009-06-07 00:42:17 +01001592 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001593}
1594
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001595static int img_rebase(int argc, char **argv)
1596{
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001597 BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001598 BlockDriver *old_backing_drv, *new_backing_drv;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001599 char *filename;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001600 const char *fmt, *cache, *out_basefmt, *out_baseimg;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001601 int c, flags, ret;
1602 int unsafe = 0;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001603 int progress = 0;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001604
1605 /* Parse commandline parameters */
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001606 fmt = NULL;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001607 cache = BDRV_DEFAULT_CACHE;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001608 out_baseimg = NULL;
1609 out_basefmt = NULL;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001610 for(;;) {
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001611 c = getopt(argc, argv, "uhf:F:b:pt:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001612 if (c == -1) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001613 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001614 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001615 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001616 case '?':
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001617 case 'h':
1618 help();
1619 return 0;
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001620 case 'f':
1621 fmt = optarg;
1622 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001623 case 'F':
1624 out_basefmt = optarg;
1625 break;
1626 case 'b':
1627 out_baseimg = optarg;
1628 break;
1629 case 'u':
1630 unsafe = 1;
1631 break;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001632 case 'p':
1633 progress = 1;
1634 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001635 case 't':
1636 cache = optarg;
1637 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001638 }
1639 }
1640
Anthony Liguori9a9d9db2011-04-13 15:51:47 +01001641 if ((optind >= argc) || (!unsafe && !out_baseimg)) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001642 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001643 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001644 filename = argv[optind++];
1645
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001646 qemu_progress_init(progress, 2.0);
1647 qemu_progress_print(0, 100);
1648
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001649 flags = BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +01001650 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001651 if (ret < 0) {
1652 error_report("Invalid cache option: %s", cache);
1653 return -1;
1654 }
1655
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001656 /*
1657 * Open the images.
1658 *
1659 * Ignore the old backing file for unsafe rebase in case we want to correct
1660 * the reference to a renamed or moved backing file.
1661 */
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +01001662 bs = bdrv_new_open(filename, fmt, flags, true);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001663 if (!bs) {
1664 return 1;
1665 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001666
1667 /* Find the right drivers for the backing files */
1668 old_backing_drv = NULL;
1669 new_backing_drv = NULL;
1670
1671 if (!unsafe && bs->backing_format[0] != '\0') {
1672 old_backing_drv = bdrv_find_format(bs->backing_format);
1673 if (old_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001674 error_report("Invalid format name: '%s'", bs->backing_format);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001675 ret = -1;
1676 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001677 }
1678 }
1679
1680 if (out_basefmt != NULL) {
1681 new_backing_drv = bdrv_find_format(out_basefmt);
1682 if (new_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001683 error_report("Invalid format name: '%s'", out_basefmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001684 ret = -1;
1685 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001686 }
1687 }
1688
1689 /* For safe rebasing we need to compare old and new backing file */
1690 if (unsafe) {
1691 /* Make the compiler happy */
1692 bs_old_backing = NULL;
1693 bs_new_backing = NULL;
1694 } else {
1695 char backing_name[1024];
1696
1697 bs_old_backing = bdrv_new("old_backing");
1698 bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001699 ret = bdrv_open(bs_old_backing, backing_name, BDRV_O_FLAGS,
1700 old_backing_drv);
1701 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001702 error_report("Could not open old backing file '%s'", backing_name);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001703 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001704 }
Alex Bligha6166732012-10-16 13:46:18 +01001705 if (out_baseimg[0]) {
1706 bs_new_backing = bdrv_new("new_backing");
1707 ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS,
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001708 new_backing_drv);
Alex Bligha6166732012-10-16 13:46:18 +01001709 if (ret) {
1710 error_report("Could not open new backing file '%s'",
1711 out_baseimg);
1712 goto out;
1713 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001714 }
1715 }
1716
1717 /*
1718 * Check each unallocated cluster in the COW file. If it is unallocated,
1719 * accesses go to the backing file. We must therefore compare this cluster
1720 * in the old and new backing file, and if they differ we need to copy it
1721 * from the old backing file into the COW file.
1722 *
1723 * If qemu-img crashes during this step, no harm is done. The content of
1724 * the image is the same as the original one at any time.
1725 */
1726 if (!unsafe) {
1727 uint64_t num_sectors;
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01001728 uint64_t old_backing_num_sectors;
Alex Bligha6166732012-10-16 13:46:18 +01001729 uint64_t new_backing_num_sectors = 0;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001730 uint64_t sector;
Kevin Wolfcc60e322010-04-29 14:47:48 +02001731 int n;
TeLeMand6771bf2010-02-08 16:20:00 +08001732 uint8_t * buf_old;
1733 uint8_t * buf_new;
Kevin Wolf1f710492012-10-12 14:29:18 +02001734 float local_progress = 0;
TeLeMand6771bf2010-02-08 16:20:00 +08001735
Kevin Wolfbb1c0592011-08-08 14:09:12 +02001736 buf_old = qemu_blockalign(bs, IO_BUF_SIZE);
1737 buf_new = qemu_blockalign(bs, IO_BUF_SIZE);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001738
1739 bdrv_get_geometry(bs, &num_sectors);
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01001740 bdrv_get_geometry(bs_old_backing, &old_backing_num_sectors);
Alex Bligha6166732012-10-16 13:46:18 +01001741 if (bs_new_backing) {
1742 bdrv_get_geometry(bs_new_backing, &new_backing_num_sectors);
1743 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001744
Kevin Wolf1f710492012-10-12 14:29:18 +02001745 if (num_sectors != 0) {
1746 local_progress = (float)100 /
1747 (num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512));
1748 }
1749
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001750 for (sector = 0; sector < num_sectors; sector += n) {
1751
1752 /* How many sectors can we handle with the next read? */
1753 if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
1754 n = (IO_BUF_SIZE / 512);
1755 } else {
1756 n = num_sectors - sector;
1757 }
1758
1759 /* If the cluster is allocated, we don't need to take action */
Kevin Wolfcc60e322010-04-29 14:47:48 +02001760 ret = bdrv_is_allocated(bs, sector, n, &n);
1761 if (ret) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001762 continue;
1763 }
1764
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01001765 /*
1766 * Read old and new backing file and take into consideration that
1767 * backing files may be smaller than the COW image.
1768 */
1769 if (sector >= old_backing_num_sectors) {
1770 memset(buf_old, 0, n * BDRV_SECTOR_SIZE);
1771 } else {
1772 if (sector + n > old_backing_num_sectors) {
1773 n = old_backing_num_sectors - sector;
1774 }
1775
1776 ret = bdrv_read(bs_old_backing, sector, buf_old, n);
1777 if (ret < 0) {
1778 error_report("error while reading from old backing file");
1779 goto out;
1780 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001781 }
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01001782
Alex Bligha6166732012-10-16 13:46:18 +01001783 if (sector >= new_backing_num_sectors || !bs_new_backing) {
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01001784 memset(buf_new, 0, n * BDRV_SECTOR_SIZE);
1785 } else {
1786 if (sector + n > new_backing_num_sectors) {
1787 n = new_backing_num_sectors - sector;
1788 }
1789
1790 ret = bdrv_read(bs_new_backing, sector, buf_new, n);
1791 if (ret < 0) {
1792 error_report("error while reading from new backing file");
1793 goto out;
1794 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001795 }
1796
1797 /* If they differ, we need to write to the COW file */
1798 uint64_t written = 0;
1799
1800 while (written < n) {
1801 int pnum;
1802
1803 if (compare_sectors(buf_old + written * 512,
Kevin Wolf60b1bd42010-02-17 12:32:59 +01001804 buf_new + written * 512, n - written, &pnum))
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001805 {
1806 ret = bdrv_write(bs, sector + written,
1807 buf_old + written * 512, pnum);
1808 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001809 error_report("Error while writing to COW image: %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001810 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001811 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001812 }
1813 }
1814
1815 written += pnum;
1816 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001817 qemu_progress_print(local_progress, 100);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001818 }
TeLeMand6771bf2010-02-08 16:20:00 +08001819
Kevin Wolfbb1c0592011-08-08 14:09:12 +02001820 qemu_vfree(buf_old);
1821 qemu_vfree(buf_new);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001822 }
1823
1824 /*
1825 * Change the backing file. All clusters that are different from the old
1826 * backing file are overwritten in the COW file now, so the visible content
1827 * doesn't change when we switch the backing file.
1828 */
Alex Bligha6166732012-10-16 13:46:18 +01001829 if (out_baseimg && *out_baseimg) {
1830 ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
1831 } else {
1832 ret = bdrv_change_backing_file(bs, NULL, NULL);
1833 }
1834
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001835 if (ret == -ENOSPC) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001836 error_report("Could not change the backing file to '%s': No "
1837 "space left in the file header", out_baseimg);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001838 } else if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001839 error_report("Could not change the backing file to '%s': %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001840 out_baseimg, strerror(-ret));
1841 }
1842
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001843 qemu_progress_print(100, 0);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001844 /*
1845 * TODO At this point it is possible to check if any clusters that are
1846 * allocated in the COW file are the same in the backing file. If so, they
1847 * could be dropped from the COW file. Don't do this before switching the
1848 * backing file, in case of a crash this would lead to corruption.
1849 */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001850out:
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001851 qemu_progress_end();
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001852 /* Cleanup */
1853 if (!unsafe) {
Kevin Wolfeb863ad2011-03-31 12:39:51 +02001854 if (bs_old_backing != NULL) {
1855 bdrv_delete(bs_old_backing);
1856 }
1857 if (bs_new_backing != NULL) {
1858 bdrv_delete(bs_new_backing);
1859 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001860 }
1861
1862 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001863 if (ret) {
1864 return 1;
1865 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001866 return 0;
1867}
1868
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001869static int img_resize(int argc, char **argv)
1870{
1871 int c, ret, relative;
1872 const char *filename, *fmt, *size;
1873 int64_t n, total_size;
Jes Sorensen2a819982010-12-06 17:08:31 +01001874 BlockDriverState *bs = NULL;
Dong Xu Wang20caf0f2012-08-06 10:18:42 +08001875 QemuOpts *param;
1876 static QemuOptsList resize_options = {
1877 .name = "resize_options",
1878 .head = QTAILQ_HEAD_INITIALIZER(resize_options.head),
1879 .desc = {
1880 {
1881 .name = BLOCK_OPT_SIZE,
1882 .type = QEMU_OPT_SIZE,
1883 .help = "Virtual disk size"
1884 }, {
1885 /* end of list */
1886 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001887 },
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001888 };
1889
Kevin Wolfe80fec72011-04-29 10:58:12 +02001890 /* Remove size from argv manually so that negative numbers are not treated
1891 * as options by getopt. */
1892 if (argc < 3) {
1893 help();
1894 return 1;
1895 }
1896
1897 size = argv[--argc];
1898
1899 /* Parse getopt arguments */
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001900 fmt = NULL;
1901 for(;;) {
1902 c = getopt(argc, argv, "f:h");
1903 if (c == -1) {
1904 break;
1905 }
1906 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001907 case '?':
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001908 case 'h':
1909 help();
1910 break;
1911 case 'f':
1912 fmt = optarg;
1913 break;
1914 }
1915 }
Kevin Wolfe80fec72011-04-29 10:58:12 +02001916 if (optind >= argc) {
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001917 help();
1918 }
1919 filename = argv[optind++];
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001920
1921 /* Choose grow, shrink, or absolute resize mode */
1922 switch (size[0]) {
1923 case '+':
1924 relative = 1;
1925 size++;
1926 break;
1927 case '-':
1928 relative = -1;
1929 size++;
1930 break;
1931 default:
1932 relative = 0;
1933 break;
1934 }
1935
1936 /* Parse size */
Dong Xu Wange478b442012-12-06 14:47:22 +08001937 param = qemu_opts_create_nofail(&resize_options);
Dong Xu Wang20caf0f2012-08-06 10:18:42 +08001938 if (qemu_opt_set(param, BLOCK_OPT_SIZE, size)) {
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001939 /* Error message already printed when size parsing fails */
Jes Sorensen2a819982010-12-06 17:08:31 +01001940 ret = -1;
Dong Xu Wang20caf0f2012-08-06 10:18:42 +08001941 qemu_opts_del(param);
Jes Sorensen2a819982010-12-06 17:08:31 +01001942 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001943 }
Dong Xu Wang20caf0f2012-08-06 10:18:42 +08001944 n = qemu_opt_get_size(param, BLOCK_OPT_SIZE, 0);
1945 qemu_opts_del(param);
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001946
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +01001947 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR, true);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001948 if (!bs) {
Jes Sorensen2a819982010-12-06 17:08:31 +01001949 ret = -1;
1950 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001951 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001952
1953 if (relative) {
1954 total_size = bdrv_getlength(bs) + n * relative;
1955 } else {
1956 total_size = n;
1957 }
1958 if (total_size <= 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001959 error_report("New image size must be positive");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001960 ret = -1;
1961 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001962 }
1963
1964 ret = bdrv_truncate(bs, total_size);
1965 switch (ret) {
1966 case 0:
1967 printf("Image resized.\n");
1968 break;
1969 case -ENOTSUP:
Kevin Wolf259b2172012-03-06 12:44:45 +01001970 error_report("This image does not support resize");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001971 break;
1972 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +01001973 error_report("Image is read-only");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001974 break;
1975 default:
Jes Sorensen15654a62010-12-16 14:31:53 +01001976 error_report("Error resizing image (%d)", -ret);
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001977 break;
1978 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001979out:
Jes Sorensen2a819982010-12-06 17:08:31 +01001980 if (bs) {
1981 bdrv_delete(bs);
1982 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001983 if (ret) {
1984 return 1;
1985 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001986 return 0;
1987}
1988
Anthony Liguoric227f092009-10-01 16:12:16 -05001989static const img_cmd_t img_cmds[] = {
Stuart Brady153859b2009-06-07 00:42:17 +01001990#define DEF(option, callback, arg_string) \
1991 { option, callback },
1992#include "qemu-img-cmds.h"
1993#undef DEF
1994#undef GEN_DOCS
1995 { NULL, NULL, },
1996};
1997
bellardea2384d2004-08-01 21:59:26 +00001998int main(int argc, char **argv)
1999{
Anthony Liguoric227f092009-10-01 16:12:16 -05002000 const img_cmd_t *cmd;
Stuart Brady153859b2009-06-07 00:42:17 +01002001 const char *cmdname;
bellardea2384d2004-08-01 21:59:26 +00002002
Kevin Wolf53f76e52010-12-16 15:10:32 +01002003 error_set_progname(argv[0]);
2004
Paolo Bonzini2592c592012-11-03 18:10:17 +01002005 qemu_init_main_loop();
bellardea2384d2004-08-01 21:59:26 +00002006 bdrv_init();
2007 if (argc < 2)
2008 help();
Stuart Brady153859b2009-06-07 00:42:17 +01002009 cmdname = argv[1];
aurel328f9b1572009-02-09 18:14:31 +00002010 argc--; argv++;
Stuart Brady153859b2009-06-07 00:42:17 +01002011
2012 /* find the command */
2013 for(cmd = img_cmds; cmd->name != NULL; cmd++) {
2014 if (!strcmp(cmdname, cmd->name)) {
2015 return cmd->handler(argc, argv);
2016 }
bellardea2384d2004-08-01 21:59:26 +00002017 }
Stuart Brady153859b2009-06-07 00:42:17 +01002018
2019 /* not found */
2020 help();
bellardea2384d2004-08-01 21:59:26 +00002021 return 0;
2022}