blob: 2fee782217641f32c8cff954be74b284f81da46d [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"
Stefan Hajnoczi92196b22011-08-04 12:26:52 +010069 " options are: 'none', 'writeback' (default), 'writethrough', 'directsync'\n"
70 " and 'unsafe'\n"
malc3f020d72010-02-08 12:04:56 +030071 " 'size' is the disk image size in bytes. Optional suffixes\n"
72 " 'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M)\n"
73 " and T (terabyte, 1024G) are supported. 'b' is ignored.\n"
74 " 'output_filename' is the destination disk image filename\n"
75 " 'output_fmt' is the destination format\n"
76 " 'options' is a comma separated list of format specific options in a\n"
77 " name=value format. Use -o ? for an overview of the options supported by the\n"
78 " used format\n"
79 " '-c' indicates that target image must be compressed (qcow format only)\n"
80 " '-u' enables unsafe rebasing. It is assumed that old and new backing file\n"
81 " match exactly. The image doesn't need a working backing file before\n"
82 " rebasing in this case (useful for renaming the backing file)\n"
83 " '-h' with or without a command shows this help and lists the supported formats\n"
Jes Sorensen6b837bc2011-03-30 14:16:25 +020084 " '-p' show progress of command (only certain commands)\n"
malc3f020d72010-02-08 12:04:56 +030085 "\n"
86 "Parameters to snapshot subcommand:\n"
87 " 'snapshot' is the name of the snapshot to create, apply or delete\n"
88 " '-a' applies a snapshot (revert disk to saved state)\n"
89 " '-c' creates a snapshot\n"
90 " '-d' deletes a snapshot\n"
Paolo Bonzinie00291c2010-02-04 16:49:56 +010091 " '-l' lists all snapshots in the given image\n";
92
93 printf("%s\nSupported formats:", help_msg);
bellardea2384d2004-08-01 21:59:26 +000094 bdrv_iterate_format(format_print, NULL);
95 printf("\n");
96 exit(1);
97}
98
bellardea2384d2004-08-01 21:59:26 +000099#if defined(WIN32)
100/* XXX: put correct support for win32 */
101static int read_password(char *buf, int buf_size)
102{
103 int c, i;
104 printf("Password: ");
105 fflush(stdout);
106 i = 0;
107 for(;;) {
108 c = getchar();
109 if (c == '\n')
110 break;
111 if (i < (buf_size - 1))
112 buf[i++] = c;
113 }
114 buf[i] = '\0';
115 return 0;
116}
117
118#else
119
120#include <termios.h>
121
122static struct termios oldtty;
123
124static void term_exit(void)
125{
126 tcsetattr (0, TCSANOW, &oldtty);
127}
128
129static void term_init(void)
130{
131 struct termios tty;
132
133 tcgetattr (0, &tty);
134 oldtty = tty;
135
136 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
137 |INLCR|IGNCR|ICRNL|IXON);
138 tty.c_oflag |= OPOST;
139 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
140 tty.c_cflag &= ~(CSIZE|PARENB);
141 tty.c_cflag |= CS8;
142 tty.c_cc[VMIN] = 1;
143 tty.c_cc[VTIME] = 0;
ths3b46e622007-09-17 08:09:54 +0000144
bellardea2384d2004-08-01 21:59:26 +0000145 tcsetattr (0, TCSANOW, &tty);
146
147 atexit(term_exit);
148}
149
pbrook3f379ab2007-11-11 03:33:13 +0000150static int read_password(char *buf, int buf_size)
bellardea2384d2004-08-01 21:59:26 +0000151{
152 uint8_t ch;
153 int i, ret;
154
155 printf("password: ");
156 fflush(stdout);
157 term_init();
158 i = 0;
159 for(;;) {
160 ret = read(0, &ch, 1);
161 if (ret == -1) {
162 if (errno == EAGAIN || errno == EINTR) {
163 continue;
164 } else {
165 ret = -1;
166 break;
167 }
168 } else if (ret == 0) {
169 ret = -1;
170 break;
171 } else {
172 if (ch == '\r') {
173 ret = 0;
174 break;
175 }
176 if (i < (buf_size - 1))
177 buf[i++] = ch;
178 }
179 }
180 term_exit();
181 buf[i] = '\0';
182 printf("\n");
183 return ret;
184}
185#endif
186
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100187static int print_block_option_help(const char *filename, const char *fmt)
188{
189 BlockDriver *drv, *proto_drv;
190 QEMUOptionParameter *create_options = NULL;
191
192 /* Find driver and parse its options */
193 drv = bdrv_find_format(fmt);
194 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100195 error_report("Unknown file format '%s'", fmt);
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100196 return 1;
197 }
198
199 proto_drv = bdrv_find_protocol(filename);
200 if (!proto_drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100201 error_report("Unknown protocol '%s'", filename);
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100202 return 1;
203 }
204
205 create_options = append_option_parameters(create_options,
206 drv->create_options);
207 create_options = append_option_parameters(create_options,
208 proto_drv->create_options);
209 print_option_help(create_options);
210 free_option_parameters(create_options);
211 return 0;
212}
213
bellard75c23802004-08-27 21:28:58 +0000214static BlockDriverState *bdrv_new_open(const char *filename,
Sheng Yang9bc378c2010-01-29 10:15:06 +0800215 const char *fmt,
Stefan Hajnoczif163d072010-04-13 10:29:34 +0100216 int flags)
bellard75c23802004-08-27 21:28:58 +0000217{
218 BlockDriverState *bs;
219 BlockDriver *drv;
220 char password[256];
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100221 int ret;
bellard75c23802004-08-27 21:28:58 +0000222
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100223 bs = bdrv_new("image");
Kevin Wolfad717132010-12-16 15:37:41 +0100224
bellard75c23802004-08-27 21:28:58 +0000225 if (fmt) {
226 drv = bdrv_find_format(fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900227 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100228 error_report("Unknown file format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900229 goto fail;
230 }
bellard75c23802004-08-27 21:28:58 +0000231 } else {
232 drv = NULL;
233 }
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100234
235 ret = bdrv_open(bs, filename, flags, drv);
236 if (ret < 0) {
237 error_report("Could not open '%s': %s", filename, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900238 goto fail;
bellard75c23802004-08-27 21:28:58 +0000239 }
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100240
bellard75c23802004-08-27 21:28:58 +0000241 if (bdrv_is_encrypted(bs)) {
242 printf("Disk image '%s' is encrypted.\n", filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900243 if (read_password(password, sizeof(password)) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100244 error_report("No password given");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900245 goto fail;
246 }
247 if (bdrv_set_key(bs, password) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100248 error_report("invalid password");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900249 goto fail;
250 }
bellard75c23802004-08-27 21:28:58 +0000251 }
252 return bs;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900253fail:
254 if (bs) {
255 bdrv_delete(bs);
256 }
257 return NULL;
bellard75c23802004-08-27 21:28:58 +0000258}
259
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900260static int add_old_style_options(const char *fmt, QEMUOptionParameter *list,
Jes Sorenseneec77d92010-12-07 17:44:34 +0100261 const char *base_filename,
262 const char *base_fmt)
Kevin Wolfefa84d42009-05-18 16:42:12 +0200263{
Kevin Wolfefa84d42009-05-18 16:42:12 +0200264 if (base_filename) {
265 if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100266 error_report("Backing file not supported for file format '%s'",
267 fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900268 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200269 }
270 }
271 if (base_fmt) {
272 if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100273 error_report("Backing file format not supported for file "
274 "format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900275 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200276 }
277 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900278 return 0;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200279}
280
bellardea2384d2004-08-01 21:59:26 +0000281static int img_create(int argc, char **argv)
282{
Jes Sorenseneec77d92010-12-07 17:44:34 +0100283 int c, ret = 0;
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100284 uint64_t img_size = -1;
bellardea2384d2004-08-01 21:59:26 +0000285 const char *fmt = "raw";
aliguori9230eaf2009-03-28 17:55:19 +0000286 const char *base_fmt = NULL;
bellardea2384d2004-08-01 21:59:26 +0000287 const char *filename;
288 const char *base_filename = NULL;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200289 char *options = NULL;
ths3b46e622007-09-17 08:09:54 +0000290
bellardea2384d2004-08-01 21:59:26 +0000291 for(;;) {
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200292 c = getopt(argc, argv, "F:b:f:he6o:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100293 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000294 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100295 }
bellardea2384d2004-08-01 21:59:26 +0000296 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100297 case '?':
bellardea2384d2004-08-01 21:59:26 +0000298 case 'h':
299 help();
300 break;
aliguori9230eaf2009-03-28 17:55:19 +0000301 case 'F':
302 base_fmt = optarg;
303 break;
bellardea2384d2004-08-01 21:59:26 +0000304 case 'b':
305 base_filename = optarg;
306 break;
307 case 'f':
308 fmt = optarg;
309 break;
310 case 'e':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200311 error_report("option -e is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100312 "encryption\' instead!");
313 return 1;
thsd8871c52007-10-24 16:11:42 +0000314 case '6':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200315 error_report("option -6 is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100316 "compat6\' instead!");
317 return 1;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200318 case 'o':
319 options = optarg;
320 break;
bellardea2384d2004-08-01 21:59:26 +0000321 }
322 }
aliguori9230eaf2009-03-28 17:55:19 +0000323
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900324 /* Get the filename */
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100325 if (optind >= argc) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900326 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100327 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900328 filename = argv[optind++];
329
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100330 /* Get image size, if specified */
331 if (optind < argc) {
Jes Sorensen70b4f4b2011-01-05 11:41:02 +0100332 int64_t sval;
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100333 sval = strtosz_suffix(argv[optind++], NULL, STRTOSZ_DEFSUFFIX_B);
334 if (sval < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100335 error_report("Invalid image size specified! You may use k, M, G or "
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100336 "T suffixes for ");
Jes Sorensen15654a62010-12-16 14:31:53 +0100337 error_report("kilobytes, megabytes, gigabytes and terabytes.");
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100338 ret = -1;
339 goto out;
340 }
341 img_size = (uint64_t)sval;
342 }
343
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100344 if (options && !strcmp(options, "?")) {
345 ret = print_block_option_help(filename, fmt);
346 goto out;
347 }
348
Jes Sorensenf88e1a42010-12-16 13:52:15 +0100349 ret = bdrv_img_create(filename, fmt, base_filename, base_fmt,
350 options, img_size, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900351out:
352 if (ret) {
353 return 1;
354 }
bellardea2384d2004-08-01 21:59:26 +0000355 return 0;
356}
357
Kevin Wolfe076f332010-06-29 11:43:13 +0200358/*
359 * Checks an image for consistency. Exit codes:
360 *
361 * 0 - Check completed, image is good
362 * 1 - Check not completed because of internal errors
363 * 2 - Check completed, image is corrupted
364 * 3 - Check completed, image has leaked clusters, but is good otherwise
365 */
aliguori15859692009-04-21 23:11:53 +0000366static int img_check(int argc, char **argv)
367{
368 int c, ret;
369 const char *filename, *fmt;
aliguori15859692009-04-21 23:11:53 +0000370 BlockDriverState *bs;
Kevin Wolfe076f332010-06-29 11:43:13 +0200371 BdrvCheckResult result;
aliguori15859692009-04-21 23:11:53 +0000372
373 fmt = NULL;
374 for(;;) {
375 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100376 if (c == -1) {
aliguori15859692009-04-21 23:11:53 +0000377 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100378 }
aliguori15859692009-04-21 23:11:53 +0000379 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100380 case '?':
aliguori15859692009-04-21 23:11:53 +0000381 case 'h':
382 help();
383 break;
384 case 'f':
385 fmt = optarg;
386 break;
387 }
388 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100389 if (optind >= argc) {
aliguori15859692009-04-21 23:11:53 +0000390 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100391 }
aliguori15859692009-04-21 23:11:53 +0000392 filename = argv[optind++];
393
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100394 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900395 if (!bs) {
396 return 1;
397 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200398 ret = bdrv_check(bs, &result);
399
400 if (ret == -ENOTSUP) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100401 error_report("This image format does not support checks");
Kevin Wolfe076f332010-06-29 11:43:13 +0200402 bdrv_delete(bs);
403 return 1;
404 }
405
406 if (!(result.corruptions || result.leaks || result.check_errors)) {
407 printf("No errors were found on the image.\n");
408 } else {
409 if (result.corruptions) {
410 printf("\n%d errors were found on the image.\n"
411 "Data may be corrupted, or further writes to the image "
412 "may corrupt it.\n",
413 result.corruptions);
aliguori15859692009-04-21 23:11:53 +0000414 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200415
416 if (result.leaks) {
417 printf("\n%d leaked clusters were found on the image.\n"
418 "This means waste of disk space, but no harm to data.\n",
419 result.leaks);
420 }
421
422 if (result.check_errors) {
423 printf("\n%d internal errors have occurred during the check.\n",
424 result.check_errors);
425 }
aliguori15859692009-04-21 23:11:53 +0000426 }
427
428 bdrv_delete(bs);
Kevin Wolfe076f332010-06-29 11:43:13 +0200429
430 if (ret < 0 || result.check_errors) {
431 printf("\nAn error has occurred during the check: %s\n"
432 "The check is not complete and may have missed error.\n",
433 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900434 return 1;
435 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200436
437 if (result.corruptions) {
438 return 2;
439 } else if (result.leaks) {
440 return 3;
441 } else {
442 return 0;
443 }
aliguori15859692009-04-21 23:11:53 +0000444}
445
bellardea2384d2004-08-01 21:59:26 +0000446static int img_commit(int argc, char **argv)
447{
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400448 int c, ret, flags;
449 const char *filename, *fmt, *cache;
bellardea2384d2004-08-01 21:59:26 +0000450 BlockDriverState *bs;
451
452 fmt = NULL;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400453 cache = BDRV_DEFAULT_CACHE;
bellardea2384d2004-08-01 21:59:26 +0000454 for(;;) {
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400455 c = getopt(argc, argv, "f:ht:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100456 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000457 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100458 }
bellardea2384d2004-08-01 21:59:26 +0000459 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100460 case '?':
bellardea2384d2004-08-01 21:59:26 +0000461 case 'h':
462 help();
463 break;
464 case 'f':
465 fmt = optarg;
466 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400467 case 't':
468 cache = optarg;
469 break;
bellardea2384d2004-08-01 21:59:26 +0000470 }
471 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100472 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +0000473 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100474 }
bellardea2384d2004-08-01 21:59:26 +0000475 filename = argv[optind++];
476
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400477 flags = BDRV_O_RDWR;
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +0100478 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400479 if (ret < 0) {
480 error_report("Invalid cache option: %s", cache);
481 return -1;
482 }
483
484 bs = bdrv_new_open(filename, fmt, flags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900485 if (!bs) {
486 return 1;
487 }
bellardea2384d2004-08-01 21:59:26 +0000488 ret = bdrv_commit(bs);
489 switch(ret) {
490 case 0:
491 printf("Image committed.\n");
492 break;
493 case -ENOENT:
Jes Sorensen15654a62010-12-16 14:31:53 +0100494 error_report("No disk inserted");
bellardea2384d2004-08-01 21:59:26 +0000495 break;
496 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +0100497 error_report("Image is read-only");
bellardea2384d2004-08-01 21:59:26 +0000498 break;
499 case -ENOTSUP:
Jes Sorensen15654a62010-12-16 14:31:53 +0100500 error_report("Image is already committed");
bellardea2384d2004-08-01 21:59:26 +0000501 break;
502 default:
Jes Sorensen15654a62010-12-16 14:31:53 +0100503 error_report("Error while committing image");
bellardea2384d2004-08-01 21:59:26 +0000504 break;
505 }
506
507 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900508 if (ret) {
509 return 1;
510 }
bellardea2384d2004-08-01 21:59:26 +0000511 return 0;
512}
513
Dmitry Konishchevf6a00aa2011-05-18 15:03:59 +0400514/*
515 * Checks whether the sector is not a zero sector.
516 *
517 * Attention! The len must be a multiple of 4 * sizeof(long) due to
518 * restriction of optimizations in this function.
519 */
bellardea2384d2004-08-01 21:59:26 +0000520static int is_not_zero(const uint8_t *sector, int len)
521{
Dmitry Konishchevf6a00aa2011-05-18 15:03:59 +0400522 /*
523 * Use long as the biggest available internal data type that fits into the
524 * CPU register and unroll the loop to smooth out the effect of memory
525 * latency.
526 */
527
bellardea2384d2004-08-01 21:59:26 +0000528 int i;
Dmitry Konishchevf6a00aa2011-05-18 15:03:59 +0400529 long d0, d1, d2, d3;
530 const long * const data = (const long *) sector;
531
532 len /= sizeof(long);
533
534 for(i = 0; i < len; i += 4) {
535 d0 = data[i + 0];
536 d1 = data[i + 1];
537 d2 = data[i + 2];
538 d3 = data[i + 3];
539
540 if (d0 || d1 || d2 || d3) {
bellardea2384d2004-08-01 21:59:26 +0000541 return 1;
Dmitry Konishchevf6a00aa2011-05-18 15:03:59 +0400542 }
bellardea2384d2004-08-01 21:59:26 +0000543 }
Dmitry Konishchevf6a00aa2011-05-18 15:03:59 +0400544
bellardea2384d2004-08-01 21:59:26 +0000545 return 0;
546}
547
thsf58c7b32008-06-05 21:53:49 +0000548/*
549 * Returns true iff the first sector pointed to by 'buf' contains at least
550 * a non-NUL byte.
551 *
552 * 'pnum' is set to the number of sectors (including and immediately following
553 * the first one) that are known to be in the same allocated/unallocated state.
554 */
bellardea2384d2004-08-01 21:59:26 +0000555static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
556{
557 int v, i;
558
559 if (n <= 0) {
560 *pnum = 0;
561 return 0;
562 }
563 v = is_not_zero(buf, 512);
564 for(i = 1; i < n; i++) {
565 buf += 512;
566 if (v != is_not_zero(buf, 512))
567 break;
568 }
569 *pnum = i;
570 return v;
571}
572
Kevin Wolf3e85c6f2010-01-12 12:55:18 +0100573/*
574 * Compares two buffers sector by sector. Returns 0 if the first sector of both
575 * buffers matches, non-zero otherwise.
576 *
577 * pnum is set to the number of sectors (including and immediately following
578 * the first one) that are known to have the same comparison result
579 */
580static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
581 int *pnum)
582{
583 int res, i;
584
585 if (n <= 0) {
586 *pnum = 0;
587 return 0;
588 }
589
590 res = !!memcmp(buf1, buf2, 512);
591 for(i = 1; i < n; i++) {
592 buf1 += 512;
593 buf2 += 512;
594
595 if (!!memcmp(buf1, buf2, 512) != res) {
596 break;
597 }
598 }
599
600 *pnum = i;
601 return res;
602}
603
Kevin Wolf80ee15a2009-09-15 12:30:43 +0200604#define IO_BUF_SIZE (2 * 1024 * 1024)
bellardea2384d2004-08-01 21:59:26 +0000605
606static int img_convert(int argc, char **argv)
607{
Jes Sorenseneec77d92010-12-07 17:44:34 +0100608 int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400609 int progress = 0, flags;
610 const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900611 BlockDriver *drv, *proto_drv;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900612 BlockDriverState **bs = NULL, *out_bs = NULL;
ths96b8f132007-12-17 01:35:20 +0000613 int64_t total_sectors, nb_sectors, sector_num, bs_offset;
614 uint64_t bs_sectors;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900615 uint8_t * buf = NULL;
bellardea2384d2004-08-01 21:59:26 +0000616 const uint8_t *buf1;
bellardfaea38e2006-08-05 21:31:00 +0000617 BlockDriverInfo bdi;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900618 QEMUOptionParameter *param = NULL, *create_options = NULL;
Kevin Wolfa18953f2010-10-14 15:46:04 +0200619 QEMUOptionParameter *out_baseimg_param;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200620 char *options = NULL;
edison51ef6722010-09-21 19:58:41 -0700621 const char *snapshot_name = NULL;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200622 float local_progress;
bellardea2384d2004-08-01 21:59:26 +0000623
624 fmt = NULL;
625 out_fmt = "raw";
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400626 cache = "unsafe";
thsf58c7b32008-06-05 21:53:49 +0000627 out_baseimg = NULL;
Jes Sorenseneec77d92010-12-07 17:44:34 +0100628 compress = 0;
bellardea2384d2004-08-01 21:59:26 +0000629 for(;;) {
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400630 c = getopt(argc, argv, "f:O:B:s:hce6o:pt:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100631 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000632 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100633 }
bellardea2384d2004-08-01 21:59:26 +0000634 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100635 case '?':
bellardea2384d2004-08-01 21:59:26 +0000636 case 'h':
637 help();
638 break;
639 case 'f':
640 fmt = optarg;
641 break;
642 case 'O':
643 out_fmt = optarg;
644 break;
thsf58c7b32008-06-05 21:53:49 +0000645 case 'B':
646 out_baseimg = optarg;
647 break;
bellardea2384d2004-08-01 21:59:26 +0000648 case 'c':
Jes Sorenseneec77d92010-12-07 17:44:34 +0100649 compress = 1;
bellardea2384d2004-08-01 21:59:26 +0000650 break;
651 case 'e':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200652 error_report("option -e is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100653 "encryption\' instead!");
654 return 1;
thsec36ba12007-09-16 21:59:02 +0000655 case '6':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200656 error_report("option -6 is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100657 "compat6\' instead!");
658 return 1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200659 case 'o':
660 options = optarg;
661 break;
edison51ef6722010-09-21 19:58:41 -0700662 case 's':
663 snapshot_name = optarg;
664 break;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200665 case 'p':
666 progress = 1;
667 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400668 case 't':
669 cache = optarg;
670 break;
bellardea2384d2004-08-01 21:59:26 +0000671 }
672 }
ths3b46e622007-09-17 08:09:54 +0000673
balrog926c2d22007-10-31 01:11:44 +0000674 bs_n = argc - optind - 1;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100675 if (bs_n < 1) {
676 help();
677 }
balrog926c2d22007-10-31 01:11:44 +0000678
679 out_filename = argv[argc - 1];
thsf58c7b32008-06-05 21:53:49 +0000680
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100681 if (options && !strcmp(options, "?")) {
682 ret = print_block_option_help(out_filename, out_fmt);
683 goto out;
684 }
685
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900686 if (bs_n > 1 && out_baseimg) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100687 error_report("-B makes no sense when concatenating multiple input "
688 "images");
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100689 ret = -1;
690 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900691 }
balrog926c2d22007-10-31 01:11:44 +0000692
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200693 qemu_progress_init(progress, 2.0);
694 qemu_progress_print(0, 100);
695
Anthony Liguori7267c092011-08-20 22:09:37 -0500696 bs = g_malloc0(bs_n * sizeof(BlockDriverState *));
balrog926c2d22007-10-31 01:11:44 +0000697
698 total_sectors = 0;
699 for (bs_i = 0; bs_i < bs_n; bs_i++) {
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100700 bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900701 if (!bs[bs_i]) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100702 error_report("Could not open '%s'", argv[optind + bs_i]);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900703 ret = -1;
704 goto out;
705 }
balrog926c2d22007-10-31 01:11:44 +0000706 bdrv_get_geometry(bs[bs_i], &bs_sectors);
707 total_sectors += bs_sectors;
708 }
bellardea2384d2004-08-01 21:59:26 +0000709
edison51ef6722010-09-21 19:58:41 -0700710 if (snapshot_name != NULL) {
711 if (bs_n > 1) {
Markus Armbruster6daf1942011-06-22 14:03:54 +0200712 error_report("No support for concatenating multiple snapshot");
edison51ef6722010-09-21 19:58:41 -0700713 ret = -1;
714 goto out;
715 }
716 if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
Markus Armbruster6daf1942011-06-22 14:03:54 +0200717 error_report("Failed to load snapshot");
edison51ef6722010-09-21 19:58:41 -0700718 ret = -1;
719 goto out;
720 }
721 }
722
Kevin Wolfefa84d42009-05-18 16:42:12 +0200723 /* Find driver and parse its options */
bellardea2384d2004-08-01 21:59:26 +0000724 drv = bdrv_find_format(out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900725 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100726 error_report("Unknown file format '%s'", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900727 ret = -1;
728 goto out;
729 }
balrog926c2d22007-10-31 01:11:44 +0000730
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900731 proto_drv = bdrv_find_protocol(out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900732 if (!proto_drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100733 error_report("Unknown protocol '%s'", out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900734 ret = -1;
735 goto out;
736 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900737
738 create_options = append_option_parameters(create_options,
739 drv->create_options);
740 create_options = append_option_parameters(create_options,
741 proto_drv->create_options);
Kevin Wolfdb08adf2009-06-04 15:39:38 +0200742
Kevin Wolfefa84d42009-05-18 16:42:12 +0200743 if (options) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900744 param = parse_option_parameters(options, create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200745 if (param == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100746 error_report("Invalid options for file format '%s'.", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900747 ret = -1;
748 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200749 }
750 } else {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900751 param = parse_option_parameters("", create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200752 }
753
754 set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
Jes Sorenseneec77d92010-12-07 17:44:34 +0100755 ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900756 if (ret < 0) {
757 goto out;
758 }
Kevin Wolfefa84d42009-05-18 16:42:12 +0200759
Kevin Wolfa18953f2010-10-14 15:46:04 +0200760 /* Get backing file name if -o backing_file was used */
761 out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
762 if (out_baseimg_param) {
763 out_baseimg = out_baseimg_param->value.s;
764 }
765
Kevin Wolfefa84d42009-05-18 16:42:12 +0200766 /* Check if compression is supported */
Jes Sorenseneec77d92010-12-07 17:44:34 +0100767 if (compress) {
Kevin Wolfefa84d42009-05-18 16:42:12 +0200768 QEMUOptionParameter *encryption =
769 get_option_parameter(param, BLOCK_OPT_ENCRYPT);
770
771 if (!drv->bdrv_write_compressed) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100772 error_report("Compression not supported for this file format");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900773 ret = -1;
774 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200775 }
776
777 if (encryption && encryption->value.n) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100778 error_report("Compression and encryption not supported at "
779 "the same time");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900780 ret = -1;
781 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200782 }
783 }
784
785 /* Create the new image */
786 ret = bdrv_create(drv, out_filename, param);
bellardea2384d2004-08-01 21:59:26 +0000787 if (ret < 0) {
788 if (ret == -ENOTSUP) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100789 error_report("Formatting not supported for file format '%s'",
790 out_fmt);
aurel326e9ea0c2009-04-15 14:42:46 +0000791 } else if (ret == -EFBIG) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100792 error_report("The image size is too large for file format '%s'",
793 out_fmt);
bellardea2384d2004-08-01 21:59:26 +0000794 } else {
Jes Sorensen15654a62010-12-16 14:31:53 +0100795 error_report("%s: error while converting %s: %s",
796 out_filename, out_fmt, strerror(-ret));
bellardea2384d2004-08-01 21:59:26 +0000797 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900798 goto out;
bellardea2384d2004-08-01 21:59:26 +0000799 }
ths3b46e622007-09-17 08:09:54 +0000800
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400801 flags = BDRV_O_RDWR;
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +0100802 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400803 if (ret < 0) {
804 error_report("Invalid cache option: %s", cache);
805 return -1;
806 }
807
808 out_bs = bdrv_new_open(out_filename, out_fmt, flags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900809 if (!out_bs) {
810 ret = -1;
811 goto out;
812 }
bellardea2384d2004-08-01 21:59:26 +0000813
balrog926c2d22007-10-31 01:11:44 +0000814 bs_i = 0;
815 bs_offset = 0;
816 bdrv_get_geometry(bs[0], &bs_sectors);
Kevin Wolfbb1c0592011-08-08 14:09:12 +0200817 buf = qemu_blockalign(out_bs, IO_BUF_SIZE);
balrog926c2d22007-10-31 01:11:44 +0000818
Jes Sorenseneec77d92010-12-07 17:44:34 +0100819 if (compress) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900820 ret = bdrv_get_info(out_bs, &bdi);
821 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100822 error_report("could not get block driver info");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900823 goto out;
824 }
bellardfaea38e2006-08-05 21:31:00 +0000825 cluster_size = bdi.cluster_size;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900826 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100827 error_report("invalid cluster size");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900828 ret = -1;
829 goto out;
830 }
bellardea2384d2004-08-01 21:59:26 +0000831 cluster_sectors = cluster_size >> 9;
832 sector_num = 0;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200833
834 nb_sectors = total_sectors;
835 local_progress = (float)100 /
Jes Sorensen4ee96412011-05-06 11:39:11 +0200836 (nb_sectors / MIN(nb_sectors, cluster_sectors));
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200837
bellardea2384d2004-08-01 21:59:26 +0000838 for(;;) {
balrog926c2d22007-10-31 01:11:44 +0000839 int64_t bs_num;
840 int remainder;
841 uint8_t *buf2;
842
bellardea2384d2004-08-01 21:59:26 +0000843 nb_sectors = total_sectors - sector_num;
844 if (nb_sectors <= 0)
845 break;
846 if (nb_sectors >= cluster_sectors)
847 n = cluster_sectors;
848 else
849 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000850
851 bs_num = sector_num - bs_offset;
852 assert (bs_num >= 0);
853 remainder = n;
854 buf2 = buf;
855 while (remainder > 0) {
856 int nlow;
857 while (bs_num == bs_sectors) {
858 bs_i++;
859 assert (bs_i < bs_n);
860 bs_offset += bs_sectors;
861 bdrv_get_geometry(bs[bs_i], &bs_sectors);
862 bs_num = 0;
Blue Swirl0bfcd592010-05-22 08:02:12 +0000863 /* printf("changing part: sector_num=%" PRId64 ", "
864 "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64
865 "\n", sector_num, bs_i, bs_offset, bs_sectors); */
balrog926c2d22007-10-31 01:11:44 +0000866 }
867 assert (bs_num < bs_sectors);
868
869 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
870
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900871 ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
872 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100873 error_report("error while reading");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900874 goto out;
875 }
balrog926c2d22007-10-31 01:11:44 +0000876
877 buf2 += nlow * 512;
878 bs_num += nlow;
879
880 remainder -= nlow;
881 }
882 assert (remainder == 0);
883
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100884 if (n < cluster_sectors) {
bellardea2384d2004-08-01 21:59:26 +0000885 memset(buf + n * 512, 0, cluster_size - n * 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100886 }
bellardea2384d2004-08-01 21:59:26 +0000887 if (is_not_zero(buf, cluster_size)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900888 ret = bdrv_write_compressed(out_bs, sector_num, buf,
889 cluster_sectors);
890 if (ret != 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100891 error_report("error while compressing sector %" PRId64,
bellardec3757d2006-06-14 15:50:07 +0000892 sector_num);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900893 goto out;
894 }
bellardea2384d2004-08-01 21:59:26 +0000895 }
896 sector_num += n;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200897 qemu_progress_print(local_progress, 100);
bellardea2384d2004-08-01 21:59:26 +0000898 }
bellardfaea38e2006-08-05 21:31:00 +0000899 /* signal EOF to align */
900 bdrv_write_compressed(out_bs, 0, NULL, 0);
bellardea2384d2004-08-01 21:59:26 +0000901 } else {
Kevin Wolff2feebb2010-04-14 17:30:35 +0200902 int has_zero_init = bdrv_has_zero_init(out_bs);
903
thsf58c7b32008-06-05 21:53:49 +0000904 sector_num = 0; // total number of sectors converted so far
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200905 nb_sectors = total_sectors - sector_num;
906 local_progress = (float)100 /
Jes Sorensen4ee96412011-05-06 11:39:11 +0200907 (nb_sectors / MIN(nb_sectors, IO_BUF_SIZE / 512));
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200908
bellardea2384d2004-08-01 21:59:26 +0000909 for(;;) {
910 nb_sectors = total_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100911 if (nb_sectors <= 0) {
bellardea2384d2004-08-01 21:59:26 +0000912 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100913 }
914 if (nb_sectors >= (IO_BUF_SIZE / 512)) {
bellardea2384d2004-08-01 21:59:26 +0000915 n = (IO_BUF_SIZE / 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100916 } else {
bellardea2384d2004-08-01 21:59:26 +0000917 n = nb_sectors;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100918 }
balrog926c2d22007-10-31 01:11:44 +0000919
920 while (sector_num - bs_offset >= bs_sectors) {
921 bs_i ++;
922 assert (bs_i < bs_n);
923 bs_offset += bs_sectors;
924 bdrv_get_geometry(bs[bs_i], &bs_sectors);
Blue Swirl0bfcd592010-05-22 08:02:12 +0000925 /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "
926 "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",
balrog926c2d22007-10-31 01:11:44 +0000927 sector_num, bs_i, bs_offset, bs_sectors); */
928 }
929
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100930 if (n > bs_offset + bs_sectors - sector_num) {
balrog926c2d22007-10-31 01:11:44 +0000931 n = bs_offset + bs_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100932 }
balrog926c2d22007-10-31 01:11:44 +0000933
Kevin Wolff2feebb2010-04-14 17:30:35 +0200934 if (has_zero_init) {
Akkarit Sangpetchd0320442009-07-17 10:02:15 +0200935 /* If the output image is being created as a copy on write image,
936 assume that sectors which are unallocated in the input image
937 are present in both the output's and input's base images (no
938 need to copy them). */
939 if (out_baseimg) {
940 if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
941 n, &n1)) {
942 sector_num += n1;
943 continue;
944 }
945 /* The next 'n1' sectors are allocated in the input image. Copy
946 only those as they may be followed by unallocated sectors. */
947 n = n1;
aliguori93c65b42009-04-05 17:40:43 +0000948 }
aliguori93c65b42009-04-05 17:40:43 +0000949 } else {
950 n1 = n;
thsf58c7b32008-06-05 21:53:49 +0000951 }
952
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900953 ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
954 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100955 error_report("error while reading");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900956 goto out;
957 }
bellardea2384d2004-08-01 21:59:26 +0000958 /* NOTE: at the same time we convert, we do not write zero
959 sectors to have a chance to compress the image. Ideally, we
960 should add a specific call to have the info to go faster */
961 buf1 = buf;
962 while (n > 0) {
thsf58c7b32008-06-05 21:53:49 +0000963 /* If the output image is being created as a copy on write image,
964 copy all sectors even the ones containing only NUL bytes,
aliguori93c65b42009-04-05 17:40:43 +0000965 because they may differ from the sectors in the base image.
966
967 If the output is to a host device, we also write out
968 sectors that are entirely 0, since whatever data was
969 already there is garbage, not 0s. */
Kevin Wolff2feebb2010-04-14 17:30:35 +0200970 if (!has_zero_init || out_baseimg ||
aliguori93c65b42009-04-05 17:40:43 +0000971 is_allocated_sectors(buf1, n, &n1)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900972 ret = bdrv_write(out_bs, sector_num, buf1, n1);
973 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100974 error_report("error while writing");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900975 goto out;
976 }
bellardea2384d2004-08-01 21:59:26 +0000977 }
978 sector_num += n1;
979 n -= n1;
980 buf1 += n1 * 512;
981 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200982 qemu_progress_print(local_progress, 100);
bellardea2384d2004-08-01 21:59:26 +0000983 }
984 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900985out:
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200986 qemu_progress_end();
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900987 free_option_parameters(create_options);
988 free_option_parameters(param);
Kevin Wolfbb1c0592011-08-08 14:09:12 +0200989 qemu_vfree(buf);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900990 if (out_bs) {
991 bdrv_delete(out_bs);
992 }
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100993 if (bs) {
994 for (bs_i = 0; bs_i < bs_n; bs_i++) {
995 if (bs[bs_i]) {
996 bdrv_delete(bs[bs_i]);
997 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900998 }
Anthony Liguori7267c092011-08-20 22:09:37 -0500999 g_free(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001000 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001001 if (ret) {
1002 return 1;
1003 }
bellardea2384d2004-08-01 21:59:26 +00001004 return 0;
1005}
1006
bellard57d1a2b2004-08-03 21:15:11 +00001007
bellardfaea38e2006-08-05 21:31:00 +00001008static void dump_snapshots(BlockDriverState *bs)
1009{
1010 QEMUSnapshotInfo *sn_tab, *sn;
1011 int nb_sns, i;
1012 char buf[256];
1013
1014 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1015 if (nb_sns <= 0)
1016 return;
1017 printf("Snapshot list:\n");
1018 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
1019 for(i = 0; i < nb_sns; i++) {
1020 sn = &sn_tab[i];
1021 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
1022 }
Anthony Liguori7267c092011-08-20 22:09:37 -05001023 g_free(sn_tab);
bellardfaea38e2006-08-05 21:31:00 +00001024}
1025
bellardea2384d2004-08-01 21:59:26 +00001026static int img_info(int argc, char **argv)
1027{
1028 int c;
1029 const char *filename, *fmt;
bellardea2384d2004-08-01 21:59:26 +00001030 BlockDriverState *bs;
1031 char fmt_name[128], size_buf[128], dsize_buf[128];
ths96b8f132007-12-17 01:35:20 +00001032 uint64_t total_sectors;
1033 int64_t allocated_size;
bellard93b6b2a2006-08-01 15:51:11 +00001034 char backing_filename[1024];
1035 char backing_filename2[1024];
bellardfaea38e2006-08-05 21:31:00 +00001036 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +00001037
1038 fmt = NULL;
1039 for(;;) {
1040 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001041 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +00001042 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001043 }
bellardea2384d2004-08-01 21:59:26 +00001044 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001045 case '?':
bellardea2384d2004-08-01 21:59:26 +00001046 case 'h':
1047 help();
1048 break;
1049 case 'f':
1050 fmt = optarg;
1051 break;
1052 }
1053 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001054 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +00001055 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001056 }
bellardea2384d2004-08-01 21:59:26 +00001057 filename = argv[optind++];
1058
Stefan Hajnocziadfe0782010-04-13 10:29:35 +01001059 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001060 if (!bs) {
1061 return 1;
1062 }
bellardea2384d2004-08-01 21:59:26 +00001063 bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
1064 bdrv_get_geometry(bs, &total_sectors);
1065 get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
Fam Zheng4a1d5e12011-07-12 19:56:39 +08001066 allocated_size = bdrv_get_allocated_file_size(bs);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001067 if (allocated_size < 0) {
blueswir1a10ea302008-08-24 10:30:33 +00001068 snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001069 } else {
ths5fafdf22007-09-16 21:08:06 +00001070 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
bellardde167e42005-04-28 21:15:08 +00001071 allocated_size);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001072 }
bellardea2384d2004-08-01 21:59:26 +00001073 printf("image: %s\n"
1074 "file format: %s\n"
bellardec3757d2006-06-14 15:50:07 +00001075 "virtual size: %s (%" PRId64 " bytes)\n"
bellardea2384d2004-08-01 21:59:26 +00001076 "disk size: %s\n",
ths5fafdf22007-09-16 21:08:06 +00001077 filename, fmt_name, size_buf,
bellardec3757d2006-06-14 15:50:07 +00001078 (total_sectors * 512),
bellardea2384d2004-08-01 21:59:26 +00001079 dsize_buf);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001080 if (bdrv_is_encrypted(bs)) {
bellardea2384d2004-08-01 21:59:26 +00001081 printf("encrypted: yes\n");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001082 }
bellardfaea38e2006-08-05 21:31:00 +00001083 if (bdrv_get_info(bs, &bdi) >= 0) {
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001084 if (bdi.cluster_size != 0) {
bellardfaea38e2006-08-05 21:31:00 +00001085 printf("cluster_size: %d\n", bdi.cluster_size);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001086 }
bellardfaea38e2006-08-05 21:31:00 +00001087 }
bellard93b6b2a2006-08-01 15:51:11 +00001088 bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
bellardfaea38e2006-08-05 21:31:00 +00001089 if (backing_filename[0] != '\0') {
bellard93b6b2a2006-08-01 15:51:11 +00001090 path_combine(backing_filename2, sizeof(backing_filename2),
1091 filename, backing_filename);
ths5fafdf22007-09-16 21:08:06 +00001092 printf("backing file: %s (actual path: %s)\n",
bellard93b6b2a2006-08-01 15:51:11 +00001093 backing_filename,
1094 backing_filename2);
bellardfaea38e2006-08-05 21:31:00 +00001095 }
1096 dump_snapshots(bs);
bellardea2384d2004-08-01 21:59:26 +00001097 bdrv_delete(bs);
1098 return 0;
1099}
1100
aliguorif7b4a942009-01-07 17:40:15 +00001101#define SNAPSHOT_LIST 1
1102#define SNAPSHOT_CREATE 2
1103#define SNAPSHOT_APPLY 3
1104#define SNAPSHOT_DELETE 4
1105
Stuart Brady153859b2009-06-07 00:42:17 +01001106static int img_snapshot(int argc, char **argv)
aliguorif7b4a942009-01-07 17:40:15 +00001107{
1108 BlockDriverState *bs;
1109 QEMUSnapshotInfo sn;
1110 char *filename, *snapshot_name = NULL;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001111 int c, ret = 0, bdrv_oflags;
aliguorif7b4a942009-01-07 17:40:15 +00001112 int action = 0;
1113 qemu_timeval tv;
1114
Kevin Wolf710da702011-01-10 12:33:02 +01001115 bdrv_oflags = BDRV_O_FLAGS | BDRV_O_RDWR;
aliguorif7b4a942009-01-07 17:40:15 +00001116 /* Parse commandline parameters */
1117 for(;;) {
1118 c = getopt(argc, argv, "la:c:d:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001119 if (c == -1) {
aliguorif7b4a942009-01-07 17:40:15 +00001120 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001121 }
aliguorif7b4a942009-01-07 17:40:15 +00001122 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001123 case '?':
aliguorif7b4a942009-01-07 17:40:15 +00001124 case 'h':
1125 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001126 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001127 case 'l':
1128 if (action) {
1129 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001130 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001131 }
1132 action = SNAPSHOT_LIST;
Naphtali Spreif5edb012010-01-17 16:48:13 +02001133 bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
aliguorif7b4a942009-01-07 17:40:15 +00001134 break;
1135 case 'a':
1136 if (action) {
1137 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001138 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001139 }
1140 action = SNAPSHOT_APPLY;
1141 snapshot_name = optarg;
1142 break;
1143 case 'c':
1144 if (action) {
1145 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001146 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001147 }
1148 action = SNAPSHOT_CREATE;
1149 snapshot_name = optarg;
1150 break;
1151 case 'd':
1152 if (action) {
1153 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001154 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001155 }
1156 action = SNAPSHOT_DELETE;
1157 snapshot_name = optarg;
1158 break;
1159 }
1160 }
1161
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001162 if (optind >= argc) {
aliguorif7b4a942009-01-07 17:40:15 +00001163 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001164 }
aliguorif7b4a942009-01-07 17:40:15 +00001165 filename = argv[optind++];
1166
1167 /* Open the image */
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001168 bs = bdrv_new_open(filename, NULL, bdrv_oflags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001169 if (!bs) {
1170 return 1;
1171 }
aliguorif7b4a942009-01-07 17:40:15 +00001172
1173 /* Perform the requested action */
1174 switch(action) {
1175 case SNAPSHOT_LIST:
1176 dump_snapshots(bs);
1177 break;
1178
1179 case SNAPSHOT_CREATE:
1180 memset(&sn, 0, sizeof(sn));
1181 pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
1182
1183 qemu_gettimeofday(&tv);
1184 sn.date_sec = tv.tv_sec;
1185 sn.date_nsec = tv.tv_usec * 1000;
1186
1187 ret = bdrv_snapshot_create(bs, &sn);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001188 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001189 error_report("Could not create snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001190 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001191 }
aliguorif7b4a942009-01-07 17:40:15 +00001192 break;
1193
1194 case SNAPSHOT_APPLY:
1195 ret = bdrv_snapshot_goto(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001196 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001197 error_report("Could not apply snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001198 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001199 }
aliguorif7b4a942009-01-07 17:40:15 +00001200 break;
1201
1202 case SNAPSHOT_DELETE:
1203 ret = bdrv_snapshot_delete(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001204 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001205 error_report("Could not delete snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001206 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001207 }
aliguorif7b4a942009-01-07 17:40:15 +00001208 break;
1209 }
1210
1211 /* Cleanup */
1212 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001213 if (ret) {
1214 return 1;
1215 }
Stuart Brady153859b2009-06-07 00:42:17 +01001216 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001217}
1218
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001219static int img_rebase(int argc, char **argv)
1220{
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001221 BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001222 BlockDriver *old_backing_drv, *new_backing_drv;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001223 char *filename;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001224 const char *fmt, *cache, *out_basefmt, *out_baseimg;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001225 int c, flags, ret;
1226 int unsafe = 0;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001227 int progress = 0;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001228
1229 /* Parse commandline parameters */
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001230 fmt = NULL;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001231 cache = BDRV_DEFAULT_CACHE;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001232 out_baseimg = NULL;
1233 out_basefmt = NULL;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001234 for(;;) {
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001235 c = getopt(argc, argv, "uhf:F:b:pt:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001236 if (c == -1) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001237 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001238 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001239 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001240 case '?':
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001241 case 'h':
1242 help();
1243 return 0;
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001244 case 'f':
1245 fmt = optarg;
1246 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001247 case 'F':
1248 out_basefmt = optarg;
1249 break;
1250 case 'b':
1251 out_baseimg = optarg;
1252 break;
1253 case 'u':
1254 unsafe = 1;
1255 break;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001256 case 'p':
1257 progress = 1;
1258 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001259 case 't':
1260 cache = optarg;
1261 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001262 }
1263 }
1264
Anthony Liguori9a9d9db2011-04-13 15:51:47 +01001265 if ((optind >= argc) || (!unsafe && !out_baseimg)) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001266 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001267 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001268 filename = argv[optind++];
1269
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001270 qemu_progress_init(progress, 2.0);
1271 qemu_progress_print(0, 100);
1272
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001273 flags = BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +01001274 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001275 if (ret < 0) {
1276 error_report("Invalid cache option: %s", cache);
1277 return -1;
1278 }
1279
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001280 /*
1281 * Open the images.
1282 *
1283 * Ignore the old backing file for unsafe rebase in case we want to correct
1284 * the reference to a renamed or moved backing file.
1285 */
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001286 bs = bdrv_new_open(filename, fmt, flags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001287 if (!bs) {
1288 return 1;
1289 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001290
1291 /* Find the right drivers for the backing files */
1292 old_backing_drv = NULL;
1293 new_backing_drv = NULL;
1294
1295 if (!unsafe && bs->backing_format[0] != '\0') {
1296 old_backing_drv = bdrv_find_format(bs->backing_format);
1297 if (old_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001298 error_report("Invalid format name: '%s'", bs->backing_format);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001299 ret = -1;
1300 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001301 }
1302 }
1303
1304 if (out_basefmt != NULL) {
1305 new_backing_drv = bdrv_find_format(out_basefmt);
1306 if (new_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001307 error_report("Invalid format name: '%s'", out_basefmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001308 ret = -1;
1309 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001310 }
1311 }
1312
1313 /* For safe rebasing we need to compare old and new backing file */
1314 if (unsafe) {
1315 /* Make the compiler happy */
1316 bs_old_backing = NULL;
1317 bs_new_backing = NULL;
1318 } else {
1319 char backing_name[1024];
1320
1321 bs_old_backing = bdrv_new("old_backing");
1322 bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001323 ret = bdrv_open(bs_old_backing, backing_name, BDRV_O_FLAGS,
1324 old_backing_drv);
1325 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001326 error_report("Could not open old backing file '%s'", backing_name);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001327 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001328 }
1329
1330 bs_new_backing = bdrv_new("new_backing");
Kevin Wolfcdbae852010-08-17 18:58:55 +02001331 ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS,
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001332 new_backing_drv);
1333 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001334 error_report("Could not open new backing file '%s'", out_baseimg);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001335 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001336 }
1337 }
1338
1339 /*
1340 * Check each unallocated cluster in the COW file. If it is unallocated,
1341 * accesses go to the backing file. We must therefore compare this cluster
1342 * in the old and new backing file, and if they differ we need to copy it
1343 * from the old backing file into the COW file.
1344 *
1345 * If qemu-img crashes during this step, no harm is done. The content of
1346 * the image is the same as the original one at any time.
1347 */
1348 if (!unsafe) {
1349 uint64_t num_sectors;
1350 uint64_t sector;
Kevin Wolfcc60e322010-04-29 14:47:48 +02001351 int n;
TeLeMand6771bf2010-02-08 16:20:00 +08001352 uint8_t * buf_old;
1353 uint8_t * buf_new;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001354 float local_progress;
TeLeMand6771bf2010-02-08 16:20:00 +08001355
Kevin Wolfbb1c0592011-08-08 14:09:12 +02001356 buf_old = qemu_blockalign(bs, IO_BUF_SIZE);
1357 buf_new = qemu_blockalign(bs, IO_BUF_SIZE);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001358
1359 bdrv_get_geometry(bs, &num_sectors);
1360
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001361 local_progress = (float)100 /
Jes Sorensen4ee96412011-05-06 11:39:11 +02001362 (num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512));
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001363 for (sector = 0; sector < num_sectors; sector += n) {
1364
1365 /* How many sectors can we handle with the next read? */
1366 if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
1367 n = (IO_BUF_SIZE / 512);
1368 } else {
1369 n = num_sectors - sector;
1370 }
1371
1372 /* If the cluster is allocated, we don't need to take action */
Kevin Wolfcc60e322010-04-29 14:47:48 +02001373 ret = bdrv_is_allocated(bs, sector, n, &n);
1374 if (ret) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001375 continue;
1376 }
1377
1378 /* Read old and new backing file */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001379 ret = bdrv_read(bs_old_backing, sector, buf_old, n);
1380 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001381 error_report("error while reading from old backing file");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001382 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001383 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001384 ret = bdrv_read(bs_new_backing, sector, buf_new, n);
1385 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001386 error_report("error while reading from new backing file");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001387 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001388 }
1389
1390 /* If they differ, we need to write to the COW file */
1391 uint64_t written = 0;
1392
1393 while (written < n) {
1394 int pnum;
1395
1396 if (compare_sectors(buf_old + written * 512,
Kevin Wolf60b1bd42010-02-17 12:32:59 +01001397 buf_new + written * 512, n - written, &pnum))
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001398 {
1399 ret = bdrv_write(bs, sector + written,
1400 buf_old + written * 512, pnum);
1401 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001402 error_report("Error while writing to COW image: %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001403 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001404 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001405 }
1406 }
1407
1408 written += pnum;
1409 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001410 qemu_progress_print(local_progress, 100);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001411 }
TeLeMand6771bf2010-02-08 16:20:00 +08001412
Kevin Wolfbb1c0592011-08-08 14:09:12 +02001413 qemu_vfree(buf_old);
1414 qemu_vfree(buf_new);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001415 }
1416
1417 /*
1418 * Change the backing file. All clusters that are different from the old
1419 * backing file are overwritten in the COW file now, so the visible content
1420 * doesn't change when we switch the backing file.
1421 */
1422 ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
1423 if (ret == -ENOSPC) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001424 error_report("Could not change the backing file to '%s': No "
1425 "space left in the file header", out_baseimg);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001426 } else if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001427 error_report("Could not change the backing file to '%s': %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001428 out_baseimg, strerror(-ret));
1429 }
1430
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001431 qemu_progress_print(100, 0);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001432 /*
1433 * TODO At this point it is possible to check if any clusters that are
1434 * allocated in the COW file are the same in the backing file. If so, they
1435 * could be dropped from the COW file. Don't do this before switching the
1436 * backing file, in case of a crash this would lead to corruption.
1437 */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001438out:
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001439 qemu_progress_end();
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001440 /* Cleanup */
1441 if (!unsafe) {
Kevin Wolfeb863ad2011-03-31 12:39:51 +02001442 if (bs_old_backing != NULL) {
1443 bdrv_delete(bs_old_backing);
1444 }
1445 if (bs_new_backing != NULL) {
1446 bdrv_delete(bs_new_backing);
1447 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001448 }
1449
1450 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001451 if (ret) {
1452 return 1;
1453 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001454 return 0;
1455}
1456
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001457static int img_resize(int argc, char **argv)
1458{
1459 int c, ret, relative;
1460 const char *filename, *fmt, *size;
1461 int64_t n, total_size;
Jes Sorensen2a819982010-12-06 17:08:31 +01001462 BlockDriverState *bs = NULL;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001463 QEMUOptionParameter *param;
1464 QEMUOptionParameter resize_options[] = {
1465 {
1466 .name = BLOCK_OPT_SIZE,
1467 .type = OPT_SIZE,
1468 .help = "Virtual disk size"
1469 },
1470 { NULL }
1471 };
1472
Kevin Wolfe80fec72011-04-29 10:58:12 +02001473 /* Remove size from argv manually so that negative numbers are not treated
1474 * as options by getopt. */
1475 if (argc < 3) {
1476 help();
1477 return 1;
1478 }
1479
1480 size = argv[--argc];
1481
1482 /* Parse getopt arguments */
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001483 fmt = NULL;
1484 for(;;) {
1485 c = getopt(argc, argv, "f:h");
1486 if (c == -1) {
1487 break;
1488 }
1489 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001490 case '?':
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001491 case 'h':
1492 help();
1493 break;
1494 case 'f':
1495 fmt = optarg;
1496 break;
1497 }
1498 }
Kevin Wolfe80fec72011-04-29 10:58:12 +02001499 if (optind >= argc) {
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001500 help();
1501 }
1502 filename = argv[optind++];
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001503
1504 /* Choose grow, shrink, or absolute resize mode */
1505 switch (size[0]) {
1506 case '+':
1507 relative = 1;
1508 size++;
1509 break;
1510 case '-':
1511 relative = -1;
1512 size++;
1513 break;
1514 default:
1515 relative = 0;
1516 break;
1517 }
1518
1519 /* Parse size */
1520 param = parse_option_parameters("", resize_options, NULL);
1521 if (set_option_parameter(param, BLOCK_OPT_SIZE, size)) {
1522 /* Error message already printed when size parsing fails */
Jes Sorensen2a819982010-12-06 17:08:31 +01001523 ret = -1;
1524 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001525 }
1526 n = get_option_parameter(param, BLOCK_OPT_SIZE)->value.n;
1527 free_option_parameters(param);
1528
1529 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001530 if (!bs) {
Jes Sorensen2a819982010-12-06 17:08:31 +01001531 ret = -1;
1532 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001533 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001534
1535 if (relative) {
1536 total_size = bdrv_getlength(bs) + n * relative;
1537 } else {
1538 total_size = n;
1539 }
1540 if (total_size <= 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001541 error_report("New image size must be positive");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001542 ret = -1;
1543 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001544 }
1545
1546 ret = bdrv_truncate(bs, total_size);
1547 switch (ret) {
1548 case 0:
1549 printf("Image resized.\n");
1550 break;
1551 case -ENOTSUP:
Jes Sorensen15654a62010-12-16 14:31:53 +01001552 error_report("This image format does not support resize");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001553 break;
1554 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +01001555 error_report("Image is read-only");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001556 break;
1557 default:
Jes Sorensen15654a62010-12-16 14:31:53 +01001558 error_report("Error resizing image (%d)", -ret);
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001559 break;
1560 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001561out:
Jes Sorensen2a819982010-12-06 17:08:31 +01001562 if (bs) {
1563 bdrv_delete(bs);
1564 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001565 if (ret) {
1566 return 1;
1567 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001568 return 0;
1569}
1570
Anthony Liguoric227f092009-10-01 16:12:16 -05001571static const img_cmd_t img_cmds[] = {
Stuart Brady153859b2009-06-07 00:42:17 +01001572#define DEF(option, callback, arg_string) \
1573 { option, callback },
1574#include "qemu-img-cmds.h"
1575#undef DEF
1576#undef GEN_DOCS
1577 { NULL, NULL, },
1578};
1579
bellardea2384d2004-08-01 21:59:26 +00001580int main(int argc, char **argv)
1581{
Anthony Liguoric227f092009-10-01 16:12:16 -05001582 const img_cmd_t *cmd;
Stuart Brady153859b2009-06-07 00:42:17 +01001583 const char *cmdname;
bellardea2384d2004-08-01 21:59:26 +00001584
Kevin Wolf53f76e52010-12-16 15:10:32 +01001585 error_set_progname(argv[0]);
1586
bellardea2384d2004-08-01 21:59:26 +00001587 bdrv_init();
1588 if (argc < 2)
1589 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001590 cmdname = argv[1];
aurel328f9b1572009-02-09 18:14:31 +00001591 argc--; argv++;
Stuart Brady153859b2009-06-07 00:42:17 +01001592
1593 /* find the command */
1594 for(cmd = img_cmds; cmd->name != NULL; cmd++) {
1595 if (!strcmp(cmdname, cmd->name)) {
1596 return cmd->handler(argc, argv);
1597 }
bellardea2384d2004-08-01 21:59:26 +00001598 }
Stuart Brady153859b2009-06-07 00:42:17 +01001599
1600 /* not found */
1601 help();
bellardea2384d2004-08-01 21:59:26 +00001602 return 0;
1603}