blob: 074388ce89cc8b4f3c9fb9e2c5071b04dcc1aba5 [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
aurel32137519c2008-11-30 19:12:49 +000043
bellardea2384d2004-08-01 21:59:26 +000044static void format_print(void *opaque, const char *name)
45{
46 printf(" %s", name);
47}
48
blueswir1d2c639d2009-01-24 18:19:25 +000049/* Please keep in synch with qemu-img.texi */
pbrook3f379ab2007-11-11 03:33:13 +000050static void help(void)
bellardea2384d2004-08-01 21:59:26 +000051{
Paolo Bonzinie00291c2010-02-04 16:49:56 +010052 const char *help_msg =
53 "qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fabrice Bellard\n"
malc3f020d72010-02-08 12:04:56 +030054 "usage: qemu-img command [command options]\n"
55 "QEMU disk image utility\n"
56 "\n"
57 "Command syntax:\n"
Stuart Brady153859b2009-06-07 00:42:17 +010058#define DEF(option, callback, arg_string) \
59 " " arg_string "\n"
60#include "qemu-img-cmds.h"
61#undef DEF
62#undef GEN_DOCS
malc3f020d72010-02-08 12:04:56 +030063 "\n"
64 "Command parameters:\n"
65 " 'filename' is a disk image filename\n"
66 " 'fmt' is the disk image format. It is guessed automatically in most cases\n"
67 " 'size' is the disk image size in bytes. Optional suffixes\n"
68 " 'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M)\n"
69 " and T (terabyte, 1024G) are supported. 'b' is ignored.\n"
70 " 'output_filename' is the destination disk image filename\n"
71 " 'output_fmt' is the destination format\n"
72 " 'options' is a comma separated list of format specific options in a\n"
73 " name=value format. Use -o ? for an overview of the options supported by the\n"
74 " used format\n"
75 " '-c' indicates that target image must be compressed (qcow format only)\n"
76 " '-u' enables unsafe rebasing. It is assumed that old and new backing file\n"
77 " match exactly. The image doesn't need a working backing file before\n"
78 " rebasing in this case (useful for renaming the backing file)\n"
79 " '-h' with or without a command shows this help and lists the supported formats\n"
Jes Sorensen6b837bc2011-03-30 14:16:25 +020080 " '-p' show progress of command (only certain commands)\n"
malc3f020d72010-02-08 12:04:56 +030081 "\n"
82 "Parameters to snapshot subcommand:\n"
83 " 'snapshot' is the name of the snapshot to create, apply or delete\n"
84 " '-a' applies a snapshot (revert disk to saved state)\n"
85 " '-c' creates a snapshot\n"
86 " '-d' deletes a snapshot\n"
Paolo Bonzinie00291c2010-02-04 16:49:56 +010087 " '-l' lists all snapshots in the given image\n";
88
89 printf("%s\nSupported formats:", help_msg);
bellardea2384d2004-08-01 21:59:26 +000090 bdrv_iterate_format(format_print, NULL);
91 printf("\n");
92 exit(1);
93}
94
bellardea2384d2004-08-01 21:59:26 +000095#if defined(WIN32)
96/* XXX: put correct support for win32 */
97static int read_password(char *buf, int buf_size)
98{
99 int c, i;
100 printf("Password: ");
101 fflush(stdout);
102 i = 0;
103 for(;;) {
104 c = getchar();
105 if (c == '\n')
106 break;
107 if (i < (buf_size - 1))
108 buf[i++] = c;
109 }
110 buf[i] = '\0';
111 return 0;
112}
113
114#else
115
116#include <termios.h>
117
118static struct termios oldtty;
119
120static void term_exit(void)
121{
122 tcsetattr (0, TCSANOW, &oldtty);
123}
124
125static void term_init(void)
126{
127 struct termios tty;
128
129 tcgetattr (0, &tty);
130 oldtty = tty;
131
132 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
133 |INLCR|IGNCR|ICRNL|IXON);
134 tty.c_oflag |= OPOST;
135 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
136 tty.c_cflag &= ~(CSIZE|PARENB);
137 tty.c_cflag |= CS8;
138 tty.c_cc[VMIN] = 1;
139 tty.c_cc[VTIME] = 0;
ths3b46e622007-09-17 08:09:54 +0000140
bellardea2384d2004-08-01 21:59:26 +0000141 tcsetattr (0, TCSANOW, &tty);
142
143 atexit(term_exit);
144}
145
pbrook3f379ab2007-11-11 03:33:13 +0000146static int read_password(char *buf, int buf_size)
bellardea2384d2004-08-01 21:59:26 +0000147{
148 uint8_t ch;
149 int i, ret;
150
151 printf("password: ");
152 fflush(stdout);
153 term_init();
154 i = 0;
155 for(;;) {
156 ret = read(0, &ch, 1);
157 if (ret == -1) {
158 if (errno == EAGAIN || errno == EINTR) {
159 continue;
160 } else {
161 ret = -1;
162 break;
163 }
164 } else if (ret == 0) {
165 ret = -1;
166 break;
167 } else {
168 if (ch == '\r') {
169 ret = 0;
170 break;
171 }
172 if (i < (buf_size - 1))
173 buf[i++] = ch;
174 }
175 }
176 term_exit();
177 buf[i] = '\0';
178 printf("\n");
179 return ret;
180}
181#endif
182
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100183static int print_block_option_help(const char *filename, const char *fmt)
184{
185 BlockDriver *drv, *proto_drv;
186 QEMUOptionParameter *create_options = NULL;
187
188 /* Find driver and parse its options */
189 drv = bdrv_find_format(fmt);
190 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100191 error_report("Unknown file format '%s'", fmt);
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100192 return 1;
193 }
194
195 proto_drv = bdrv_find_protocol(filename);
196 if (!proto_drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100197 error_report("Unknown protocol '%s'", filename);
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100198 return 1;
199 }
200
201 create_options = append_option_parameters(create_options,
202 drv->create_options);
203 create_options = append_option_parameters(create_options,
204 proto_drv->create_options);
205 print_option_help(create_options);
206 free_option_parameters(create_options);
207 return 0;
208}
209
bellard75c23802004-08-27 21:28:58 +0000210static BlockDriverState *bdrv_new_open(const char *filename,
Sheng Yang9bc378c2010-01-29 10:15:06 +0800211 const char *fmt,
Stefan Hajnoczif163d072010-04-13 10:29:34 +0100212 int flags)
bellard75c23802004-08-27 21:28:58 +0000213{
214 BlockDriverState *bs;
215 BlockDriver *drv;
216 char password[256];
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100217 int ret;
bellard75c23802004-08-27 21:28:58 +0000218
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100219 bs = bdrv_new("image");
Kevin Wolfad717132010-12-16 15:37:41 +0100220
bellard75c23802004-08-27 21:28:58 +0000221 if (fmt) {
222 drv = bdrv_find_format(fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900223 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100224 error_report("Unknown file format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900225 goto fail;
226 }
bellard75c23802004-08-27 21:28:58 +0000227 } else {
228 drv = NULL;
229 }
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100230
231 ret = bdrv_open(bs, filename, flags, drv);
232 if (ret < 0) {
233 error_report("Could not open '%s': %s", filename, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900234 goto fail;
bellard75c23802004-08-27 21:28:58 +0000235 }
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100236
bellard75c23802004-08-27 21:28:58 +0000237 if (bdrv_is_encrypted(bs)) {
238 printf("Disk image '%s' is encrypted.\n", filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900239 if (read_password(password, sizeof(password)) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100240 error_report("No password given");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900241 goto fail;
242 }
243 if (bdrv_set_key(bs, password) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100244 error_report("invalid password");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900245 goto fail;
246 }
bellard75c23802004-08-27 21:28:58 +0000247 }
248 return bs;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900249fail:
250 if (bs) {
251 bdrv_delete(bs);
252 }
253 return NULL;
bellard75c23802004-08-27 21:28:58 +0000254}
255
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900256static int add_old_style_options(const char *fmt, QEMUOptionParameter *list,
Jes Sorenseneec77d92010-12-07 17:44:34 +0100257 const char *base_filename,
258 const char *base_fmt)
Kevin Wolfefa84d42009-05-18 16:42:12 +0200259{
Kevin Wolfefa84d42009-05-18 16:42:12 +0200260 if (base_filename) {
261 if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100262 error_report("Backing file not supported for file format '%s'",
263 fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900264 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200265 }
266 }
267 if (base_fmt) {
268 if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100269 error_report("Backing file format not supported for file "
270 "format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900271 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200272 }
273 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900274 return 0;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200275}
276
bellardea2384d2004-08-01 21:59:26 +0000277static int img_create(int argc, char **argv)
278{
Jes Sorenseneec77d92010-12-07 17:44:34 +0100279 int c, ret = 0;
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100280 uint64_t img_size = -1;
bellardea2384d2004-08-01 21:59:26 +0000281 const char *fmt = "raw";
aliguori9230eaf2009-03-28 17:55:19 +0000282 const char *base_fmt = NULL;
bellardea2384d2004-08-01 21:59:26 +0000283 const char *filename;
284 const char *base_filename = NULL;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200285 char *options = NULL;
ths3b46e622007-09-17 08:09:54 +0000286
bellardea2384d2004-08-01 21:59:26 +0000287 for(;;) {
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200288 c = getopt(argc, argv, "F:b:f:he6o:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100289 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000290 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100291 }
bellardea2384d2004-08-01 21:59:26 +0000292 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100293 case '?':
bellardea2384d2004-08-01 21:59:26 +0000294 case 'h':
295 help();
296 break;
aliguori9230eaf2009-03-28 17:55:19 +0000297 case 'F':
298 base_fmt = optarg;
299 break;
bellardea2384d2004-08-01 21:59:26 +0000300 case 'b':
301 base_filename = optarg;
302 break;
303 case 'f':
304 fmt = optarg;
305 break;
306 case 'e':
Jes Sorensen15654a62010-12-16 14:31:53 +0100307 error_report("qemu-img: option -e is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100308 "encryption\' instead!");
309 return 1;
thsd8871c52007-10-24 16:11:42 +0000310 case '6':
Jes Sorensen15654a62010-12-16 14:31:53 +0100311 error_report("qemu-img: option -6 is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100312 "compat6\' instead!");
313 return 1;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200314 case 'o':
315 options = optarg;
316 break;
bellardea2384d2004-08-01 21:59:26 +0000317 }
318 }
aliguori9230eaf2009-03-28 17:55:19 +0000319
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900320 /* Get the filename */
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100321 if (optind >= argc) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900322 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100323 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900324 filename = argv[optind++];
325
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100326 /* Get image size, if specified */
327 if (optind < argc) {
Jes Sorensen70b4f4b2011-01-05 11:41:02 +0100328 int64_t sval;
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100329 sval = strtosz_suffix(argv[optind++], NULL, STRTOSZ_DEFSUFFIX_B);
330 if (sval < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100331 error_report("Invalid image size specified! You may use k, M, G or "
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100332 "T suffixes for ");
Jes Sorensen15654a62010-12-16 14:31:53 +0100333 error_report("kilobytes, megabytes, gigabytes and terabytes.");
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100334 ret = -1;
335 goto out;
336 }
337 img_size = (uint64_t)sval;
338 }
339
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100340 if (options && !strcmp(options, "?")) {
341 ret = print_block_option_help(filename, fmt);
342 goto out;
343 }
344
Jes Sorensenf88e1a42010-12-16 13:52:15 +0100345 ret = bdrv_img_create(filename, fmt, base_filename, base_fmt,
346 options, img_size, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900347out:
348 if (ret) {
349 return 1;
350 }
bellardea2384d2004-08-01 21:59:26 +0000351 return 0;
352}
353
Kevin Wolfe076f332010-06-29 11:43:13 +0200354/*
355 * Checks an image for consistency. Exit codes:
356 *
357 * 0 - Check completed, image is good
358 * 1 - Check not completed because of internal errors
359 * 2 - Check completed, image is corrupted
360 * 3 - Check completed, image has leaked clusters, but is good otherwise
361 */
aliguori15859692009-04-21 23:11:53 +0000362static int img_check(int argc, char **argv)
363{
364 int c, ret;
365 const char *filename, *fmt;
aliguori15859692009-04-21 23:11:53 +0000366 BlockDriverState *bs;
Kevin Wolfe076f332010-06-29 11:43:13 +0200367 BdrvCheckResult result;
aliguori15859692009-04-21 23:11:53 +0000368
369 fmt = NULL;
370 for(;;) {
371 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100372 if (c == -1) {
aliguori15859692009-04-21 23:11:53 +0000373 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100374 }
aliguori15859692009-04-21 23:11:53 +0000375 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100376 case '?':
aliguori15859692009-04-21 23:11:53 +0000377 case 'h':
378 help();
379 break;
380 case 'f':
381 fmt = optarg;
382 break;
383 }
384 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100385 if (optind >= argc) {
aliguori15859692009-04-21 23:11:53 +0000386 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100387 }
aliguori15859692009-04-21 23:11:53 +0000388 filename = argv[optind++];
389
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100390 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900391 if (!bs) {
392 return 1;
393 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200394 ret = bdrv_check(bs, &result);
395
396 if (ret == -ENOTSUP) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100397 error_report("This image format does not support checks");
Kevin Wolfe076f332010-06-29 11:43:13 +0200398 bdrv_delete(bs);
399 return 1;
400 }
401
402 if (!(result.corruptions || result.leaks || result.check_errors)) {
403 printf("No errors were found on the image.\n");
404 } else {
405 if (result.corruptions) {
406 printf("\n%d errors were found on the image.\n"
407 "Data may be corrupted, or further writes to the image "
408 "may corrupt it.\n",
409 result.corruptions);
aliguori15859692009-04-21 23:11:53 +0000410 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200411
412 if (result.leaks) {
413 printf("\n%d leaked clusters were found on the image.\n"
414 "This means waste of disk space, but no harm to data.\n",
415 result.leaks);
416 }
417
418 if (result.check_errors) {
419 printf("\n%d internal errors have occurred during the check.\n",
420 result.check_errors);
421 }
aliguori15859692009-04-21 23:11:53 +0000422 }
423
424 bdrv_delete(bs);
Kevin Wolfe076f332010-06-29 11:43:13 +0200425
426 if (ret < 0 || result.check_errors) {
427 printf("\nAn error has occurred during the check: %s\n"
428 "The check is not complete and may have missed error.\n",
429 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900430 return 1;
431 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200432
433 if (result.corruptions) {
434 return 2;
435 } else if (result.leaks) {
436 return 3;
437 } else {
438 return 0;
439 }
aliguori15859692009-04-21 23:11:53 +0000440}
441
bellardea2384d2004-08-01 21:59:26 +0000442static int img_commit(int argc, char **argv)
443{
444 int c, ret;
445 const char *filename, *fmt;
bellardea2384d2004-08-01 21:59:26 +0000446 BlockDriverState *bs;
447
448 fmt = NULL;
449 for(;;) {
450 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100451 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000452 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100453 }
bellardea2384d2004-08-01 21:59:26 +0000454 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100455 case '?':
bellardea2384d2004-08-01 21:59:26 +0000456 case 'h':
457 help();
458 break;
459 case 'f':
460 fmt = optarg;
461 break;
462 }
463 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100464 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +0000465 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100466 }
bellardea2384d2004-08-01 21:59:26 +0000467 filename = argv[optind++];
468
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100469 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900470 if (!bs) {
471 return 1;
472 }
bellardea2384d2004-08-01 21:59:26 +0000473 ret = bdrv_commit(bs);
474 switch(ret) {
475 case 0:
476 printf("Image committed.\n");
477 break;
478 case -ENOENT:
Jes Sorensen15654a62010-12-16 14:31:53 +0100479 error_report("No disk inserted");
bellardea2384d2004-08-01 21:59:26 +0000480 break;
481 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +0100482 error_report("Image is read-only");
bellardea2384d2004-08-01 21:59:26 +0000483 break;
484 case -ENOTSUP:
Jes Sorensen15654a62010-12-16 14:31:53 +0100485 error_report("Image is already committed");
bellardea2384d2004-08-01 21:59:26 +0000486 break;
487 default:
Jes Sorensen15654a62010-12-16 14:31:53 +0100488 error_report("Error while committing image");
bellardea2384d2004-08-01 21:59:26 +0000489 break;
490 }
491
492 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900493 if (ret) {
494 return 1;
495 }
bellardea2384d2004-08-01 21:59:26 +0000496 return 0;
497}
498
499static int is_not_zero(const uint8_t *sector, int len)
500{
501 int i;
502 len >>= 2;
503 for(i = 0;i < len; i++) {
504 if (((uint32_t *)sector)[i] != 0)
505 return 1;
506 }
507 return 0;
508}
509
thsf58c7b32008-06-05 21:53:49 +0000510/*
511 * Returns true iff the first sector pointed to by 'buf' contains at least
512 * a non-NUL byte.
513 *
514 * 'pnum' is set to the number of sectors (including and immediately following
515 * the first one) that are known to be in the same allocated/unallocated state.
516 */
bellardea2384d2004-08-01 21:59:26 +0000517static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
518{
519 int v, i;
520
521 if (n <= 0) {
522 *pnum = 0;
523 return 0;
524 }
525 v = is_not_zero(buf, 512);
526 for(i = 1; i < n; i++) {
527 buf += 512;
528 if (v != is_not_zero(buf, 512))
529 break;
530 }
531 *pnum = i;
532 return v;
533}
534
Kevin Wolf3e85c6f2010-01-12 12:55:18 +0100535/*
536 * Compares two buffers sector by sector. Returns 0 if the first sector of both
537 * buffers matches, non-zero otherwise.
538 *
539 * pnum is set to the number of sectors (including and immediately following
540 * the first one) that are known to have the same comparison result
541 */
542static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
543 int *pnum)
544{
545 int res, i;
546
547 if (n <= 0) {
548 *pnum = 0;
549 return 0;
550 }
551
552 res = !!memcmp(buf1, buf2, 512);
553 for(i = 1; i < n; i++) {
554 buf1 += 512;
555 buf2 += 512;
556
557 if (!!memcmp(buf1, buf2, 512) != res) {
558 break;
559 }
560 }
561
562 *pnum = i;
563 return res;
564}
565
Kevin Wolf80ee15a2009-09-15 12:30:43 +0200566#define IO_BUF_SIZE (2 * 1024 * 1024)
bellardea2384d2004-08-01 21:59:26 +0000567
568static int img_convert(int argc, char **argv)
569{
Jes Sorenseneec77d92010-12-07 17:44:34 +0100570 int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200571 int progress = 0;
thsf58c7b32008-06-05 21:53:49 +0000572 const char *fmt, *out_fmt, *out_baseimg, *out_filename;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900573 BlockDriver *drv, *proto_drv;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900574 BlockDriverState **bs = NULL, *out_bs = NULL;
ths96b8f132007-12-17 01:35:20 +0000575 int64_t total_sectors, nb_sectors, sector_num, bs_offset;
576 uint64_t bs_sectors;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900577 uint8_t * buf = NULL;
bellardea2384d2004-08-01 21:59:26 +0000578 const uint8_t *buf1;
bellardfaea38e2006-08-05 21:31:00 +0000579 BlockDriverInfo bdi;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900580 QEMUOptionParameter *param = NULL, *create_options = NULL;
Kevin Wolfa18953f2010-10-14 15:46:04 +0200581 QEMUOptionParameter *out_baseimg_param;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200582 char *options = NULL;
edison51ef6722010-09-21 19:58:41 -0700583 const char *snapshot_name = NULL;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200584 float local_progress;
bellardea2384d2004-08-01 21:59:26 +0000585
586 fmt = NULL;
587 out_fmt = "raw";
thsf58c7b32008-06-05 21:53:49 +0000588 out_baseimg = NULL;
Jes Sorenseneec77d92010-12-07 17:44:34 +0100589 compress = 0;
bellardea2384d2004-08-01 21:59:26 +0000590 for(;;) {
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200591 c = getopt(argc, argv, "f:O:B:s:hce6o:p");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100592 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000593 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100594 }
bellardea2384d2004-08-01 21:59:26 +0000595 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100596 case '?':
bellardea2384d2004-08-01 21:59:26 +0000597 case 'h':
598 help();
599 break;
600 case 'f':
601 fmt = optarg;
602 break;
603 case 'O':
604 out_fmt = optarg;
605 break;
thsf58c7b32008-06-05 21:53:49 +0000606 case 'B':
607 out_baseimg = optarg;
608 break;
bellardea2384d2004-08-01 21:59:26 +0000609 case 'c':
Jes Sorenseneec77d92010-12-07 17:44:34 +0100610 compress = 1;
bellardea2384d2004-08-01 21:59:26 +0000611 break;
612 case 'e':
Jes Sorensen15654a62010-12-16 14:31:53 +0100613 error_report("qemu-img: option -e is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100614 "encryption\' instead!");
615 return 1;
thsec36ba12007-09-16 21:59:02 +0000616 case '6':
Jes Sorensen15654a62010-12-16 14:31:53 +0100617 error_report("qemu-img: option -6 is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100618 "compat6\' instead!");
619 return 1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200620 case 'o':
621 options = optarg;
622 break;
edison51ef6722010-09-21 19:58:41 -0700623 case 's':
624 snapshot_name = optarg;
625 break;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200626 case 'p':
627 progress = 1;
628 break;
bellardea2384d2004-08-01 21:59:26 +0000629 }
630 }
ths3b46e622007-09-17 08:09:54 +0000631
balrog926c2d22007-10-31 01:11:44 +0000632 bs_n = argc - optind - 1;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100633 if (bs_n < 1) {
634 help();
635 }
balrog926c2d22007-10-31 01:11:44 +0000636
637 out_filename = argv[argc - 1];
thsf58c7b32008-06-05 21:53:49 +0000638
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100639 if (options && !strcmp(options, "?")) {
640 ret = print_block_option_help(out_filename, out_fmt);
641 goto out;
642 }
643
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900644 if (bs_n > 1 && out_baseimg) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100645 error_report("-B makes no sense when concatenating multiple input "
646 "images");
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100647 ret = -1;
648 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900649 }
balrog926c2d22007-10-31 01:11:44 +0000650
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200651 qemu_progress_init(progress, 2.0);
652 qemu_progress_print(0, 100);
653
Jes Sorensen5bdf61f2010-12-06 15:25:35 +0100654 bs = qemu_mallocz(bs_n * sizeof(BlockDriverState *));
balrog926c2d22007-10-31 01:11:44 +0000655
656 total_sectors = 0;
657 for (bs_i = 0; bs_i < bs_n; bs_i++) {
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100658 bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900659 if (!bs[bs_i]) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100660 error_report("Could not open '%s'", argv[optind + bs_i]);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900661 ret = -1;
662 goto out;
663 }
balrog926c2d22007-10-31 01:11:44 +0000664 bdrv_get_geometry(bs[bs_i], &bs_sectors);
665 total_sectors += bs_sectors;
666 }
bellardea2384d2004-08-01 21:59:26 +0000667
edison51ef6722010-09-21 19:58:41 -0700668 if (snapshot_name != NULL) {
669 if (bs_n > 1) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100670 error_report("No support for concatenating multiple snapshot\n");
edison51ef6722010-09-21 19:58:41 -0700671 ret = -1;
672 goto out;
673 }
674 if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100675 error_report("Failed to load snapshot\n");
edison51ef6722010-09-21 19:58:41 -0700676 ret = -1;
677 goto out;
678 }
679 }
680
Kevin Wolfefa84d42009-05-18 16:42:12 +0200681 /* Find driver and parse its options */
bellardea2384d2004-08-01 21:59:26 +0000682 drv = bdrv_find_format(out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900683 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100684 error_report("Unknown file format '%s'", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900685 ret = -1;
686 goto out;
687 }
balrog926c2d22007-10-31 01:11:44 +0000688
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900689 proto_drv = bdrv_find_protocol(out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900690 if (!proto_drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100691 error_report("Unknown protocol '%s'", out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900692 ret = -1;
693 goto out;
694 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900695
696 create_options = append_option_parameters(create_options,
697 drv->create_options);
698 create_options = append_option_parameters(create_options,
699 proto_drv->create_options);
Kevin Wolfdb08adf2009-06-04 15:39:38 +0200700
Kevin Wolfefa84d42009-05-18 16:42:12 +0200701 if (options) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900702 param = parse_option_parameters(options, create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200703 if (param == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100704 error_report("Invalid options for file format '%s'.", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900705 ret = -1;
706 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200707 }
708 } else {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900709 param = parse_option_parameters("", create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200710 }
711
712 set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
Jes Sorenseneec77d92010-12-07 17:44:34 +0100713 ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900714 if (ret < 0) {
715 goto out;
716 }
Kevin Wolfefa84d42009-05-18 16:42:12 +0200717
Kevin Wolfa18953f2010-10-14 15:46:04 +0200718 /* Get backing file name if -o backing_file was used */
719 out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
720 if (out_baseimg_param) {
721 out_baseimg = out_baseimg_param->value.s;
722 }
723
Kevin Wolfefa84d42009-05-18 16:42:12 +0200724 /* Check if compression is supported */
Jes Sorenseneec77d92010-12-07 17:44:34 +0100725 if (compress) {
Kevin Wolfefa84d42009-05-18 16:42:12 +0200726 QEMUOptionParameter *encryption =
727 get_option_parameter(param, BLOCK_OPT_ENCRYPT);
728
729 if (!drv->bdrv_write_compressed) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100730 error_report("Compression not supported for this file format");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900731 ret = -1;
732 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200733 }
734
735 if (encryption && encryption->value.n) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100736 error_report("Compression and encryption not supported at "
737 "the same time");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900738 ret = -1;
739 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200740 }
741 }
742
743 /* Create the new image */
744 ret = bdrv_create(drv, out_filename, param);
bellardea2384d2004-08-01 21:59:26 +0000745 if (ret < 0) {
746 if (ret == -ENOTSUP) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100747 error_report("Formatting not supported for file format '%s'",
748 out_fmt);
aurel326e9ea0c2009-04-15 14:42:46 +0000749 } else if (ret == -EFBIG) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100750 error_report("The image size is too large for file format '%s'",
751 out_fmt);
bellardea2384d2004-08-01 21:59:26 +0000752 } else {
Jes Sorensen15654a62010-12-16 14:31:53 +0100753 error_report("%s: error while converting %s: %s",
754 out_filename, out_fmt, strerror(-ret));
bellardea2384d2004-08-01 21:59:26 +0000755 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900756 goto out;
bellardea2384d2004-08-01 21:59:26 +0000757 }
ths3b46e622007-09-17 08:09:54 +0000758
Kevin Wolf1bd8e172010-08-31 13:44:25 +0200759 out_bs = bdrv_new_open(out_filename, out_fmt,
760 BDRV_O_FLAGS | BDRV_O_RDWR | BDRV_O_NO_FLUSH);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900761 if (!out_bs) {
762 ret = -1;
763 goto out;
764 }
bellardea2384d2004-08-01 21:59:26 +0000765
balrog926c2d22007-10-31 01:11:44 +0000766 bs_i = 0;
767 bs_offset = 0;
768 bdrv_get_geometry(bs[0], &bs_sectors);
TeLeMand6771bf2010-02-08 16:20:00 +0800769 buf = qemu_malloc(IO_BUF_SIZE);
balrog926c2d22007-10-31 01:11:44 +0000770
Jes Sorenseneec77d92010-12-07 17:44:34 +0100771 if (compress) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900772 ret = bdrv_get_info(out_bs, &bdi);
773 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100774 error_report("could not get block driver info");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900775 goto out;
776 }
bellardfaea38e2006-08-05 21:31:00 +0000777 cluster_size = bdi.cluster_size;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900778 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100779 error_report("invalid cluster size");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900780 ret = -1;
781 goto out;
782 }
bellardea2384d2004-08-01 21:59:26 +0000783 cluster_sectors = cluster_size >> 9;
784 sector_num = 0;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200785
786 nb_sectors = total_sectors;
787 local_progress = (float)100 /
788 (nb_sectors / MIN(nb_sectors, (cluster_sectors)));
789
bellardea2384d2004-08-01 21:59:26 +0000790 for(;;) {
balrog926c2d22007-10-31 01:11:44 +0000791 int64_t bs_num;
792 int remainder;
793 uint8_t *buf2;
794
bellardea2384d2004-08-01 21:59:26 +0000795 nb_sectors = total_sectors - sector_num;
796 if (nb_sectors <= 0)
797 break;
798 if (nb_sectors >= cluster_sectors)
799 n = cluster_sectors;
800 else
801 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000802
803 bs_num = sector_num - bs_offset;
804 assert (bs_num >= 0);
805 remainder = n;
806 buf2 = buf;
807 while (remainder > 0) {
808 int nlow;
809 while (bs_num == bs_sectors) {
810 bs_i++;
811 assert (bs_i < bs_n);
812 bs_offset += bs_sectors;
813 bdrv_get_geometry(bs[bs_i], &bs_sectors);
814 bs_num = 0;
Blue Swirl0bfcd592010-05-22 08:02:12 +0000815 /* printf("changing part: sector_num=%" PRId64 ", "
816 "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64
817 "\n", sector_num, bs_i, bs_offset, bs_sectors); */
balrog926c2d22007-10-31 01:11:44 +0000818 }
819 assert (bs_num < bs_sectors);
820
821 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
822
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900823 ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
824 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100825 error_report("error while reading");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900826 goto out;
827 }
balrog926c2d22007-10-31 01:11:44 +0000828
829 buf2 += nlow * 512;
830 bs_num += nlow;
831
832 remainder -= nlow;
833 }
834 assert (remainder == 0);
835
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100836 if (n < cluster_sectors) {
bellardea2384d2004-08-01 21:59:26 +0000837 memset(buf + n * 512, 0, cluster_size - n * 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100838 }
bellardea2384d2004-08-01 21:59:26 +0000839 if (is_not_zero(buf, cluster_size)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900840 ret = bdrv_write_compressed(out_bs, sector_num, buf,
841 cluster_sectors);
842 if (ret != 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100843 error_report("error while compressing sector %" PRId64,
bellardec3757d2006-06-14 15:50:07 +0000844 sector_num);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900845 goto out;
846 }
bellardea2384d2004-08-01 21:59:26 +0000847 }
848 sector_num += n;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200849 qemu_progress_print(local_progress, 100);
bellardea2384d2004-08-01 21:59:26 +0000850 }
bellardfaea38e2006-08-05 21:31:00 +0000851 /* signal EOF to align */
852 bdrv_write_compressed(out_bs, 0, NULL, 0);
bellardea2384d2004-08-01 21:59:26 +0000853 } else {
Kevin Wolff2feebb2010-04-14 17:30:35 +0200854 int has_zero_init = bdrv_has_zero_init(out_bs);
855
thsf58c7b32008-06-05 21:53:49 +0000856 sector_num = 0; // total number of sectors converted so far
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200857 nb_sectors = total_sectors - sector_num;
858 local_progress = (float)100 /
859 (nb_sectors / MIN(nb_sectors, (IO_BUF_SIZE / 512)));
860
bellardea2384d2004-08-01 21:59:26 +0000861 for(;;) {
862 nb_sectors = total_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100863 if (nb_sectors <= 0) {
bellardea2384d2004-08-01 21:59:26 +0000864 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100865 }
866 if (nb_sectors >= (IO_BUF_SIZE / 512)) {
bellardea2384d2004-08-01 21:59:26 +0000867 n = (IO_BUF_SIZE / 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100868 } else {
bellardea2384d2004-08-01 21:59:26 +0000869 n = nb_sectors;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100870 }
balrog926c2d22007-10-31 01:11:44 +0000871
872 while (sector_num - bs_offset >= bs_sectors) {
873 bs_i ++;
874 assert (bs_i < bs_n);
875 bs_offset += bs_sectors;
876 bdrv_get_geometry(bs[bs_i], &bs_sectors);
Blue Swirl0bfcd592010-05-22 08:02:12 +0000877 /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "
878 "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",
balrog926c2d22007-10-31 01:11:44 +0000879 sector_num, bs_i, bs_offset, bs_sectors); */
880 }
881
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100882 if (n > bs_offset + bs_sectors - sector_num) {
balrog926c2d22007-10-31 01:11:44 +0000883 n = bs_offset + bs_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100884 }
balrog926c2d22007-10-31 01:11:44 +0000885
Kevin Wolff2feebb2010-04-14 17:30:35 +0200886 if (has_zero_init) {
Akkarit Sangpetchd0320442009-07-17 10:02:15 +0200887 /* If the output image is being created as a copy on write image,
888 assume that sectors which are unallocated in the input image
889 are present in both the output's and input's base images (no
890 need to copy them). */
891 if (out_baseimg) {
892 if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
893 n, &n1)) {
894 sector_num += n1;
895 continue;
896 }
897 /* The next 'n1' sectors are allocated in the input image. Copy
898 only those as they may be followed by unallocated sectors. */
899 n = n1;
aliguori93c65b42009-04-05 17:40:43 +0000900 }
aliguori93c65b42009-04-05 17:40:43 +0000901 } else {
902 n1 = n;
thsf58c7b32008-06-05 21:53:49 +0000903 }
904
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900905 ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
906 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100907 error_report("error while reading");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900908 goto out;
909 }
bellardea2384d2004-08-01 21:59:26 +0000910 /* NOTE: at the same time we convert, we do not write zero
911 sectors to have a chance to compress the image. Ideally, we
912 should add a specific call to have the info to go faster */
913 buf1 = buf;
914 while (n > 0) {
thsf58c7b32008-06-05 21:53:49 +0000915 /* If the output image is being created as a copy on write image,
916 copy all sectors even the ones containing only NUL bytes,
aliguori93c65b42009-04-05 17:40:43 +0000917 because they may differ from the sectors in the base image.
918
919 If the output is to a host device, we also write out
920 sectors that are entirely 0, since whatever data was
921 already there is garbage, not 0s. */
Kevin Wolff2feebb2010-04-14 17:30:35 +0200922 if (!has_zero_init || out_baseimg ||
aliguori93c65b42009-04-05 17:40:43 +0000923 is_allocated_sectors(buf1, n, &n1)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900924 ret = bdrv_write(out_bs, sector_num, buf1, n1);
925 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100926 error_report("error while writing");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900927 goto out;
928 }
bellardea2384d2004-08-01 21:59:26 +0000929 }
930 sector_num += n1;
931 n -= n1;
932 buf1 += n1 * 512;
933 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200934 qemu_progress_print(local_progress, 100);
bellardea2384d2004-08-01 21:59:26 +0000935 }
936 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900937out:
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200938 qemu_progress_end();
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900939 free_option_parameters(create_options);
940 free_option_parameters(param);
TeLeMand6771bf2010-02-08 16:20:00 +0800941 qemu_free(buf);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900942 if (out_bs) {
943 bdrv_delete(out_bs);
944 }
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100945 if (bs) {
946 for (bs_i = 0; bs_i < bs_n; bs_i++) {
947 if (bs[bs_i]) {
948 bdrv_delete(bs[bs_i]);
949 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900950 }
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100951 qemu_free(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900952 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900953 if (ret) {
954 return 1;
955 }
bellardea2384d2004-08-01 21:59:26 +0000956 return 0;
957}
958
bellard57d1a2b2004-08-03 21:15:11 +0000959#ifdef _WIN32
960static int64_t get_allocated_file_size(const char *filename)
961{
bellarde8445332006-06-14 15:32:10 +0000962 typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
963 get_compressed_t get_compressed;
bellard57d1a2b2004-08-03 21:15:11 +0000964 struct _stati64 st;
bellarde8445332006-06-14 15:32:10 +0000965
966 /* WinNT support GetCompressedFileSize to determine allocate size */
967 get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
968 if (get_compressed) {
969 DWORD high, low;
970 low = get_compressed(filename, &high);
971 if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
972 return (((int64_t) high) << 32) + low;
973 }
974
ths5fafdf22007-09-16 21:08:06 +0000975 if (_stati64(filename, &st) < 0)
bellard57d1a2b2004-08-03 21:15:11 +0000976 return -1;
977 return st.st_size;
978}
979#else
980static int64_t get_allocated_file_size(const char *filename)
981{
982 struct stat st;
ths5fafdf22007-09-16 21:08:06 +0000983 if (stat(filename, &st) < 0)
bellard57d1a2b2004-08-03 21:15:11 +0000984 return -1;
985 return (int64_t)st.st_blocks * 512;
986}
987#endif
988
bellardfaea38e2006-08-05 21:31:00 +0000989static void dump_snapshots(BlockDriverState *bs)
990{
991 QEMUSnapshotInfo *sn_tab, *sn;
992 int nb_sns, i;
993 char buf[256];
994
995 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
996 if (nb_sns <= 0)
997 return;
998 printf("Snapshot list:\n");
999 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
1000 for(i = 0; i < nb_sns; i++) {
1001 sn = &sn_tab[i];
1002 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
1003 }
1004 qemu_free(sn_tab);
1005}
1006
bellardea2384d2004-08-01 21:59:26 +00001007static int img_info(int argc, char **argv)
1008{
1009 int c;
1010 const char *filename, *fmt;
bellardea2384d2004-08-01 21:59:26 +00001011 BlockDriverState *bs;
1012 char fmt_name[128], size_buf[128], dsize_buf[128];
ths96b8f132007-12-17 01:35:20 +00001013 uint64_t total_sectors;
1014 int64_t allocated_size;
bellard93b6b2a2006-08-01 15:51:11 +00001015 char backing_filename[1024];
1016 char backing_filename2[1024];
bellardfaea38e2006-08-05 21:31:00 +00001017 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +00001018
1019 fmt = NULL;
1020 for(;;) {
1021 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001022 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +00001023 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001024 }
bellardea2384d2004-08-01 21:59:26 +00001025 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001026 case '?':
bellardea2384d2004-08-01 21:59:26 +00001027 case 'h':
1028 help();
1029 break;
1030 case 'f':
1031 fmt = optarg;
1032 break;
1033 }
1034 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001035 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +00001036 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001037 }
bellardea2384d2004-08-01 21:59:26 +00001038 filename = argv[optind++];
1039
Stefan Hajnocziadfe0782010-04-13 10:29:35 +01001040 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001041 if (!bs) {
1042 return 1;
1043 }
bellardea2384d2004-08-01 21:59:26 +00001044 bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
1045 bdrv_get_geometry(bs, &total_sectors);
1046 get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
bellard57d1a2b2004-08-03 21:15:11 +00001047 allocated_size = get_allocated_file_size(filename);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001048 if (allocated_size < 0) {
blueswir1a10ea302008-08-24 10:30:33 +00001049 snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001050 } else {
ths5fafdf22007-09-16 21:08:06 +00001051 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
bellardde167e42005-04-28 21:15:08 +00001052 allocated_size);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001053 }
bellardea2384d2004-08-01 21:59:26 +00001054 printf("image: %s\n"
1055 "file format: %s\n"
bellardec3757d2006-06-14 15:50:07 +00001056 "virtual size: %s (%" PRId64 " bytes)\n"
bellardea2384d2004-08-01 21:59:26 +00001057 "disk size: %s\n",
ths5fafdf22007-09-16 21:08:06 +00001058 filename, fmt_name, size_buf,
bellardec3757d2006-06-14 15:50:07 +00001059 (total_sectors * 512),
bellardea2384d2004-08-01 21:59:26 +00001060 dsize_buf);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001061 if (bdrv_is_encrypted(bs)) {
bellardea2384d2004-08-01 21:59:26 +00001062 printf("encrypted: yes\n");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001063 }
bellardfaea38e2006-08-05 21:31:00 +00001064 if (bdrv_get_info(bs, &bdi) >= 0) {
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001065 if (bdi.cluster_size != 0) {
bellardfaea38e2006-08-05 21:31:00 +00001066 printf("cluster_size: %d\n", bdi.cluster_size);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001067 }
bellardfaea38e2006-08-05 21:31:00 +00001068 }
bellard93b6b2a2006-08-01 15:51:11 +00001069 bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
bellardfaea38e2006-08-05 21:31:00 +00001070 if (backing_filename[0] != '\0') {
bellard93b6b2a2006-08-01 15:51:11 +00001071 path_combine(backing_filename2, sizeof(backing_filename2),
1072 filename, backing_filename);
ths5fafdf22007-09-16 21:08:06 +00001073 printf("backing file: %s (actual path: %s)\n",
bellard93b6b2a2006-08-01 15:51:11 +00001074 backing_filename,
1075 backing_filename2);
bellardfaea38e2006-08-05 21:31:00 +00001076 }
1077 dump_snapshots(bs);
bellardea2384d2004-08-01 21:59:26 +00001078 bdrv_delete(bs);
1079 return 0;
1080}
1081
aliguorif7b4a942009-01-07 17:40:15 +00001082#define SNAPSHOT_LIST 1
1083#define SNAPSHOT_CREATE 2
1084#define SNAPSHOT_APPLY 3
1085#define SNAPSHOT_DELETE 4
1086
Stuart Brady153859b2009-06-07 00:42:17 +01001087static int img_snapshot(int argc, char **argv)
aliguorif7b4a942009-01-07 17:40:15 +00001088{
1089 BlockDriverState *bs;
1090 QEMUSnapshotInfo sn;
1091 char *filename, *snapshot_name = NULL;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001092 int c, ret = 0, bdrv_oflags;
aliguorif7b4a942009-01-07 17:40:15 +00001093 int action = 0;
1094 qemu_timeval tv;
1095
Kevin Wolf710da702011-01-10 12:33:02 +01001096 bdrv_oflags = BDRV_O_FLAGS | BDRV_O_RDWR;
aliguorif7b4a942009-01-07 17:40:15 +00001097 /* Parse commandline parameters */
1098 for(;;) {
1099 c = getopt(argc, argv, "la:c:d:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001100 if (c == -1) {
aliguorif7b4a942009-01-07 17:40:15 +00001101 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001102 }
aliguorif7b4a942009-01-07 17:40:15 +00001103 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001104 case '?':
aliguorif7b4a942009-01-07 17:40:15 +00001105 case 'h':
1106 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001107 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001108 case 'l':
1109 if (action) {
1110 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001111 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001112 }
1113 action = SNAPSHOT_LIST;
Naphtali Spreif5edb012010-01-17 16:48:13 +02001114 bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
aliguorif7b4a942009-01-07 17:40:15 +00001115 break;
1116 case 'a':
1117 if (action) {
1118 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001119 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001120 }
1121 action = SNAPSHOT_APPLY;
1122 snapshot_name = optarg;
1123 break;
1124 case 'c':
1125 if (action) {
1126 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001127 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001128 }
1129 action = SNAPSHOT_CREATE;
1130 snapshot_name = optarg;
1131 break;
1132 case 'd':
1133 if (action) {
1134 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001135 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001136 }
1137 action = SNAPSHOT_DELETE;
1138 snapshot_name = optarg;
1139 break;
1140 }
1141 }
1142
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001143 if (optind >= argc) {
aliguorif7b4a942009-01-07 17:40:15 +00001144 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001145 }
aliguorif7b4a942009-01-07 17:40:15 +00001146 filename = argv[optind++];
1147
1148 /* Open the image */
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001149 bs = bdrv_new_open(filename, NULL, bdrv_oflags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001150 if (!bs) {
1151 return 1;
1152 }
aliguorif7b4a942009-01-07 17:40:15 +00001153
1154 /* Perform the requested action */
1155 switch(action) {
1156 case SNAPSHOT_LIST:
1157 dump_snapshots(bs);
1158 break;
1159
1160 case SNAPSHOT_CREATE:
1161 memset(&sn, 0, sizeof(sn));
1162 pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
1163
1164 qemu_gettimeofday(&tv);
1165 sn.date_sec = tv.tv_sec;
1166 sn.date_nsec = tv.tv_usec * 1000;
1167
1168 ret = bdrv_snapshot_create(bs, &sn);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001169 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001170 error_report("Could not create snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001171 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001172 }
aliguorif7b4a942009-01-07 17:40:15 +00001173 break;
1174
1175 case SNAPSHOT_APPLY:
1176 ret = bdrv_snapshot_goto(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001177 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001178 error_report("Could not apply snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001179 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001180 }
aliguorif7b4a942009-01-07 17:40:15 +00001181 break;
1182
1183 case SNAPSHOT_DELETE:
1184 ret = bdrv_snapshot_delete(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001185 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001186 error_report("Could not delete snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001187 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001188 }
aliguorif7b4a942009-01-07 17:40:15 +00001189 break;
1190 }
1191
1192 /* Cleanup */
1193 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001194 if (ret) {
1195 return 1;
1196 }
Stuart Brady153859b2009-06-07 00:42:17 +01001197 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001198}
1199
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001200static int img_rebase(int argc, char **argv)
1201{
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001202 BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001203 BlockDriver *old_backing_drv, *new_backing_drv;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001204 char *filename;
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001205 const char *fmt, *out_basefmt, *out_baseimg;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001206 int c, flags, ret;
1207 int unsafe = 0;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001208 int progress = 0;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001209
1210 /* Parse commandline parameters */
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001211 fmt = NULL;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001212 out_baseimg = NULL;
1213 out_basefmt = NULL;
1214
1215 for(;;) {
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001216 c = getopt(argc, argv, "uhf:F:b:p");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001217 if (c == -1) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001218 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001219 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001220 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001221 case '?':
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001222 case 'h':
1223 help();
1224 return 0;
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001225 case 'f':
1226 fmt = optarg;
1227 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001228 case 'F':
1229 out_basefmt = optarg;
1230 break;
1231 case 'b':
1232 out_baseimg = optarg;
1233 break;
1234 case 'u':
1235 unsafe = 1;
1236 break;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001237 case 'p':
1238 progress = 1;
1239 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001240 }
1241 }
1242
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001243 if ((optind >= argc) || !out_baseimg) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001244 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001245 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001246 filename = argv[optind++];
1247
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001248 qemu_progress_init(progress, 2.0);
1249 qemu_progress_print(0, 100);
1250
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001251 /*
1252 * Open the images.
1253 *
1254 * Ignore the old backing file for unsafe rebase in case we want to correct
1255 * the reference to a renamed or moved backing file.
1256 */
Stefan Hajnocziadfe0782010-04-13 10:29:35 +01001257 flags = BDRV_O_FLAGS | BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001258 bs = bdrv_new_open(filename, fmt, flags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001259 if (!bs) {
1260 return 1;
1261 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001262
1263 /* Find the right drivers for the backing files */
1264 old_backing_drv = NULL;
1265 new_backing_drv = NULL;
1266
1267 if (!unsafe && bs->backing_format[0] != '\0') {
1268 old_backing_drv = bdrv_find_format(bs->backing_format);
1269 if (old_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001270 error_report("Invalid format name: '%s'", bs->backing_format);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001271 ret = -1;
1272 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001273 }
1274 }
1275
1276 if (out_basefmt != NULL) {
1277 new_backing_drv = bdrv_find_format(out_basefmt);
1278 if (new_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001279 error_report("Invalid format name: '%s'", out_basefmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001280 ret = -1;
1281 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001282 }
1283 }
1284
1285 /* For safe rebasing we need to compare old and new backing file */
1286 if (unsafe) {
1287 /* Make the compiler happy */
1288 bs_old_backing = NULL;
1289 bs_new_backing = NULL;
1290 } else {
1291 char backing_name[1024];
1292
1293 bs_old_backing = bdrv_new("old_backing");
1294 bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001295 ret = bdrv_open(bs_old_backing, backing_name, BDRV_O_FLAGS,
1296 old_backing_drv);
1297 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001298 error_report("Could not open old backing file '%s'", backing_name);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001299 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001300 }
1301
1302 bs_new_backing = bdrv_new("new_backing");
Kevin Wolfcdbae852010-08-17 18:58:55 +02001303 ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS,
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001304 new_backing_drv);
1305 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001306 error_report("Could not open new backing file '%s'", out_baseimg);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001307 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001308 }
1309 }
1310
1311 /*
1312 * Check each unallocated cluster in the COW file. If it is unallocated,
1313 * accesses go to the backing file. We must therefore compare this cluster
1314 * in the old and new backing file, and if they differ we need to copy it
1315 * from the old backing file into the COW file.
1316 *
1317 * If qemu-img crashes during this step, no harm is done. The content of
1318 * the image is the same as the original one at any time.
1319 */
1320 if (!unsafe) {
1321 uint64_t num_sectors;
1322 uint64_t sector;
Kevin Wolfcc60e322010-04-29 14:47:48 +02001323 int n;
TeLeMand6771bf2010-02-08 16:20:00 +08001324 uint8_t * buf_old;
1325 uint8_t * buf_new;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001326 float local_progress;
TeLeMand6771bf2010-02-08 16:20:00 +08001327
1328 buf_old = qemu_malloc(IO_BUF_SIZE);
1329 buf_new = qemu_malloc(IO_BUF_SIZE);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001330
1331 bdrv_get_geometry(bs, &num_sectors);
1332
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001333 local_progress = (float)100 /
1334 (num_sectors / MIN(num_sectors, (IO_BUF_SIZE / 512)));
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001335 for (sector = 0; sector < num_sectors; sector += n) {
1336
1337 /* How many sectors can we handle with the next read? */
1338 if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
1339 n = (IO_BUF_SIZE / 512);
1340 } else {
1341 n = num_sectors - sector;
1342 }
1343
1344 /* If the cluster is allocated, we don't need to take action */
Kevin Wolfcc60e322010-04-29 14:47:48 +02001345 ret = bdrv_is_allocated(bs, sector, n, &n);
1346 if (ret) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001347 continue;
1348 }
1349
1350 /* Read old and new backing file */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001351 ret = bdrv_read(bs_old_backing, sector, buf_old, n);
1352 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001353 error_report("error while reading from old backing file");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001354 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001355 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001356 ret = bdrv_read(bs_new_backing, sector, buf_new, n);
1357 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001358 error_report("error while reading from new backing file");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001359 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001360 }
1361
1362 /* If they differ, we need to write to the COW file */
1363 uint64_t written = 0;
1364
1365 while (written < n) {
1366 int pnum;
1367
1368 if (compare_sectors(buf_old + written * 512,
Kevin Wolf60b1bd42010-02-17 12:32:59 +01001369 buf_new + written * 512, n - written, &pnum))
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001370 {
1371 ret = bdrv_write(bs, sector + written,
1372 buf_old + written * 512, pnum);
1373 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001374 error_report("Error while writing to COW image: %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001375 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001376 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001377 }
1378 }
1379
1380 written += pnum;
1381 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001382 qemu_progress_print(local_progress, 100);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001383 }
TeLeMand6771bf2010-02-08 16:20:00 +08001384
1385 qemu_free(buf_old);
1386 qemu_free(buf_new);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001387 }
1388
1389 /*
1390 * Change the backing file. All clusters that are different from the old
1391 * backing file are overwritten in the COW file now, so the visible content
1392 * doesn't change when we switch the backing file.
1393 */
1394 ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
1395 if (ret == -ENOSPC) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001396 error_report("Could not change the backing file to '%s': No "
1397 "space left in the file header", out_baseimg);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001398 } else if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001399 error_report("Could not change the backing file to '%s': %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001400 out_baseimg, strerror(-ret));
1401 }
1402
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001403 qemu_progress_print(100, 0);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001404 /*
1405 * TODO At this point it is possible to check if any clusters that are
1406 * allocated in the COW file are the same in the backing file. If so, they
1407 * could be dropped from the COW file. Don't do this before switching the
1408 * backing file, in case of a crash this would lead to corruption.
1409 */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001410out:
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001411 qemu_progress_end();
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001412 /* Cleanup */
1413 if (!unsafe) {
1414 bdrv_delete(bs_old_backing);
1415 bdrv_delete(bs_new_backing);
1416 }
1417
1418 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001419 if (ret) {
1420 return 1;
1421 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001422 return 0;
1423}
1424
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001425static int img_resize(int argc, char **argv)
1426{
1427 int c, ret, relative;
1428 const char *filename, *fmt, *size;
1429 int64_t n, total_size;
Jes Sorensen2a819982010-12-06 17:08:31 +01001430 BlockDriverState *bs = NULL;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001431 QEMUOptionParameter *param;
1432 QEMUOptionParameter resize_options[] = {
1433 {
1434 .name = BLOCK_OPT_SIZE,
1435 .type = OPT_SIZE,
1436 .help = "Virtual disk size"
1437 },
1438 { NULL }
1439 };
1440
1441 fmt = NULL;
1442 for(;;) {
1443 c = getopt(argc, argv, "f:h");
1444 if (c == -1) {
1445 break;
1446 }
1447 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001448 case '?':
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001449 case 'h':
1450 help();
1451 break;
1452 case 'f':
1453 fmt = optarg;
1454 break;
1455 }
1456 }
1457 if (optind + 1 >= argc) {
1458 help();
1459 }
1460 filename = argv[optind++];
1461 size = argv[optind++];
1462
1463 /* Choose grow, shrink, or absolute resize mode */
1464 switch (size[0]) {
1465 case '+':
1466 relative = 1;
1467 size++;
1468 break;
1469 case '-':
1470 relative = -1;
1471 size++;
1472 break;
1473 default:
1474 relative = 0;
1475 break;
1476 }
1477
1478 /* Parse size */
1479 param = parse_option_parameters("", resize_options, NULL);
1480 if (set_option_parameter(param, BLOCK_OPT_SIZE, size)) {
1481 /* Error message already printed when size parsing fails */
Jes Sorensen2a819982010-12-06 17:08:31 +01001482 ret = -1;
1483 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001484 }
1485 n = get_option_parameter(param, BLOCK_OPT_SIZE)->value.n;
1486 free_option_parameters(param);
1487
1488 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001489 if (!bs) {
Jes Sorensen2a819982010-12-06 17:08:31 +01001490 ret = -1;
1491 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001492 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001493
1494 if (relative) {
1495 total_size = bdrv_getlength(bs) + n * relative;
1496 } else {
1497 total_size = n;
1498 }
1499 if (total_size <= 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001500 error_report("New image size must be positive");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001501 ret = -1;
1502 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001503 }
1504
1505 ret = bdrv_truncate(bs, total_size);
1506 switch (ret) {
1507 case 0:
1508 printf("Image resized.\n");
1509 break;
1510 case -ENOTSUP:
Jes Sorensen15654a62010-12-16 14:31:53 +01001511 error_report("This image format does not support resize");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001512 break;
1513 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +01001514 error_report("Image is read-only");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001515 break;
1516 default:
Jes Sorensen15654a62010-12-16 14:31:53 +01001517 error_report("Error resizing image (%d)", -ret);
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001518 break;
1519 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001520out:
Jes Sorensen2a819982010-12-06 17:08:31 +01001521 if (bs) {
1522 bdrv_delete(bs);
1523 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001524 if (ret) {
1525 return 1;
1526 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001527 return 0;
1528}
1529
Anthony Liguoric227f092009-10-01 16:12:16 -05001530static const img_cmd_t img_cmds[] = {
Stuart Brady153859b2009-06-07 00:42:17 +01001531#define DEF(option, callback, arg_string) \
1532 { option, callback },
1533#include "qemu-img-cmds.h"
1534#undef DEF
1535#undef GEN_DOCS
1536 { NULL, NULL, },
1537};
1538
bellardea2384d2004-08-01 21:59:26 +00001539int main(int argc, char **argv)
1540{
Anthony Liguoric227f092009-10-01 16:12:16 -05001541 const img_cmd_t *cmd;
Stuart Brady153859b2009-06-07 00:42:17 +01001542 const char *cmdname;
bellardea2384d2004-08-01 21:59:26 +00001543
Kevin Wolf53f76e52010-12-16 15:10:32 +01001544 error_set_progname(argv[0]);
1545
bellardea2384d2004-08-01 21:59:26 +00001546 bdrv_init();
1547 if (argc < 2)
1548 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001549 cmdname = argv[1];
aurel328f9b1572009-02-09 18:14:31 +00001550 argc--; argv++;
Stuart Brady153859b2009-06-07 00:42:17 +01001551
1552 /* find the command */
1553 for(cmd = img_cmds; cmd->name != NULL; cmd++) {
1554 if (!strcmp(cmdname, cmd->name)) {
1555 return cmd->handler(argc, argv);
1556 }
bellardea2384d2004-08-01 21:59:26 +00001557 }
Stuart Brady153859b2009-06-07 00:42:17 +01001558
1559 /* not found */
1560 help();
bellardea2384d2004-08-01 21:59:26 +00001561 return 0;
1562}