blob: 5e203c231fa05ee22bd70c5cafd2f4303fcffd2d [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"
69 " options are: 'none', 'writeback' (default), 'writethrough' and 'unsafe'\n"
malc3f020d72010-02-08 12:04:56 +030070 " 'size' is the disk image size in bytes. Optional suffixes\n"
71 " 'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M)\n"
72 " and T (terabyte, 1024G) are supported. 'b' is ignored.\n"
73 " 'output_filename' is the destination disk image filename\n"
74 " 'output_fmt' is the destination format\n"
75 " 'options' is a comma separated list of format specific options in a\n"
76 " name=value format. Use -o ? for an overview of the options supported by the\n"
77 " used format\n"
78 " '-c' indicates that target image must be compressed (qcow format only)\n"
79 " '-u' enables unsafe rebasing. It is assumed that old and new backing file\n"
80 " match exactly. The image doesn't need a working backing file before\n"
81 " rebasing in this case (useful for renaming the backing file)\n"
82 " '-h' with or without a command shows this help and lists the supported formats\n"
Jes Sorensen6b837bc2011-03-30 14:16:25 +020083 " '-p' show progress of command (only certain commands)\n"
malc3f020d72010-02-08 12:04:56 +030084 "\n"
85 "Parameters to snapshot subcommand:\n"
86 " 'snapshot' is the name of the snapshot to create, apply or delete\n"
87 " '-a' applies a snapshot (revert disk to saved state)\n"
88 " '-c' creates a snapshot\n"
89 " '-d' deletes a snapshot\n"
Paolo Bonzinie00291c2010-02-04 16:49:56 +010090 " '-l' lists all snapshots in the given image\n";
91
92 printf("%s\nSupported formats:", help_msg);
bellardea2384d2004-08-01 21:59:26 +000093 bdrv_iterate_format(format_print, NULL);
94 printf("\n");
95 exit(1);
96}
97
bellardea2384d2004-08-01 21:59:26 +000098#if defined(WIN32)
99/* XXX: put correct support for win32 */
100static int read_password(char *buf, int buf_size)
101{
102 int c, i;
103 printf("Password: ");
104 fflush(stdout);
105 i = 0;
106 for(;;) {
107 c = getchar();
108 if (c == '\n')
109 break;
110 if (i < (buf_size - 1))
111 buf[i++] = c;
112 }
113 buf[i] = '\0';
114 return 0;
115}
116
117#else
118
119#include <termios.h>
120
121static struct termios oldtty;
122
123static void term_exit(void)
124{
125 tcsetattr (0, TCSANOW, &oldtty);
126}
127
128static void term_init(void)
129{
130 struct termios tty;
131
132 tcgetattr (0, &tty);
133 oldtty = tty;
134
135 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
136 |INLCR|IGNCR|ICRNL|IXON);
137 tty.c_oflag |= OPOST;
138 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
139 tty.c_cflag &= ~(CSIZE|PARENB);
140 tty.c_cflag |= CS8;
141 tty.c_cc[VMIN] = 1;
142 tty.c_cc[VTIME] = 0;
ths3b46e622007-09-17 08:09:54 +0000143
bellardea2384d2004-08-01 21:59:26 +0000144 tcsetattr (0, TCSANOW, &tty);
145
146 atexit(term_exit);
147}
148
pbrook3f379ab2007-11-11 03:33:13 +0000149static int read_password(char *buf, int buf_size)
bellardea2384d2004-08-01 21:59:26 +0000150{
151 uint8_t ch;
152 int i, ret;
153
154 printf("password: ");
155 fflush(stdout);
156 term_init();
157 i = 0;
158 for(;;) {
159 ret = read(0, &ch, 1);
160 if (ret == -1) {
161 if (errno == EAGAIN || errno == EINTR) {
162 continue;
163 } else {
164 ret = -1;
165 break;
166 }
167 } else if (ret == 0) {
168 ret = -1;
169 break;
170 } else {
171 if (ch == '\r') {
172 ret = 0;
173 break;
174 }
175 if (i < (buf_size - 1))
176 buf[i++] = ch;
177 }
178 }
179 term_exit();
180 buf[i] = '\0';
181 printf("\n");
182 return ret;
183}
184#endif
185
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100186static int print_block_option_help(const char *filename, const char *fmt)
187{
188 BlockDriver *drv, *proto_drv;
189 QEMUOptionParameter *create_options = NULL;
190
191 /* Find driver and parse its options */
192 drv = bdrv_find_format(fmt);
193 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100194 error_report("Unknown file format '%s'", fmt);
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100195 return 1;
196 }
197
198 proto_drv = bdrv_find_protocol(filename);
199 if (!proto_drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100200 error_report("Unknown protocol '%s'", filename);
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100201 return 1;
202 }
203
204 create_options = append_option_parameters(create_options,
205 drv->create_options);
206 create_options = append_option_parameters(create_options,
207 proto_drv->create_options);
208 print_option_help(create_options);
209 free_option_parameters(create_options);
210 return 0;
211}
212
bellard75c23802004-08-27 21:28:58 +0000213static BlockDriverState *bdrv_new_open(const char *filename,
Sheng Yang9bc378c2010-01-29 10:15:06 +0800214 const char *fmt,
Stefan Hajnoczif163d072010-04-13 10:29:34 +0100215 int flags)
bellard75c23802004-08-27 21:28:58 +0000216{
217 BlockDriverState *bs;
218 BlockDriver *drv;
219 char password[256];
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100220 int ret;
bellard75c23802004-08-27 21:28:58 +0000221
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100222 bs = bdrv_new("image");
Kevin Wolfad717132010-12-16 15:37:41 +0100223
bellard75c23802004-08-27 21:28:58 +0000224 if (fmt) {
225 drv = bdrv_find_format(fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900226 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100227 error_report("Unknown file format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900228 goto fail;
229 }
bellard75c23802004-08-27 21:28:58 +0000230 } else {
231 drv = NULL;
232 }
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100233
234 ret = bdrv_open(bs, filename, flags, drv);
235 if (ret < 0) {
236 error_report("Could not open '%s': %s", filename, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900237 goto fail;
bellard75c23802004-08-27 21:28:58 +0000238 }
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100239
bellard75c23802004-08-27 21:28:58 +0000240 if (bdrv_is_encrypted(bs)) {
241 printf("Disk image '%s' is encrypted.\n", filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900242 if (read_password(password, sizeof(password)) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100243 error_report("No password given");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900244 goto fail;
245 }
246 if (bdrv_set_key(bs, password) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100247 error_report("invalid password");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900248 goto fail;
249 }
bellard75c23802004-08-27 21:28:58 +0000250 }
251 return bs;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900252fail:
253 if (bs) {
254 bdrv_delete(bs);
255 }
256 return NULL;
bellard75c23802004-08-27 21:28:58 +0000257}
258
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900259static int add_old_style_options(const char *fmt, QEMUOptionParameter *list,
Jes Sorenseneec77d92010-12-07 17:44:34 +0100260 const char *base_filename,
261 const char *base_fmt)
Kevin Wolfefa84d42009-05-18 16:42:12 +0200262{
Kevin Wolfefa84d42009-05-18 16:42:12 +0200263 if (base_filename) {
264 if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100265 error_report("Backing file not supported for file format '%s'",
266 fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900267 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200268 }
269 }
270 if (base_fmt) {
271 if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100272 error_report("Backing file format not supported for file "
273 "format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900274 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200275 }
276 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900277 return 0;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200278}
279
bellardea2384d2004-08-01 21:59:26 +0000280static int img_create(int argc, char **argv)
281{
Jes Sorenseneec77d92010-12-07 17:44:34 +0100282 int c, ret = 0;
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100283 uint64_t img_size = -1;
bellardea2384d2004-08-01 21:59:26 +0000284 const char *fmt = "raw";
aliguori9230eaf2009-03-28 17:55:19 +0000285 const char *base_fmt = NULL;
bellardea2384d2004-08-01 21:59:26 +0000286 const char *filename;
287 const char *base_filename = NULL;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200288 char *options = NULL;
ths3b46e622007-09-17 08:09:54 +0000289
bellardea2384d2004-08-01 21:59:26 +0000290 for(;;) {
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200291 c = getopt(argc, argv, "F:b:f:he6o:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100292 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000293 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100294 }
bellardea2384d2004-08-01 21:59:26 +0000295 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100296 case '?':
bellardea2384d2004-08-01 21:59:26 +0000297 case 'h':
298 help();
299 break;
aliguori9230eaf2009-03-28 17:55:19 +0000300 case 'F':
301 base_fmt = optarg;
302 break;
bellardea2384d2004-08-01 21:59:26 +0000303 case 'b':
304 base_filename = optarg;
305 break;
306 case 'f':
307 fmt = optarg;
308 break;
309 case 'e':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200310 error_report("option -e is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100311 "encryption\' instead!");
312 return 1;
thsd8871c52007-10-24 16:11:42 +0000313 case '6':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200314 error_report("option -6 is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100315 "compat6\' instead!");
316 return 1;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200317 case 'o':
318 options = optarg;
319 break;
bellardea2384d2004-08-01 21:59:26 +0000320 }
321 }
aliguori9230eaf2009-03-28 17:55:19 +0000322
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900323 /* Get the filename */
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100324 if (optind >= argc) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900325 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100326 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900327 filename = argv[optind++];
328
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100329 /* Get image size, if specified */
330 if (optind < argc) {
Jes Sorensen70b4f4b2011-01-05 11:41:02 +0100331 int64_t sval;
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100332 sval = strtosz_suffix(argv[optind++], NULL, STRTOSZ_DEFSUFFIX_B);
333 if (sval < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100334 error_report("Invalid image size specified! You may use k, M, G or "
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100335 "T suffixes for ");
Jes Sorensen15654a62010-12-16 14:31:53 +0100336 error_report("kilobytes, megabytes, gigabytes and terabytes.");
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100337 ret = -1;
338 goto out;
339 }
340 img_size = (uint64_t)sval;
341 }
342
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100343 if (options && !strcmp(options, "?")) {
344 ret = print_block_option_help(filename, fmt);
345 goto out;
346 }
347
Jes Sorensenf88e1a42010-12-16 13:52:15 +0100348 ret = bdrv_img_create(filename, fmt, base_filename, base_fmt,
349 options, img_size, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900350out:
351 if (ret) {
352 return 1;
353 }
bellardea2384d2004-08-01 21:59:26 +0000354 return 0;
355}
356
Kevin Wolfe076f332010-06-29 11:43:13 +0200357/*
358 * Checks an image for consistency. Exit codes:
359 *
360 * 0 - Check completed, image is good
361 * 1 - Check not completed because of internal errors
362 * 2 - Check completed, image is corrupted
363 * 3 - Check completed, image has leaked clusters, but is good otherwise
364 */
aliguori15859692009-04-21 23:11:53 +0000365static int img_check(int argc, char **argv)
366{
367 int c, ret;
368 const char *filename, *fmt;
aliguori15859692009-04-21 23:11:53 +0000369 BlockDriverState *bs;
Kevin Wolfe076f332010-06-29 11:43:13 +0200370 BdrvCheckResult result;
aliguori15859692009-04-21 23:11:53 +0000371
372 fmt = NULL;
373 for(;;) {
374 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100375 if (c == -1) {
aliguori15859692009-04-21 23:11:53 +0000376 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100377 }
aliguori15859692009-04-21 23:11:53 +0000378 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100379 case '?':
aliguori15859692009-04-21 23:11:53 +0000380 case 'h':
381 help();
382 break;
383 case 'f':
384 fmt = optarg;
385 break;
386 }
387 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100388 if (optind >= argc) {
aliguori15859692009-04-21 23:11:53 +0000389 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100390 }
aliguori15859692009-04-21 23:11:53 +0000391 filename = argv[optind++];
392
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100393 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900394 if (!bs) {
395 return 1;
396 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200397 ret = bdrv_check(bs, &result);
398
399 if (ret == -ENOTSUP) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100400 error_report("This image format does not support checks");
Kevin Wolfe076f332010-06-29 11:43:13 +0200401 bdrv_delete(bs);
402 return 1;
403 }
404
405 if (!(result.corruptions || result.leaks || result.check_errors)) {
406 printf("No errors were found on the image.\n");
407 } else {
408 if (result.corruptions) {
409 printf("\n%d errors were found on the image.\n"
410 "Data may be corrupted, or further writes to the image "
411 "may corrupt it.\n",
412 result.corruptions);
aliguori15859692009-04-21 23:11:53 +0000413 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200414
415 if (result.leaks) {
416 printf("\n%d leaked clusters were found on the image.\n"
417 "This means waste of disk space, but no harm to data.\n",
418 result.leaks);
419 }
420
421 if (result.check_errors) {
422 printf("\n%d internal errors have occurred during the check.\n",
423 result.check_errors);
424 }
aliguori15859692009-04-21 23:11:53 +0000425 }
426
427 bdrv_delete(bs);
Kevin Wolfe076f332010-06-29 11:43:13 +0200428
429 if (ret < 0 || result.check_errors) {
430 printf("\nAn error has occurred during the check: %s\n"
431 "The check is not complete and may have missed error.\n",
432 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900433 return 1;
434 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200435
436 if (result.corruptions) {
437 return 2;
438 } else if (result.leaks) {
439 return 3;
440 } else {
441 return 0;
442 }
aliguori15859692009-04-21 23:11:53 +0000443}
444
bellardea2384d2004-08-01 21:59:26 +0000445static int img_commit(int argc, char **argv)
446{
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400447 int c, ret, flags;
448 const char *filename, *fmt, *cache;
bellardea2384d2004-08-01 21:59:26 +0000449 BlockDriverState *bs;
450
451 fmt = NULL;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400452 cache = BDRV_DEFAULT_CACHE;
bellardea2384d2004-08-01 21:59:26 +0000453 for(;;) {
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400454 c = getopt(argc, argv, "f:ht:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100455 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000456 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100457 }
bellardea2384d2004-08-01 21:59:26 +0000458 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100459 case '?':
bellardea2384d2004-08-01 21:59:26 +0000460 case 'h':
461 help();
462 break;
463 case 'f':
464 fmt = optarg;
465 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400466 case 't':
467 cache = optarg;
468 break;
bellardea2384d2004-08-01 21:59:26 +0000469 }
470 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100471 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +0000472 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100473 }
bellardea2384d2004-08-01 21:59:26 +0000474 filename = argv[optind++];
475
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400476 flags = BDRV_O_RDWR;
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +0100477 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400478 if (ret < 0) {
479 error_report("Invalid cache option: %s", cache);
480 return -1;
481 }
482
483 bs = bdrv_new_open(filename, fmt, flags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900484 if (!bs) {
485 return 1;
486 }
bellardea2384d2004-08-01 21:59:26 +0000487 ret = bdrv_commit(bs);
488 switch(ret) {
489 case 0:
490 printf("Image committed.\n");
491 break;
492 case -ENOENT:
Jes Sorensen15654a62010-12-16 14:31:53 +0100493 error_report("No disk inserted");
bellardea2384d2004-08-01 21:59:26 +0000494 break;
495 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +0100496 error_report("Image is read-only");
bellardea2384d2004-08-01 21:59:26 +0000497 break;
498 case -ENOTSUP:
Jes Sorensen15654a62010-12-16 14:31:53 +0100499 error_report("Image is already committed");
bellardea2384d2004-08-01 21:59:26 +0000500 break;
501 default:
Jes Sorensen15654a62010-12-16 14:31:53 +0100502 error_report("Error while committing image");
bellardea2384d2004-08-01 21:59:26 +0000503 break;
504 }
505
506 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900507 if (ret) {
508 return 1;
509 }
bellardea2384d2004-08-01 21:59:26 +0000510 return 0;
511}
512
Dmitry Konishchevf6a00aa2011-05-18 15:03:59 +0400513/*
514 * Checks whether the sector is not a zero sector.
515 *
516 * Attention! The len must be a multiple of 4 * sizeof(long) due to
517 * restriction of optimizations in this function.
518 */
bellardea2384d2004-08-01 21:59:26 +0000519static int is_not_zero(const uint8_t *sector, int len)
520{
Dmitry Konishchevf6a00aa2011-05-18 15:03:59 +0400521 /*
522 * Use long as the biggest available internal data type that fits into the
523 * CPU register and unroll the loop to smooth out the effect of memory
524 * latency.
525 */
526
bellardea2384d2004-08-01 21:59:26 +0000527 int i;
Dmitry Konishchevf6a00aa2011-05-18 15:03:59 +0400528 long d0, d1, d2, d3;
529 const long * const data = (const long *) sector;
530
531 len /= sizeof(long);
532
533 for(i = 0; i < len; i += 4) {
534 d0 = data[i + 0];
535 d1 = data[i + 1];
536 d2 = data[i + 2];
537 d3 = data[i + 3];
538
539 if (d0 || d1 || d2 || d3) {
bellardea2384d2004-08-01 21:59:26 +0000540 return 1;
Dmitry Konishchevf6a00aa2011-05-18 15:03:59 +0400541 }
bellardea2384d2004-08-01 21:59:26 +0000542 }
Dmitry Konishchevf6a00aa2011-05-18 15:03:59 +0400543
bellardea2384d2004-08-01 21:59:26 +0000544 return 0;
545}
546
thsf58c7b32008-06-05 21:53:49 +0000547/*
548 * Returns true iff the first sector pointed to by 'buf' contains at least
549 * a non-NUL byte.
550 *
551 * 'pnum' is set to the number of sectors (including and immediately following
552 * the first one) that are known to be in the same allocated/unallocated state.
553 */
bellardea2384d2004-08-01 21:59:26 +0000554static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
555{
556 int v, i;
557
558 if (n <= 0) {
559 *pnum = 0;
560 return 0;
561 }
562 v = is_not_zero(buf, 512);
563 for(i = 1; i < n; i++) {
564 buf += 512;
565 if (v != is_not_zero(buf, 512))
566 break;
567 }
568 *pnum = i;
569 return v;
570}
571
Kevin Wolf3e85c6f2010-01-12 12:55:18 +0100572/*
573 * Compares two buffers sector by sector. Returns 0 if the first sector of both
574 * buffers matches, non-zero otherwise.
575 *
576 * pnum is set to the number of sectors (including and immediately following
577 * the first one) that are known to have the same comparison result
578 */
579static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
580 int *pnum)
581{
582 int res, i;
583
584 if (n <= 0) {
585 *pnum = 0;
586 return 0;
587 }
588
589 res = !!memcmp(buf1, buf2, 512);
590 for(i = 1; i < n; i++) {
591 buf1 += 512;
592 buf2 += 512;
593
594 if (!!memcmp(buf1, buf2, 512) != res) {
595 break;
596 }
597 }
598
599 *pnum = i;
600 return res;
601}
602
Kevin Wolf80ee15a2009-09-15 12:30:43 +0200603#define IO_BUF_SIZE (2 * 1024 * 1024)
bellardea2384d2004-08-01 21:59:26 +0000604
605static int img_convert(int argc, char **argv)
606{
Jes Sorenseneec77d92010-12-07 17:44:34 +0100607 int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400608 int progress = 0, flags;
609 const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900610 BlockDriver *drv, *proto_drv;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900611 BlockDriverState **bs = NULL, *out_bs = NULL;
ths96b8f132007-12-17 01:35:20 +0000612 int64_t total_sectors, nb_sectors, sector_num, bs_offset;
613 uint64_t bs_sectors;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900614 uint8_t * buf = NULL;
bellardea2384d2004-08-01 21:59:26 +0000615 const uint8_t *buf1;
bellardfaea38e2006-08-05 21:31:00 +0000616 BlockDriverInfo bdi;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900617 QEMUOptionParameter *param = NULL, *create_options = NULL;
Kevin Wolfa18953f2010-10-14 15:46:04 +0200618 QEMUOptionParameter *out_baseimg_param;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200619 char *options = NULL;
edison51ef6722010-09-21 19:58:41 -0700620 const char *snapshot_name = NULL;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200621 float local_progress;
bellardea2384d2004-08-01 21:59:26 +0000622
623 fmt = NULL;
624 out_fmt = "raw";
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400625 cache = "unsafe";
thsf58c7b32008-06-05 21:53:49 +0000626 out_baseimg = NULL;
Jes Sorenseneec77d92010-12-07 17:44:34 +0100627 compress = 0;
bellardea2384d2004-08-01 21:59:26 +0000628 for(;;) {
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400629 c = getopt(argc, argv, "f:O:B:s:hce6o:pt:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100630 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000631 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100632 }
bellardea2384d2004-08-01 21:59:26 +0000633 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100634 case '?':
bellardea2384d2004-08-01 21:59:26 +0000635 case 'h':
636 help();
637 break;
638 case 'f':
639 fmt = optarg;
640 break;
641 case 'O':
642 out_fmt = optarg;
643 break;
thsf58c7b32008-06-05 21:53:49 +0000644 case 'B':
645 out_baseimg = optarg;
646 break;
bellardea2384d2004-08-01 21:59:26 +0000647 case 'c':
Jes Sorenseneec77d92010-12-07 17:44:34 +0100648 compress = 1;
bellardea2384d2004-08-01 21:59:26 +0000649 break;
650 case 'e':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200651 error_report("option -e is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100652 "encryption\' instead!");
653 return 1;
thsec36ba12007-09-16 21:59:02 +0000654 case '6':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200655 error_report("option -6 is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100656 "compat6\' instead!");
657 return 1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200658 case 'o':
659 options = optarg;
660 break;
edison51ef6722010-09-21 19:58:41 -0700661 case 's':
662 snapshot_name = optarg;
663 break;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200664 case 'p':
665 progress = 1;
666 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400667 case 't':
668 cache = optarg;
669 break;
bellardea2384d2004-08-01 21:59:26 +0000670 }
671 }
ths3b46e622007-09-17 08:09:54 +0000672
balrog926c2d22007-10-31 01:11:44 +0000673 bs_n = argc - optind - 1;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100674 if (bs_n < 1) {
675 help();
676 }
balrog926c2d22007-10-31 01:11:44 +0000677
678 out_filename = argv[argc - 1];
thsf58c7b32008-06-05 21:53:49 +0000679
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100680 if (options && !strcmp(options, "?")) {
681 ret = print_block_option_help(out_filename, out_fmt);
682 goto out;
683 }
684
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900685 if (bs_n > 1 && out_baseimg) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100686 error_report("-B makes no sense when concatenating multiple input "
687 "images");
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100688 ret = -1;
689 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900690 }
balrog926c2d22007-10-31 01:11:44 +0000691
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200692 qemu_progress_init(progress, 2.0);
693 qemu_progress_print(0, 100);
694
Anthony Liguori7267c092011-08-20 22:09:37 -0500695 bs = g_malloc0(bs_n * sizeof(BlockDriverState *));
balrog926c2d22007-10-31 01:11:44 +0000696
697 total_sectors = 0;
698 for (bs_i = 0; bs_i < bs_n; bs_i++) {
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100699 bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900700 if (!bs[bs_i]) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100701 error_report("Could not open '%s'", argv[optind + bs_i]);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900702 ret = -1;
703 goto out;
704 }
balrog926c2d22007-10-31 01:11:44 +0000705 bdrv_get_geometry(bs[bs_i], &bs_sectors);
706 total_sectors += bs_sectors;
707 }
bellardea2384d2004-08-01 21:59:26 +0000708
edison51ef6722010-09-21 19:58:41 -0700709 if (snapshot_name != NULL) {
710 if (bs_n > 1) {
Markus Armbruster6daf1942011-06-22 14:03:54 +0200711 error_report("No support for concatenating multiple snapshot");
edison51ef6722010-09-21 19:58:41 -0700712 ret = -1;
713 goto out;
714 }
715 if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
Markus Armbruster6daf1942011-06-22 14:03:54 +0200716 error_report("Failed to load snapshot");
edison51ef6722010-09-21 19:58:41 -0700717 ret = -1;
718 goto out;
719 }
720 }
721
Kevin Wolfefa84d42009-05-18 16:42:12 +0200722 /* Find driver and parse its options */
bellardea2384d2004-08-01 21:59:26 +0000723 drv = bdrv_find_format(out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900724 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100725 error_report("Unknown file format '%s'", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900726 ret = -1;
727 goto out;
728 }
balrog926c2d22007-10-31 01:11:44 +0000729
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900730 proto_drv = bdrv_find_protocol(out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900731 if (!proto_drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100732 error_report("Unknown protocol '%s'", out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900733 ret = -1;
734 goto out;
735 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900736
737 create_options = append_option_parameters(create_options,
738 drv->create_options);
739 create_options = append_option_parameters(create_options,
740 proto_drv->create_options);
Kevin Wolfdb08adf2009-06-04 15:39:38 +0200741
Kevin Wolfefa84d42009-05-18 16:42:12 +0200742 if (options) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900743 param = parse_option_parameters(options, create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200744 if (param == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100745 error_report("Invalid options for file format '%s'.", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900746 ret = -1;
747 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200748 }
749 } else {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900750 param = parse_option_parameters("", create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200751 }
752
753 set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
Jes Sorenseneec77d92010-12-07 17:44:34 +0100754 ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900755 if (ret < 0) {
756 goto out;
757 }
Kevin Wolfefa84d42009-05-18 16:42:12 +0200758
Kevin Wolfa18953f2010-10-14 15:46:04 +0200759 /* Get backing file name if -o backing_file was used */
760 out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
761 if (out_baseimg_param) {
762 out_baseimg = out_baseimg_param->value.s;
763 }
764
Kevin Wolfefa84d42009-05-18 16:42:12 +0200765 /* Check if compression is supported */
Jes Sorenseneec77d92010-12-07 17:44:34 +0100766 if (compress) {
Kevin Wolfefa84d42009-05-18 16:42:12 +0200767 QEMUOptionParameter *encryption =
768 get_option_parameter(param, BLOCK_OPT_ENCRYPT);
769
770 if (!drv->bdrv_write_compressed) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100771 error_report("Compression not supported for this file format");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900772 ret = -1;
773 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200774 }
775
776 if (encryption && encryption->value.n) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100777 error_report("Compression and encryption not supported at "
778 "the same time");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900779 ret = -1;
780 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200781 }
782 }
783
784 /* Create the new image */
785 ret = bdrv_create(drv, out_filename, param);
bellardea2384d2004-08-01 21:59:26 +0000786 if (ret < 0) {
787 if (ret == -ENOTSUP) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100788 error_report("Formatting not supported for file format '%s'",
789 out_fmt);
aurel326e9ea0c2009-04-15 14:42:46 +0000790 } else if (ret == -EFBIG) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100791 error_report("The image size is too large for file format '%s'",
792 out_fmt);
bellardea2384d2004-08-01 21:59:26 +0000793 } else {
Jes Sorensen15654a62010-12-16 14:31:53 +0100794 error_report("%s: error while converting %s: %s",
795 out_filename, out_fmt, strerror(-ret));
bellardea2384d2004-08-01 21:59:26 +0000796 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900797 goto out;
bellardea2384d2004-08-01 21:59:26 +0000798 }
ths3b46e622007-09-17 08:09:54 +0000799
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400800 flags = BDRV_O_RDWR;
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +0100801 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400802 if (ret < 0) {
803 error_report("Invalid cache option: %s", cache);
804 return -1;
805 }
806
807 out_bs = bdrv_new_open(out_filename, out_fmt, flags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900808 if (!out_bs) {
809 ret = -1;
810 goto out;
811 }
bellardea2384d2004-08-01 21:59:26 +0000812
balrog926c2d22007-10-31 01:11:44 +0000813 bs_i = 0;
814 bs_offset = 0;
815 bdrv_get_geometry(bs[0], &bs_sectors);
Anthony Liguori7267c092011-08-20 22:09:37 -0500816 buf = g_malloc(IO_BUF_SIZE);
balrog926c2d22007-10-31 01:11:44 +0000817
Jes Sorenseneec77d92010-12-07 17:44:34 +0100818 if (compress) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900819 ret = bdrv_get_info(out_bs, &bdi);
820 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100821 error_report("could not get block driver info");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900822 goto out;
823 }
bellardfaea38e2006-08-05 21:31:00 +0000824 cluster_size = bdi.cluster_size;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900825 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100826 error_report("invalid cluster size");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900827 ret = -1;
828 goto out;
829 }
bellardea2384d2004-08-01 21:59:26 +0000830 cluster_sectors = cluster_size >> 9;
831 sector_num = 0;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200832
833 nb_sectors = total_sectors;
834 local_progress = (float)100 /
Jes Sorensen4ee96412011-05-06 11:39:11 +0200835 (nb_sectors / MIN(nb_sectors, cluster_sectors));
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200836
bellardea2384d2004-08-01 21:59:26 +0000837 for(;;) {
balrog926c2d22007-10-31 01:11:44 +0000838 int64_t bs_num;
839 int remainder;
840 uint8_t *buf2;
841
bellardea2384d2004-08-01 21:59:26 +0000842 nb_sectors = total_sectors - sector_num;
843 if (nb_sectors <= 0)
844 break;
845 if (nb_sectors >= cluster_sectors)
846 n = cluster_sectors;
847 else
848 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000849
850 bs_num = sector_num - bs_offset;
851 assert (bs_num >= 0);
852 remainder = n;
853 buf2 = buf;
854 while (remainder > 0) {
855 int nlow;
856 while (bs_num == bs_sectors) {
857 bs_i++;
858 assert (bs_i < bs_n);
859 bs_offset += bs_sectors;
860 bdrv_get_geometry(bs[bs_i], &bs_sectors);
861 bs_num = 0;
Blue Swirl0bfcd592010-05-22 08:02:12 +0000862 /* printf("changing part: sector_num=%" PRId64 ", "
863 "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64
864 "\n", sector_num, bs_i, bs_offset, bs_sectors); */
balrog926c2d22007-10-31 01:11:44 +0000865 }
866 assert (bs_num < bs_sectors);
867
868 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
869
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900870 ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
871 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100872 error_report("error while reading");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900873 goto out;
874 }
balrog926c2d22007-10-31 01:11:44 +0000875
876 buf2 += nlow * 512;
877 bs_num += nlow;
878
879 remainder -= nlow;
880 }
881 assert (remainder == 0);
882
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100883 if (n < cluster_sectors) {
bellardea2384d2004-08-01 21:59:26 +0000884 memset(buf + n * 512, 0, cluster_size - n * 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100885 }
bellardea2384d2004-08-01 21:59:26 +0000886 if (is_not_zero(buf, cluster_size)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900887 ret = bdrv_write_compressed(out_bs, sector_num, buf,
888 cluster_sectors);
889 if (ret != 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100890 error_report("error while compressing sector %" PRId64,
bellardec3757d2006-06-14 15:50:07 +0000891 sector_num);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900892 goto out;
893 }
bellardea2384d2004-08-01 21:59:26 +0000894 }
895 sector_num += n;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200896 qemu_progress_print(local_progress, 100);
bellardea2384d2004-08-01 21:59:26 +0000897 }
bellardfaea38e2006-08-05 21:31:00 +0000898 /* signal EOF to align */
899 bdrv_write_compressed(out_bs, 0, NULL, 0);
bellardea2384d2004-08-01 21:59:26 +0000900 } else {
Kevin Wolff2feebb2010-04-14 17:30:35 +0200901 int has_zero_init = bdrv_has_zero_init(out_bs);
902
thsf58c7b32008-06-05 21:53:49 +0000903 sector_num = 0; // total number of sectors converted so far
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200904 nb_sectors = total_sectors - sector_num;
905 local_progress = (float)100 /
Jes Sorensen4ee96412011-05-06 11:39:11 +0200906 (nb_sectors / MIN(nb_sectors, IO_BUF_SIZE / 512));
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200907
bellardea2384d2004-08-01 21:59:26 +0000908 for(;;) {
909 nb_sectors = total_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100910 if (nb_sectors <= 0) {
bellardea2384d2004-08-01 21:59:26 +0000911 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100912 }
913 if (nb_sectors >= (IO_BUF_SIZE / 512)) {
bellardea2384d2004-08-01 21:59:26 +0000914 n = (IO_BUF_SIZE / 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100915 } else {
bellardea2384d2004-08-01 21:59:26 +0000916 n = nb_sectors;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100917 }
balrog926c2d22007-10-31 01:11:44 +0000918
919 while (sector_num - bs_offset >= bs_sectors) {
920 bs_i ++;
921 assert (bs_i < bs_n);
922 bs_offset += bs_sectors;
923 bdrv_get_geometry(bs[bs_i], &bs_sectors);
Blue Swirl0bfcd592010-05-22 08:02:12 +0000924 /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "
925 "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",
balrog926c2d22007-10-31 01:11:44 +0000926 sector_num, bs_i, bs_offset, bs_sectors); */
927 }
928
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100929 if (n > bs_offset + bs_sectors - sector_num) {
balrog926c2d22007-10-31 01:11:44 +0000930 n = bs_offset + bs_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100931 }
balrog926c2d22007-10-31 01:11:44 +0000932
Kevin Wolff2feebb2010-04-14 17:30:35 +0200933 if (has_zero_init) {
Akkarit Sangpetchd0320442009-07-17 10:02:15 +0200934 /* If the output image is being created as a copy on write image,
935 assume that sectors which are unallocated in the input image
936 are present in both the output's and input's base images (no
937 need to copy them). */
938 if (out_baseimg) {
939 if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
940 n, &n1)) {
941 sector_num += n1;
942 continue;
943 }
944 /* The next 'n1' sectors are allocated in the input image. Copy
945 only those as they may be followed by unallocated sectors. */
946 n = n1;
aliguori93c65b42009-04-05 17:40:43 +0000947 }
aliguori93c65b42009-04-05 17:40:43 +0000948 } else {
949 n1 = n;
thsf58c7b32008-06-05 21:53:49 +0000950 }
951
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900952 ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
953 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100954 error_report("error while reading");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900955 goto out;
956 }
bellardea2384d2004-08-01 21:59:26 +0000957 /* NOTE: at the same time we convert, we do not write zero
958 sectors to have a chance to compress the image. Ideally, we
959 should add a specific call to have the info to go faster */
960 buf1 = buf;
961 while (n > 0) {
thsf58c7b32008-06-05 21:53:49 +0000962 /* If the output image is being created as a copy on write image,
963 copy all sectors even the ones containing only NUL bytes,
aliguori93c65b42009-04-05 17:40:43 +0000964 because they may differ from the sectors in the base image.
965
966 If the output is to a host device, we also write out
967 sectors that are entirely 0, since whatever data was
968 already there is garbage, not 0s. */
Kevin Wolff2feebb2010-04-14 17:30:35 +0200969 if (!has_zero_init || out_baseimg ||
aliguori93c65b42009-04-05 17:40:43 +0000970 is_allocated_sectors(buf1, n, &n1)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900971 ret = bdrv_write(out_bs, sector_num, buf1, n1);
972 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100973 error_report("error while writing");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900974 goto out;
975 }
bellardea2384d2004-08-01 21:59:26 +0000976 }
977 sector_num += n1;
978 n -= n1;
979 buf1 += n1 * 512;
980 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200981 qemu_progress_print(local_progress, 100);
bellardea2384d2004-08-01 21:59:26 +0000982 }
983 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900984out:
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200985 qemu_progress_end();
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900986 free_option_parameters(create_options);
987 free_option_parameters(param);
Anthony Liguori7267c092011-08-20 22:09:37 -0500988 g_free(buf);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900989 if (out_bs) {
990 bdrv_delete(out_bs);
991 }
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100992 if (bs) {
993 for (bs_i = 0; bs_i < bs_n; bs_i++) {
994 if (bs[bs_i]) {
995 bdrv_delete(bs[bs_i]);
996 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900997 }
Anthony Liguori7267c092011-08-20 22:09:37 -0500998 g_free(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900999 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001000 if (ret) {
1001 return 1;
1002 }
bellardea2384d2004-08-01 21:59:26 +00001003 return 0;
1004}
1005
bellard57d1a2b2004-08-03 21:15:11 +00001006
bellardfaea38e2006-08-05 21:31:00 +00001007static void dump_snapshots(BlockDriverState *bs)
1008{
1009 QEMUSnapshotInfo *sn_tab, *sn;
1010 int nb_sns, i;
1011 char buf[256];
1012
1013 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1014 if (nb_sns <= 0)
1015 return;
1016 printf("Snapshot list:\n");
1017 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
1018 for(i = 0; i < nb_sns; i++) {
1019 sn = &sn_tab[i];
1020 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
1021 }
Anthony Liguori7267c092011-08-20 22:09:37 -05001022 g_free(sn_tab);
bellardfaea38e2006-08-05 21:31:00 +00001023}
1024
bellardea2384d2004-08-01 21:59:26 +00001025static int img_info(int argc, char **argv)
1026{
1027 int c;
1028 const char *filename, *fmt;
bellardea2384d2004-08-01 21:59:26 +00001029 BlockDriverState *bs;
1030 char fmt_name[128], size_buf[128], dsize_buf[128];
ths96b8f132007-12-17 01:35:20 +00001031 uint64_t total_sectors;
1032 int64_t allocated_size;
bellard93b6b2a2006-08-01 15:51:11 +00001033 char backing_filename[1024];
1034 char backing_filename2[1024];
bellardfaea38e2006-08-05 21:31:00 +00001035 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +00001036
1037 fmt = NULL;
1038 for(;;) {
1039 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001040 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +00001041 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001042 }
bellardea2384d2004-08-01 21:59:26 +00001043 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001044 case '?':
bellardea2384d2004-08-01 21:59:26 +00001045 case 'h':
1046 help();
1047 break;
1048 case 'f':
1049 fmt = optarg;
1050 break;
1051 }
1052 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001053 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +00001054 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001055 }
bellardea2384d2004-08-01 21:59:26 +00001056 filename = argv[optind++];
1057
Stefan Hajnocziadfe0782010-04-13 10:29:35 +01001058 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001059 if (!bs) {
1060 return 1;
1061 }
bellardea2384d2004-08-01 21:59:26 +00001062 bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
1063 bdrv_get_geometry(bs, &total_sectors);
1064 get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
Fam Zheng4a1d5e12011-07-12 19:56:39 +08001065 allocated_size = bdrv_get_allocated_file_size(bs);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001066 if (allocated_size < 0) {
blueswir1a10ea302008-08-24 10:30:33 +00001067 snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001068 } else {
ths5fafdf22007-09-16 21:08:06 +00001069 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
bellardde167e42005-04-28 21:15:08 +00001070 allocated_size);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001071 }
bellardea2384d2004-08-01 21:59:26 +00001072 printf("image: %s\n"
1073 "file format: %s\n"
bellardec3757d2006-06-14 15:50:07 +00001074 "virtual size: %s (%" PRId64 " bytes)\n"
bellardea2384d2004-08-01 21:59:26 +00001075 "disk size: %s\n",
ths5fafdf22007-09-16 21:08:06 +00001076 filename, fmt_name, size_buf,
bellardec3757d2006-06-14 15:50:07 +00001077 (total_sectors * 512),
bellardea2384d2004-08-01 21:59:26 +00001078 dsize_buf);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001079 if (bdrv_is_encrypted(bs)) {
bellardea2384d2004-08-01 21:59:26 +00001080 printf("encrypted: yes\n");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001081 }
bellardfaea38e2006-08-05 21:31:00 +00001082 if (bdrv_get_info(bs, &bdi) >= 0) {
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001083 if (bdi.cluster_size != 0) {
bellardfaea38e2006-08-05 21:31:00 +00001084 printf("cluster_size: %d\n", bdi.cluster_size);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001085 }
bellardfaea38e2006-08-05 21:31:00 +00001086 }
bellard93b6b2a2006-08-01 15:51:11 +00001087 bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
bellardfaea38e2006-08-05 21:31:00 +00001088 if (backing_filename[0] != '\0') {
bellard93b6b2a2006-08-01 15:51:11 +00001089 path_combine(backing_filename2, sizeof(backing_filename2),
1090 filename, backing_filename);
ths5fafdf22007-09-16 21:08:06 +00001091 printf("backing file: %s (actual path: %s)\n",
bellard93b6b2a2006-08-01 15:51:11 +00001092 backing_filename,
1093 backing_filename2);
bellardfaea38e2006-08-05 21:31:00 +00001094 }
1095 dump_snapshots(bs);
bellardea2384d2004-08-01 21:59:26 +00001096 bdrv_delete(bs);
1097 return 0;
1098}
1099
aliguorif7b4a942009-01-07 17:40:15 +00001100#define SNAPSHOT_LIST 1
1101#define SNAPSHOT_CREATE 2
1102#define SNAPSHOT_APPLY 3
1103#define SNAPSHOT_DELETE 4
1104
Stuart Brady153859b2009-06-07 00:42:17 +01001105static int img_snapshot(int argc, char **argv)
aliguorif7b4a942009-01-07 17:40:15 +00001106{
1107 BlockDriverState *bs;
1108 QEMUSnapshotInfo sn;
1109 char *filename, *snapshot_name = NULL;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001110 int c, ret = 0, bdrv_oflags;
aliguorif7b4a942009-01-07 17:40:15 +00001111 int action = 0;
1112 qemu_timeval tv;
1113
Kevin Wolf710da702011-01-10 12:33:02 +01001114 bdrv_oflags = BDRV_O_FLAGS | BDRV_O_RDWR;
aliguorif7b4a942009-01-07 17:40:15 +00001115 /* Parse commandline parameters */
1116 for(;;) {
1117 c = getopt(argc, argv, "la:c:d:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001118 if (c == -1) {
aliguorif7b4a942009-01-07 17:40:15 +00001119 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001120 }
aliguorif7b4a942009-01-07 17:40:15 +00001121 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001122 case '?':
aliguorif7b4a942009-01-07 17:40:15 +00001123 case 'h':
1124 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001125 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001126 case 'l':
1127 if (action) {
1128 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001129 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001130 }
1131 action = SNAPSHOT_LIST;
Naphtali Spreif5edb012010-01-17 16:48:13 +02001132 bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
aliguorif7b4a942009-01-07 17:40:15 +00001133 break;
1134 case 'a':
1135 if (action) {
1136 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001137 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001138 }
1139 action = SNAPSHOT_APPLY;
1140 snapshot_name = optarg;
1141 break;
1142 case 'c':
1143 if (action) {
1144 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001145 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001146 }
1147 action = SNAPSHOT_CREATE;
1148 snapshot_name = optarg;
1149 break;
1150 case 'd':
1151 if (action) {
1152 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001153 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001154 }
1155 action = SNAPSHOT_DELETE;
1156 snapshot_name = optarg;
1157 break;
1158 }
1159 }
1160
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001161 if (optind >= argc) {
aliguorif7b4a942009-01-07 17:40:15 +00001162 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001163 }
aliguorif7b4a942009-01-07 17:40:15 +00001164 filename = argv[optind++];
1165
1166 /* Open the image */
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001167 bs = bdrv_new_open(filename, NULL, bdrv_oflags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001168 if (!bs) {
1169 return 1;
1170 }
aliguorif7b4a942009-01-07 17:40:15 +00001171
1172 /* Perform the requested action */
1173 switch(action) {
1174 case SNAPSHOT_LIST:
1175 dump_snapshots(bs);
1176 break;
1177
1178 case SNAPSHOT_CREATE:
1179 memset(&sn, 0, sizeof(sn));
1180 pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
1181
1182 qemu_gettimeofday(&tv);
1183 sn.date_sec = tv.tv_sec;
1184 sn.date_nsec = tv.tv_usec * 1000;
1185
1186 ret = bdrv_snapshot_create(bs, &sn);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001187 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001188 error_report("Could not create snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001189 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001190 }
aliguorif7b4a942009-01-07 17:40:15 +00001191 break;
1192
1193 case SNAPSHOT_APPLY:
1194 ret = bdrv_snapshot_goto(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001195 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001196 error_report("Could not apply snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001197 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001198 }
aliguorif7b4a942009-01-07 17:40:15 +00001199 break;
1200
1201 case SNAPSHOT_DELETE:
1202 ret = bdrv_snapshot_delete(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001203 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001204 error_report("Could not delete snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001205 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001206 }
aliguorif7b4a942009-01-07 17:40:15 +00001207 break;
1208 }
1209
1210 /* Cleanup */
1211 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001212 if (ret) {
1213 return 1;
1214 }
Stuart Brady153859b2009-06-07 00:42:17 +01001215 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001216}
1217
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001218static int img_rebase(int argc, char **argv)
1219{
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001220 BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001221 BlockDriver *old_backing_drv, *new_backing_drv;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001222 char *filename;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001223 const char *fmt, *cache, *out_basefmt, *out_baseimg;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001224 int c, flags, ret;
1225 int unsafe = 0;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001226 int progress = 0;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001227
1228 /* Parse commandline parameters */
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001229 fmt = NULL;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001230 cache = BDRV_DEFAULT_CACHE;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001231 out_baseimg = NULL;
1232 out_basefmt = NULL;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001233 for(;;) {
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001234 c = getopt(argc, argv, "uhf:F:b:pt:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001235 if (c == -1) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001236 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001237 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001238 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001239 case '?':
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001240 case 'h':
1241 help();
1242 return 0;
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001243 case 'f':
1244 fmt = optarg;
1245 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001246 case 'F':
1247 out_basefmt = optarg;
1248 break;
1249 case 'b':
1250 out_baseimg = optarg;
1251 break;
1252 case 'u':
1253 unsafe = 1;
1254 break;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001255 case 'p':
1256 progress = 1;
1257 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001258 case 't':
1259 cache = optarg;
1260 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001261 }
1262 }
1263
Anthony Liguori9a9d9db2011-04-13 15:51:47 +01001264 if ((optind >= argc) || (!unsafe && !out_baseimg)) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001265 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001266 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001267 filename = argv[optind++];
1268
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001269 qemu_progress_init(progress, 2.0);
1270 qemu_progress_print(0, 100);
1271
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001272 flags = BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +01001273 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001274 if (ret < 0) {
1275 error_report("Invalid cache option: %s", cache);
1276 return -1;
1277 }
1278
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001279 /*
1280 * Open the images.
1281 *
1282 * Ignore the old backing file for unsafe rebase in case we want to correct
1283 * the reference to a renamed or moved backing file.
1284 */
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001285 bs = bdrv_new_open(filename, fmt, flags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001286 if (!bs) {
1287 return 1;
1288 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001289
1290 /* Find the right drivers for the backing files */
1291 old_backing_drv = NULL;
1292 new_backing_drv = NULL;
1293
1294 if (!unsafe && bs->backing_format[0] != '\0') {
1295 old_backing_drv = bdrv_find_format(bs->backing_format);
1296 if (old_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001297 error_report("Invalid format name: '%s'", bs->backing_format);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001298 ret = -1;
1299 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001300 }
1301 }
1302
1303 if (out_basefmt != NULL) {
1304 new_backing_drv = bdrv_find_format(out_basefmt);
1305 if (new_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001306 error_report("Invalid format name: '%s'", out_basefmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001307 ret = -1;
1308 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001309 }
1310 }
1311
1312 /* For safe rebasing we need to compare old and new backing file */
1313 if (unsafe) {
1314 /* Make the compiler happy */
1315 bs_old_backing = NULL;
1316 bs_new_backing = NULL;
1317 } else {
1318 char backing_name[1024];
1319
1320 bs_old_backing = bdrv_new("old_backing");
1321 bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001322 ret = bdrv_open(bs_old_backing, backing_name, BDRV_O_FLAGS,
1323 old_backing_drv);
1324 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001325 error_report("Could not open old backing file '%s'", backing_name);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001326 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001327 }
1328
1329 bs_new_backing = bdrv_new("new_backing");
Kevin Wolfcdbae852010-08-17 18:58:55 +02001330 ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS,
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001331 new_backing_drv);
1332 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001333 error_report("Could not open new backing file '%s'", out_baseimg);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001334 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001335 }
1336 }
1337
1338 /*
1339 * Check each unallocated cluster in the COW file. If it is unallocated,
1340 * accesses go to the backing file. We must therefore compare this cluster
1341 * in the old and new backing file, and if they differ we need to copy it
1342 * from the old backing file into the COW file.
1343 *
1344 * If qemu-img crashes during this step, no harm is done. The content of
1345 * the image is the same as the original one at any time.
1346 */
1347 if (!unsafe) {
1348 uint64_t num_sectors;
1349 uint64_t sector;
Kevin Wolfcc60e322010-04-29 14:47:48 +02001350 int n;
TeLeMand6771bf2010-02-08 16:20:00 +08001351 uint8_t * buf_old;
1352 uint8_t * buf_new;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001353 float local_progress;
TeLeMand6771bf2010-02-08 16:20:00 +08001354
Anthony Liguori7267c092011-08-20 22:09:37 -05001355 buf_old = g_malloc(IO_BUF_SIZE);
1356 buf_new = g_malloc(IO_BUF_SIZE);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001357
1358 bdrv_get_geometry(bs, &num_sectors);
1359
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001360 local_progress = (float)100 /
Jes Sorensen4ee96412011-05-06 11:39:11 +02001361 (num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512));
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001362 for (sector = 0; sector < num_sectors; sector += n) {
1363
1364 /* How many sectors can we handle with the next read? */
1365 if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
1366 n = (IO_BUF_SIZE / 512);
1367 } else {
1368 n = num_sectors - sector;
1369 }
1370
1371 /* If the cluster is allocated, we don't need to take action */
Kevin Wolfcc60e322010-04-29 14:47:48 +02001372 ret = bdrv_is_allocated(bs, sector, n, &n);
1373 if (ret) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001374 continue;
1375 }
1376
1377 /* Read old and new backing file */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001378 ret = bdrv_read(bs_old_backing, sector, buf_old, n);
1379 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001380 error_report("error while reading from old backing file");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001381 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001382 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001383 ret = bdrv_read(bs_new_backing, sector, buf_new, n);
1384 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001385 error_report("error while reading from new backing file");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001386 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001387 }
1388
1389 /* If they differ, we need to write to the COW file */
1390 uint64_t written = 0;
1391
1392 while (written < n) {
1393 int pnum;
1394
1395 if (compare_sectors(buf_old + written * 512,
Kevin Wolf60b1bd42010-02-17 12:32:59 +01001396 buf_new + written * 512, n - written, &pnum))
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001397 {
1398 ret = bdrv_write(bs, sector + written,
1399 buf_old + written * 512, pnum);
1400 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001401 error_report("Error while writing to COW image: %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001402 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001403 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001404 }
1405 }
1406
1407 written += pnum;
1408 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001409 qemu_progress_print(local_progress, 100);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001410 }
TeLeMand6771bf2010-02-08 16:20:00 +08001411
Anthony Liguori7267c092011-08-20 22:09:37 -05001412 g_free(buf_old);
1413 g_free(buf_new);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001414 }
1415
1416 /*
1417 * Change the backing file. All clusters that are different from the old
1418 * backing file are overwritten in the COW file now, so the visible content
1419 * doesn't change when we switch the backing file.
1420 */
1421 ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
1422 if (ret == -ENOSPC) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001423 error_report("Could not change the backing file to '%s': No "
1424 "space left in the file header", out_baseimg);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001425 } else if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001426 error_report("Could not change the backing file to '%s': %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001427 out_baseimg, strerror(-ret));
1428 }
1429
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001430 qemu_progress_print(100, 0);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001431 /*
1432 * TODO At this point it is possible to check if any clusters that are
1433 * allocated in the COW file are the same in the backing file. If so, they
1434 * could be dropped from the COW file. Don't do this before switching the
1435 * backing file, in case of a crash this would lead to corruption.
1436 */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001437out:
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001438 qemu_progress_end();
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001439 /* Cleanup */
1440 if (!unsafe) {
Kevin Wolfeb863ad2011-03-31 12:39:51 +02001441 if (bs_old_backing != NULL) {
1442 bdrv_delete(bs_old_backing);
1443 }
1444 if (bs_new_backing != NULL) {
1445 bdrv_delete(bs_new_backing);
1446 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001447 }
1448
1449 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001450 if (ret) {
1451 return 1;
1452 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001453 return 0;
1454}
1455
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001456static int img_resize(int argc, char **argv)
1457{
1458 int c, ret, relative;
1459 const char *filename, *fmt, *size;
1460 int64_t n, total_size;
Jes Sorensen2a819982010-12-06 17:08:31 +01001461 BlockDriverState *bs = NULL;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001462 QEMUOptionParameter *param;
1463 QEMUOptionParameter resize_options[] = {
1464 {
1465 .name = BLOCK_OPT_SIZE,
1466 .type = OPT_SIZE,
1467 .help = "Virtual disk size"
1468 },
1469 { NULL }
1470 };
1471
Kevin Wolfe80fec72011-04-29 10:58:12 +02001472 /* Remove size from argv manually so that negative numbers are not treated
1473 * as options by getopt. */
1474 if (argc < 3) {
1475 help();
1476 return 1;
1477 }
1478
1479 size = argv[--argc];
1480
1481 /* Parse getopt arguments */
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001482 fmt = NULL;
1483 for(;;) {
1484 c = getopt(argc, argv, "f:h");
1485 if (c == -1) {
1486 break;
1487 }
1488 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001489 case '?':
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001490 case 'h':
1491 help();
1492 break;
1493 case 'f':
1494 fmt = optarg;
1495 break;
1496 }
1497 }
Kevin Wolfe80fec72011-04-29 10:58:12 +02001498 if (optind >= argc) {
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001499 help();
1500 }
1501 filename = argv[optind++];
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001502
1503 /* Choose grow, shrink, or absolute resize mode */
1504 switch (size[0]) {
1505 case '+':
1506 relative = 1;
1507 size++;
1508 break;
1509 case '-':
1510 relative = -1;
1511 size++;
1512 break;
1513 default:
1514 relative = 0;
1515 break;
1516 }
1517
1518 /* Parse size */
1519 param = parse_option_parameters("", resize_options, NULL);
1520 if (set_option_parameter(param, BLOCK_OPT_SIZE, size)) {
1521 /* Error message already printed when size parsing fails */
Jes Sorensen2a819982010-12-06 17:08:31 +01001522 ret = -1;
1523 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001524 }
1525 n = get_option_parameter(param, BLOCK_OPT_SIZE)->value.n;
1526 free_option_parameters(param);
1527
1528 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001529 if (!bs) {
Jes Sorensen2a819982010-12-06 17:08:31 +01001530 ret = -1;
1531 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001532 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001533
1534 if (relative) {
1535 total_size = bdrv_getlength(bs) + n * relative;
1536 } else {
1537 total_size = n;
1538 }
1539 if (total_size <= 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001540 error_report("New image size must be positive");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001541 ret = -1;
1542 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001543 }
1544
1545 ret = bdrv_truncate(bs, total_size);
1546 switch (ret) {
1547 case 0:
1548 printf("Image resized.\n");
1549 break;
1550 case -ENOTSUP:
Jes Sorensen15654a62010-12-16 14:31:53 +01001551 error_report("This image format does not support resize");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001552 break;
1553 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +01001554 error_report("Image is read-only");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001555 break;
1556 default:
Jes Sorensen15654a62010-12-16 14:31:53 +01001557 error_report("Error resizing image (%d)", -ret);
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001558 break;
1559 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001560out:
Jes Sorensen2a819982010-12-06 17:08:31 +01001561 if (bs) {
1562 bdrv_delete(bs);
1563 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001564 if (ret) {
1565 return 1;
1566 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001567 return 0;
1568}
1569
Anthony Liguoric227f092009-10-01 16:12:16 -05001570static const img_cmd_t img_cmds[] = {
Stuart Brady153859b2009-06-07 00:42:17 +01001571#define DEF(option, callback, arg_string) \
1572 { option, callback },
1573#include "qemu-img-cmds.h"
1574#undef DEF
1575#undef GEN_DOCS
1576 { NULL, NULL, },
1577};
1578
bellardea2384d2004-08-01 21:59:26 +00001579int main(int argc, char **argv)
1580{
Anthony Liguoric227f092009-10-01 16:12:16 -05001581 const img_cmd_t *cmd;
Stuart Brady153859b2009-06-07 00:42:17 +01001582 const char *cmdname;
bellardea2384d2004-08-01 21:59:26 +00001583
Kevin Wolf53f76e52010-12-16 15:10:32 +01001584 error_set_progname(argv[0]);
1585
bellardea2384d2004-08-01 21:59:26 +00001586 bdrv_init();
1587 if (argc < 2)
1588 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001589 cmdname = argv[1];
aurel328f9b1572009-02-09 18:14:31 +00001590 argc--; argv++;
Stuart Brady153859b2009-06-07 00:42:17 +01001591
1592 /* find the command */
1593 for(cmd = img_cmds; cmd->name != NULL; cmd++) {
1594 if (!strcmp(cmdname, cmd->name)) {
1595 return cmd->handler(argc, argv);
1596 }
bellardea2384d2004-08-01 21:59:26 +00001597 }
Stuart Brady153859b2009-06-07 00:42:17 +01001598
1599 /* not found */
1600 help();
bellardea2384d2004-08-01 21:59:26 +00001601 return 0;
1602}