blob: c45ff62a28b9ee1c6c5662c855d4a257c35e92d2 [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 */
pbrookfaf07962007-11-11 02:51:17 +000024#include "qemu-common.h"
Kevin Wolf9ea2ea72009-05-18 16:42:11 +020025#include "qemu-option.h"
Kevin Wolf53f76e52010-12-16 15:10:32 +010026#include "qemu-error.h"
aliguorif7b4a942009-01-07 17:40:15 +000027#include "osdep.h"
Jes Sorensendc786bc2010-10-26 10:39:23 +020028#include "sysemu.h"
thsec36ba12007-09-16 21:59:02 +000029#include "block_int.h"
aliguori9230eaf2009-03-28 17:55:19 +000030#include <stdio.h>
bellardea2384d2004-08-01 21:59:26 +000031
bellarde8445332006-06-14 15:32:10 +000032#ifdef _WIN32
33#include <windows.h>
34#endif
35
Anthony Liguoric227f092009-10-01 16:12:16 -050036typedef struct img_cmd_t {
Stuart Brady153859b2009-06-07 00:42:17 +010037 const char *name;
38 int (*handler)(int argc, char **argv);
Anthony Liguoric227f092009-10-01 16:12:16 -050039} img_cmd_t;
Stuart Brady153859b2009-06-07 00:42:17 +010040
aurel32137519c2008-11-30 19:12:49 +000041/* Default to cache=writeback as data integrity is not important for qemu-tcg. */
Stefan Hajnocziadfe0782010-04-13 10:29:35 +010042#define BDRV_O_FLAGS BDRV_O_CACHE_WB
Federico Simoncelli661a0f72011-06-20 12:48:19 -040043#define BDRV_DEFAULT_CACHE "writeback"
aurel32137519c2008-11-30 19:12:49 +000044
bellardea2384d2004-08-01 21:59:26 +000045static void format_print(void *opaque, const char *name)
46{
47 printf(" %s", name);
48}
49
blueswir1d2c639d2009-01-24 18:19:25 +000050/* Please keep in synch with qemu-img.texi */
pbrook3f379ab2007-11-11 03:33:13 +000051static void help(void)
bellardea2384d2004-08-01 21:59:26 +000052{
Paolo Bonzinie00291c2010-02-04 16:49:56 +010053 const char *help_msg =
54 "qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fabrice Bellard\n"
malc3f020d72010-02-08 12:04:56 +030055 "usage: qemu-img command [command options]\n"
56 "QEMU disk image utility\n"
57 "\n"
58 "Command syntax:\n"
Stuart Brady153859b2009-06-07 00:42:17 +010059#define DEF(option, callback, arg_string) \
60 " " arg_string "\n"
61#include "qemu-img-cmds.h"
62#undef DEF
63#undef GEN_DOCS
malc3f020d72010-02-08 12:04:56 +030064 "\n"
65 "Command parameters:\n"
66 " 'filename' is a disk image filename\n"
67 " 'fmt' is the disk image format. It is guessed automatically in most cases\n"
Federico Simoncelli661a0f72011-06-20 12:48:19 -040068 " 'cache' is the cache mode used to write the output disk image, the valid\n"
Liu Yuan80ccf932012-04-20 17:10:56 +080069 " options are: 'none', 'writeback' (default, except for convert), 'writethrough',\n"
70 " 'directsync' and 'unsafe' (default for convert)\n"
malc3f020d72010-02-08 12:04:56 +030071 " 'size' is the disk image size in bytes. Optional suffixes\n"
72 " 'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M)\n"
73 " and T (terabyte, 1024G) are supported. 'b' is ignored.\n"
74 " 'output_filename' is the destination disk image filename\n"
75 " 'output_fmt' is the destination format\n"
76 " 'options' is a comma separated list of format specific options in a\n"
77 " name=value format. Use -o ? for an overview of the options supported by the\n"
78 " used format\n"
79 " '-c' indicates that target image must be compressed (qcow format only)\n"
80 " '-u' enables unsafe rebasing. It is assumed that old and new backing file\n"
81 " match exactly. The image doesn't need a working backing file before\n"
82 " rebasing in this case (useful for renaming the backing file)\n"
83 " '-h' with or without a command shows this help and lists the supported formats\n"
Jes Sorensen6b837bc2011-03-30 14:16:25 +020084 " '-p' show progress of command (only certain commands)\n"
Kevin Wolfa22f1232011-08-26 15:27:13 +020085 " '-S' indicates the consecutive number of bytes that must contain only zeros\n"
86 " for qemu-img to create a sparse image during conversion\n"
malc3f020d72010-02-08 12:04:56 +030087 "\n"
Kevin Wolf4534ff52012-05-11 16:07:02 +020088 "Parameters to check subcommand:\n"
89 " '-r' tries to repair any inconsistencies that are found during the check.\n"
90 " '-r leaks' repairs only cluster leaks, whereas '-r all' fixes all\n"
91 " kinds of errors, with a higher risk of choosing the wrong fix or\n"
92 " hiding corruption that has already occured.\n"
93 "\n"
malc3f020d72010-02-08 12:04:56 +030094 "Parameters to snapshot subcommand:\n"
95 " 'snapshot' is the name of the snapshot to create, apply or delete\n"
96 " '-a' applies a snapshot (revert disk to saved state)\n"
97 " '-c' creates a snapshot\n"
98 " '-d' deletes a snapshot\n"
Paolo Bonzinie00291c2010-02-04 16:49:56 +010099 " '-l' lists all snapshots in the given image\n";
100
101 printf("%s\nSupported formats:", help_msg);
bellardea2384d2004-08-01 21:59:26 +0000102 bdrv_iterate_format(format_print, NULL);
103 printf("\n");
104 exit(1);
105}
106
bellardea2384d2004-08-01 21:59:26 +0000107#if defined(WIN32)
108/* XXX: put correct support for win32 */
109static int read_password(char *buf, int buf_size)
110{
111 int c, i;
112 printf("Password: ");
113 fflush(stdout);
114 i = 0;
115 for(;;) {
116 c = getchar();
117 if (c == '\n')
118 break;
119 if (i < (buf_size - 1))
120 buf[i++] = c;
121 }
122 buf[i] = '\0';
123 return 0;
124}
125
126#else
127
128#include <termios.h>
129
130static struct termios oldtty;
131
132static void term_exit(void)
133{
134 tcsetattr (0, TCSANOW, &oldtty);
135}
136
137static void term_init(void)
138{
139 struct termios tty;
140
141 tcgetattr (0, &tty);
142 oldtty = tty;
143
144 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
145 |INLCR|IGNCR|ICRNL|IXON);
146 tty.c_oflag |= OPOST;
147 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
148 tty.c_cflag &= ~(CSIZE|PARENB);
149 tty.c_cflag |= CS8;
150 tty.c_cc[VMIN] = 1;
151 tty.c_cc[VTIME] = 0;
ths3b46e622007-09-17 08:09:54 +0000152
bellardea2384d2004-08-01 21:59:26 +0000153 tcsetattr (0, TCSANOW, &tty);
154
155 atexit(term_exit);
156}
157
pbrook3f379ab2007-11-11 03:33:13 +0000158static int read_password(char *buf, int buf_size)
bellardea2384d2004-08-01 21:59:26 +0000159{
160 uint8_t ch;
161 int i, ret;
162
163 printf("password: ");
164 fflush(stdout);
165 term_init();
166 i = 0;
167 for(;;) {
168 ret = read(0, &ch, 1);
169 if (ret == -1) {
170 if (errno == EAGAIN || errno == EINTR) {
171 continue;
172 } else {
173 ret = -1;
174 break;
175 }
176 } else if (ret == 0) {
177 ret = -1;
178 break;
179 } else {
180 if (ch == '\r') {
181 ret = 0;
182 break;
183 }
184 if (i < (buf_size - 1))
185 buf[i++] = ch;
186 }
187 }
188 term_exit();
189 buf[i] = '\0';
190 printf("\n");
191 return ret;
192}
193#endif
194
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100195static int print_block_option_help(const char *filename, const char *fmt)
196{
197 BlockDriver *drv, *proto_drv;
198 QEMUOptionParameter *create_options = NULL;
199
200 /* Find driver and parse its options */
201 drv = bdrv_find_format(fmt);
202 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100203 error_report("Unknown file format '%s'", fmt);
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100204 return 1;
205 }
206
207 proto_drv = bdrv_find_protocol(filename);
208 if (!proto_drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100209 error_report("Unknown protocol '%s'", filename);
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100210 return 1;
211 }
212
213 create_options = append_option_parameters(create_options,
214 drv->create_options);
215 create_options = append_option_parameters(create_options,
216 proto_drv->create_options);
217 print_option_help(create_options);
218 free_option_parameters(create_options);
219 return 0;
220}
221
bellard75c23802004-08-27 21:28:58 +0000222static BlockDriverState *bdrv_new_open(const char *filename,
Sheng Yang9bc378c2010-01-29 10:15:06 +0800223 const char *fmt,
Stefan Hajnoczif163d072010-04-13 10:29:34 +0100224 int flags)
bellard75c23802004-08-27 21:28:58 +0000225{
226 BlockDriverState *bs;
227 BlockDriver *drv;
228 char password[256];
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100229 int ret;
bellard75c23802004-08-27 21:28:58 +0000230
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100231 bs = bdrv_new("image");
Kevin Wolfad717132010-12-16 15:37:41 +0100232
bellard75c23802004-08-27 21:28:58 +0000233 if (fmt) {
234 drv = bdrv_find_format(fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900235 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100236 error_report("Unknown file format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900237 goto fail;
238 }
bellard75c23802004-08-27 21:28:58 +0000239 } else {
240 drv = NULL;
241 }
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100242
243 ret = bdrv_open(bs, filename, flags, drv);
244 if (ret < 0) {
245 error_report("Could not open '%s': %s", filename, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900246 goto fail;
bellard75c23802004-08-27 21:28:58 +0000247 }
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100248
bellard75c23802004-08-27 21:28:58 +0000249 if (bdrv_is_encrypted(bs)) {
250 printf("Disk image '%s' is encrypted.\n", filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900251 if (read_password(password, sizeof(password)) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100252 error_report("No password given");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900253 goto fail;
254 }
255 if (bdrv_set_key(bs, password) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100256 error_report("invalid password");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900257 goto fail;
258 }
bellard75c23802004-08-27 21:28:58 +0000259 }
260 return bs;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900261fail:
262 if (bs) {
263 bdrv_delete(bs);
264 }
265 return NULL;
bellard75c23802004-08-27 21:28:58 +0000266}
267
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900268static int add_old_style_options(const char *fmt, QEMUOptionParameter *list,
Jes Sorenseneec77d92010-12-07 17:44:34 +0100269 const char *base_filename,
270 const char *base_fmt)
Kevin Wolfefa84d42009-05-18 16:42:12 +0200271{
Kevin Wolfefa84d42009-05-18 16:42:12 +0200272 if (base_filename) {
273 if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100274 error_report("Backing file not supported for file format '%s'",
275 fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900276 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200277 }
278 }
279 if (base_fmt) {
280 if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100281 error_report("Backing file format not supported for file "
282 "format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900283 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200284 }
285 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900286 return 0;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200287}
288
bellardea2384d2004-08-01 21:59:26 +0000289static int img_create(int argc, char **argv)
290{
Jes Sorenseneec77d92010-12-07 17:44:34 +0100291 int c, ret = 0;
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100292 uint64_t img_size = -1;
bellardea2384d2004-08-01 21:59:26 +0000293 const char *fmt = "raw";
aliguori9230eaf2009-03-28 17:55:19 +0000294 const char *base_fmt = NULL;
bellardea2384d2004-08-01 21:59:26 +0000295 const char *filename;
296 const char *base_filename = NULL;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200297 char *options = NULL;
ths3b46e622007-09-17 08:09:54 +0000298
bellardea2384d2004-08-01 21:59:26 +0000299 for(;;) {
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200300 c = getopt(argc, argv, "F:b:f:he6o:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100301 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000302 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100303 }
bellardea2384d2004-08-01 21:59:26 +0000304 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100305 case '?':
bellardea2384d2004-08-01 21:59:26 +0000306 case 'h':
307 help();
308 break;
aliguori9230eaf2009-03-28 17:55:19 +0000309 case 'F':
310 base_fmt = optarg;
311 break;
bellardea2384d2004-08-01 21:59:26 +0000312 case 'b':
313 base_filename = optarg;
314 break;
315 case 'f':
316 fmt = optarg;
317 break;
318 case 'e':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200319 error_report("option -e is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100320 "encryption\' instead!");
321 return 1;
thsd8871c52007-10-24 16:11:42 +0000322 case '6':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200323 error_report("option -6 is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100324 "compat6\' instead!");
325 return 1;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200326 case 'o':
327 options = optarg;
328 break;
bellardea2384d2004-08-01 21:59:26 +0000329 }
330 }
aliguori9230eaf2009-03-28 17:55:19 +0000331
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900332 /* Get the filename */
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100333 if (optind >= argc) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900334 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100335 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900336 filename = argv[optind++];
337
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100338 /* Get image size, if specified */
339 if (optind < argc) {
Jes Sorensen70b4f4b2011-01-05 11:41:02 +0100340 int64_t sval;
Markus Armbrustere36b3692011-11-22 09:46:05 +0100341 char *end;
342 sval = strtosz_suffix(argv[optind++], &end, STRTOSZ_DEFSUFFIX_B);
343 if (sval < 0 || *end) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100344 error_report("Invalid image size specified! You may use k, M, G or "
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100345 "T suffixes for ");
Jes Sorensen15654a62010-12-16 14:31:53 +0100346 error_report("kilobytes, megabytes, gigabytes and terabytes.");
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100347 ret = -1;
348 goto out;
349 }
350 img_size = (uint64_t)sval;
351 }
352
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100353 if (options && !strcmp(options, "?")) {
354 ret = print_block_option_help(filename, fmt);
355 goto out;
356 }
357
Jes Sorensenf88e1a42010-12-16 13:52:15 +0100358 ret = bdrv_img_create(filename, fmt, base_filename, base_fmt,
359 options, img_size, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900360out:
361 if (ret) {
362 return 1;
363 }
bellardea2384d2004-08-01 21:59:26 +0000364 return 0;
365}
366
Kevin Wolfe076f332010-06-29 11:43:13 +0200367/*
368 * Checks an image for consistency. Exit codes:
369 *
370 * 0 - Check completed, image is good
371 * 1 - Check not completed because of internal errors
372 * 2 - Check completed, image is corrupted
373 * 3 - Check completed, image has leaked clusters, but is good otherwise
374 */
aliguori15859692009-04-21 23:11:53 +0000375static int img_check(int argc, char **argv)
376{
377 int c, ret;
378 const char *filename, *fmt;
aliguori15859692009-04-21 23:11:53 +0000379 BlockDriverState *bs;
Kevin Wolfe076f332010-06-29 11:43:13 +0200380 BdrvCheckResult result;
Kevin Wolf4534ff52012-05-11 16:07:02 +0200381 int fix = 0;
382 int flags = BDRV_O_FLAGS;
aliguori15859692009-04-21 23:11:53 +0000383
384 fmt = NULL;
385 for(;;) {
Kevin Wolf4534ff52012-05-11 16:07:02 +0200386 c = getopt(argc, argv, "f:hr:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100387 if (c == -1) {
aliguori15859692009-04-21 23:11:53 +0000388 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100389 }
aliguori15859692009-04-21 23:11:53 +0000390 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100391 case '?':
aliguori15859692009-04-21 23:11:53 +0000392 case 'h':
393 help();
394 break;
395 case 'f':
396 fmt = optarg;
397 break;
Kevin Wolf4534ff52012-05-11 16:07:02 +0200398 case 'r':
399 flags |= BDRV_O_RDWR;
400
401 if (!strcmp(optarg, "leaks")) {
402 fix = BDRV_FIX_LEAKS;
403 } else if (!strcmp(optarg, "all")) {
404 fix = BDRV_FIX_LEAKS | BDRV_FIX_ERRORS;
405 } else {
406 help();
407 }
408 break;
aliguori15859692009-04-21 23:11:53 +0000409 }
410 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100411 if (optind >= argc) {
aliguori15859692009-04-21 23:11:53 +0000412 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100413 }
aliguori15859692009-04-21 23:11:53 +0000414 filename = argv[optind++];
415
Kevin Wolf4534ff52012-05-11 16:07:02 +0200416 bs = bdrv_new_open(filename, fmt, flags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900417 if (!bs) {
418 return 1;
419 }
Kevin Wolf4534ff52012-05-11 16:07:02 +0200420 ret = bdrv_check(bs, &result, fix);
Kevin Wolfe076f332010-06-29 11:43:13 +0200421
422 if (ret == -ENOTSUP) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100423 error_report("This image format does not support checks");
Kevin Wolfe076f332010-06-29 11:43:13 +0200424 bdrv_delete(bs);
425 return 1;
426 }
427
428 if (!(result.corruptions || result.leaks || result.check_errors)) {
429 printf("No errors were found on the image.\n");
430 } else {
431 if (result.corruptions) {
432 printf("\n%d errors were found on the image.\n"
433 "Data may be corrupted, or further writes to the image "
434 "may corrupt it.\n",
435 result.corruptions);
aliguori15859692009-04-21 23:11:53 +0000436 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200437
438 if (result.leaks) {
439 printf("\n%d leaked clusters were found on the image.\n"
440 "This means waste of disk space, but no harm to data.\n",
441 result.leaks);
442 }
443
444 if (result.check_errors) {
445 printf("\n%d internal errors have occurred during the check.\n",
446 result.check_errors);
447 }
aliguori15859692009-04-21 23:11:53 +0000448 }
449
Dong Xu Wangf8111c22012-03-15 20:13:31 +0800450 if (result.bfi.total_clusters != 0 && result.bfi.allocated_clusters != 0) {
451 printf("%" PRId64 "/%" PRId64 "= %0.2f%% allocated, %0.2f%% fragmented\n",
452 result.bfi.allocated_clusters, result.bfi.total_clusters,
453 result.bfi.allocated_clusters * 100.0 / result.bfi.total_clusters,
454 result.bfi.fragmented_clusters * 100.0 / result.bfi.allocated_clusters);
455 }
456
aliguori15859692009-04-21 23:11:53 +0000457 bdrv_delete(bs);
Kevin Wolfe076f332010-06-29 11:43:13 +0200458
459 if (ret < 0 || result.check_errors) {
460 printf("\nAn error has occurred during the check: %s\n"
461 "The check is not complete and may have missed error.\n",
462 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900463 return 1;
464 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200465
466 if (result.corruptions) {
467 return 2;
468 } else if (result.leaks) {
469 return 3;
470 } else {
471 return 0;
472 }
aliguori15859692009-04-21 23:11:53 +0000473}
474
bellardea2384d2004-08-01 21:59:26 +0000475static int img_commit(int argc, char **argv)
476{
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400477 int c, ret, flags;
478 const char *filename, *fmt, *cache;
bellardea2384d2004-08-01 21:59:26 +0000479 BlockDriverState *bs;
480
481 fmt = NULL;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400482 cache = BDRV_DEFAULT_CACHE;
bellardea2384d2004-08-01 21:59:26 +0000483 for(;;) {
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400484 c = getopt(argc, argv, "f:ht:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100485 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000486 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100487 }
bellardea2384d2004-08-01 21:59:26 +0000488 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100489 case '?':
bellardea2384d2004-08-01 21:59:26 +0000490 case 'h':
491 help();
492 break;
493 case 'f':
494 fmt = optarg;
495 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400496 case 't':
497 cache = optarg;
498 break;
bellardea2384d2004-08-01 21:59:26 +0000499 }
500 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100501 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +0000502 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100503 }
bellardea2384d2004-08-01 21:59:26 +0000504 filename = argv[optind++];
505
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400506 flags = BDRV_O_RDWR;
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +0100507 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400508 if (ret < 0) {
509 error_report("Invalid cache option: %s", cache);
510 return -1;
511 }
512
513 bs = bdrv_new_open(filename, fmt, flags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900514 if (!bs) {
515 return 1;
516 }
bellardea2384d2004-08-01 21:59:26 +0000517 ret = bdrv_commit(bs);
518 switch(ret) {
519 case 0:
520 printf("Image committed.\n");
521 break;
522 case -ENOENT:
Jes Sorensen15654a62010-12-16 14:31:53 +0100523 error_report("No disk inserted");
bellardea2384d2004-08-01 21:59:26 +0000524 break;
525 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +0100526 error_report("Image is read-only");
bellardea2384d2004-08-01 21:59:26 +0000527 break;
528 case -ENOTSUP:
Jes Sorensen15654a62010-12-16 14:31:53 +0100529 error_report("Image is already committed");
bellardea2384d2004-08-01 21:59:26 +0000530 break;
531 default:
Jes Sorensen15654a62010-12-16 14:31:53 +0100532 error_report("Error while committing image");
bellardea2384d2004-08-01 21:59:26 +0000533 break;
534 }
535
536 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900537 if (ret) {
538 return 1;
539 }
bellardea2384d2004-08-01 21:59:26 +0000540 return 0;
541}
542
Dmitry Konishchevf6a00aa2011-05-18 15:03:59 +0400543/*
thsf58c7b32008-06-05 21:53:49 +0000544 * Returns true iff the first sector pointed to by 'buf' contains at least
545 * a non-NUL byte.
546 *
547 * 'pnum' is set to the number of sectors (including and immediately following
548 * the first one) that are known to be in the same allocated/unallocated state.
549 */
bellardea2384d2004-08-01 21:59:26 +0000550static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
551{
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000552 bool is_zero;
553 int i;
bellardea2384d2004-08-01 21:59:26 +0000554
555 if (n <= 0) {
556 *pnum = 0;
557 return 0;
558 }
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000559 is_zero = buffer_is_zero(buf, 512);
bellardea2384d2004-08-01 21:59:26 +0000560 for(i = 1; i < n; i++) {
561 buf += 512;
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000562 if (is_zero != buffer_is_zero(buf, 512)) {
bellardea2384d2004-08-01 21:59:26 +0000563 break;
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000564 }
bellardea2384d2004-08-01 21:59:26 +0000565 }
566 *pnum = i;
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000567 return !is_zero;
bellardea2384d2004-08-01 21:59:26 +0000568}
569
Kevin Wolf3e85c6f2010-01-12 12:55:18 +0100570/*
Kevin Wolfa22f1232011-08-26 15:27:13 +0200571 * Like is_allocated_sectors, but if the buffer starts with a used sector,
572 * up to 'min' consecutive sectors containing zeros are ignored. This avoids
573 * breaking up write requests for only small sparse areas.
574 */
575static int is_allocated_sectors_min(const uint8_t *buf, int n, int *pnum,
576 int min)
577{
578 int ret;
579 int num_checked, num_used;
580
581 if (n < min) {
582 min = n;
583 }
584
585 ret = is_allocated_sectors(buf, n, pnum);
586 if (!ret) {
587 return ret;
588 }
589
590 num_used = *pnum;
591 buf += BDRV_SECTOR_SIZE * *pnum;
592 n -= *pnum;
593 num_checked = num_used;
594
595 while (n > 0) {
596 ret = is_allocated_sectors(buf, n, pnum);
597
598 buf += BDRV_SECTOR_SIZE * *pnum;
599 n -= *pnum;
600 num_checked += *pnum;
601 if (ret) {
602 num_used = num_checked;
603 } else if (*pnum >= min) {
604 break;
605 }
606 }
607
608 *pnum = num_used;
609 return 1;
610}
611
612/*
Kevin Wolf3e85c6f2010-01-12 12:55:18 +0100613 * Compares two buffers sector by sector. Returns 0 if the first sector of both
614 * buffers matches, non-zero otherwise.
615 *
616 * pnum is set to the number of sectors (including and immediately following
617 * the first one) that are known to have the same comparison result
618 */
619static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
620 int *pnum)
621{
622 int res, i;
623
624 if (n <= 0) {
625 *pnum = 0;
626 return 0;
627 }
628
629 res = !!memcmp(buf1, buf2, 512);
630 for(i = 1; i < n; i++) {
631 buf1 += 512;
632 buf2 += 512;
633
634 if (!!memcmp(buf1, buf2, 512) != res) {
635 break;
636 }
637 }
638
639 *pnum = i;
640 return res;
641}
642
Kevin Wolf80ee15a2009-09-15 12:30:43 +0200643#define IO_BUF_SIZE (2 * 1024 * 1024)
bellardea2384d2004-08-01 21:59:26 +0000644
645static int img_convert(int argc, char **argv)
646{
Jes Sorenseneec77d92010-12-07 17:44:34 +0100647 int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400648 int progress = 0, flags;
649 const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900650 BlockDriver *drv, *proto_drv;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900651 BlockDriverState **bs = NULL, *out_bs = NULL;
ths96b8f132007-12-17 01:35:20 +0000652 int64_t total_sectors, nb_sectors, sector_num, bs_offset;
653 uint64_t bs_sectors;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900654 uint8_t * buf = NULL;
bellardea2384d2004-08-01 21:59:26 +0000655 const uint8_t *buf1;
bellardfaea38e2006-08-05 21:31:00 +0000656 BlockDriverInfo bdi;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900657 QEMUOptionParameter *param = NULL, *create_options = NULL;
Kevin Wolfa18953f2010-10-14 15:46:04 +0200658 QEMUOptionParameter *out_baseimg_param;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200659 char *options = NULL;
edison51ef6722010-09-21 19:58:41 -0700660 const char *snapshot_name = NULL;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200661 float local_progress;
Kevin Wolfa22f1232011-08-26 15:27:13 +0200662 int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */
bellardea2384d2004-08-01 21:59:26 +0000663
664 fmt = NULL;
665 out_fmt = "raw";
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400666 cache = "unsafe";
thsf58c7b32008-06-05 21:53:49 +0000667 out_baseimg = NULL;
Jes Sorenseneec77d92010-12-07 17:44:34 +0100668 compress = 0;
bellardea2384d2004-08-01 21:59:26 +0000669 for(;;) {
Kevin Wolfa22f1232011-08-26 15:27:13 +0200670 c = getopt(argc, argv, "f:O:B:s:hce6o:pS:t:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100671 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000672 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100673 }
bellardea2384d2004-08-01 21:59:26 +0000674 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100675 case '?':
bellardea2384d2004-08-01 21:59:26 +0000676 case 'h':
677 help();
678 break;
679 case 'f':
680 fmt = optarg;
681 break;
682 case 'O':
683 out_fmt = optarg;
684 break;
thsf58c7b32008-06-05 21:53:49 +0000685 case 'B':
686 out_baseimg = optarg;
687 break;
bellardea2384d2004-08-01 21:59:26 +0000688 case 'c':
Jes Sorenseneec77d92010-12-07 17:44:34 +0100689 compress = 1;
bellardea2384d2004-08-01 21:59:26 +0000690 break;
691 case 'e':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200692 error_report("option -e is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100693 "encryption\' instead!");
694 return 1;
thsec36ba12007-09-16 21:59:02 +0000695 case '6':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200696 error_report("option -6 is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100697 "compat6\' instead!");
698 return 1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200699 case 'o':
700 options = optarg;
701 break;
edison51ef6722010-09-21 19:58:41 -0700702 case 's':
703 snapshot_name = optarg;
704 break;
Kevin Wolfa22f1232011-08-26 15:27:13 +0200705 case 'S':
706 {
707 int64_t sval;
Markus Armbrustere36b3692011-11-22 09:46:05 +0100708 char *end;
709 sval = strtosz_suffix(optarg, &end, STRTOSZ_DEFSUFFIX_B);
710 if (sval < 0 || *end) {
Kevin Wolfa22f1232011-08-26 15:27:13 +0200711 error_report("Invalid minimum zero buffer size for sparse output specified");
712 return 1;
713 }
714
715 min_sparse = sval / BDRV_SECTOR_SIZE;
716 break;
717 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200718 case 'p':
719 progress = 1;
720 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400721 case 't':
722 cache = optarg;
723 break;
bellardea2384d2004-08-01 21:59:26 +0000724 }
725 }
ths3b46e622007-09-17 08:09:54 +0000726
balrog926c2d22007-10-31 01:11:44 +0000727 bs_n = argc - optind - 1;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100728 if (bs_n < 1) {
729 help();
730 }
balrog926c2d22007-10-31 01:11:44 +0000731
732 out_filename = argv[argc - 1];
thsf58c7b32008-06-05 21:53:49 +0000733
Charles Arnoldfa170c12012-05-11 10:57:54 -0600734 /* Initialize before goto out */
735 qemu_progress_init(progress, 2.0);
736
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100737 if (options && !strcmp(options, "?")) {
738 ret = print_block_option_help(out_filename, out_fmt);
739 goto out;
740 }
741
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900742 if (bs_n > 1 && out_baseimg) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100743 error_report("-B makes no sense when concatenating multiple input "
744 "images");
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100745 ret = -1;
746 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900747 }
Dong Xu Wangf8111c22012-03-15 20:13:31 +0800748
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200749 qemu_progress_print(0, 100);
750
Anthony Liguori7267c092011-08-20 22:09:37 -0500751 bs = g_malloc0(bs_n * sizeof(BlockDriverState *));
balrog926c2d22007-10-31 01:11:44 +0000752
753 total_sectors = 0;
754 for (bs_i = 0; bs_i < bs_n; bs_i++) {
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100755 bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900756 if (!bs[bs_i]) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100757 error_report("Could not open '%s'", argv[optind + bs_i]);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900758 ret = -1;
759 goto out;
760 }
balrog926c2d22007-10-31 01:11:44 +0000761 bdrv_get_geometry(bs[bs_i], &bs_sectors);
762 total_sectors += bs_sectors;
763 }
bellardea2384d2004-08-01 21:59:26 +0000764
edison51ef6722010-09-21 19:58:41 -0700765 if (snapshot_name != NULL) {
766 if (bs_n > 1) {
Markus Armbruster6daf1942011-06-22 14:03:54 +0200767 error_report("No support for concatenating multiple snapshot");
edison51ef6722010-09-21 19:58:41 -0700768 ret = -1;
769 goto out;
770 }
771 if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
Markus Armbruster6daf1942011-06-22 14:03:54 +0200772 error_report("Failed to load snapshot");
edison51ef6722010-09-21 19:58:41 -0700773 ret = -1;
774 goto out;
775 }
776 }
777
Kevin Wolfefa84d42009-05-18 16:42:12 +0200778 /* Find driver and parse its options */
bellardea2384d2004-08-01 21:59:26 +0000779 drv = bdrv_find_format(out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900780 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100781 error_report("Unknown file format '%s'", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900782 ret = -1;
783 goto out;
784 }
balrog926c2d22007-10-31 01:11:44 +0000785
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900786 proto_drv = bdrv_find_protocol(out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900787 if (!proto_drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100788 error_report("Unknown protocol '%s'", out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900789 ret = -1;
790 goto out;
791 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900792
793 create_options = append_option_parameters(create_options,
794 drv->create_options);
795 create_options = append_option_parameters(create_options,
796 proto_drv->create_options);
Kevin Wolfdb08adf2009-06-04 15:39:38 +0200797
Kevin Wolfefa84d42009-05-18 16:42:12 +0200798 if (options) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900799 param = parse_option_parameters(options, create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200800 if (param == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100801 error_report("Invalid options for file format '%s'.", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900802 ret = -1;
803 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200804 }
805 } else {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900806 param = parse_option_parameters("", create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200807 }
808
809 set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
Jes Sorenseneec77d92010-12-07 17:44:34 +0100810 ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900811 if (ret < 0) {
812 goto out;
813 }
Kevin Wolfefa84d42009-05-18 16:42:12 +0200814
Kevin Wolfa18953f2010-10-14 15:46:04 +0200815 /* Get backing file name if -o backing_file was used */
816 out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
817 if (out_baseimg_param) {
818 out_baseimg = out_baseimg_param->value.s;
819 }
820
Kevin Wolfefa84d42009-05-18 16:42:12 +0200821 /* Check if compression is supported */
Jes Sorenseneec77d92010-12-07 17:44:34 +0100822 if (compress) {
Kevin Wolfefa84d42009-05-18 16:42:12 +0200823 QEMUOptionParameter *encryption =
824 get_option_parameter(param, BLOCK_OPT_ENCRYPT);
Kevin Wolf41521fa2011-10-18 16:19:42 +0200825 QEMUOptionParameter *preallocation =
826 get_option_parameter(param, BLOCK_OPT_PREALLOC);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200827
828 if (!drv->bdrv_write_compressed) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100829 error_report("Compression not supported for this file format");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900830 ret = -1;
831 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200832 }
833
834 if (encryption && encryption->value.n) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100835 error_report("Compression and encryption not supported at "
836 "the same time");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900837 ret = -1;
838 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200839 }
Kevin Wolf41521fa2011-10-18 16:19:42 +0200840
841 if (preallocation && preallocation->value.s
842 && strcmp(preallocation->value.s, "off"))
843 {
844 error_report("Compression and preallocation not supported at "
845 "the same time");
846 ret = -1;
847 goto out;
848 }
Kevin Wolfefa84d42009-05-18 16:42:12 +0200849 }
850
851 /* Create the new image */
852 ret = bdrv_create(drv, out_filename, param);
bellardea2384d2004-08-01 21:59:26 +0000853 if (ret < 0) {
854 if (ret == -ENOTSUP) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100855 error_report("Formatting not supported for file format '%s'",
856 out_fmt);
aurel326e9ea0c2009-04-15 14:42:46 +0000857 } else if (ret == -EFBIG) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100858 error_report("The image size is too large for file format '%s'",
859 out_fmt);
bellardea2384d2004-08-01 21:59:26 +0000860 } else {
Jes Sorensen15654a62010-12-16 14:31:53 +0100861 error_report("%s: error while converting %s: %s",
862 out_filename, out_fmt, strerror(-ret));
bellardea2384d2004-08-01 21:59:26 +0000863 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900864 goto out;
bellardea2384d2004-08-01 21:59:26 +0000865 }
ths3b46e622007-09-17 08:09:54 +0000866
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400867 flags = BDRV_O_RDWR;
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +0100868 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400869 if (ret < 0) {
870 error_report("Invalid cache option: %s", cache);
871 return -1;
872 }
873
874 out_bs = bdrv_new_open(out_filename, out_fmt, flags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900875 if (!out_bs) {
876 ret = -1;
877 goto out;
878 }
bellardea2384d2004-08-01 21:59:26 +0000879
balrog926c2d22007-10-31 01:11:44 +0000880 bs_i = 0;
881 bs_offset = 0;
882 bdrv_get_geometry(bs[0], &bs_sectors);
Kevin Wolfbb1c0592011-08-08 14:09:12 +0200883 buf = qemu_blockalign(out_bs, IO_BUF_SIZE);
balrog926c2d22007-10-31 01:11:44 +0000884
Jes Sorenseneec77d92010-12-07 17:44:34 +0100885 if (compress) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900886 ret = bdrv_get_info(out_bs, &bdi);
887 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100888 error_report("could not get block driver info");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900889 goto out;
890 }
bellardfaea38e2006-08-05 21:31:00 +0000891 cluster_size = bdi.cluster_size;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900892 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100893 error_report("invalid cluster size");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900894 ret = -1;
895 goto out;
896 }
bellardea2384d2004-08-01 21:59:26 +0000897 cluster_sectors = cluster_size >> 9;
898 sector_num = 0;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200899
900 nb_sectors = total_sectors;
901 local_progress = (float)100 /
Jes Sorensen4ee96412011-05-06 11:39:11 +0200902 (nb_sectors / MIN(nb_sectors, cluster_sectors));
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200903
bellardea2384d2004-08-01 21:59:26 +0000904 for(;;) {
balrog926c2d22007-10-31 01:11:44 +0000905 int64_t bs_num;
906 int remainder;
907 uint8_t *buf2;
908
bellardea2384d2004-08-01 21:59:26 +0000909 nb_sectors = total_sectors - sector_num;
910 if (nb_sectors <= 0)
911 break;
912 if (nb_sectors >= cluster_sectors)
913 n = cluster_sectors;
914 else
915 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000916
917 bs_num = sector_num - bs_offset;
918 assert (bs_num >= 0);
919 remainder = n;
920 buf2 = buf;
921 while (remainder > 0) {
922 int nlow;
923 while (bs_num == bs_sectors) {
924 bs_i++;
925 assert (bs_i < bs_n);
926 bs_offset += bs_sectors;
927 bdrv_get_geometry(bs[bs_i], &bs_sectors);
928 bs_num = 0;
Blue Swirl0bfcd592010-05-22 08:02:12 +0000929 /* printf("changing part: sector_num=%" PRId64 ", "
930 "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64
931 "\n", sector_num, bs_i, bs_offset, bs_sectors); */
balrog926c2d22007-10-31 01:11:44 +0000932 }
933 assert (bs_num < bs_sectors);
934
935 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
936
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900937 ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
938 if (ret < 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +0100939 error_report("error while reading sector %" PRId64 ": %s",
940 bs_num, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900941 goto out;
942 }
balrog926c2d22007-10-31 01:11:44 +0000943
944 buf2 += nlow * 512;
945 bs_num += nlow;
946
947 remainder -= nlow;
948 }
949 assert (remainder == 0);
950
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100951 if (n < cluster_sectors) {
bellardea2384d2004-08-01 21:59:26 +0000952 memset(buf + n * 512, 0, cluster_size - n * 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100953 }
Stefan Hajnoczi1a6d39f2012-02-07 13:27:24 +0000954 if (!buffer_is_zero(buf, cluster_size)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900955 ret = bdrv_write_compressed(out_bs, sector_num, buf,
956 cluster_sectors);
957 if (ret != 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +0100958 error_report("error while compressing sector %" PRId64
959 ": %s", sector_num, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900960 goto out;
961 }
bellardea2384d2004-08-01 21:59:26 +0000962 }
963 sector_num += n;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200964 qemu_progress_print(local_progress, 100);
bellardea2384d2004-08-01 21:59:26 +0000965 }
bellardfaea38e2006-08-05 21:31:00 +0000966 /* signal EOF to align */
967 bdrv_write_compressed(out_bs, 0, NULL, 0);
bellardea2384d2004-08-01 21:59:26 +0000968 } else {
Kevin Wolff2feebb2010-04-14 17:30:35 +0200969 int has_zero_init = bdrv_has_zero_init(out_bs);
970
thsf58c7b32008-06-05 21:53:49 +0000971 sector_num = 0; // total number of sectors converted so far
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200972 nb_sectors = total_sectors - sector_num;
973 local_progress = (float)100 /
Jes Sorensen4ee96412011-05-06 11:39:11 +0200974 (nb_sectors / MIN(nb_sectors, IO_BUF_SIZE / 512));
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200975
bellardea2384d2004-08-01 21:59:26 +0000976 for(;;) {
977 nb_sectors = total_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100978 if (nb_sectors <= 0) {
bellardea2384d2004-08-01 21:59:26 +0000979 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100980 }
981 if (nb_sectors >= (IO_BUF_SIZE / 512)) {
bellardea2384d2004-08-01 21:59:26 +0000982 n = (IO_BUF_SIZE / 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100983 } else {
bellardea2384d2004-08-01 21:59:26 +0000984 n = nb_sectors;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100985 }
balrog926c2d22007-10-31 01:11:44 +0000986
987 while (sector_num - bs_offset >= bs_sectors) {
988 bs_i ++;
989 assert (bs_i < bs_n);
990 bs_offset += bs_sectors;
991 bdrv_get_geometry(bs[bs_i], &bs_sectors);
Blue Swirl0bfcd592010-05-22 08:02:12 +0000992 /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "
993 "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",
balrog926c2d22007-10-31 01:11:44 +0000994 sector_num, bs_i, bs_offset, bs_sectors); */
995 }
996
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100997 if (n > bs_offset + bs_sectors - sector_num) {
balrog926c2d22007-10-31 01:11:44 +0000998 n = bs_offset + bs_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100999 }
balrog926c2d22007-10-31 01:11:44 +00001000
Kevin Wolff2feebb2010-04-14 17:30:35 +02001001 if (has_zero_init) {
Akkarit Sangpetchd0320442009-07-17 10:02:15 +02001002 /* If the output image is being created as a copy on write image,
1003 assume that sectors which are unallocated in the input image
1004 are present in both the output's and input's base images (no
1005 need to copy them). */
1006 if (out_baseimg) {
1007 if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
1008 n, &n1)) {
1009 sector_num += n1;
1010 continue;
1011 }
1012 /* The next 'n1' sectors are allocated in the input image. Copy
1013 only those as they may be followed by unallocated sectors. */
1014 n = n1;
aliguori93c65b42009-04-05 17:40:43 +00001015 }
aliguori93c65b42009-04-05 17:40:43 +00001016 } else {
1017 n1 = n;
thsf58c7b32008-06-05 21:53:49 +00001018 }
1019
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001020 ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
1021 if (ret < 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +01001022 error_report("error while reading sector %" PRId64 ": %s",
1023 sector_num - bs_offset, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001024 goto out;
1025 }
bellardea2384d2004-08-01 21:59:26 +00001026 /* NOTE: at the same time we convert, we do not write zero
1027 sectors to have a chance to compress the image. Ideally, we
1028 should add a specific call to have the info to go faster */
1029 buf1 = buf;
1030 while (n > 0) {
thsf58c7b32008-06-05 21:53:49 +00001031 /* If the output image is being created as a copy on write image,
1032 copy all sectors even the ones containing only NUL bytes,
aliguori93c65b42009-04-05 17:40:43 +00001033 because they may differ from the sectors in the base image.
1034
1035 If the output is to a host device, we also write out
1036 sectors that are entirely 0, since whatever data was
1037 already there is garbage, not 0s. */
Kevin Wolff2feebb2010-04-14 17:30:35 +02001038 if (!has_zero_init || out_baseimg ||
Kevin Wolfa22f1232011-08-26 15:27:13 +02001039 is_allocated_sectors_min(buf1, n, &n1, min_sparse)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001040 ret = bdrv_write(out_bs, sector_num, buf1, n1);
1041 if (ret < 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +01001042 error_report("error while writing sector %" PRId64
1043 ": %s", sector_num, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001044 goto out;
1045 }
bellardea2384d2004-08-01 21:59:26 +00001046 }
1047 sector_num += n1;
1048 n -= n1;
1049 buf1 += n1 * 512;
1050 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001051 qemu_progress_print(local_progress, 100);
bellardea2384d2004-08-01 21:59:26 +00001052 }
1053 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001054out:
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001055 qemu_progress_end();
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001056 free_option_parameters(create_options);
1057 free_option_parameters(param);
Kevin Wolfbb1c0592011-08-08 14:09:12 +02001058 qemu_vfree(buf);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001059 if (out_bs) {
1060 bdrv_delete(out_bs);
1061 }
Jes Sorensen31ca34b2010-12-06 15:25:36 +01001062 if (bs) {
1063 for (bs_i = 0; bs_i < bs_n; bs_i++) {
1064 if (bs[bs_i]) {
1065 bdrv_delete(bs[bs_i]);
1066 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001067 }
Anthony Liguori7267c092011-08-20 22:09:37 -05001068 g_free(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001069 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001070 if (ret) {
1071 return 1;
1072 }
bellardea2384d2004-08-01 21:59:26 +00001073 return 0;
1074}
1075
bellard57d1a2b2004-08-03 21:15:11 +00001076
bellardfaea38e2006-08-05 21:31:00 +00001077static void dump_snapshots(BlockDriverState *bs)
1078{
1079 QEMUSnapshotInfo *sn_tab, *sn;
1080 int nb_sns, i;
1081 char buf[256];
1082
1083 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1084 if (nb_sns <= 0)
1085 return;
1086 printf("Snapshot list:\n");
1087 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
1088 for(i = 0; i < nb_sns; i++) {
1089 sn = &sn_tab[i];
1090 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
1091 }
Anthony Liguori7267c092011-08-20 22:09:37 -05001092 g_free(sn_tab);
bellardfaea38e2006-08-05 21:31:00 +00001093}
1094
bellardea2384d2004-08-01 21:59:26 +00001095static int img_info(int argc, char **argv)
1096{
1097 int c;
1098 const char *filename, *fmt;
bellardea2384d2004-08-01 21:59:26 +00001099 BlockDriverState *bs;
1100 char fmt_name[128], size_buf[128], dsize_buf[128];
ths96b8f132007-12-17 01:35:20 +00001101 uint64_t total_sectors;
1102 int64_t allocated_size;
bellard93b6b2a2006-08-01 15:51:11 +00001103 char backing_filename[1024];
1104 char backing_filename2[1024];
bellardfaea38e2006-08-05 21:31:00 +00001105 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +00001106
1107 fmt = NULL;
1108 for(;;) {
1109 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001110 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +00001111 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001112 }
bellardea2384d2004-08-01 21:59:26 +00001113 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001114 case '?':
bellardea2384d2004-08-01 21:59:26 +00001115 case 'h':
1116 help();
1117 break;
1118 case 'f':
1119 fmt = optarg;
1120 break;
1121 }
1122 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001123 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +00001124 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001125 }
bellardea2384d2004-08-01 21:59:26 +00001126 filename = argv[optind++];
1127
Stefan Hajnocziadfe0782010-04-13 10:29:35 +01001128 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001129 if (!bs) {
1130 return 1;
1131 }
bellardea2384d2004-08-01 21:59:26 +00001132 bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
1133 bdrv_get_geometry(bs, &total_sectors);
1134 get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
Fam Zheng4a1d5e12011-07-12 19:56:39 +08001135 allocated_size = bdrv_get_allocated_file_size(bs);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001136 if (allocated_size < 0) {
blueswir1a10ea302008-08-24 10:30:33 +00001137 snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001138 } else {
ths5fafdf22007-09-16 21:08:06 +00001139 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
bellardde167e42005-04-28 21:15:08 +00001140 allocated_size);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001141 }
bellardea2384d2004-08-01 21:59:26 +00001142 printf("image: %s\n"
1143 "file format: %s\n"
bellardec3757d2006-06-14 15:50:07 +00001144 "virtual size: %s (%" PRId64 " bytes)\n"
bellardea2384d2004-08-01 21:59:26 +00001145 "disk size: %s\n",
ths5fafdf22007-09-16 21:08:06 +00001146 filename, fmt_name, size_buf,
bellardec3757d2006-06-14 15:50:07 +00001147 (total_sectors * 512),
bellardea2384d2004-08-01 21:59:26 +00001148 dsize_buf);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001149 if (bdrv_is_encrypted(bs)) {
bellardea2384d2004-08-01 21:59:26 +00001150 printf("encrypted: yes\n");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001151 }
bellardfaea38e2006-08-05 21:31:00 +00001152 if (bdrv_get_info(bs, &bdi) >= 0) {
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001153 if (bdi.cluster_size != 0) {
bellardfaea38e2006-08-05 21:31:00 +00001154 printf("cluster_size: %d\n", bdi.cluster_size);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001155 }
Dong Xu Wang64c79162012-03-15 20:13:33 +08001156 if (bdi.is_dirty) {
1157 printf("cleanly shut down: no\n");
1158 }
bellardfaea38e2006-08-05 21:31:00 +00001159 }
bellard93b6b2a2006-08-01 15:51:11 +00001160 bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
bellardfaea38e2006-08-05 21:31:00 +00001161 if (backing_filename[0] != '\0') {
Paolo Bonzinidc5a1372012-05-08 16:51:50 +02001162 bdrv_get_full_backing_filename(bs, backing_filename2,
1163 sizeof(backing_filename2));
1164 printf("backing file: %s", backing_filename);
1165 if (strcmp(backing_filename, backing_filename2) != 0) {
1166 printf(" (actual path: %s)", backing_filename2);
1167 }
1168 putchar('\n');
bellardfaea38e2006-08-05 21:31:00 +00001169 }
1170 dump_snapshots(bs);
bellardea2384d2004-08-01 21:59:26 +00001171 bdrv_delete(bs);
1172 return 0;
1173}
1174
aliguorif7b4a942009-01-07 17:40:15 +00001175#define SNAPSHOT_LIST 1
1176#define SNAPSHOT_CREATE 2
1177#define SNAPSHOT_APPLY 3
1178#define SNAPSHOT_DELETE 4
1179
Stuart Brady153859b2009-06-07 00:42:17 +01001180static int img_snapshot(int argc, char **argv)
aliguorif7b4a942009-01-07 17:40:15 +00001181{
1182 BlockDriverState *bs;
1183 QEMUSnapshotInfo sn;
1184 char *filename, *snapshot_name = NULL;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001185 int c, ret = 0, bdrv_oflags;
aliguorif7b4a942009-01-07 17:40:15 +00001186 int action = 0;
1187 qemu_timeval tv;
1188
Kevin Wolf710da702011-01-10 12:33:02 +01001189 bdrv_oflags = BDRV_O_FLAGS | BDRV_O_RDWR;
aliguorif7b4a942009-01-07 17:40:15 +00001190 /* Parse commandline parameters */
1191 for(;;) {
1192 c = getopt(argc, argv, "la:c:d:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001193 if (c == -1) {
aliguorif7b4a942009-01-07 17:40:15 +00001194 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001195 }
aliguorif7b4a942009-01-07 17:40:15 +00001196 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001197 case '?':
aliguorif7b4a942009-01-07 17:40:15 +00001198 case 'h':
1199 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001200 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001201 case 'l':
1202 if (action) {
1203 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001204 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001205 }
1206 action = SNAPSHOT_LIST;
Naphtali Spreif5edb012010-01-17 16:48:13 +02001207 bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
aliguorif7b4a942009-01-07 17:40:15 +00001208 break;
1209 case 'a':
1210 if (action) {
1211 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001212 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001213 }
1214 action = SNAPSHOT_APPLY;
1215 snapshot_name = optarg;
1216 break;
1217 case 'c':
1218 if (action) {
1219 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001220 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001221 }
1222 action = SNAPSHOT_CREATE;
1223 snapshot_name = optarg;
1224 break;
1225 case 'd':
1226 if (action) {
1227 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001228 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001229 }
1230 action = SNAPSHOT_DELETE;
1231 snapshot_name = optarg;
1232 break;
1233 }
1234 }
1235
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001236 if (optind >= argc) {
aliguorif7b4a942009-01-07 17:40:15 +00001237 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001238 }
aliguorif7b4a942009-01-07 17:40:15 +00001239 filename = argv[optind++];
1240
1241 /* Open the image */
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001242 bs = bdrv_new_open(filename, NULL, bdrv_oflags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001243 if (!bs) {
1244 return 1;
1245 }
aliguorif7b4a942009-01-07 17:40:15 +00001246
1247 /* Perform the requested action */
1248 switch(action) {
1249 case SNAPSHOT_LIST:
1250 dump_snapshots(bs);
1251 break;
1252
1253 case SNAPSHOT_CREATE:
1254 memset(&sn, 0, sizeof(sn));
1255 pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
1256
1257 qemu_gettimeofday(&tv);
1258 sn.date_sec = tv.tv_sec;
1259 sn.date_nsec = tv.tv_usec * 1000;
1260
1261 ret = bdrv_snapshot_create(bs, &sn);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001262 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001263 error_report("Could not create snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001264 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001265 }
aliguorif7b4a942009-01-07 17:40:15 +00001266 break;
1267
1268 case SNAPSHOT_APPLY:
1269 ret = bdrv_snapshot_goto(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001270 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001271 error_report("Could not apply snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001272 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001273 }
aliguorif7b4a942009-01-07 17:40:15 +00001274 break;
1275
1276 case SNAPSHOT_DELETE:
1277 ret = bdrv_snapshot_delete(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001278 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001279 error_report("Could not delete snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001280 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001281 }
aliguorif7b4a942009-01-07 17:40:15 +00001282 break;
1283 }
1284
1285 /* Cleanup */
1286 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001287 if (ret) {
1288 return 1;
1289 }
Stuart Brady153859b2009-06-07 00:42:17 +01001290 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001291}
1292
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001293static int img_rebase(int argc, char **argv)
1294{
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001295 BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001296 BlockDriver *old_backing_drv, *new_backing_drv;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001297 char *filename;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001298 const char *fmt, *cache, *out_basefmt, *out_baseimg;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001299 int c, flags, ret;
1300 int unsafe = 0;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001301 int progress = 0;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001302
1303 /* Parse commandline parameters */
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001304 fmt = NULL;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001305 cache = BDRV_DEFAULT_CACHE;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001306 out_baseimg = NULL;
1307 out_basefmt = NULL;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001308 for(;;) {
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001309 c = getopt(argc, argv, "uhf:F:b:pt:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001310 if (c == -1) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001311 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001312 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001313 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001314 case '?':
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001315 case 'h':
1316 help();
1317 return 0;
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001318 case 'f':
1319 fmt = optarg;
1320 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001321 case 'F':
1322 out_basefmt = optarg;
1323 break;
1324 case 'b':
1325 out_baseimg = optarg;
1326 break;
1327 case 'u':
1328 unsafe = 1;
1329 break;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001330 case 'p':
1331 progress = 1;
1332 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001333 case 't':
1334 cache = optarg;
1335 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001336 }
1337 }
1338
Anthony Liguori9a9d9db2011-04-13 15:51:47 +01001339 if ((optind >= argc) || (!unsafe && !out_baseimg)) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001340 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001341 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001342 filename = argv[optind++];
1343
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001344 qemu_progress_init(progress, 2.0);
1345 qemu_progress_print(0, 100);
1346
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001347 flags = BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +01001348 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001349 if (ret < 0) {
1350 error_report("Invalid cache option: %s", cache);
1351 return -1;
1352 }
1353
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001354 /*
1355 * Open the images.
1356 *
1357 * Ignore the old backing file for unsafe rebase in case we want to correct
1358 * the reference to a renamed or moved backing file.
1359 */
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001360 bs = bdrv_new_open(filename, fmt, flags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001361 if (!bs) {
1362 return 1;
1363 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001364
1365 /* Find the right drivers for the backing files */
1366 old_backing_drv = NULL;
1367 new_backing_drv = NULL;
1368
1369 if (!unsafe && bs->backing_format[0] != '\0') {
1370 old_backing_drv = bdrv_find_format(bs->backing_format);
1371 if (old_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001372 error_report("Invalid format name: '%s'", bs->backing_format);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001373 ret = -1;
1374 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001375 }
1376 }
1377
1378 if (out_basefmt != NULL) {
1379 new_backing_drv = bdrv_find_format(out_basefmt);
1380 if (new_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001381 error_report("Invalid format name: '%s'", out_basefmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001382 ret = -1;
1383 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001384 }
1385 }
1386
1387 /* For safe rebasing we need to compare old and new backing file */
1388 if (unsafe) {
1389 /* Make the compiler happy */
1390 bs_old_backing = NULL;
1391 bs_new_backing = NULL;
1392 } else {
1393 char backing_name[1024];
1394
1395 bs_old_backing = bdrv_new("old_backing");
1396 bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001397 ret = bdrv_open(bs_old_backing, backing_name, BDRV_O_FLAGS,
1398 old_backing_drv);
1399 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001400 error_report("Could not open old backing file '%s'", backing_name);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001401 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001402 }
1403
1404 bs_new_backing = bdrv_new("new_backing");
Kevin Wolfcdbae852010-08-17 18:58:55 +02001405 ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS,
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001406 new_backing_drv);
1407 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001408 error_report("Could not open new backing file '%s'", out_baseimg);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001409 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001410 }
1411 }
1412
1413 /*
1414 * Check each unallocated cluster in the COW file. If it is unallocated,
1415 * accesses go to the backing file. We must therefore compare this cluster
1416 * in the old and new backing file, and if they differ we need to copy it
1417 * from the old backing file into the COW file.
1418 *
1419 * If qemu-img crashes during this step, no harm is done. The content of
1420 * the image is the same as the original one at any time.
1421 */
1422 if (!unsafe) {
1423 uint64_t num_sectors;
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01001424 uint64_t old_backing_num_sectors;
1425 uint64_t new_backing_num_sectors;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001426 uint64_t sector;
Kevin Wolfcc60e322010-04-29 14:47:48 +02001427 int n;
TeLeMand6771bf2010-02-08 16:20:00 +08001428 uint8_t * buf_old;
1429 uint8_t * buf_new;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001430 float local_progress;
TeLeMand6771bf2010-02-08 16:20:00 +08001431
Kevin Wolfbb1c0592011-08-08 14:09:12 +02001432 buf_old = qemu_blockalign(bs, IO_BUF_SIZE);
1433 buf_new = qemu_blockalign(bs, IO_BUF_SIZE);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001434
1435 bdrv_get_geometry(bs, &num_sectors);
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01001436 bdrv_get_geometry(bs_old_backing, &old_backing_num_sectors);
1437 bdrv_get_geometry(bs_new_backing, &new_backing_num_sectors);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001438
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001439 local_progress = (float)100 /
Jes Sorensen4ee96412011-05-06 11:39:11 +02001440 (num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512));
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001441 for (sector = 0; sector < num_sectors; sector += n) {
1442
1443 /* How many sectors can we handle with the next read? */
1444 if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
1445 n = (IO_BUF_SIZE / 512);
1446 } else {
1447 n = num_sectors - sector;
1448 }
1449
1450 /* If the cluster is allocated, we don't need to take action */
Kevin Wolfcc60e322010-04-29 14:47:48 +02001451 ret = bdrv_is_allocated(bs, sector, n, &n);
1452 if (ret) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001453 continue;
1454 }
1455
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01001456 /*
1457 * Read old and new backing file and take into consideration that
1458 * backing files may be smaller than the COW image.
1459 */
1460 if (sector >= old_backing_num_sectors) {
1461 memset(buf_old, 0, n * BDRV_SECTOR_SIZE);
1462 } else {
1463 if (sector + n > old_backing_num_sectors) {
1464 n = old_backing_num_sectors - sector;
1465 }
1466
1467 ret = bdrv_read(bs_old_backing, sector, buf_old, n);
1468 if (ret < 0) {
1469 error_report("error while reading from old backing file");
1470 goto out;
1471 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001472 }
Kevin Wolf87a1b3e2011-12-07 12:42:10 +01001473
1474 if (sector >= new_backing_num_sectors) {
1475 memset(buf_new, 0, n * BDRV_SECTOR_SIZE);
1476 } else {
1477 if (sector + n > new_backing_num_sectors) {
1478 n = new_backing_num_sectors - sector;
1479 }
1480
1481 ret = bdrv_read(bs_new_backing, sector, buf_new, n);
1482 if (ret < 0) {
1483 error_report("error while reading from new backing file");
1484 goto out;
1485 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001486 }
1487
1488 /* If they differ, we need to write to the COW file */
1489 uint64_t written = 0;
1490
1491 while (written < n) {
1492 int pnum;
1493
1494 if (compare_sectors(buf_old + written * 512,
Kevin Wolf60b1bd42010-02-17 12:32:59 +01001495 buf_new + written * 512, n - written, &pnum))
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001496 {
1497 ret = bdrv_write(bs, sector + written,
1498 buf_old + written * 512, pnum);
1499 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001500 error_report("Error while writing to COW image: %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001501 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001502 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001503 }
1504 }
1505
1506 written += pnum;
1507 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001508 qemu_progress_print(local_progress, 100);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001509 }
TeLeMand6771bf2010-02-08 16:20:00 +08001510
Kevin Wolfbb1c0592011-08-08 14:09:12 +02001511 qemu_vfree(buf_old);
1512 qemu_vfree(buf_new);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001513 }
1514
1515 /*
1516 * Change the backing file. All clusters that are different from the old
1517 * backing file are overwritten in the COW file now, so the visible content
1518 * doesn't change when we switch the backing file.
1519 */
1520 ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
1521 if (ret == -ENOSPC) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001522 error_report("Could not change the backing file to '%s': No "
1523 "space left in the file header", out_baseimg);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001524 } else if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001525 error_report("Could not change the backing file to '%s': %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001526 out_baseimg, strerror(-ret));
1527 }
1528
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001529 qemu_progress_print(100, 0);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001530 /*
1531 * TODO At this point it is possible to check if any clusters that are
1532 * allocated in the COW file are the same in the backing file. If so, they
1533 * could be dropped from the COW file. Don't do this before switching the
1534 * backing file, in case of a crash this would lead to corruption.
1535 */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001536out:
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001537 qemu_progress_end();
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001538 /* Cleanup */
1539 if (!unsafe) {
Kevin Wolfeb863ad2011-03-31 12:39:51 +02001540 if (bs_old_backing != NULL) {
1541 bdrv_delete(bs_old_backing);
1542 }
1543 if (bs_new_backing != NULL) {
1544 bdrv_delete(bs_new_backing);
1545 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001546 }
1547
1548 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001549 if (ret) {
1550 return 1;
1551 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001552 return 0;
1553}
1554
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001555static int img_resize(int argc, char **argv)
1556{
1557 int c, ret, relative;
1558 const char *filename, *fmt, *size;
1559 int64_t n, total_size;
Jes Sorensen2a819982010-12-06 17:08:31 +01001560 BlockDriverState *bs = NULL;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001561 QEMUOptionParameter *param;
1562 QEMUOptionParameter resize_options[] = {
1563 {
1564 .name = BLOCK_OPT_SIZE,
1565 .type = OPT_SIZE,
1566 .help = "Virtual disk size"
1567 },
1568 { NULL }
1569 };
1570
Kevin Wolfe80fec72011-04-29 10:58:12 +02001571 /* Remove size from argv manually so that negative numbers are not treated
1572 * as options by getopt. */
1573 if (argc < 3) {
1574 help();
1575 return 1;
1576 }
1577
1578 size = argv[--argc];
1579
1580 /* Parse getopt arguments */
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001581 fmt = NULL;
1582 for(;;) {
1583 c = getopt(argc, argv, "f:h");
1584 if (c == -1) {
1585 break;
1586 }
1587 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001588 case '?':
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001589 case 'h':
1590 help();
1591 break;
1592 case 'f':
1593 fmt = optarg;
1594 break;
1595 }
1596 }
Kevin Wolfe80fec72011-04-29 10:58:12 +02001597 if (optind >= argc) {
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001598 help();
1599 }
1600 filename = argv[optind++];
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001601
1602 /* Choose grow, shrink, or absolute resize mode */
1603 switch (size[0]) {
1604 case '+':
1605 relative = 1;
1606 size++;
1607 break;
1608 case '-':
1609 relative = -1;
1610 size++;
1611 break;
1612 default:
1613 relative = 0;
1614 break;
1615 }
1616
1617 /* Parse size */
1618 param = parse_option_parameters("", resize_options, NULL);
1619 if (set_option_parameter(param, BLOCK_OPT_SIZE, size)) {
1620 /* Error message already printed when size parsing fails */
Jes Sorensen2a819982010-12-06 17:08:31 +01001621 ret = -1;
1622 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001623 }
1624 n = get_option_parameter(param, BLOCK_OPT_SIZE)->value.n;
1625 free_option_parameters(param);
1626
1627 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001628 if (!bs) {
Jes Sorensen2a819982010-12-06 17:08:31 +01001629 ret = -1;
1630 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001631 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001632
1633 if (relative) {
1634 total_size = bdrv_getlength(bs) + n * relative;
1635 } else {
1636 total_size = n;
1637 }
1638 if (total_size <= 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001639 error_report("New image size must be positive");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001640 ret = -1;
1641 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001642 }
1643
1644 ret = bdrv_truncate(bs, total_size);
1645 switch (ret) {
1646 case 0:
1647 printf("Image resized.\n");
1648 break;
1649 case -ENOTSUP:
Kevin Wolf259b2172012-03-06 12:44:45 +01001650 error_report("This image does not support resize");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001651 break;
1652 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +01001653 error_report("Image is read-only");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001654 break;
1655 default:
Jes Sorensen15654a62010-12-16 14:31:53 +01001656 error_report("Error resizing image (%d)", -ret);
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001657 break;
1658 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001659out:
Jes Sorensen2a819982010-12-06 17:08:31 +01001660 if (bs) {
1661 bdrv_delete(bs);
1662 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001663 if (ret) {
1664 return 1;
1665 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001666 return 0;
1667}
1668
Anthony Liguoric227f092009-10-01 16:12:16 -05001669static const img_cmd_t img_cmds[] = {
Stuart Brady153859b2009-06-07 00:42:17 +01001670#define DEF(option, callback, arg_string) \
1671 { option, callback },
1672#include "qemu-img-cmds.h"
1673#undef DEF
1674#undef GEN_DOCS
1675 { NULL, NULL, },
1676};
1677
bellardea2384d2004-08-01 21:59:26 +00001678int main(int argc, char **argv)
1679{
Anthony Liguoric227f092009-10-01 16:12:16 -05001680 const img_cmd_t *cmd;
Stuart Brady153859b2009-06-07 00:42:17 +01001681 const char *cmdname;
bellardea2384d2004-08-01 21:59:26 +00001682
Kevin Wolf53f76e52010-12-16 15:10:32 +01001683 error_set_progname(argv[0]);
1684
bellardea2384d2004-08-01 21:59:26 +00001685 bdrv_init();
1686 if (argc < 2)
1687 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001688 cmdname = argv[1];
aurel328f9b1572009-02-09 18:14:31 +00001689 argc--; argv++;
Stuart Brady153859b2009-06-07 00:42:17 +01001690
Zhi Yong Wu67d384e2012-02-19 22:24:35 +08001691 qemu_init_main_loop();
1692
Stuart Brady153859b2009-06-07 00:42:17 +01001693 /* find the command */
1694 for(cmd = img_cmds; cmd->name != NULL; cmd++) {
1695 if (!strcmp(cmdname, cmd->name)) {
1696 return cmd->handler(argc, argv);
1697 }
bellardea2384d2004-08-01 21:59:26 +00001698 }
Stuart Brady153859b2009-06-07 00:42:17 +01001699
1700 /* not found */
1701 help();
bellardea2384d2004-08-01 21:59:26 +00001702 return 0;
1703}