blob: 595b6f513607402278091cd31754d806d6dbccf9 [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"
26#include "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{
Jes Sorenseneec77d92010-12-07 17:44:34 +0100297 int c, ret = 0;
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.");
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100354 ret = -1;
355 goto out;
356 }
357 img_size = (uint64_t)sval;
358 }
359
Peter Maydellc8057f92012-08-02 13:45:54 +0100360 if (options && is_help_option(options)) {
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100361 ret = print_block_option_help(filename, fmt);
362 goto out;
363 }
364
Luiz Capitulino9b375252012-11-30 10:52:05 -0200365 bdrv_img_create(filename, fmt, base_filename, base_fmt,
366 options, img_size, BDRV_O_FLAGS, &local_err);
367 if (error_is_set(&local_err)) {
368 error_report("%s", error_get_pretty(local_err));
369 error_free(local_err);
370 ret = -1;
371 }
372
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900373out:
374 if (ret) {
375 return 1;
376 }
bellardea2384d2004-08-01 21:59:26 +0000377 return 0;
378}
379
Kevin Wolfe076f332010-06-29 11:43:13 +0200380/*
381 * Checks an image for consistency. Exit codes:
382 *
383 * 0 - Check completed, image is good
384 * 1 - Check not completed because of internal errors
385 * 2 - Check completed, image is corrupted
386 * 3 - Check completed, image has leaked clusters, but is good otherwise
387 */
aliguori15859692009-04-21 23:11:53 +0000388static int img_check(int argc, char **argv)
389{
390 int c, ret;
391 const char *filename, *fmt;
aliguori15859692009-04-21 23:11:53 +0000392 BlockDriverState *bs;
Kevin Wolfe076f332010-06-29 11:43:13 +0200393 BdrvCheckResult result;
Kevin Wolf4534ff52012-05-11 16:07:02 +0200394 int fix = 0;
Stefan Hajnoczi058f8f12012-08-09 13:05:56 +0100395 int flags = BDRV_O_FLAGS | BDRV_O_CHECK;
aliguori15859692009-04-21 23:11:53 +0000396
397 fmt = NULL;
398 for(;;) {
Kevin Wolf4534ff52012-05-11 16:07:02 +0200399 c = getopt(argc, argv, "f:hr:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100400 if (c == -1) {
aliguori15859692009-04-21 23:11:53 +0000401 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100402 }
aliguori15859692009-04-21 23:11:53 +0000403 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100404 case '?':
aliguori15859692009-04-21 23:11:53 +0000405 case 'h':
406 help();
407 break;
408 case 'f':
409 fmt = optarg;
410 break;
Kevin Wolf4534ff52012-05-11 16:07:02 +0200411 case 'r':
412 flags |= BDRV_O_RDWR;
413
414 if (!strcmp(optarg, "leaks")) {
415 fix = BDRV_FIX_LEAKS;
416 } else if (!strcmp(optarg, "all")) {
417 fix = BDRV_FIX_LEAKS | BDRV_FIX_ERRORS;
418 } else {
419 help();
420 }
421 break;
aliguori15859692009-04-21 23:11:53 +0000422 }
423 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100424 if (optind >= argc) {
aliguori15859692009-04-21 23:11:53 +0000425 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100426 }
aliguori15859692009-04-21 23:11:53 +0000427 filename = argv[optind++];
428
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +0100429 bs = bdrv_new_open(filename, fmt, flags, true);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900430 if (!bs) {
431 return 1;
432 }
Kevin Wolf4534ff52012-05-11 16:07:02 +0200433 ret = bdrv_check(bs, &result, fix);
Kevin Wolfe076f332010-06-29 11:43:13 +0200434
435 if (ret == -ENOTSUP) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100436 error_report("This image format does not support checks");
Kevin Wolfe076f332010-06-29 11:43:13 +0200437 bdrv_delete(bs);
438 return 1;
439 }
440
Kevin Wolfccf34712012-05-11 18:16:54 +0200441 if (result.corruptions_fixed || result.leaks_fixed) {
442 printf("The following inconsistencies were found and repaired:\n\n"
443 " %d leaked clusters\n"
444 " %d corruptions\n\n"
445 "Double checking the fixed image now...\n",
446 result.leaks_fixed,
447 result.corruptions_fixed);
448 ret = bdrv_check(bs, &result, 0);
449 }
450
Kevin Wolfe076f332010-06-29 11:43:13 +0200451 if (!(result.corruptions || result.leaks || result.check_errors)) {
452 printf("No errors were found on the image.\n");
453 } else {
454 if (result.corruptions) {
455 printf("\n%d errors were found on the image.\n"
456 "Data may be corrupted, or further writes to the image "
457 "may corrupt it.\n",
458 result.corruptions);
aliguori15859692009-04-21 23:11:53 +0000459 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200460
461 if (result.leaks) {
462 printf("\n%d leaked clusters were found on the image.\n"
463 "This means waste of disk space, but no harm to data.\n",
464 result.leaks);
465 }
466
467 if (result.check_errors) {
468 printf("\n%d internal errors have occurred during the check.\n",
469 result.check_errors);
470 }
aliguori15859692009-04-21 23:11:53 +0000471 }
472
Dong Xu Wangf8111c22012-03-15 20:13:31 +0800473 if (result.bfi.total_clusters != 0 && result.bfi.allocated_clusters != 0) {
474 printf("%" PRId64 "/%" PRId64 "= %0.2f%% allocated, %0.2f%% fragmented\n",
475 result.bfi.allocated_clusters, result.bfi.total_clusters,
476 result.bfi.allocated_clusters * 100.0 / result.bfi.total_clusters,
477 result.bfi.fragmented_clusters * 100.0 / result.bfi.allocated_clusters);
478 }
479
aliguori15859692009-04-21 23:11:53 +0000480 bdrv_delete(bs);
Kevin Wolfe076f332010-06-29 11:43:13 +0200481
482 if (ret < 0 || result.check_errors) {
483 printf("\nAn error has occurred during the check: %s\n"
484 "The check is not complete and may have missed error.\n",
485 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900486 return 1;
487 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200488
489 if (result.corruptions) {
490 return 2;
491 } else if (result.leaks) {
492 return 3;
493 } else {
494 return 0;
495 }
aliguori15859692009-04-21 23:11:53 +0000496}
497
bellardea2384d2004-08-01 21:59:26 +0000498static int img_commit(int argc, char **argv)
499{
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400500 int c, ret, flags;
501 const char *filename, *fmt, *cache;
bellardea2384d2004-08-01 21:59:26 +0000502 BlockDriverState *bs;
503
504 fmt = NULL;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400505 cache = BDRV_DEFAULT_CACHE;
bellardea2384d2004-08-01 21:59:26 +0000506 for(;;) {
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400507 c = getopt(argc, argv, "f:ht:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100508 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000509 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100510 }
bellardea2384d2004-08-01 21:59:26 +0000511 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100512 case '?':
bellardea2384d2004-08-01 21:59:26 +0000513 case 'h':
514 help();
515 break;
516 case 'f':
517 fmt = optarg;
518 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400519 case 't':
520 cache = optarg;
521 break;
bellardea2384d2004-08-01 21:59:26 +0000522 }
523 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100524 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +0000525 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100526 }
bellardea2384d2004-08-01 21:59:26 +0000527 filename = argv[optind++];
528
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400529 flags = BDRV_O_RDWR;
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +0100530 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400531 if (ret < 0) {
532 error_report("Invalid cache option: %s", cache);
533 return -1;
534 }
535
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +0100536 bs = bdrv_new_open(filename, fmt, flags, true);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900537 if (!bs) {
538 return 1;
539 }
bellardea2384d2004-08-01 21:59:26 +0000540 ret = bdrv_commit(bs);
541 switch(ret) {
542 case 0:
543 printf("Image committed.\n");
544 break;
545 case -ENOENT:
Jes Sorensen15654a62010-12-16 14:31:53 +0100546 error_report("No disk inserted");
bellardea2384d2004-08-01 21:59:26 +0000547 break;
548 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +0100549 error_report("Image is read-only");
bellardea2384d2004-08-01 21:59:26 +0000550 break;
551 case -ENOTSUP:
Jes Sorensen15654a62010-12-16 14:31:53 +0100552 error_report("Image is already committed");
bellardea2384d2004-08-01 21:59:26 +0000553 break;
554 default:
Jes Sorensen15654a62010-12-16 14:31:53 +0100555 error_report("Error while committing image");
bellardea2384d2004-08-01 21:59:26 +0000556 break;
557 }
558
559 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900560 if (ret) {
561 return 1;
562 }
bellardea2384d2004-08-01 21:59:26 +0000563 return 0;
564}
565
Dmitry Konishchevf6a00aa2011-05-18 15:03:59 +0400566/*
thsf58c7b32008-06-05 21:53:49 +0000567 * Returns true iff the first sector pointed to by 'buf' contains at least
568 * a non-NUL byte.
569 *
570 * 'pnum' is set to the number of sectors (including and immediately following
571 * the first one) that are known to be in the same allocated/unallocated state.
572 */
bellardea2384d2004-08-01 21:59:26 +0000573static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
574{
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000575 bool is_zero;
576 int i;
bellardea2384d2004-08-01 21:59:26 +0000577
578 if (n <= 0) {
579 *pnum = 0;
580 return 0;
581 }
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000582 is_zero = buffer_is_zero(buf, 512);
bellardea2384d2004-08-01 21:59:26 +0000583 for(i = 1; i < n; i++) {
584 buf += 512;
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000585 if (is_zero != buffer_is_zero(buf, 512)) {
bellardea2384d2004-08-01 21:59:26 +0000586 break;
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000587 }
bellardea2384d2004-08-01 21:59:26 +0000588 }
589 *pnum = i;
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000590 return !is_zero;
bellardea2384d2004-08-01 21:59:26 +0000591}
592
Kevin Wolf3e85c6f2010-01-12 12:55:18 +0100593/*
Kevin Wolfa22f1232011-08-26 15:27:13 +0200594 * Like is_allocated_sectors, but if the buffer starts with a used sector,
595 * up to 'min' consecutive sectors containing zeros are ignored. This avoids
596 * breaking up write requests for only small sparse areas.
597 */
598static int is_allocated_sectors_min(const uint8_t *buf, int n, int *pnum,
599 int min)
600{
601 int ret;
602 int num_checked, num_used;
603
604 if (n < min) {
605 min = n;
606 }
607
608 ret = is_allocated_sectors(buf, n, pnum);
609 if (!ret) {
610 return ret;
611 }
612
613 num_used = *pnum;
614 buf += BDRV_SECTOR_SIZE * *pnum;
615 n -= *pnum;
616 num_checked = num_used;
617
618 while (n > 0) {
619 ret = is_allocated_sectors(buf, n, pnum);
620
621 buf += BDRV_SECTOR_SIZE * *pnum;
622 n -= *pnum;
623 num_checked += *pnum;
624 if (ret) {
625 num_used = num_checked;
626 } else if (*pnum >= min) {
627 break;
628 }
629 }
630
631 *pnum = num_used;
632 return 1;
633}
634
635/*
Kevin Wolf3e85c6f2010-01-12 12:55:18 +0100636 * Compares two buffers sector by sector. Returns 0 if the first sector of both
637 * buffers matches, non-zero otherwise.
638 *
639 * pnum is set to the number of sectors (including and immediately following
640 * the first one) that are known to have the same comparison result
641 */
642static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
643 int *pnum)
644{
645 int res, i;
646
647 if (n <= 0) {
648 *pnum = 0;
649 return 0;
650 }
651
652 res = !!memcmp(buf1, buf2, 512);
653 for(i = 1; i < n; i++) {
654 buf1 += 512;
655 buf2 += 512;
656
657 if (!!memcmp(buf1, buf2, 512) != res) {
658 break;
659 }
660 }
661
662 *pnum = i;
663 return res;
664}
665
Kevin Wolf80ee15a2009-09-15 12:30:43 +0200666#define IO_BUF_SIZE (2 * 1024 * 1024)
bellardea2384d2004-08-01 21:59:26 +0000667
668static int img_convert(int argc, char **argv)
669{
Jes Sorenseneec77d92010-12-07 17:44:34 +0100670 int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400671 int progress = 0, flags;
672 const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900673 BlockDriver *drv, *proto_drv;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900674 BlockDriverState **bs = NULL, *out_bs = NULL;
ths96b8f132007-12-17 01:35:20 +0000675 int64_t total_sectors, nb_sectors, sector_num, bs_offset;
676 uint64_t bs_sectors;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900677 uint8_t * buf = NULL;
bellardea2384d2004-08-01 21:59:26 +0000678 const uint8_t *buf1;
bellardfaea38e2006-08-05 21:31:00 +0000679 BlockDriverInfo bdi;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900680 QEMUOptionParameter *param = NULL, *create_options = NULL;
Kevin Wolfa18953f2010-10-14 15:46:04 +0200681 QEMUOptionParameter *out_baseimg_param;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200682 char *options = NULL;
edison51ef6722010-09-21 19:58:41 -0700683 const char *snapshot_name = NULL;
Kevin Wolf1f710492012-10-12 14:29:18 +0200684 float local_progress = 0;
Kevin Wolfa22f1232011-08-26 15:27:13 +0200685 int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */
bellardea2384d2004-08-01 21:59:26 +0000686
687 fmt = NULL;
688 out_fmt = "raw";
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400689 cache = "unsafe";
thsf58c7b32008-06-05 21:53:49 +0000690 out_baseimg = NULL;
Jes Sorenseneec77d92010-12-07 17:44:34 +0100691 compress = 0;
bellardea2384d2004-08-01 21:59:26 +0000692 for(;;) {
Kevin Wolfa22f1232011-08-26 15:27:13 +0200693 c = getopt(argc, argv, "f:O:B:s:hce6o:pS:t:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100694 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000695 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100696 }
bellardea2384d2004-08-01 21:59:26 +0000697 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100698 case '?':
bellardea2384d2004-08-01 21:59:26 +0000699 case 'h':
700 help();
701 break;
702 case 'f':
703 fmt = optarg;
704 break;
705 case 'O':
706 out_fmt = optarg;
707 break;
thsf58c7b32008-06-05 21:53:49 +0000708 case 'B':
709 out_baseimg = optarg;
710 break;
bellardea2384d2004-08-01 21:59:26 +0000711 case 'c':
Jes Sorenseneec77d92010-12-07 17:44:34 +0100712 compress = 1;
bellardea2384d2004-08-01 21:59:26 +0000713 break;
714 case 'e':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200715 error_report("option -e is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100716 "encryption\' instead!");
717 return 1;
thsec36ba12007-09-16 21:59:02 +0000718 case '6':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200719 error_report("option -6 is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100720 "compat6\' instead!");
721 return 1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200722 case 'o':
723 options = optarg;
724 break;
edison51ef6722010-09-21 19:58:41 -0700725 case 's':
726 snapshot_name = optarg;
727 break;
Kevin Wolfa22f1232011-08-26 15:27:13 +0200728 case 'S':
729 {
730 int64_t sval;
Markus Armbrustere36b3692011-11-22 09:46:05 +0100731 char *end;
732 sval = strtosz_suffix(optarg, &end, STRTOSZ_DEFSUFFIX_B);
733 if (sval < 0 || *end) {
Kevin Wolfa22f1232011-08-26 15:27:13 +0200734 error_report("Invalid minimum zero buffer size for sparse output specified");
735 return 1;
736 }
737
738 min_sparse = sval / BDRV_SECTOR_SIZE;
739 break;
740 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200741 case 'p':
742 progress = 1;
743 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400744 case 't':
745 cache = optarg;
746 break;
bellardea2384d2004-08-01 21:59:26 +0000747 }
748 }
ths3b46e622007-09-17 08:09:54 +0000749
balrog926c2d22007-10-31 01:11:44 +0000750 bs_n = argc - optind - 1;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100751 if (bs_n < 1) {
752 help();
753 }
balrog926c2d22007-10-31 01:11:44 +0000754
755 out_filename = argv[argc - 1];
thsf58c7b32008-06-05 21:53:49 +0000756
Charles Arnoldfa170c12012-05-11 10:57:54 -0600757 /* Initialize before goto out */
758 qemu_progress_init(progress, 2.0);
759
Peter Maydellc8057f92012-08-02 13:45:54 +0100760 if (options && is_help_option(options)) {
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100761 ret = print_block_option_help(out_filename, out_fmt);
762 goto out;
763 }
764
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900765 if (bs_n > 1 && out_baseimg) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100766 error_report("-B makes no sense when concatenating multiple input "
767 "images");
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100768 ret = -1;
769 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900770 }
Dong Xu Wangf8111c22012-03-15 20:13:31 +0800771
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200772 qemu_progress_print(0, 100);
773
Anthony Liguori7267c092011-08-20 22:09:37 -0500774 bs = g_malloc0(bs_n * sizeof(BlockDriverState *));
balrog926c2d22007-10-31 01:11:44 +0000775
776 total_sectors = 0;
777 for (bs_i = 0; bs_i < bs_n; bs_i++) {
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +0100778 bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS, true);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900779 if (!bs[bs_i]) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100780 error_report("Could not open '%s'", argv[optind + bs_i]);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900781 ret = -1;
782 goto out;
783 }
balrog926c2d22007-10-31 01:11:44 +0000784 bdrv_get_geometry(bs[bs_i], &bs_sectors);
785 total_sectors += bs_sectors;
786 }
bellardea2384d2004-08-01 21:59:26 +0000787
edison51ef6722010-09-21 19:58:41 -0700788 if (snapshot_name != NULL) {
789 if (bs_n > 1) {
Markus Armbruster6daf1942011-06-22 14:03:54 +0200790 error_report("No support for concatenating multiple snapshot");
edison51ef6722010-09-21 19:58:41 -0700791 ret = -1;
792 goto out;
793 }
794 if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
Markus Armbruster6daf1942011-06-22 14:03:54 +0200795 error_report("Failed to load snapshot");
edison51ef6722010-09-21 19:58:41 -0700796 ret = -1;
797 goto out;
798 }
799 }
800
Kevin Wolfefa84d42009-05-18 16:42:12 +0200801 /* Find driver and parse its options */
bellardea2384d2004-08-01 21:59:26 +0000802 drv = bdrv_find_format(out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900803 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100804 error_report("Unknown file format '%s'", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900805 ret = -1;
806 goto out;
807 }
balrog926c2d22007-10-31 01:11:44 +0000808
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900809 proto_drv = bdrv_find_protocol(out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900810 if (!proto_drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100811 error_report("Unknown protocol '%s'", out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900812 ret = -1;
813 goto out;
814 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900815
816 create_options = append_option_parameters(create_options,
817 drv->create_options);
818 create_options = append_option_parameters(create_options,
819 proto_drv->create_options);
Kevin Wolfdb08adf2009-06-04 15:39:38 +0200820
Kevin Wolfefa84d42009-05-18 16:42:12 +0200821 if (options) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900822 param = parse_option_parameters(options, create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200823 if (param == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100824 error_report("Invalid options for file format '%s'.", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900825 ret = -1;
826 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200827 }
828 } else {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900829 param = parse_option_parameters("", create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200830 }
831
832 set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
Jes Sorenseneec77d92010-12-07 17:44:34 +0100833 ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900834 if (ret < 0) {
835 goto out;
836 }
Kevin Wolfefa84d42009-05-18 16:42:12 +0200837
Kevin Wolfa18953f2010-10-14 15:46:04 +0200838 /* Get backing file name if -o backing_file was used */
839 out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
840 if (out_baseimg_param) {
841 out_baseimg = out_baseimg_param->value.s;
842 }
843
Kevin Wolfefa84d42009-05-18 16:42:12 +0200844 /* Check if compression is supported */
Jes Sorenseneec77d92010-12-07 17:44:34 +0100845 if (compress) {
Kevin Wolfefa84d42009-05-18 16:42:12 +0200846 QEMUOptionParameter *encryption =
847 get_option_parameter(param, BLOCK_OPT_ENCRYPT);
Kevin Wolf41521fa2011-10-18 16:19:42 +0200848 QEMUOptionParameter *preallocation =
849 get_option_parameter(param, BLOCK_OPT_PREALLOC);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200850
851 if (!drv->bdrv_write_compressed) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100852 error_report("Compression not supported for this file format");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900853 ret = -1;
854 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200855 }
856
857 if (encryption && encryption->value.n) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100858 error_report("Compression and encryption not supported at "
859 "the same time");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900860 ret = -1;
861 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200862 }
Kevin Wolf41521fa2011-10-18 16:19:42 +0200863
864 if (preallocation && preallocation->value.s
865 && strcmp(preallocation->value.s, "off"))
866 {
867 error_report("Compression and preallocation not supported at "
868 "the same time");
869 ret = -1;
870 goto out;
871 }
Kevin Wolfefa84d42009-05-18 16:42:12 +0200872 }
873
874 /* Create the new image */
875 ret = bdrv_create(drv, out_filename, param);
bellardea2384d2004-08-01 21:59:26 +0000876 if (ret < 0) {
877 if (ret == -ENOTSUP) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100878 error_report("Formatting not supported for file format '%s'",
879 out_fmt);
aurel326e9ea0c2009-04-15 14:42:46 +0000880 } else if (ret == -EFBIG) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100881 error_report("The image size is too large for file format '%s'",
882 out_fmt);
bellardea2384d2004-08-01 21:59:26 +0000883 } else {
Jes Sorensen15654a62010-12-16 14:31:53 +0100884 error_report("%s: error while converting %s: %s",
885 out_filename, out_fmt, strerror(-ret));
bellardea2384d2004-08-01 21:59:26 +0000886 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900887 goto out;
bellardea2384d2004-08-01 21:59:26 +0000888 }
ths3b46e622007-09-17 08:09:54 +0000889
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400890 flags = BDRV_O_RDWR;
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +0100891 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400892 if (ret < 0) {
893 error_report("Invalid cache option: %s", cache);
894 return -1;
895 }
896
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +0100897 out_bs = bdrv_new_open(out_filename, out_fmt, flags, true);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900898 if (!out_bs) {
899 ret = -1;
900 goto out;
901 }
bellardea2384d2004-08-01 21:59:26 +0000902
balrog926c2d22007-10-31 01:11:44 +0000903 bs_i = 0;
904 bs_offset = 0;
905 bdrv_get_geometry(bs[0], &bs_sectors);
Kevin Wolfbb1c0592011-08-08 14:09:12 +0200906 buf = qemu_blockalign(out_bs, IO_BUF_SIZE);
balrog926c2d22007-10-31 01:11:44 +0000907
Jes Sorenseneec77d92010-12-07 17:44:34 +0100908 if (compress) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900909 ret = bdrv_get_info(out_bs, &bdi);
910 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100911 error_report("could not get block driver info");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900912 goto out;
913 }
bellardfaea38e2006-08-05 21:31:00 +0000914 cluster_size = bdi.cluster_size;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900915 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100916 error_report("invalid cluster size");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900917 ret = -1;
918 goto out;
919 }
bellardea2384d2004-08-01 21:59:26 +0000920 cluster_sectors = cluster_size >> 9;
921 sector_num = 0;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200922
923 nb_sectors = total_sectors;
Kevin Wolf1f710492012-10-12 14:29:18 +0200924 if (nb_sectors != 0) {
925 local_progress = (float)100 /
926 (nb_sectors / MIN(nb_sectors, cluster_sectors));
927 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200928
bellardea2384d2004-08-01 21:59:26 +0000929 for(;;) {
balrog926c2d22007-10-31 01:11:44 +0000930 int64_t bs_num;
931 int remainder;
932 uint8_t *buf2;
933
bellardea2384d2004-08-01 21:59:26 +0000934 nb_sectors = total_sectors - sector_num;
935 if (nb_sectors <= 0)
936 break;
937 if (nb_sectors >= cluster_sectors)
938 n = cluster_sectors;
939 else
940 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000941
942 bs_num = sector_num - bs_offset;
943 assert (bs_num >= 0);
944 remainder = n;
945 buf2 = buf;
946 while (remainder > 0) {
947 int nlow;
948 while (bs_num == bs_sectors) {
949 bs_i++;
950 assert (bs_i < bs_n);
951 bs_offset += bs_sectors;
952 bdrv_get_geometry(bs[bs_i], &bs_sectors);
953 bs_num = 0;
Blue Swirl0bfcd592010-05-22 08:02:12 +0000954 /* printf("changing part: sector_num=%" PRId64 ", "
955 "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64
956 "\n", sector_num, bs_i, bs_offset, bs_sectors); */
balrog926c2d22007-10-31 01:11:44 +0000957 }
958 assert (bs_num < bs_sectors);
959
960 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
961
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900962 ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
963 if (ret < 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +0100964 error_report("error while reading sector %" PRId64 ": %s",
965 bs_num, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900966 goto out;
967 }
balrog926c2d22007-10-31 01:11:44 +0000968
969 buf2 += nlow * 512;
970 bs_num += nlow;
971
972 remainder -= nlow;
973 }
974 assert (remainder == 0);
975
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100976 if (n < cluster_sectors) {
bellardea2384d2004-08-01 21:59:26 +0000977 memset(buf + n * 512, 0, cluster_size - n * 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100978 }
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000979 if (!buffer_is_zero(buf, cluster_size)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900980 ret = bdrv_write_compressed(out_bs, sector_num, buf,
981 cluster_sectors);
982 if (ret != 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +0100983 error_report("error while compressing sector %" PRId64
984 ": %s", sector_num, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900985 goto out;
986 }
bellardea2384d2004-08-01 21:59:26 +0000987 }
988 sector_num += n;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200989 qemu_progress_print(local_progress, 100);
bellardea2384d2004-08-01 21:59:26 +0000990 }
bellardfaea38e2006-08-05 21:31:00 +0000991 /* signal EOF to align */
992 bdrv_write_compressed(out_bs, 0, NULL, 0);
bellardea2384d2004-08-01 21:59:26 +0000993 } else {
Kevin Wolff2feebb2010-04-14 17:30:35 +0200994 int has_zero_init = bdrv_has_zero_init(out_bs);
995
thsf58c7b32008-06-05 21:53:49 +0000996 sector_num = 0; // total number of sectors converted so far
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200997 nb_sectors = total_sectors - sector_num;
Kevin Wolf1f710492012-10-12 14:29:18 +0200998 if (nb_sectors != 0) {
999 local_progress = (float)100 /
1000 (nb_sectors / MIN(nb_sectors, IO_BUF_SIZE / 512));
1001 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001002
bellardea2384d2004-08-01 21:59:26 +00001003 for(;;) {
1004 nb_sectors = total_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001005 if (nb_sectors <= 0) {
bellardea2384d2004-08-01 21:59:26 +00001006 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001007 }
1008 if (nb_sectors >= (IO_BUF_SIZE / 512)) {
bellardea2384d2004-08-01 21:59:26 +00001009 n = (IO_BUF_SIZE / 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001010 } else {
bellardea2384d2004-08-01 21:59:26 +00001011 n = nb_sectors;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001012 }
balrog926c2d22007-10-31 01:11:44 +00001013
1014 while (sector_num - bs_offset >= bs_sectors) {
1015 bs_i ++;
1016 assert (bs_i < bs_n);
1017 bs_offset += bs_sectors;
1018 bdrv_get_geometry(bs[bs_i], &bs_sectors);
Blue Swirl0bfcd592010-05-22 08:02:12 +00001019 /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "
1020 "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",
balrog926c2d22007-10-31 01:11:44 +00001021 sector_num, bs_i, bs_offset, bs_sectors); */
1022 }
1023
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001024 if (n > bs_offset + bs_sectors - sector_num) {
balrog926c2d22007-10-31 01:11:44 +00001025 n = bs_offset + bs_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001026 }
balrog926c2d22007-10-31 01:11:44 +00001027
Kevin Wolff2feebb2010-04-14 17:30:35 +02001028 if (has_zero_init) {
Akkarit Sangpetchd0320442009-07-17 10:02:15 +02001029 /* If the output image is being created as a copy on write image,
1030 assume that sectors which are unallocated in the input image
1031 are present in both the output's and input's base images (no
1032 need to copy them). */
1033 if (out_baseimg) {
1034 if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
1035 n, &n1)) {
1036 sector_num += n1;
1037 continue;
1038 }
1039 /* The next 'n1' sectors are allocated in the input image. Copy
1040 only those as they may be followed by unallocated sectors. */
1041 n = n1;
aliguori93c65b42009-04-05 17:40:43 +00001042 }
aliguori93c65b42009-04-05 17:40:43 +00001043 } else {
1044 n1 = n;
thsf58c7b32008-06-05 21:53:49 +00001045 }
1046
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001047 ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
1048 if (ret < 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +01001049 error_report("error while reading sector %" PRId64 ": %s",
1050 sector_num - bs_offset, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001051 goto out;
1052 }
bellardea2384d2004-08-01 21:59:26 +00001053 /* NOTE: at the same time we convert, we do not write zero
1054 sectors to have a chance to compress the image. Ideally, we
1055 should add a specific call to have the info to go faster */
1056 buf1 = buf;
1057 while (n > 0) {
thsf58c7b32008-06-05 21:53:49 +00001058 /* If the output image is being created as a copy on write image,
1059 copy all sectors even the ones containing only NUL bytes,
aliguori93c65b42009-04-05 17:40:43 +00001060 because they may differ from the sectors in the base image.
1061
1062 If the output is to a host device, we also write out
1063 sectors that are entirely 0, since whatever data was
1064 already there is garbage, not 0s. */
Kevin Wolff2feebb2010-04-14 17:30:35 +02001065 if (!has_zero_init || out_baseimg ||
Kevin Wolfa22f1232011-08-26 15:27:13 +02001066 is_allocated_sectors_min(buf1, n, &n1, min_sparse)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001067 ret = bdrv_write(out_bs, sector_num, buf1, n1);
1068 if (ret < 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +01001069 error_report("error while writing sector %" PRId64
1070 ": %s", sector_num, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001071 goto out;
1072 }
bellardea2384d2004-08-01 21:59:26 +00001073 }
1074 sector_num += n1;
1075 n -= n1;
1076 buf1 += n1 * 512;
1077 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001078 qemu_progress_print(local_progress, 100);
bellardea2384d2004-08-01 21:59:26 +00001079 }
1080 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001081out:
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001082 qemu_progress_end();
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001083 free_option_parameters(create_options);
1084 free_option_parameters(param);
Kevin Wolfbb1c0592011-08-08 14:09:12 +02001085 qemu_vfree(buf);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001086 if (out_bs) {
1087 bdrv_delete(out_bs);
1088 }
Jes Sorensen31ca34b2010-12-06 15:25:36 +01001089 if (bs) {
1090 for (bs_i = 0; bs_i < bs_n; bs_i++) {
1091 if (bs[bs_i]) {
1092 bdrv_delete(bs[bs_i]);
1093 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001094 }
Anthony Liguori7267c092011-08-20 22:09:37 -05001095 g_free(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001096 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001097 if (ret) {
1098 return 1;
1099 }
bellardea2384d2004-08-01 21:59:26 +00001100 return 0;
1101}
1102
bellard57d1a2b2004-08-03 21:15:11 +00001103
bellardfaea38e2006-08-05 21:31:00 +00001104static void dump_snapshots(BlockDriverState *bs)
1105{
1106 QEMUSnapshotInfo *sn_tab, *sn;
1107 int nb_sns, i;
1108 char buf[256];
1109
1110 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1111 if (nb_sns <= 0)
1112 return;
1113 printf("Snapshot list:\n");
1114 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
1115 for(i = 0; i < nb_sns; i++) {
1116 sn = &sn_tab[i];
1117 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
1118 }
Anthony Liguori7267c092011-08-20 22:09:37 -05001119 g_free(sn_tab);
bellardfaea38e2006-08-05 21:31:00 +00001120}
1121
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001122static void dump_json_image_info_list(ImageInfoList *list)
1123{
1124 Error *errp = NULL;
1125 QString *str;
1126 QmpOutputVisitor *ov = qmp_output_visitor_new();
1127 QObject *obj;
1128 visit_type_ImageInfoList(qmp_output_get_visitor(ov),
1129 &list, NULL, &errp);
1130 obj = qmp_output_get_qobject(ov);
1131 str = qobject_to_json_pretty(obj);
1132 assert(str != NULL);
1133 printf("%s\n", qstring_get_str(str));
1134 qobject_decref(obj);
1135 qmp_output_visitor_cleanup(ov);
1136 QDECREF(str);
1137}
1138
Benoît Canetc054b3f2012-09-05 13:09:02 +02001139static void collect_snapshots(BlockDriverState *bs , ImageInfo *info)
bellardea2384d2004-08-01 21:59:26 +00001140{
Benoît Canetc054b3f2012-09-05 13:09:02 +02001141 int i, sn_count;
1142 QEMUSnapshotInfo *sn_tab = NULL;
1143 SnapshotInfoList *info_list, *cur_item = NULL;
1144 sn_count = bdrv_snapshot_list(bs, &sn_tab);
1145
1146 for (i = 0; i < sn_count; i++) {
1147 info->has_snapshots = true;
1148 info_list = g_new0(SnapshotInfoList, 1);
1149
1150 info_list->value = g_new0(SnapshotInfo, 1);
1151 info_list->value->id = g_strdup(sn_tab[i].id_str);
1152 info_list->value->name = g_strdup(sn_tab[i].name);
1153 info_list->value->vm_state_size = sn_tab[i].vm_state_size;
1154 info_list->value->date_sec = sn_tab[i].date_sec;
1155 info_list->value->date_nsec = sn_tab[i].date_nsec;
1156 info_list->value->vm_clock_sec = sn_tab[i].vm_clock_nsec / 1000000000;
1157 info_list->value->vm_clock_nsec = sn_tab[i].vm_clock_nsec % 1000000000;
1158
1159 /* XXX: waiting for the qapi to support qemu-queue.h types */
1160 if (!cur_item) {
1161 info->snapshots = cur_item = info_list;
1162 } else {
1163 cur_item->next = info_list;
1164 cur_item = info_list;
1165 }
1166
1167 }
1168
1169 g_free(sn_tab);
1170}
1171
1172static void dump_json_image_info(ImageInfo *info)
1173{
1174 Error *errp = NULL;
1175 QString *str;
1176 QmpOutputVisitor *ov = qmp_output_visitor_new();
1177 QObject *obj;
1178 visit_type_ImageInfo(qmp_output_get_visitor(ov),
1179 &info, NULL, &errp);
1180 obj = qmp_output_get_qobject(ov);
1181 str = qobject_to_json_pretty(obj);
1182 assert(str != NULL);
1183 printf("%s\n", qstring_get_str(str));
1184 qobject_decref(obj);
1185 qmp_output_visitor_cleanup(ov);
1186 QDECREF(str);
1187}
1188
1189static void collect_image_info(BlockDriverState *bs,
1190 ImageInfo *info,
1191 const char *filename,
1192 const char *fmt)
1193{
ths96b8f132007-12-17 01:35:20 +00001194 uint64_t total_sectors;
bellard93b6b2a2006-08-01 15:51:11 +00001195 char backing_filename[1024];
1196 char backing_filename2[1024];
bellardfaea38e2006-08-05 21:31:00 +00001197 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +00001198
Benoît Canetc054b3f2012-09-05 13:09:02 +02001199 bdrv_get_geometry(bs, &total_sectors);
1200
1201 info->filename = g_strdup(filename);
1202 info->format = g_strdup(bdrv_get_format_name(bs));
1203 info->virtual_size = total_sectors * 512;
1204 info->actual_size = bdrv_get_allocated_file_size(bs);
1205 info->has_actual_size = info->actual_size >= 0;
1206 if (bdrv_is_encrypted(bs)) {
1207 info->encrypted = true;
1208 info->has_encrypted = true;
1209 }
1210 if (bdrv_get_info(bs, &bdi) >= 0) {
1211 if (bdi.cluster_size != 0) {
1212 info->cluster_size = bdi.cluster_size;
1213 info->has_cluster_size = true;
1214 }
1215 info->dirty_flag = bdi.is_dirty;
1216 info->has_dirty_flag = true;
1217 }
1218 bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
1219 if (backing_filename[0] != '\0') {
1220 info->backing_filename = g_strdup(backing_filename);
1221 info->has_backing_filename = true;
1222 bdrv_get_full_backing_filename(bs, backing_filename2,
1223 sizeof(backing_filename2));
1224
1225 if (strcmp(backing_filename, backing_filename2) != 0) {
1226 info->full_backing_filename =
1227 g_strdup(backing_filename2);
1228 info->has_full_backing_filename = true;
1229 }
1230
1231 if (bs->backing_format[0]) {
1232 info->backing_filename_format = g_strdup(bs->backing_format);
1233 info->has_backing_filename_format = true;
1234 }
1235 }
1236}
1237
1238static void dump_human_image_info(ImageInfo *info)
1239{
1240 char size_buf[128], dsize_buf[128];
1241 if (!info->has_actual_size) {
1242 snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
1243 } else {
1244 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
1245 info->actual_size);
1246 }
1247 get_human_readable_size(size_buf, sizeof(size_buf), info->virtual_size);
1248 printf("image: %s\n"
1249 "file format: %s\n"
1250 "virtual size: %s (%" PRId64 " bytes)\n"
1251 "disk size: %s\n",
1252 info->filename, info->format, size_buf,
1253 info->virtual_size,
1254 dsize_buf);
1255
1256 if (info->has_encrypted && info->encrypted) {
1257 printf("encrypted: yes\n");
1258 }
1259
1260 if (info->has_cluster_size) {
1261 printf("cluster_size: %" PRId64 "\n", info->cluster_size);
1262 }
1263
1264 if (info->has_dirty_flag && info->dirty_flag) {
1265 printf("cleanly shut down: no\n");
1266 }
1267
1268 if (info->has_backing_filename) {
1269 printf("backing file: %s", info->backing_filename);
1270 if (info->has_full_backing_filename) {
1271 printf(" (actual path: %s)", info->full_backing_filename);
1272 }
1273 putchar('\n');
1274 if (info->has_backing_filename_format) {
1275 printf("backing file format: %s\n", info->backing_filename_format);
1276 }
1277 }
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001278
1279 if (info->has_snapshots) {
1280 SnapshotInfoList *elem;
1281 char buf[256];
1282
1283 printf("Snapshot list:\n");
1284 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
1285
1286 /* Ideally bdrv_snapshot_dump() would operate on SnapshotInfoList but
1287 * we convert to the block layer's native QEMUSnapshotInfo for now.
1288 */
1289 for (elem = info->snapshots; elem; elem = elem->next) {
1290 QEMUSnapshotInfo sn = {
1291 .vm_state_size = elem->value->vm_state_size,
1292 .date_sec = elem->value->date_sec,
1293 .date_nsec = elem->value->date_nsec,
1294 .vm_clock_nsec = elem->value->vm_clock_sec * 1000000000ULL +
1295 elem->value->vm_clock_nsec,
1296 };
1297
1298 pstrcpy(sn.id_str, sizeof(sn.id_str), elem->value->id);
1299 pstrcpy(sn.name, sizeof(sn.name), elem->value->name);
1300 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), &sn));
1301 }
1302 }
Benoît Canetc054b3f2012-09-05 13:09:02 +02001303}
1304
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001305static void dump_human_image_info_list(ImageInfoList *list)
1306{
1307 ImageInfoList *elem;
1308 bool delim = false;
1309
1310 for (elem = list; elem; elem = elem->next) {
1311 if (delim) {
1312 printf("\n");
1313 }
1314 delim = true;
1315
1316 dump_human_image_info(elem->value);
1317 }
1318}
1319
1320static gboolean str_equal_func(gconstpointer a, gconstpointer b)
1321{
1322 return strcmp(a, b) == 0;
1323}
1324
1325/**
1326 * Open an image file chain and return an ImageInfoList
1327 *
1328 * @filename: topmost image filename
1329 * @fmt: topmost image format (may be NULL to autodetect)
1330 * @chain: true - enumerate entire backing file chain
1331 * false - only topmost image file
1332 *
1333 * Returns a list of ImageInfo objects or NULL if there was an error opening an
1334 * image file. If there was an error a message will have been printed to
1335 * stderr.
1336 */
1337static ImageInfoList *collect_image_info_list(const char *filename,
1338 const char *fmt,
1339 bool chain)
1340{
1341 ImageInfoList *head = NULL;
1342 ImageInfoList **last = &head;
1343 GHashTable *filenames;
1344
1345 filenames = g_hash_table_new_full(g_str_hash, str_equal_func, NULL, NULL);
1346
1347 while (filename) {
1348 BlockDriverState *bs;
1349 ImageInfo *info;
1350 ImageInfoList *elem;
1351
1352 if (g_hash_table_lookup_extended(filenames, filename, NULL, NULL)) {
1353 error_report("Backing file '%s' creates an infinite loop.",
1354 filename);
1355 goto err;
1356 }
1357 g_hash_table_insert(filenames, (gpointer)filename, NULL);
1358
1359 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING,
1360 false);
1361 if (!bs) {
1362 goto err;
1363 }
1364
1365 info = g_new0(ImageInfo, 1);
1366 collect_image_info(bs, info, filename, fmt);
1367 collect_snapshots(bs, info);
1368
1369 elem = g_new0(ImageInfoList, 1);
1370 elem->value = info;
1371 *last = elem;
1372 last = &elem->next;
1373
1374 bdrv_delete(bs);
1375
1376 filename = fmt = NULL;
1377 if (chain) {
1378 if (info->has_full_backing_filename) {
1379 filename = info->full_backing_filename;
1380 } else if (info->has_backing_filename) {
1381 filename = info->backing_filename;
1382 }
1383 if (info->has_backing_filename_format) {
1384 fmt = info->backing_filename_format;
1385 }
1386 }
1387 }
1388 g_hash_table_destroy(filenames);
1389 return head;
1390
1391err:
1392 qapi_free_ImageInfoList(head);
1393 g_hash_table_destroy(filenames);
1394 return NULL;
1395}
1396
1397enum {
1398 OPTION_OUTPUT = 256,
1399 OPTION_BACKING_CHAIN = 257,
1400};
Benoît Canetc054b3f2012-09-05 13:09:02 +02001401
1402typedef enum OutputFormat {
1403 OFORMAT_JSON,
1404 OFORMAT_HUMAN,
1405} OutputFormat;
1406
1407static int img_info(int argc, char **argv)
1408{
1409 int c;
1410 OutputFormat output_format = OFORMAT_HUMAN;
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001411 bool chain = false;
Benoît Canetc054b3f2012-09-05 13:09:02 +02001412 const char *filename, *fmt, *output;
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001413 ImageInfoList *list;
Benoît Canetc054b3f2012-09-05 13:09:02 +02001414
bellardea2384d2004-08-01 21:59:26 +00001415 fmt = NULL;
Benoît Canetc054b3f2012-09-05 13:09:02 +02001416 output = NULL;
bellardea2384d2004-08-01 21:59:26 +00001417 for(;;) {
Benoît Canetc054b3f2012-09-05 13:09:02 +02001418 int option_index = 0;
1419 static const struct option long_options[] = {
1420 {"help", no_argument, 0, 'h'},
1421 {"format", required_argument, 0, 'f'},
1422 {"output", required_argument, 0, OPTION_OUTPUT},
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001423 {"backing-chain", no_argument, 0, OPTION_BACKING_CHAIN},
Benoît Canetc054b3f2012-09-05 13:09:02 +02001424 {0, 0, 0, 0}
1425 };
1426 c = getopt_long(argc, argv, "f:h",
1427 long_options, &option_index);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001428 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +00001429 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001430 }
bellardea2384d2004-08-01 21:59:26 +00001431 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001432 case '?':
bellardea2384d2004-08-01 21:59:26 +00001433 case 'h':
1434 help();
1435 break;
1436 case 'f':
1437 fmt = optarg;
1438 break;
Benoît Canetc054b3f2012-09-05 13:09:02 +02001439 case OPTION_OUTPUT:
1440 output = optarg;
1441 break;
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001442 case OPTION_BACKING_CHAIN:
1443 chain = true;
1444 break;
bellardea2384d2004-08-01 21:59:26 +00001445 }
1446 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001447 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +00001448 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001449 }
bellardea2384d2004-08-01 21:59:26 +00001450 filename = argv[optind++];
1451
Benoît Canetc054b3f2012-09-05 13:09:02 +02001452 if (output && !strcmp(output, "json")) {
1453 output_format = OFORMAT_JSON;
1454 } else if (output && !strcmp(output, "human")) {
1455 output_format = OFORMAT_HUMAN;
1456 } else if (output) {
1457 error_report("--output must be used with human or json as argument.");
1458 return 1;
1459 }
1460
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001461 list = collect_image_info_list(filename, fmt, chain);
1462 if (!list) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001463 return 1;
1464 }
Benoît Canetc054b3f2012-09-05 13:09:02 +02001465
Benoît Canetc054b3f2012-09-05 13:09:02 +02001466 switch (output_format) {
1467 case OFORMAT_HUMAN:
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001468 dump_human_image_info_list(list);
Benoît Canetc054b3f2012-09-05 13:09:02 +02001469 break;
1470 case OFORMAT_JSON:
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001471 if (chain) {
1472 dump_json_image_info_list(list);
1473 } else {
1474 dump_json_image_info(list->value);
1475 }
Benoît Canetc054b3f2012-09-05 13:09:02 +02001476 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001477 }
Benoît Canetc054b3f2012-09-05 13:09:02 +02001478
Stefan Hajnoczi9699bf02012-10-17 14:02:31 +02001479 qapi_free_ImageInfoList(list);
bellardea2384d2004-08-01 21:59:26 +00001480 return 0;
1481}
1482
aliguorif7b4a942009-01-07 17:40:15 +00001483#define SNAPSHOT_LIST 1
1484#define SNAPSHOT_CREATE 2
1485#define SNAPSHOT_APPLY 3
1486#define SNAPSHOT_DELETE 4
1487
Stuart Brady153859b2009-06-07 00:42:17 +01001488static int img_snapshot(int argc, char **argv)
aliguorif7b4a942009-01-07 17:40:15 +00001489{
1490 BlockDriverState *bs;
1491 QEMUSnapshotInfo sn;
1492 char *filename, *snapshot_name = NULL;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001493 int c, ret = 0, bdrv_oflags;
aliguorif7b4a942009-01-07 17:40:15 +00001494 int action = 0;
1495 qemu_timeval tv;
1496
Kevin Wolf710da702011-01-10 12:33:02 +01001497 bdrv_oflags = BDRV_O_FLAGS | BDRV_O_RDWR;
aliguorif7b4a942009-01-07 17:40:15 +00001498 /* Parse commandline parameters */
1499 for(;;) {
1500 c = getopt(argc, argv, "la:c:d:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001501 if (c == -1) {
aliguorif7b4a942009-01-07 17:40:15 +00001502 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001503 }
aliguorif7b4a942009-01-07 17:40:15 +00001504 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001505 case '?':
aliguorif7b4a942009-01-07 17:40:15 +00001506 case 'h':
1507 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001508 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001509 case 'l':
1510 if (action) {
1511 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001512 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001513 }
1514 action = SNAPSHOT_LIST;
Naphtali Spreif5edb012010-01-17 16:48:13 +02001515 bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
aliguorif7b4a942009-01-07 17:40:15 +00001516 break;
1517 case 'a':
1518 if (action) {
1519 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001520 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001521 }
1522 action = SNAPSHOT_APPLY;
1523 snapshot_name = optarg;
1524 break;
1525 case 'c':
1526 if (action) {
1527 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001528 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001529 }
1530 action = SNAPSHOT_CREATE;
1531 snapshot_name = optarg;
1532 break;
1533 case 'd':
1534 if (action) {
1535 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001536 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001537 }
1538 action = SNAPSHOT_DELETE;
1539 snapshot_name = optarg;
1540 break;
1541 }
1542 }
1543
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001544 if (optind >= argc) {
aliguorif7b4a942009-01-07 17:40:15 +00001545 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001546 }
aliguorif7b4a942009-01-07 17:40:15 +00001547 filename = argv[optind++];
1548
1549 /* Open the image */
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +01001550 bs = bdrv_new_open(filename, NULL, bdrv_oflags, true);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001551 if (!bs) {
1552 return 1;
1553 }
aliguorif7b4a942009-01-07 17:40:15 +00001554
1555 /* Perform the requested action */
1556 switch(action) {
1557 case SNAPSHOT_LIST:
1558 dump_snapshots(bs);
1559 break;
1560
1561 case SNAPSHOT_CREATE:
1562 memset(&sn, 0, sizeof(sn));
1563 pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
1564
1565 qemu_gettimeofday(&tv);
1566 sn.date_sec = tv.tv_sec;
1567 sn.date_nsec = tv.tv_usec * 1000;
1568
1569 ret = bdrv_snapshot_create(bs, &sn);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001570 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001571 error_report("Could not create snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001572 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001573 }
aliguorif7b4a942009-01-07 17:40:15 +00001574 break;
1575
1576 case SNAPSHOT_APPLY:
1577 ret = bdrv_snapshot_goto(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001578 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001579 error_report("Could not apply snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001580 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001581 }
aliguorif7b4a942009-01-07 17:40:15 +00001582 break;
1583
1584 case SNAPSHOT_DELETE:
1585 ret = bdrv_snapshot_delete(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001586 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001587 error_report("Could not delete snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001588 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001589 }
aliguorif7b4a942009-01-07 17:40:15 +00001590 break;
1591 }
1592
1593 /* Cleanup */
1594 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001595 if (ret) {
1596 return 1;
1597 }
Stuart Brady153859b2009-06-07 00:42:17 +01001598 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001599}
1600
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001601static int img_rebase(int argc, char **argv)
1602{
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001603 BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001604 BlockDriver *old_backing_drv, *new_backing_drv;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001605 char *filename;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001606 const char *fmt, *cache, *out_basefmt, *out_baseimg;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001607 int c, flags, ret;
1608 int unsafe = 0;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001609 int progress = 0;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001610
1611 /* Parse commandline parameters */
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001612 fmt = NULL;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001613 cache = BDRV_DEFAULT_CACHE;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001614 out_baseimg = NULL;
1615 out_basefmt = NULL;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001616 for(;;) {
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001617 c = getopt(argc, argv, "uhf:F:b:pt:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001618 if (c == -1) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001619 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001620 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001621 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001622 case '?':
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001623 case 'h':
1624 help();
1625 return 0;
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001626 case 'f':
1627 fmt = optarg;
1628 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001629 case 'F':
1630 out_basefmt = optarg;
1631 break;
1632 case 'b':
1633 out_baseimg = optarg;
1634 break;
1635 case 'u':
1636 unsafe = 1;
1637 break;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001638 case 'p':
1639 progress = 1;
1640 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001641 case 't':
1642 cache = optarg;
1643 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001644 }
1645 }
1646
Anthony Liguori9a9d9db2011-04-13 15:51:47 +01001647 if ((optind >= argc) || (!unsafe && !out_baseimg)) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001648 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001649 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001650 filename = argv[optind++];
1651
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001652 qemu_progress_init(progress, 2.0);
1653 qemu_progress_print(0, 100);
1654
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001655 flags = BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +01001656 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001657 if (ret < 0) {
1658 error_report("Invalid cache option: %s", cache);
1659 return -1;
1660 }
1661
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001662 /*
1663 * Open the images.
1664 *
1665 * Ignore the old backing file for unsafe rebase in case we want to correct
1666 * the reference to a renamed or moved backing file.
1667 */
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +01001668 bs = bdrv_new_open(filename, fmt, flags, true);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001669 if (!bs) {
1670 return 1;
1671 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001672
1673 /* Find the right drivers for the backing files */
1674 old_backing_drv = NULL;
1675 new_backing_drv = NULL;
1676
1677 if (!unsafe && bs->backing_format[0] != '\0') {
1678 old_backing_drv = bdrv_find_format(bs->backing_format);
1679 if (old_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001680 error_report("Invalid format name: '%s'", bs->backing_format);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001681 ret = -1;
1682 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001683 }
1684 }
1685
1686 if (out_basefmt != NULL) {
1687 new_backing_drv = bdrv_find_format(out_basefmt);
1688 if (new_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001689 error_report("Invalid format name: '%s'", out_basefmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001690 ret = -1;
1691 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001692 }
1693 }
1694
1695 /* For safe rebasing we need to compare old and new backing file */
1696 if (unsafe) {
1697 /* Make the compiler happy */
1698 bs_old_backing = NULL;
1699 bs_new_backing = NULL;
1700 } else {
1701 char backing_name[1024];
1702
1703 bs_old_backing = bdrv_new("old_backing");
1704 bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001705 ret = bdrv_open(bs_old_backing, backing_name, BDRV_O_FLAGS,
1706 old_backing_drv);
1707 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001708 error_report("Could not open old backing file '%s'", backing_name);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001709 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001710 }
Alex Bligha6166732012-10-16 13:46:18 +01001711 if (out_baseimg[0]) {
1712 bs_new_backing = bdrv_new("new_backing");
1713 ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS,
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001714 new_backing_drv);
Alex Bligha6166732012-10-16 13:46:18 +01001715 if (ret) {
1716 error_report("Could not open new backing file '%s'",
1717 out_baseimg);
1718 goto out;
1719 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001720 }
1721 }
1722
1723 /*
1724 * Check each unallocated cluster in the COW file. If it is unallocated,
1725 * accesses go to the backing file. We must therefore compare this cluster
1726 * in the old and new backing file, and if they differ we need to copy it
1727 * from the old backing file into the COW file.
1728 *
1729 * If qemu-img crashes during this step, no harm is done. The content of
1730 * the image is the same as the original one at any time.
1731 */
1732 if (!unsafe) {
1733 uint64_t num_sectors;
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01001734 uint64_t old_backing_num_sectors;
Alex Bligha6166732012-10-16 13:46:18 +01001735 uint64_t new_backing_num_sectors = 0;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001736 uint64_t sector;
Kevin Wolfcc60e322010-04-29 14:47:48 +02001737 int n;
TeLeMand6771bf2010-02-08 16:20:00 +08001738 uint8_t * buf_old;
1739 uint8_t * buf_new;
Kevin Wolf1f710492012-10-12 14:29:18 +02001740 float local_progress = 0;
TeLeMand6771bf2010-02-08 16:20:00 +08001741
Kevin Wolfbb1c0592011-08-08 14:09:12 +02001742 buf_old = qemu_blockalign(bs, IO_BUF_SIZE);
1743 buf_new = qemu_blockalign(bs, IO_BUF_SIZE);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001744
1745 bdrv_get_geometry(bs, &num_sectors);
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01001746 bdrv_get_geometry(bs_old_backing, &old_backing_num_sectors);
Alex Bligha6166732012-10-16 13:46:18 +01001747 if (bs_new_backing) {
1748 bdrv_get_geometry(bs_new_backing, &new_backing_num_sectors);
1749 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001750
Kevin Wolf1f710492012-10-12 14:29:18 +02001751 if (num_sectors != 0) {
1752 local_progress = (float)100 /
1753 (num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512));
1754 }
1755
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001756 for (sector = 0; sector < num_sectors; sector += n) {
1757
1758 /* How many sectors can we handle with the next read? */
1759 if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
1760 n = (IO_BUF_SIZE / 512);
1761 } else {
1762 n = num_sectors - sector;
1763 }
1764
1765 /* If the cluster is allocated, we don't need to take action */
Kevin Wolfcc60e322010-04-29 14:47:48 +02001766 ret = bdrv_is_allocated(bs, sector, n, &n);
1767 if (ret) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001768 continue;
1769 }
1770
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01001771 /*
1772 * Read old and new backing file and take into consideration that
1773 * backing files may be smaller than the COW image.
1774 */
1775 if (sector >= old_backing_num_sectors) {
1776 memset(buf_old, 0, n * BDRV_SECTOR_SIZE);
1777 } else {
1778 if (sector + n > old_backing_num_sectors) {
1779 n = old_backing_num_sectors - sector;
1780 }
1781
1782 ret = bdrv_read(bs_old_backing, sector, buf_old, n);
1783 if (ret < 0) {
1784 error_report("error while reading from old backing file");
1785 goto out;
1786 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001787 }
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01001788
Alex Bligha6166732012-10-16 13:46:18 +01001789 if (sector >= new_backing_num_sectors || !bs_new_backing) {
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01001790 memset(buf_new, 0, n * BDRV_SECTOR_SIZE);
1791 } else {
1792 if (sector + n > new_backing_num_sectors) {
1793 n = new_backing_num_sectors - sector;
1794 }
1795
1796 ret = bdrv_read(bs_new_backing, sector, buf_new, n);
1797 if (ret < 0) {
1798 error_report("error while reading from new backing file");
1799 goto out;
1800 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001801 }
1802
1803 /* If they differ, we need to write to the COW file */
1804 uint64_t written = 0;
1805
1806 while (written < n) {
1807 int pnum;
1808
1809 if (compare_sectors(buf_old + written * 512,
Kevin Wolf60b1bd42010-02-17 12:32:59 +01001810 buf_new + written * 512, n - written, &pnum))
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001811 {
1812 ret = bdrv_write(bs, sector + written,
1813 buf_old + written * 512, pnum);
1814 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001815 error_report("Error while writing to COW image: %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001816 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001817 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001818 }
1819 }
1820
1821 written += pnum;
1822 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001823 qemu_progress_print(local_progress, 100);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001824 }
TeLeMand6771bf2010-02-08 16:20:00 +08001825
Kevin Wolfbb1c0592011-08-08 14:09:12 +02001826 qemu_vfree(buf_old);
1827 qemu_vfree(buf_new);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001828 }
1829
1830 /*
1831 * Change the backing file. All clusters that are different from the old
1832 * backing file are overwritten in the COW file now, so the visible content
1833 * doesn't change when we switch the backing file.
1834 */
Alex Bligha6166732012-10-16 13:46:18 +01001835 if (out_baseimg && *out_baseimg) {
1836 ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
1837 } else {
1838 ret = bdrv_change_backing_file(bs, NULL, NULL);
1839 }
1840
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001841 if (ret == -ENOSPC) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001842 error_report("Could not change the backing file to '%s': No "
1843 "space left in the file header", out_baseimg);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001844 } else if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001845 error_report("Could not change the backing file to '%s': %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001846 out_baseimg, strerror(-ret));
1847 }
1848
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001849 qemu_progress_print(100, 0);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001850 /*
1851 * TODO At this point it is possible to check if any clusters that are
1852 * allocated in the COW file are the same in the backing file. If so, they
1853 * could be dropped from the COW file. Don't do this before switching the
1854 * backing file, in case of a crash this would lead to corruption.
1855 */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001856out:
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001857 qemu_progress_end();
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001858 /* Cleanup */
1859 if (!unsafe) {
Kevin Wolfeb863ad2011-03-31 12:39:51 +02001860 if (bs_old_backing != NULL) {
1861 bdrv_delete(bs_old_backing);
1862 }
1863 if (bs_new_backing != NULL) {
1864 bdrv_delete(bs_new_backing);
1865 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001866 }
1867
1868 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001869 if (ret) {
1870 return 1;
1871 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001872 return 0;
1873}
1874
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001875static int img_resize(int argc, char **argv)
1876{
1877 int c, ret, relative;
1878 const char *filename, *fmt, *size;
1879 int64_t n, total_size;
Jes Sorensen2a819982010-12-06 17:08:31 +01001880 BlockDriverState *bs = NULL;
Dong Xu Wang20caf0f2012-08-06 10:18:42 +08001881 QemuOpts *param;
1882 static QemuOptsList resize_options = {
1883 .name = "resize_options",
1884 .head = QTAILQ_HEAD_INITIALIZER(resize_options.head),
1885 .desc = {
1886 {
1887 .name = BLOCK_OPT_SIZE,
1888 .type = QEMU_OPT_SIZE,
1889 .help = "Virtual disk size"
1890 }, {
1891 /* end of list */
1892 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001893 },
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001894 };
1895
Kevin Wolfe80fec72011-04-29 10:58:12 +02001896 /* Remove size from argv manually so that negative numbers are not treated
1897 * as options by getopt. */
1898 if (argc < 3) {
1899 help();
1900 return 1;
1901 }
1902
1903 size = argv[--argc];
1904
1905 /* Parse getopt arguments */
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001906 fmt = NULL;
1907 for(;;) {
1908 c = getopt(argc, argv, "f:h");
1909 if (c == -1) {
1910 break;
1911 }
1912 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001913 case '?':
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001914 case 'h':
1915 help();
1916 break;
1917 case 'f':
1918 fmt = optarg;
1919 break;
1920 }
1921 }
Kevin Wolfe80fec72011-04-29 10:58:12 +02001922 if (optind >= argc) {
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001923 help();
1924 }
1925 filename = argv[optind++];
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001926
1927 /* Choose grow, shrink, or absolute resize mode */
1928 switch (size[0]) {
1929 case '+':
1930 relative = 1;
1931 size++;
1932 break;
1933 case '-':
1934 relative = -1;
1935 size++;
1936 break;
1937 default:
1938 relative = 0;
1939 break;
1940 }
1941
1942 /* Parse size */
Dong Xu Wang20caf0f2012-08-06 10:18:42 +08001943 param = qemu_opts_create(&resize_options, NULL, 0, NULL);
1944 if (qemu_opt_set(param, BLOCK_OPT_SIZE, size)) {
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001945 /* Error message already printed when size parsing fails */
Jes Sorensen2a819982010-12-06 17:08:31 +01001946 ret = -1;
Dong Xu Wang20caf0f2012-08-06 10:18:42 +08001947 qemu_opts_del(param);
Jes Sorensen2a819982010-12-06 17:08:31 +01001948 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001949 }
Dong Xu Wang20caf0f2012-08-06 10:18:42 +08001950 n = qemu_opt_get_size(param, BLOCK_OPT_SIZE, 0);
1951 qemu_opts_del(param);
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001952
Daniel P. Berrangef0536bb2012-09-10 12:11:31 +01001953 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR, true);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001954 if (!bs) {
Jes Sorensen2a819982010-12-06 17:08:31 +01001955 ret = -1;
1956 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001957 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001958
1959 if (relative) {
1960 total_size = bdrv_getlength(bs) + n * relative;
1961 } else {
1962 total_size = n;
1963 }
1964 if (total_size <= 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001965 error_report("New image size must be positive");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001966 ret = -1;
1967 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001968 }
1969
1970 ret = bdrv_truncate(bs, total_size);
1971 switch (ret) {
1972 case 0:
1973 printf("Image resized.\n");
1974 break;
1975 case -ENOTSUP:
Kevin Wolf259b2172012-03-06 12:44:45 +01001976 error_report("This image does not support resize");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001977 break;
1978 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +01001979 error_report("Image is read-only");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001980 break;
1981 default:
Jes Sorensen15654a62010-12-16 14:31:53 +01001982 error_report("Error resizing image (%d)", -ret);
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001983 break;
1984 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001985out:
Jes Sorensen2a819982010-12-06 17:08:31 +01001986 if (bs) {
1987 bdrv_delete(bs);
1988 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001989 if (ret) {
1990 return 1;
1991 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001992 return 0;
1993}
1994
Anthony Liguoric227f092009-10-01 16:12:16 -05001995static const img_cmd_t img_cmds[] = {
Stuart Brady153859b2009-06-07 00:42:17 +01001996#define DEF(option, callback, arg_string) \
1997 { option, callback },
1998#include "qemu-img-cmds.h"
1999#undef DEF
2000#undef GEN_DOCS
2001 { NULL, NULL, },
2002};
2003
bellardea2384d2004-08-01 21:59:26 +00002004int main(int argc, char **argv)
2005{
Anthony Liguoric227f092009-10-01 16:12:16 -05002006 const img_cmd_t *cmd;
Stuart Brady153859b2009-06-07 00:42:17 +01002007 const char *cmdname;
bellardea2384d2004-08-01 21:59:26 +00002008
Kevin Wolf53f76e52010-12-16 15:10:32 +01002009 error_set_progname(argv[0]);
2010
Paolo Bonzini2592c592012-11-03 18:10:17 +01002011 qemu_init_main_loop();
bellardea2384d2004-08-01 21:59:26 +00002012 bdrv_init();
2013 if (argc < 2)
2014 help();
Stuart Brady153859b2009-06-07 00:42:17 +01002015 cmdname = argv[1];
aurel328f9b1572009-02-09 18:14:31 +00002016 argc--; argv++;
Stuart Brady153859b2009-06-07 00:42:17 +01002017
2018 /* find the command */
2019 for(cmd = img_cmds; cmd->name != NULL; cmd++) {
2020 if (!strcmp(cmdname, cmd->name)) {
2021 return cmd->handler(argc, argv);
2022 }
bellardea2384d2004-08-01 21:59:26 +00002023 }
Stuart Brady153859b2009-06-07 00:42:17 +01002024
2025 /* not found */
2026 help();
bellardea2384d2004-08-01 21:59:26 +00002027 return 0;
2028}