blob: 0561d77f9dffad0939bd21a4bae16df57ecc04cc [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) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +0100873 error_report("error while reading sector %" PRId64 ": %s",
874 bs_num, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900875 goto out;
876 }
balrog926c2d22007-10-31 01:11:44 +0000877
878 buf2 += nlow * 512;
879 bs_num += nlow;
880
881 remainder -= nlow;
882 }
883 assert (remainder == 0);
884
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100885 if (n < cluster_sectors) {
bellardea2384d2004-08-01 21:59:26 +0000886 memset(buf + n * 512, 0, cluster_size - n * 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100887 }
bellardea2384d2004-08-01 21:59:26 +0000888 if (is_not_zero(buf, cluster_size)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900889 ret = bdrv_write_compressed(out_bs, sector_num, buf,
890 cluster_sectors);
891 if (ret != 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +0100892 error_report("error while compressing sector %" PRId64
893 ": %s", sector_num, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900894 goto out;
895 }
bellardea2384d2004-08-01 21:59:26 +0000896 }
897 sector_num += n;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200898 qemu_progress_print(local_progress, 100);
bellardea2384d2004-08-01 21:59:26 +0000899 }
bellardfaea38e2006-08-05 21:31:00 +0000900 /* signal EOF to align */
901 bdrv_write_compressed(out_bs, 0, NULL, 0);
bellardea2384d2004-08-01 21:59:26 +0000902 } else {
Kevin Wolff2feebb2010-04-14 17:30:35 +0200903 int has_zero_init = bdrv_has_zero_init(out_bs);
904
thsf58c7b32008-06-05 21:53:49 +0000905 sector_num = 0; // total number of sectors converted so far
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200906 nb_sectors = total_sectors - sector_num;
907 local_progress = (float)100 /
Jes Sorensen4ee96412011-05-06 11:39:11 +0200908 (nb_sectors / MIN(nb_sectors, IO_BUF_SIZE / 512));
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200909
bellardea2384d2004-08-01 21:59:26 +0000910 for(;;) {
911 nb_sectors = total_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100912 if (nb_sectors <= 0) {
bellardea2384d2004-08-01 21:59:26 +0000913 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100914 }
915 if (nb_sectors >= (IO_BUF_SIZE / 512)) {
bellardea2384d2004-08-01 21:59:26 +0000916 n = (IO_BUF_SIZE / 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100917 } else {
bellardea2384d2004-08-01 21:59:26 +0000918 n = nb_sectors;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100919 }
balrog926c2d22007-10-31 01:11:44 +0000920
921 while (sector_num - bs_offset >= bs_sectors) {
922 bs_i ++;
923 assert (bs_i < bs_n);
924 bs_offset += bs_sectors;
925 bdrv_get_geometry(bs[bs_i], &bs_sectors);
Blue Swirl0bfcd592010-05-22 08:02:12 +0000926 /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "
927 "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",
balrog926c2d22007-10-31 01:11:44 +0000928 sector_num, bs_i, bs_offset, bs_sectors); */
929 }
930
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100931 if (n > bs_offset + bs_sectors - sector_num) {
balrog926c2d22007-10-31 01:11:44 +0000932 n = bs_offset + bs_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100933 }
balrog926c2d22007-10-31 01:11:44 +0000934
Kevin Wolff2feebb2010-04-14 17:30:35 +0200935 if (has_zero_init) {
Akkarit Sangpetchd0320442009-07-17 10:02:15 +0200936 /* If the output image is being created as a copy on write image,
937 assume that sectors which are unallocated in the input image
938 are present in both the output's and input's base images (no
939 need to copy them). */
940 if (out_baseimg) {
941 if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
942 n, &n1)) {
943 sector_num += n1;
944 continue;
945 }
946 /* The next 'n1' sectors are allocated in the input image. Copy
947 only those as they may be followed by unallocated sectors. */
948 n = n1;
aliguori93c65b42009-04-05 17:40:43 +0000949 }
aliguori93c65b42009-04-05 17:40:43 +0000950 } else {
951 n1 = n;
thsf58c7b32008-06-05 21:53:49 +0000952 }
953
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900954 ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
955 if (ret < 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +0100956 error_report("error while reading sector %" PRId64 ": %s",
957 sector_num - bs_offset, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900958 goto out;
959 }
bellardea2384d2004-08-01 21:59:26 +0000960 /* NOTE: at the same time we convert, we do not write zero
961 sectors to have a chance to compress the image. Ideally, we
962 should add a specific call to have the info to go faster */
963 buf1 = buf;
964 while (n > 0) {
thsf58c7b32008-06-05 21:53:49 +0000965 /* If the output image is being created as a copy on write image,
966 copy all sectors even the ones containing only NUL bytes,
aliguori93c65b42009-04-05 17:40:43 +0000967 because they may differ from the sectors in the base image.
968
969 If the output is to a host device, we also write out
970 sectors that are entirely 0, since whatever data was
971 already there is garbage, not 0s. */
Kevin Wolff2feebb2010-04-14 17:30:35 +0200972 if (!has_zero_init || out_baseimg ||
aliguori93c65b42009-04-05 17:40:43 +0000973 is_allocated_sectors(buf1, n, &n1)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900974 ret = bdrv_write(out_bs, sector_num, buf1, n1);
975 if (ret < 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +0100976 error_report("error while writing sector %" PRId64
977 ": %s", sector_num, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900978 goto out;
979 }
bellardea2384d2004-08-01 21:59:26 +0000980 }
981 sector_num += n1;
982 n -= n1;
983 buf1 += n1 * 512;
984 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200985 qemu_progress_print(local_progress, 100);
bellardea2384d2004-08-01 21:59:26 +0000986 }
987 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900988out:
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200989 qemu_progress_end();
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900990 free_option_parameters(create_options);
991 free_option_parameters(param);
Kevin Wolfbb1c0592011-08-08 14:09:12 +0200992 qemu_vfree(buf);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900993 if (out_bs) {
994 bdrv_delete(out_bs);
995 }
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100996 if (bs) {
997 for (bs_i = 0; bs_i < bs_n; bs_i++) {
998 if (bs[bs_i]) {
999 bdrv_delete(bs[bs_i]);
1000 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001001 }
Anthony Liguori7267c092011-08-20 22:09:37 -05001002 g_free(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001003 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001004 if (ret) {
1005 return 1;
1006 }
bellardea2384d2004-08-01 21:59:26 +00001007 return 0;
1008}
1009
bellard57d1a2b2004-08-03 21:15:11 +00001010
bellardfaea38e2006-08-05 21:31:00 +00001011static void dump_snapshots(BlockDriverState *bs)
1012{
1013 QEMUSnapshotInfo *sn_tab, *sn;
1014 int nb_sns, i;
1015 char buf[256];
1016
1017 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1018 if (nb_sns <= 0)
1019 return;
1020 printf("Snapshot list:\n");
1021 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
1022 for(i = 0; i < nb_sns; i++) {
1023 sn = &sn_tab[i];
1024 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
1025 }
Anthony Liguori7267c092011-08-20 22:09:37 -05001026 g_free(sn_tab);
bellardfaea38e2006-08-05 21:31:00 +00001027}
1028
bellardea2384d2004-08-01 21:59:26 +00001029static int img_info(int argc, char **argv)
1030{
1031 int c;
1032 const char *filename, *fmt;
bellardea2384d2004-08-01 21:59:26 +00001033 BlockDriverState *bs;
1034 char fmt_name[128], size_buf[128], dsize_buf[128];
ths96b8f132007-12-17 01:35:20 +00001035 uint64_t total_sectors;
1036 int64_t allocated_size;
bellard93b6b2a2006-08-01 15:51:11 +00001037 char backing_filename[1024];
1038 char backing_filename2[1024];
bellardfaea38e2006-08-05 21:31:00 +00001039 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +00001040
1041 fmt = NULL;
1042 for(;;) {
1043 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001044 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +00001045 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001046 }
bellardea2384d2004-08-01 21:59:26 +00001047 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001048 case '?':
bellardea2384d2004-08-01 21:59:26 +00001049 case 'h':
1050 help();
1051 break;
1052 case 'f':
1053 fmt = optarg;
1054 break;
1055 }
1056 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001057 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +00001058 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001059 }
bellardea2384d2004-08-01 21:59:26 +00001060 filename = argv[optind++];
1061
Stefan Hajnocziadfe0782010-04-13 10:29:35 +01001062 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001063 if (!bs) {
1064 return 1;
1065 }
bellardea2384d2004-08-01 21:59:26 +00001066 bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
1067 bdrv_get_geometry(bs, &total_sectors);
1068 get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
Fam Zheng4a1d5e12011-07-12 19:56:39 +08001069 allocated_size = bdrv_get_allocated_file_size(bs);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001070 if (allocated_size < 0) {
blueswir1a10ea302008-08-24 10:30:33 +00001071 snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001072 } else {
ths5fafdf22007-09-16 21:08:06 +00001073 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
bellardde167e42005-04-28 21:15:08 +00001074 allocated_size);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001075 }
bellardea2384d2004-08-01 21:59:26 +00001076 printf("image: %s\n"
1077 "file format: %s\n"
bellardec3757d2006-06-14 15:50:07 +00001078 "virtual size: %s (%" PRId64 " bytes)\n"
bellardea2384d2004-08-01 21:59:26 +00001079 "disk size: %s\n",
ths5fafdf22007-09-16 21:08:06 +00001080 filename, fmt_name, size_buf,
bellardec3757d2006-06-14 15:50:07 +00001081 (total_sectors * 512),
bellardea2384d2004-08-01 21:59:26 +00001082 dsize_buf);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001083 if (bdrv_is_encrypted(bs)) {
bellardea2384d2004-08-01 21:59:26 +00001084 printf("encrypted: yes\n");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001085 }
bellardfaea38e2006-08-05 21:31:00 +00001086 if (bdrv_get_info(bs, &bdi) >= 0) {
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001087 if (bdi.cluster_size != 0) {
bellardfaea38e2006-08-05 21:31:00 +00001088 printf("cluster_size: %d\n", bdi.cluster_size);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001089 }
bellardfaea38e2006-08-05 21:31:00 +00001090 }
bellard93b6b2a2006-08-01 15:51:11 +00001091 bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
bellardfaea38e2006-08-05 21:31:00 +00001092 if (backing_filename[0] != '\0') {
bellard93b6b2a2006-08-01 15:51:11 +00001093 path_combine(backing_filename2, sizeof(backing_filename2),
1094 filename, backing_filename);
ths5fafdf22007-09-16 21:08:06 +00001095 printf("backing file: %s (actual path: %s)\n",
bellard93b6b2a2006-08-01 15:51:11 +00001096 backing_filename,
1097 backing_filename2);
bellardfaea38e2006-08-05 21:31:00 +00001098 }
1099 dump_snapshots(bs);
bellardea2384d2004-08-01 21:59:26 +00001100 bdrv_delete(bs);
1101 return 0;
1102}
1103
aliguorif7b4a942009-01-07 17:40:15 +00001104#define SNAPSHOT_LIST 1
1105#define SNAPSHOT_CREATE 2
1106#define SNAPSHOT_APPLY 3
1107#define SNAPSHOT_DELETE 4
1108
Stuart Brady153859b2009-06-07 00:42:17 +01001109static int img_snapshot(int argc, char **argv)
aliguorif7b4a942009-01-07 17:40:15 +00001110{
1111 BlockDriverState *bs;
1112 QEMUSnapshotInfo sn;
1113 char *filename, *snapshot_name = NULL;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001114 int c, ret = 0, bdrv_oflags;
aliguorif7b4a942009-01-07 17:40:15 +00001115 int action = 0;
1116 qemu_timeval tv;
1117
Kevin Wolf710da702011-01-10 12:33:02 +01001118 bdrv_oflags = BDRV_O_FLAGS | BDRV_O_RDWR;
aliguorif7b4a942009-01-07 17:40:15 +00001119 /* Parse commandline parameters */
1120 for(;;) {
1121 c = getopt(argc, argv, "la:c:d:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001122 if (c == -1) {
aliguorif7b4a942009-01-07 17:40:15 +00001123 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001124 }
aliguorif7b4a942009-01-07 17:40:15 +00001125 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001126 case '?':
aliguorif7b4a942009-01-07 17:40:15 +00001127 case 'h':
1128 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001129 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001130 case 'l':
1131 if (action) {
1132 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001133 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001134 }
1135 action = SNAPSHOT_LIST;
Naphtali Spreif5edb012010-01-17 16:48:13 +02001136 bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
aliguorif7b4a942009-01-07 17:40:15 +00001137 break;
1138 case 'a':
1139 if (action) {
1140 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001141 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001142 }
1143 action = SNAPSHOT_APPLY;
1144 snapshot_name = optarg;
1145 break;
1146 case 'c':
1147 if (action) {
1148 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001149 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001150 }
1151 action = SNAPSHOT_CREATE;
1152 snapshot_name = optarg;
1153 break;
1154 case 'd':
1155 if (action) {
1156 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001157 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001158 }
1159 action = SNAPSHOT_DELETE;
1160 snapshot_name = optarg;
1161 break;
1162 }
1163 }
1164
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001165 if (optind >= argc) {
aliguorif7b4a942009-01-07 17:40:15 +00001166 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001167 }
aliguorif7b4a942009-01-07 17:40:15 +00001168 filename = argv[optind++];
1169
1170 /* Open the image */
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001171 bs = bdrv_new_open(filename, NULL, bdrv_oflags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001172 if (!bs) {
1173 return 1;
1174 }
aliguorif7b4a942009-01-07 17:40:15 +00001175
1176 /* Perform the requested action */
1177 switch(action) {
1178 case SNAPSHOT_LIST:
1179 dump_snapshots(bs);
1180 break;
1181
1182 case SNAPSHOT_CREATE:
1183 memset(&sn, 0, sizeof(sn));
1184 pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
1185
1186 qemu_gettimeofday(&tv);
1187 sn.date_sec = tv.tv_sec;
1188 sn.date_nsec = tv.tv_usec * 1000;
1189
1190 ret = bdrv_snapshot_create(bs, &sn);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001191 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001192 error_report("Could not create snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001193 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001194 }
aliguorif7b4a942009-01-07 17:40:15 +00001195 break;
1196
1197 case SNAPSHOT_APPLY:
1198 ret = bdrv_snapshot_goto(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001199 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001200 error_report("Could not apply snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001201 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001202 }
aliguorif7b4a942009-01-07 17:40:15 +00001203 break;
1204
1205 case SNAPSHOT_DELETE:
1206 ret = bdrv_snapshot_delete(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001207 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001208 error_report("Could not delete snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001209 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001210 }
aliguorif7b4a942009-01-07 17:40:15 +00001211 break;
1212 }
1213
1214 /* Cleanup */
1215 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001216 if (ret) {
1217 return 1;
1218 }
Stuart Brady153859b2009-06-07 00:42:17 +01001219 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001220}
1221
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001222static int img_rebase(int argc, char **argv)
1223{
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001224 BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001225 BlockDriver *old_backing_drv, *new_backing_drv;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001226 char *filename;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001227 const char *fmt, *cache, *out_basefmt, *out_baseimg;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001228 int c, flags, ret;
1229 int unsafe = 0;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001230 int progress = 0;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001231
1232 /* Parse commandline parameters */
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001233 fmt = NULL;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001234 cache = BDRV_DEFAULT_CACHE;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001235 out_baseimg = NULL;
1236 out_basefmt = NULL;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001237 for(;;) {
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001238 c = getopt(argc, argv, "uhf:F:b:pt:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001239 if (c == -1) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001240 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001241 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001242 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001243 case '?':
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001244 case 'h':
1245 help();
1246 return 0;
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001247 case 'f':
1248 fmt = optarg;
1249 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001250 case 'F':
1251 out_basefmt = optarg;
1252 break;
1253 case 'b':
1254 out_baseimg = optarg;
1255 break;
1256 case 'u':
1257 unsafe = 1;
1258 break;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001259 case 'p':
1260 progress = 1;
1261 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001262 case 't':
1263 cache = optarg;
1264 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001265 }
1266 }
1267
Anthony Liguori9a9d9db2011-04-13 15:51:47 +01001268 if ((optind >= argc) || (!unsafe && !out_baseimg)) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001269 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001270 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001271 filename = argv[optind++];
1272
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001273 qemu_progress_init(progress, 2.0);
1274 qemu_progress_print(0, 100);
1275
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001276 flags = BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +01001277 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001278 if (ret < 0) {
1279 error_report("Invalid cache option: %s", cache);
1280 return -1;
1281 }
1282
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001283 /*
1284 * Open the images.
1285 *
1286 * Ignore the old backing file for unsafe rebase in case we want to correct
1287 * the reference to a renamed or moved backing file.
1288 */
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001289 bs = bdrv_new_open(filename, fmt, flags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001290 if (!bs) {
1291 return 1;
1292 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001293
1294 /* Find the right drivers for the backing files */
1295 old_backing_drv = NULL;
1296 new_backing_drv = NULL;
1297
1298 if (!unsafe && bs->backing_format[0] != '\0') {
1299 old_backing_drv = bdrv_find_format(bs->backing_format);
1300 if (old_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001301 error_report("Invalid format name: '%s'", bs->backing_format);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001302 ret = -1;
1303 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001304 }
1305 }
1306
1307 if (out_basefmt != NULL) {
1308 new_backing_drv = bdrv_find_format(out_basefmt);
1309 if (new_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001310 error_report("Invalid format name: '%s'", out_basefmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001311 ret = -1;
1312 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001313 }
1314 }
1315
1316 /* For safe rebasing we need to compare old and new backing file */
1317 if (unsafe) {
1318 /* Make the compiler happy */
1319 bs_old_backing = NULL;
1320 bs_new_backing = NULL;
1321 } else {
1322 char backing_name[1024];
1323
1324 bs_old_backing = bdrv_new("old_backing");
1325 bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001326 ret = bdrv_open(bs_old_backing, backing_name, BDRV_O_FLAGS,
1327 old_backing_drv);
1328 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001329 error_report("Could not open old backing file '%s'", backing_name);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001330 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001331 }
1332
1333 bs_new_backing = bdrv_new("new_backing");
Kevin Wolfcdbae852010-08-17 18:58:55 +02001334 ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS,
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001335 new_backing_drv);
1336 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001337 error_report("Could not open new backing file '%s'", out_baseimg);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001338 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001339 }
1340 }
1341
1342 /*
1343 * Check each unallocated cluster in the COW file. If it is unallocated,
1344 * accesses go to the backing file. We must therefore compare this cluster
1345 * in the old and new backing file, and if they differ we need to copy it
1346 * from the old backing file into the COW file.
1347 *
1348 * If qemu-img crashes during this step, no harm is done. The content of
1349 * the image is the same as the original one at any time.
1350 */
1351 if (!unsafe) {
1352 uint64_t num_sectors;
1353 uint64_t sector;
Kevin Wolfcc60e322010-04-29 14:47:48 +02001354 int n;
TeLeMand6771bf2010-02-08 16:20:00 +08001355 uint8_t * buf_old;
1356 uint8_t * buf_new;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001357 float local_progress;
TeLeMand6771bf2010-02-08 16:20:00 +08001358
Kevin Wolfbb1c0592011-08-08 14:09:12 +02001359 buf_old = qemu_blockalign(bs, IO_BUF_SIZE);
1360 buf_new = qemu_blockalign(bs, IO_BUF_SIZE);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001361
1362 bdrv_get_geometry(bs, &num_sectors);
1363
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001364 local_progress = (float)100 /
Jes Sorensen4ee96412011-05-06 11:39:11 +02001365 (num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512));
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001366 for (sector = 0; sector < num_sectors; sector += n) {
1367
1368 /* How many sectors can we handle with the next read? */
1369 if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
1370 n = (IO_BUF_SIZE / 512);
1371 } else {
1372 n = num_sectors - sector;
1373 }
1374
1375 /* If the cluster is allocated, we don't need to take action */
Kevin Wolfcc60e322010-04-29 14:47:48 +02001376 ret = bdrv_is_allocated(bs, sector, n, &n);
1377 if (ret) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001378 continue;
1379 }
1380
1381 /* Read old and new backing file */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001382 ret = bdrv_read(bs_old_backing, sector, buf_old, n);
1383 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001384 error_report("error while reading from old backing file");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001385 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001386 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001387 ret = bdrv_read(bs_new_backing, sector, buf_new, n);
1388 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001389 error_report("error while reading from new backing file");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001390 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001391 }
1392
1393 /* If they differ, we need to write to the COW file */
1394 uint64_t written = 0;
1395
1396 while (written < n) {
1397 int pnum;
1398
1399 if (compare_sectors(buf_old + written * 512,
Kevin Wolf60b1bd42010-02-17 12:32:59 +01001400 buf_new + written * 512, n - written, &pnum))
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001401 {
1402 ret = bdrv_write(bs, sector + written,
1403 buf_old + written * 512, pnum);
1404 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001405 error_report("Error while writing to COW image: %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001406 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001407 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001408 }
1409 }
1410
1411 written += pnum;
1412 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001413 qemu_progress_print(local_progress, 100);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001414 }
TeLeMand6771bf2010-02-08 16:20:00 +08001415
Kevin Wolfbb1c0592011-08-08 14:09:12 +02001416 qemu_vfree(buf_old);
1417 qemu_vfree(buf_new);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001418 }
1419
1420 /*
1421 * Change the backing file. All clusters that are different from the old
1422 * backing file are overwritten in the COW file now, so the visible content
1423 * doesn't change when we switch the backing file.
1424 */
1425 ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
1426 if (ret == -ENOSPC) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001427 error_report("Could not change the backing file to '%s': No "
1428 "space left in the file header", out_baseimg);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001429 } else if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001430 error_report("Could not change the backing file to '%s': %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001431 out_baseimg, strerror(-ret));
1432 }
1433
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001434 qemu_progress_print(100, 0);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001435 /*
1436 * TODO At this point it is possible to check if any clusters that are
1437 * allocated in the COW file are the same in the backing file. If so, they
1438 * could be dropped from the COW file. Don't do this before switching the
1439 * backing file, in case of a crash this would lead to corruption.
1440 */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001441out:
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001442 qemu_progress_end();
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001443 /* Cleanup */
1444 if (!unsafe) {
Kevin Wolfeb863ad2011-03-31 12:39:51 +02001445 if (bs_old_backing != NULL) {
1446 bdrv_delete(bs_old_backing);
1447 }
1448 if (bs_new_backing != NULL) {
1449 bdrv_delete(bs_new_backing);
1450 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001451 }
1452
1453 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001454 if (ret) {
1455 return 1;
1456 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001457 return 0;
1458}
1459
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001460static int img_resize(int argc, char **argv)
1461{
1462 int c, ret, relative;
1463 const char *filename, *fmt, *size;
1464 int64_t n, total_size;
Jes Sorensen2a819982010-12-06 17:08:31 +01001465 BlockDriverState *bs = NULL;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001466 QEMUOptionParameter *param;
1467 QEMUOptionParameter resize_options[] = {
1468 {
1469 .name = BLOCK_OPT_SIZE,
1470 .type = OPT_SIZE,
1471 .help = "Virtual disk size"
1472 },
1473 { NULL }
1474 };
1475
Kevin Wolfe80fec72011-04-29 10:58:12 +02001476 /* Remove size from argv manually so that negative numbers are not treated
1477 * as options by getopt. */
1478 if (argc < 3) {
1479 help();
1480 return 1;
1481 }
1482
1483 size = argv[--argc];
1484
1485 /* Parse getopt arguments */
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001486 fmt = NULL;
1487 for(;;) {
1488 c = getopt(argc, argv, "f:h");
1489 if (c == -1) {
1490 break;
1491 }
1492 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001493 case '?':
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001494 case 'h':
1495 help();
1496 break;
1497 case 'f':
1498 fmt = optarg;
1499 break;
1500 }
1501 }
Kevin Wolfe80fec72011-04-29 10:58:12 +02001502 if (optind >= argc) {
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001503 help();
1504 }
1505 filename = argv[optind++];
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001506
1507 /* Choose grow, shrink, or absolute resize mode */
1508 switch (size[0]) {
1509 case '+':
1510 relative = 1;
1511 size++;
1512 break;
1513 case '-':
1514 relative = -1;
1515 size++;
1516 break;
1517 default:
1518 relative = 0;
1519 break;
1520 }
1521
1522 /* Parse size */
1523 param = parse_option_parameters("", resize_options, NULL);
1524 if (set_option_parameter(param, BLOCK_OPT_SIZE, size)) {
1525 /* Error message already printed when size parsing fails */
Jes Sorensen2a819982010-12-06 17:08:31 +01001526 ret = -1;
1527 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001528 }
1529 n = get_option_parameter(param, BLOCK_OPT_SIZE)->value.n;
1530 free_option_parameters(param);
1531
1532 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001533 if (!bs) {
Jes Sorensen2a819982010-12-06 17:08:31 +01001534 ret = -1;
1535 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001536 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001537
1538 if (relative) {
1539 total_size = bdrv_getlength(bs) + n * relative;
1540 } else {
1541 total_size = n;
1542 }
1543 if (total_size <= 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001544 error_report("New image size must be positive");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001545 ret = -1;
1546 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001547 }
1548
1549 ret = bdrv_truncate(bs, total_size);
1550 switch (ret) {
1551 case 0:
1552 printf("Image resized.\n");
1553 break;
1554 case -ENOTSUP:
Jes Sorensen15654a62010-12-16 14:31:53 +01001555 error_report("This image format does not support resize");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001556 break;
1557 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +01001558 error_report("Image is read-only");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001559 break;
1560 default:
Jes Sorensen15654a62010-12-16 14:31:53 +01001561 error_report("Error resizing image (%d)", -ret);
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001562 break;
1563 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001564out:
Jes Sorensen2a819982010-12-06 17:08:31 +01001565 if (bs) {
1566 bdrv_delete(bs);
1567 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001568 if (ret) {
1569 return 1;
1570 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001571 return 0;
1572}
1573
Anthony Liguoric227f092009-10-01 16:12:16 -05001574static const img_cmd_t img_cmds[] = {
Stuart Brady153859b2009-06-07 00:42:17 +01001575#define DEF(option, callback, arg_string) \
1576 { option, callback },
1577#include "qemu-img-cmds.h"
1578#undef DEF
1579#undef GEN_DOCS
1580 { NULL, NULL, },
1581};
1582
bellardea2384d2004-08-01 21:59:26 +00001583int main(int argc, char **argv)
1584{
Anthony Liguoric227f092009-10-01 16:12:16 -05001585 const img_cmd_t *cmd;
Stuart Brady153859b2009-06-07 00:42:17 +01001586 const char *cmdname;
bellardea2384d2004-08-01 21:59:26 +00001587
Kevin Wolf53f76e52010-12-16 15:10:32 +01001588 error_set_progname(argv[0]);
1589
bellardea2384d2004-08-01 21:59:26 +00001590 bdrv_init();
1591 if (argc < 2)
1592 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001593 cmdname = argv[1];
aurel328f9b1572009-02-09 18:14:31 +00001594 argc--; argv++;
Stuart Brady153859b2009-06-07 00:42:17 +01001595
1596 /* find the command */
1597 for(cmd = img_cmds; cmd->name != NULL; cmd++) {
1598 if (!strcmp(cmdname, cmd->name)) {
1599 return cmd->handler(argc, argv);
1600 }
bellardea2384d2004-08-01 21:59:26 +00001601 }
Stuart Brady153859b2009-06-07 00:42:17 +01001602
1603 /* not found */
1604 help();
bellardea2384d2004-08-01 21:59:26 +00001605 return 0;
1606}