blob: 86127f0b1142fc976f5864efc7d79c51f669f4f0 [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"
Kevin Wolfa22f1232011-08-26 15:27:13 +020085 " '-S' indicates the consecutive number of bytes that must contain only zeros\n"
86 " for qemu-img to create a sparse image during conversion\n"
malc3f020d72010-02-08 12:04:56 +030087 "\n"
88 "Parameters to snapshot subcommand:\n"
89 " 'snapshot' is the name of the snapshot to create, apply or delete\n"
90 " '-a' applies a snapshot (revert disk to saved state)\n"
91 " '-c' creates a snapshot\n"
92 " '-d' deletes a snapshot\n"
Paolo Bonzinie00291c2010-02-04 16:49:56 +010093 " '-l' lists all snapshots in the given image\n";
94
95 printf("%s\nSupported formats:", help_msg);
bellardea2384d2004-08-01 21:59:26 +000096 bdrv_iterate_format(format_print, NULL);
97 printf("\n");
98 exit(1);
99}
100
bellardea2384d2004-08-01 21:59:26 +0000101#if defined(WIN32)
102/* XXX: put correct support for win32 */
103static int read_password(char *buf, int buf_size)
104{
105 int c, i;
106 printf("Password: ");
107 fflush(stdout);
108 i = 0;
109 for(;;) {
110 c = getchar();
111 if (c == '\n')
112 break;
113 if (i < (buf_size - 1))
114 buf[i++] = c;
115 }
116 buf[i] = '\0';
117 return 0;
118}
119
120#else
121
122#include <termios.h>
123
124static struct termios oldtty;
125
126static void term_exit(void)
127{
128 tcsetattr (0, TCSANOW, &oldtty);
129}
130
131static void term_init(void)
132{
133 struct termios tty;
134
135 tcgetattr (0, &tty);
136 oldtty = tty;
137
138 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
139 |INLCR|IGNCR|ICRNL|IXON);
140 tty.c_oflag |= OPOST;
141 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
142 tty.c_cflag &= ~(CSIZE|PARENB);
143 tty.c_cflag |= CS8;
144 tty.c_cc[VMIN] = 1;
145 tty.c_cc[VTIME] = 0;
ths3b46e622007-09-17 08:09:54 +0000146
bellardea2384d2004-08-01 21:59:26 +0000147 tcsetattr (0, TCSANOW, &tty);
148
149 atexit(term_exit);
150}
151
pbrook3f379ab2007-11-11 03:33:13 +0000152static int read_password(char *buf, int buf_size)
bellardea2384d2004-08-01 21:59:26 +0000153{
154 uint8_t ch;
155 int i, ret;
156
157 printf("password: ");
158 fflush(stdout);
159 term_init();
160 i = 0;
161 for(;;) {
162 ret = read(0, &ch, 1);
163 if (ret == -1) {
164 if (errno == EAGAIN || errno == EINTR) {
165 continue;
166 } else {
167 ret = -1;
168 break;
169 }
170 } else if (ret == 0) {
171 ret = -1;
172 break;
173 } else {
174 if (ch == '\r') {
175 ret = 0;
176 break;
177 }
178 if (i < (buf_size - 1))
179 buf[i++] = ch;
180 }
181 }
182 term_exit();
183 buf[i] = '\0';
184 printf("\n");
185 return ret;
186}
187#endif
188
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100189static int print_block_option_help(const char *filename, const char *fmt)
190{
191 BlockDriver *drv, *proto_drv;
192 QEMUOptionParameter *create_options = NULL;
193
194 /* Find driver and parse its options */
195 drv = bdrv_find_format(fmt);
196 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100197 error_report("Unknown file format '%s'", fmt);
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100198 return 1;
199 }
200
201 proto_drv = bdrv_find_protocol(filename);
202 if (!proto_drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100203 error_report("Unknown protocol '%s'", filename);
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100204 return 1;
205 }
206
207 create_options = append_option_parameters(create_options,
208 drv->create_options);
209 create_options = append_option_parameters(create_options,
210 proto_drv->create_options);
211 print_option_help(create_options);
212 free_option_parameters(create_options);
213 return 0;
214}
215
bellard75c23802004-08-27 21:28:58 +0000216static BlockDriverState *bdrv_new_open(const char *filename,
Sheng Yang9bc378c2010-01-29 10:15:06 +0800217 const char *fmt,
Stefan Hajnoczif163d072010-04-13 10:29:34 +0100218 int flags)
bellard75c23802004-08-27 21:28:58 +0000219{
220 BlockDriverState *bs;
221 BlockDriver *drv;
222 char password[256];
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100223 int ret;
bellard75c23802004-08-27 21:28:58 +0000224
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100225 bs = bdrv_new("image");
Kevin Wolfad717132010-12-16 15:37:41 +0100226
bellard75c23802004-08-27 21:28:58 +0000227 if (fmt) {
228 drv = bdrv_find_format(fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900229 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100230 error_report("Unknown file format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900231 goto fail;
232 }
bellard75c23802004-08-27 21:28:58 +0000233 } else {
234 drv = NULL;
235 }
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100236
237 ret = bdrv_open(bs, filename, flags, drv);
238 if (ret < 0) {
239 error_report("Could not open '%s': %s", filename, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900240 goto fail;
bellard75c23802004-08-27 21:28:58 +0000241 }
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100242
bellard75c23802004-08-27 21:28:58 +0000243 if (bdrv_is_encrypted(bs)) {
244 printf("Disk image '%s' is encrypted.\n", filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900245 if (read_password(password, sizeof(password)) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100246 error_report("No password given");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900247 goto fail;
248 }
249 if (bdrv_set_key(bs, password) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100250 error_report("invalid password");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900251 goto fail;
252 }
bellard75c23802004-08-27 21:28:58 +0000253 }
254 return bs;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900255fail:
256 if (bs) {
257 bdrv_delete(bs);
258 }
259 return NULL;
bellard75c23802004-08-27 21:28:58 +0000260}
261
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900262static int add_old_style_options(const char *fmt, QEMUOptionParameter *list,
Jes Sorenseneec77d92010-12-07 17:44:34 +0100263 const char *base_filename,
264 const char *base_fmt)
Kevin Wolfefa84d42009-05-18 16:42:12 +0200265{
Kevin Wolfefa84d42009-05-18 16:42:12 +0200266 if (base_filename) {
267 if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100268 error_report("Backing file not supported for file format '%s'",
269 fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900270 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200271 }
272 }
273 if (base_fmt) {
274 if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100275 error_report("Backing file format not supported for file "
276 "format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900277 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200278 }
279 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900280 return 0;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200281}
282
bellardea2384d2004-08-01 21:59:26 +0000283static int img_create(int argc, char **argv)
284{
Jes Sorenseneec77d92010-12-07 17:44:34 +0100285 int c, ret = 0;
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100286 uint64_t img_size = -1;
bellardea2384d2004-08-01 21:59:26 +0000287 const char *fmt = "raw";
aliguori9230eaf2009-03-28 17:55:19 +0000288 const char *base_fmt = NULL;
bellardea2384d2004-08-01 21:59:26 +0000289 const char *filename;
290 const char *base_filename = NULL;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200291 char *options = NULL;
ths3b46e622007-09-17 08:09:54 +0000292
bellardea2384d2004-08-01 21:59:26 +0000293 for(;;) {
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200294 c = getopt(argc, argv, "F:b:f:he6o:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100295 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000296 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100297 }
bellardea2384d2004-08-01 21:59:26 +0000298 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100299 case '?':
bellardea2384d2004-08-01 21:59:26 +0000300 case 'h':
301 help();
302 break;
aliguori9230eaf2009-03-28 17:55:19 +0000303 case 'F':
304 base_fmt = optarg;
305 break;
bellardea2384d2004-08-01 21:59:26 +0000306 case 'b':
307 base_filename = optarg;
308 break;
309 case 'f':
310 fmt = optarg;
311 break;
312 case 'e':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200313 error_report("option -e is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100314 "encryption\' instead!");
315 return 1;
thsd8871c52007-10-24 16:11:42 +0000316 case '6':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200317 error_report("option -6 is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100318 "compat6\' instead!");
319 return 1;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200320 case 'o':
321 options = optarg;
322 break;
bellardea2384d2004-08-01 21:59:26 +0000323 }
324 }
aliguori9230eaf2009-03-28 17:55:19 +0000325
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900326 /* Get the filename */
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100327 if (optind >= argc) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900328 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100329 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900330 filename = argv[optind++];
331
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100332 /* Get image size, if specified */
333 if (optind < argc) {
Jes Sorensen70b4f4b2011-01-05 11:41:02 +0100334 int64_t sval;
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100335 sval = strtosz_suffix(argv[optind++], NULL, STRTOSZ_DEFSUFFIX_B);
336 if (sval < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100337 error_report("Invalid image size specified! You may use k, M, G or "
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100338 "T suffixes for ");
Jes Sorensen15654a62010-12-16 14:31:53 +0100339 error_report("kilobytes, megabytes, gigabytes and terabytes.");
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100340 ret = -1;
341 goto out;
342 }
343 img_size = (uint64_t)sval;
344 }
345
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100346 if (options && !strcmp(options, "?")) {
347 ret = print_block_option_help(filename, fmt);
348 goto out;
349 }
350
Jes Sorensenf88e1a42010-12-16 13:52:15 +0100351 ret = bdrv_img_create(filename, fmt, base_filename, base_fmt,
352 options, img_size, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900353out:
354 if (ret) {
355 return 1;
356 }
bellardea2384d2004-08-01 21:59:26 +0000357 return 0;
358}
359
Kevin Wolfe076f332010-06-29 11:43:13 +0200360/*
361 * Checks an image for consistency. Exit codes:
362 *
363 * 0 - Check completed, image is good
364 * 1 - Check not completed because of internal errors
365 * 2 - Check completed, image is corrupted
366 * 3 - Check completed, image has leaked clusters, but is good otherwise
367 */
aliguori15859692009-04-21 23:11:53 +0000368static int img_check(int argc, char **argv)
369{
370 int c, ret;
371 const char *filename, *fmt;
aliguori15859692009-04-21 23:11:53 +0000372 BlockDriverState *bs;
Kevin Wolfe076f332010-06-29 11:43:13 +0200373 BdrvCheckResult result;
aliguori15859692009-04-21 23:11:53 +0000374
375 fmt = NULL;
376 for(;;) {
377 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100378 if (c == -1) {
aliguori15859692009-04-21 23:11:53 +0000379 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100380 }
aliguori15859692009-04-21 23:11:53 +0000381 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100382 case '?':
aliguori15859692009-04-21 23:11:53 +0000383 case 'h':
384 help();
385 break;
386 case 'f':
387 fmt = optarg;
388 break;
389 }
390 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100391 if (optind >= argc) {
aliguori15859692009-04-21 23:11:53 +0000392 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100393 }
aliguori15859692009-04-21 23:11:53 +0000394 filename = argv[optind++];
395
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100396 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900397 if (!bs) {
398 return 1;
399 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200400 ret = bdrv_check(bs, &result);
401
402 if (ret == -ENOTSUP) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100403 error_report("This image format does not support checks");
Kevin Wolfe076f332010-06-29 11:43:13 +0200404 bdrv_delete(bs);
405 return 1;
406 }
407
408 if (!(result.corruptions || result.leaks || result.check_errors)) {
409 printf("No errors were found on the image.\n");
410 } else {
411 if (result.corruptions) {
412 printf("\n%d errors were found on the image.\n"
413 "Data may be corrupted, or further writes to the image "
414 "may corrupt it.\n",
415 result.corruptions);
aliguori15859692009-04-21 23:11:53 +0000416 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200417
418 if (result.leaks) {
419 printf("\n%d leaked clusters were found on the image.\n"
420 "This means waste of disk space, but no harm to data.\n",
421 result.leaks);
422 }
423
424 if (result.check_errors) {
425 printf("\n%d internal errors have occurred during the check.\n",
426 result.check_errors);
427 }
aliguori15859692009-04-21 23:11:53 +0000428 }
429
430 bdrv_delete(bs);
Kevin Wolfe076f332010-06-29 11:43:13 +0200431
432 if (ret < 0 || result.check_errors) {
433 printf("\nAn error has occurred during the check: %s\n"
434 "The check is not complete and may have missed error.\n",
435 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900436 return 1;
437 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200438
439 if (result.corruptions) {
440 return 2;
441 } else if (result.leaks) {
442 return 3;
443 } else {
444 return 0;
445 }
aliguori15859692009-04-21 23:11:53 +0000446}
447
bellardea2384d2004-08-01 21:59:26 +0000448static int img_commit(int argc, char **argv)
449{
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400450 int c, ret, flags;
451 const char *filename, *fmt, *cache;
bellardea2384d2004-08-01 21:59:26 +0000452 BlockDriverState *bs;
453
454 fmt = NULL;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400455 cache = BDRV_DEFAULT_CACHE;
bellardea2384d2004-08-01 21:59:26 +0000456 for(;;) {
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400457 c = getopt(argc, argv, "f:ht:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100458 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000459 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100460 }
bellardea2384d2004-08-01 21:59:26 +0000461 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100462 case '?':
bellardea2384d2004-08-01 21:59:26 +0000463 case 'h':
464 help();
465 break;
466 case 'f':
467 fmt = optarg;
468 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400469 case 't':
470 cache = optarg;
471 break;
bellardea2384d2004-08-01 21:59:26 +0000472 }
473 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100474 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +0000475 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100476 }
bellardea2384d2004-08-01 21:59:26 +0000477 filename = argv[optind++];
478
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400479 flags = BDRV_O_RDWR;
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +0100480 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400481 if (ret < 0) {
482 error_report("Invalid cache option: %s", cache);
483 return -1;
484 }
485
486 bs = bdrv_new_open(filename, fmt, flags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900487 if (!bs) {
488 return 1;
489 }
bellardea2384d2004-08-01 21:59:26 +0000490 ret = bdrv_commit(bs);
491 switch(ret) {
492 case 0:
493 printf("Image committed.\n");
494 break;
495 case -ENOENT:
Jes Sorensen15654a62010-12-16 14:31:53 +0100496 error_report("No disk inserted");
bellardea2384d2004-08-01 21:59:26 +0000497 break;
498 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +0100499 error_report("Image is read-only");
bellardea2384d2004-08-01 21:59:26 +0000500 break;
501 case -ENOTSUP:
Jes Sorensen15654a62010-12-16 14:31:53 +0100502 error_report("Image is already committed");
bellardea2384d2004-08-01 21:59:26 +0000503 break;
504 default:
Jes Sorensen15654a62010-12-16 14:31:53 +0100505 error_report("Error while committing image");
bellardea2384d2004-08-01 21:59:26 +0000506 break;
507 }
508
509 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900510 if (ret) {
511 return 1;
512 }
bellardea2384d2004-08-01 21:59:26 +0000513 return 0;
514}
515
Dmitry Konishchevf6a00aa2011-05-18 15:03:59 +0400516/*
517 * Checks whether the sector is not a zero sector.
518 *
519 * Attention! The len must be a multiple of 4 * sizeof(long) due to
520 * restriction of optimizations in this function.
521 */
bellardea2384d2004-08-01 21:59:26 +0000522static int is_not_zero(const uint8_t *sector, int len)
523{
Dmitry Konishchevf6a00aa2011-05-18 15:03:59 +0400524 /*
525 * Use long as the biggest available internal data type that fits into the
526 * CPU register and unroll the loop to smooth out the effect of memory
527 * latency.
528 */
529
bellardea2384d2004-08-01 21:59:26 +0000530 int i;
Dmitry Konishchevf6a00aa2011-05-18 15:03:59 +0400531 long d0, d1, d2, d3;
532 const long * const data = (const long *) sector;
533
534 len /= sizeof(long);
535
536 for(i = 0; i < len; i += 4) {
537 d0 = data[i + 0];
538 d1 = data[i + 1];
539 d2 = data[i + 2];
540 d3 = data[i + 3];
541
542 if (d0 || d1 || d2 || d3) {
bellardea2384d2004-08-01 21:59:26 +0000543 return 1;
Dmitry Konishchevf6a00aa2011-05-18 15:03:59 +0400544 }
bellardea2384d2004-08-01 21:59:26 +0000545 }
Dmitry Konishchevf6a00aa2011-05-18 15:03:59 +0400546
bellardea2384d2004-08-01 21:59:26 +0000547 return 0;
548}
549
thsf58c7b32008-06-05 21:53:49 +0000550/*
551 * Returns true iff the first sector pointed to by 'buf' contains at least
552 * a non-NUL byte.
553 *
554 * 'pnum' is set to the number of sectors (including and immediately following
555 * the first one) that are known to be in the same allocated/unallocated state.
556 */
bellardea2384d2004-08-01 21:59:26 +0000557static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
558{
559 int v, i;
560
561 if (n <= 0) {
562 *pnum = 0;
563 return 0;
564 }
565 v = is_not_zero(buf, 512);
566 for(i = 1; i < n; i++) {
567 buf += 512;
568 if (v != is_not_zero(buf, 512))
569 break;
570 }
571 *pnum = i;
572 return v;
573}
574
Kevin Wolf3e85c6f2010-01-12 12:55:18 +0100575/*
Kevin Wolfa22f1232011-08-26 15:27:13 +0200576 * Like is_allocated_sectors, but if the buffer starts with a used sector,
577 * up to 'min' consecutive sectors containing zeros are ignored. This avoids
578 * breaking up write requests for only small sparse areas.
579 */
580static int is_allocated_sectors_min(const uint8_t *buf, int n, int *pnum,
581 int min)
582{
583 int ret;
584 int num_checked, num_used;
585
586 if (n < min) {
587 min = n;
588 }
589
590 ret = is_allocated_sectors(buf, n, pnum);
591 if (!ret) {
592 return ret;
593 }
594
595 num_used = *pnum;
596 buf += BDRV_SECTOR_SIZE * *pnum;
597 n -= *pnum;
598 num_checked = num_used;
599
600 while (n > 0) {
601 ret = is_allocated_sectors(buf, n, pnum);
602
603 buf += BDRV_SECTOR_SIZE * *pnum;
604 n -= *pnum;
605 num_checked += *pnum;
606 if (ret) {
607 num_used = num_checked;
608 } else if (*pnum >= min) {
609 break;
610 }
611 }
612
613 *pnum = num_used;
614 return 1;
615}
616
617/*
Kevin Wolf3e85c6f2010-01-12 12:55:18 +0100618 * Compares two buffers sector by sector. Returns 0 if the first sector of both
619 * buffers matches, non-zero otherwise.
620 *
621 * pnum is set to the number of sectors (including and immediately following
622 * the first one) that are known to have the same comparison result
623 */
624static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
625 int *pnum)
626{
627 int res, i;
628
629 if (n <= 0) {
630 *pnum = 0;
631 return 0;
632 }
633
634 res = !!memcmp(buf1, buf2, 512);
635 for(i = 1; i < n; i++) {
636 buf1 += 512;
637 buf2 += 512;
638
639 if (!!memcmp(buf1, buf2, 512) != res) {
640 break;
641 }
642 }
643
644 *pnum = i;
645 return res;
646}
647
Kevin Wolf80ee15a2009-09-15 12:30:43 +0200648#define IO_BUF_SIZE (2 * 1024 * 1024)
bellardea2384d2004-08-01 21:59:26 +0000649
650static int img_convert(int argc, char **argv)
651{
Jes Sorenseneec77d92010-12-07 17:44:34 +0100652 int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400653 int progress = 0, flags;
654 const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900655 BlockDriver *drv, *proto_drv;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900656 BlockDriverState **bs = NULL, *out_bs = NULL;
ths96b8f132007-12-17 01:35:20 +0000657 int64_t total_sectors, nb_sectors, sector_num, bs_offset;
658 uint64_t bs_sectors;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900659 uint8_t * buf = NULL;
bellardea2384d2004-08-01 21:59:26 +0000660 const uint8_t *buf1;
bellardfaea38e2006-08-05 21:31:00 +0000661 BlockDriverInfo bdi;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900662 QEMUOptionParameter *param = NULL, *create_options = NULL;
Kevin Wolfa18953f2010-10-14 15:46:04 +0200663 QEMUOptionParameter *out_baseimg_param;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200664 char *options = NULL;
edison51ef6722010-09-21 19:58:41 -0700665 const char *snapshot_name = NULL;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200666 float local_progress;
Kevin Wolfa22f1232011-08-26 15:27:13 +0200667 int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */
bellardea2384d2004-08-01 21:59:26 +0000668
669 fmt = NULL;
670 out_fmt = "raw";
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400671 cache = "unsafe";
thsf58c7b32008-06-05 21:53:49 +0000672 out_baseimg = NULL;
Jes Sorenseneec77d92010-12-07 17:44:34 +0100673 compress = 0;
bellardea2384d2004-08-01 21:59:26 +0000674 for(;;) {
Kevin Wolfa22f1232011-08-26 15:27:13 +0200675 c = getopt(argc, argv, "f:O:B:s:hce6o:pS:t:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100676 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000677 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100678 }
bellardea2384d2004-08-01 21:59:26 +0000679 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100680 case '?':
bellardea2384d2004-08-01 21:59:26 +0000681 case 'h':
682 help();
683 break;
684 case 'f':
685 fmt = optarg;
686 break;
687 case 'O':
688 out_fmt = optarg;
689 break;
thsf58c7b32008-06-05 21:53:49 +0000690 case 'B':
691 out_baseimg = optarg;
692 break;
bellardea2384d2004-08-01 21:59:26 +0000693 case 'c':
Jes Sorenseneec77d92010-12-07 17:44:34 +0100694 compress = 1;
bellardea2384d2004-08-01 21:59:26 +0000695 break;
696 case 'e':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200697 error_report("option -e is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100698 "encryption\' instead!");
699 return 1;
thsec36ba12007-09-16 21:59:02 +0000700 case '6':
Markus Armbruster9d42e152011-06-22 14:03:55 +0200701 error_report("option -6 is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100702 "compat6\' instead!");
703 return 1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200704 case 'o':
705 options = optarg;
706 break;
edison51ef6722010-09-21 19:58:41 -0700707 case 's':
708 snapshot_name = optarg;
709 break;
Kevin Wolfa22f1232011-08-26 15:27:13 +0200710 case 'S':
711 {
712 int64_t sval;
713 sval = strtosz_suffix(optarg, NULL, STRTOSZ_DEFSUFFIX_B);
714 if (sval < 0) {
715 error_report("Invalid minimum zero buffer size for sparse output specified");
716 return 1;
717 }
718
719 min_sparse = sval / BDRV_SECTOR_SIZE;
720 break;
721 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200722 case 'p':
723 progress = 1;
724 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400725 case 't':
726 cache = optarg;
727 break;
bellardea2384d2004-08-01 21:59:26 +0000728 }
729 }
ths3b46e622007-09-17 08:09:54 +0000730
balrog926c2d22007-10-31 01:11:44 +0000731 bs_n = argc - optind - 1;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100732 if (bs_n < 1) {
733 help();
734 }
balrog926c2d22007-10-31 01:11:44 +0000735
736 out_filename = argv[argc - 1];
thsf58c7b32008-06-05 21:53:49 +0000737
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100738 if (options && !strcmp(options, "?")) {
739 ret = print_block_option_help(out_filename, out_fmt);
740 goto out;
741 }
742
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900743 if (bs_n > 1 && out_baseimg) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100744 error_report("-B makes no sense when concatenating multiple input "
745 "images");
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100746 ret = -1;
747 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900748 }
balrog926c2d22007-10-31 01:11:44 +0000749
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200750 qemu_progress_init(progress, 2.0);
751 qemu_progress_print(0, 100);
752
Anthony Liguori7267c092011-08-20 22:09:37 -0500753 bs = g_malloc0(bs_n * sizeof(BlockDriverState *));
balrog926c2d22007-10-31 01:11:44 +0000754
755 total_sectors = 0;
756 for (bs_i = 0; bs_i < bs_n; bs_i++) {
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100757 bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900758 if (!bs[bs_i]) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100759 error_report("Could not open '%s'", argv[optind + bs_i]);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900760 ret = -1;
761 goto out;
762 }
balrog926c2d22007-10-31 01:11:44 +0000763 bdrv_get_geometry(bs[bs_i], &bs_sectors);
764 total_sectors += bs_sectors;
765 }
bellardea2384d2004-08-01 21:59:26 +0000766
edison51ef6722010-09-21 19:58:41 -0700767 if (snapshot_name != NULL) {
768 if (bs_n > 1) {
Markus Armbruster6daf1942011-06-22 14:03:54 +0200769 error_report("No support for concatenating multiple snapshot");
edison51ef6722010-09-21 19:58:41 -0700770 ret = -1;
771 goto out;
772 }
773 if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
Markus Armbruster6daf1942011-06-22 14:03:54 +0200774 error_report("Failed to load snapshot");
edison51ef6722010-09-21 19:58:41 -0700775 ret = -1;
776 goto out;
777 }
778 }
779
Kevin Wolfefa84d42009-05-18 16:42:12 +0200780 /* Find driver and parse its options */
bellardea2384d2004-08-01 21:59:26 +0000781 drv = bdrv_find_format(out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900782 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100783 error_report("Unknown file format '%s'", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900784 ret = -1;
785 goto out;
786 }
balrog926c2d22007-10-31 01:11:44 +0000787
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900788 proto_drv = bdrv_find_protocol(out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900789 if (!proto_drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100790 error_report("Unknown protocol '%s'", out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900791 ret = -1;
792 goto out;
793 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900794
795 create_options = append_option_parameters(create_options,
796 drv->create_options);
797 create_options = append_option_parameters(create_options,
798 proto_drv->create_options);
Kevin Wolfdb08adf2009-06-04 15:39:38 +0200799
Kevin Wolfefa84d42009-05-18 16:42:12 +0200800 if (options) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900801 param = parse_option_parameters(options, create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200802 if (param == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100803 error_report("Invalid options for file format '%s'.", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900804 ret = -1;
805 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200806 }
807 } else {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900808 param = parse_option_parameters("", create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200809 }
810
811 set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
Jes Sorenseneec77d92010-12-07 17:44:34 +0100812 ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900813 if (ret < 0) {
814 goto out;
815 }
Kevin Wolfefa84d42009-05-18 16:42:12 +0200816
Kevin Wolfa18953f2010-10-14 15:46:04 +0200817 /* Get backing file name if -o backing_file was used */
818 out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
819 if (out_baseimg_param) {
820 out_baseimg = out_baseimg_param->value.s;
821 }
822
Kevin Wolfefa84d42009-05-18 16:42:12 +0200823 /* Check if compression is supported */
Jes Sorenseneec77d92010-12-07 17:44:34 +0100824 if (compress) {
Kevin Wolfefa84d42009-05-18 16:42:12 +0200825 QEMUOptionParameter *encryption =
826 get_option_parameter(param, BLOCK_OPT_ENCRYPT);
Kevin Wolf41521fa2011-10-18 16:19:42 +0200827 QEMUOptionParameter *preallocation =
828 get_option_parameter(param, BLOCK_OPT_PREALLOC);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200829
830 if (!drv->bdrv_write_compressed) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100831 error_report("Compression not supported for this file format");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900832 ret = -1;
833 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200834 }
835
836 if (encryption && encryption->value.n) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100837 error_report("Compression and encryption not supported at "
838 "the same time");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900839 ret = -1;
840 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200841 }
Kevin Wolf41521fa2011-10-18 16:19:42 +0200842
843 if (preallocation && preallocation->value.s
844 && strcmp(preallocation->value.s, "off"))
845 {
846 error_report("Compression and preallocation not supported at "
847 "the same time");
848 ret = -1;
849 goto out;
850 }
Kevin Wolfefa84d42009-05-18 16:42:12 +0200851 }
852
853 /* Create the new image */
854 ret = bdrv_create(drv, out_filename, param);
bellardea2384d2004-08-01 21:59:26 +0000855 if (ret < 0) {
856 if (ret == -ENOTSUP) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100857 error_report("Formatting not supported for file format '%s'",
858 out_fmt);
aurel326e9ea0c2009-04-15 14:42:46 +0000859 } else if (ret == -EFBIG) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100860 error_report("The image size is too large for file format '%s'",
861 out_fmt);
bellardea2384d2004-08-01 21:59:26 +0000862 } else {
Jes Sorensen15654a62010-12-16 14:31:53 +0100863 error_report("%s: error while converting %s: %s",
864 out_filename, out_fmt, strerror(-ret));
bellardea2384d2004-08-01 21:59:26 +0000865 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900866 goto out;
bellardea2384d2004-08-01 21:59:26 +0000867 }
ths3b46e622007-09-17 08:09:54 +0000868
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400869 flags = BDRV_O_RDWR;
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +0100870 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -0400871 if (ret < 0) {
872 error_report("Invalid cache option: %s", cache);
873 return -1;
874 }
875
876 out_bs = bdrv_new_open(out_filename, out_fmt, flags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900877 if (!out_bs) {
878 ret = -1;
879 goto out;
880 }
bellardea2384d2004-08-01 21:59:26 +0000881
balrog926c2d22007-10-31 01:11:44 +0000882 bs_i = 0;
883 bs_offset = 0;
884 bdrv_get_geometry(bs[0], &bs_sectors);
Kevin Wolfbb1c0592011-08-08 14:09:12 +0200885 buf = qemu_blockalign(out_bs, IO_BUF_SIZE);
balrog926c2d22007-10-31 01:11:44 +0000886
Jes Sorenseneec77d92010-12-07 17:44:34 +0100887 if (compress) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900888 ret = bdrv_get_info(out_bs, &bdi);
889 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100890 error_report("could not get block driver info");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900891 goto out;
892 }
bellardfaea38e2006-08-05 21:31:00 +0000893 cluster_size = bdi.cluster_size;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900894 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100895 error_report("invalid cluster size");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900896 ret = -1;
897 goto out;
898 }
bellardea2384d2004-08-01 21:59:26 +0000899 cluster_sectors = cluster_size >> 9;
900 sector_num = 0;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200901
902 nb_sectors = total_sectors;
903 local_progress = (float)100 /
Jes Sorensen4ee96412011-05-06 11:39:11 +0200904 (nb_sectors / MIN(nb_sectors, cluster_sectors));
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200905
bellardea2384d2004-08-01 21:59:26 +0000906 for(;;) {
balrog926c2d22007-10-31 01:11:44 +0000907 int64_t bs_num;
908 int remainder;
909 uint8_t *buf2;
910
bellardea2384d2004-08-01 21:59:26 +0000911 nb_sectors = total_sectors - sector_num;
912 if (nb_sectors <= 0)
913 break;
914 if (nb_sectors >= cluster_sectors)
915 n = cluster_sectors;
916 else
917 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000918
919 bs_num = sector_num - bs_offset;
920 assert (bs_num >= 0);
921 remainder = n;
922 buf2 = buf;
923 while (remainder > 0) {
924 int nlow;
925 while (bs_num == bs_sectors) {
926 bs_i++;
927 assert (bs_i < bs_n);
928 bs_offset += bs_sectors;
929 bdrv_get_geometry(bs[bs_i], &bs_sectors);
930 bs_num = 0;
Blue Swirl0bfcd592010-05-22 08:02:12 +0000931 /* printf("changing part: sector_num=%" PRId64 ", "
932 "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64
933 "\n", sector_num, bs_i, bs_offset, bs_sectors); */
balrog926c2d22007-10-31 01:11:44 +0000934 }
935 assert (bs_num < bs_sectors);
936
937 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
938
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900939 ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
940 if (ret < 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +0100941 error_report("error while reading sector %" PRId64 ": %s",
942 bs_num, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900943 goto out;
944 }
balrog926c2d22007-10-31 01:11:44 +0000945
946 buf2 += nlow * 512;
947 bs_num += nlow;
948
949 remainder -= nlow;
950 }
951 assert (remainder == 0);
952
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100953 if (n < cluster_sectors) {
bellardea2384d2004-08-01 21:59:26 +0000954 memset(buf + n * 512, 0, cluster_size - n * 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100955 }
bellardea2384d2004-08-01 21:59:26 +0000956 if (is_not_zero(buf, cluster_size)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900957 ret = bdrv_write_compressed(out_bs, sector_num, buf,
958 cluster_sectors);
959 if (ret != 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +0100960 error_report("error while compressing sector %" PRId64
961 ": %s", sector_num, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900962 goto out;
963 }
bellardea2384d2004-08-01 21:59:26 +0000964 }
965 sector_num += n;
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200966 qemu_progress_print(local_progress, 100);
bellardea2384d2004-08-01 21:59:26 +0000967 }
bellardfaea38e2006-08-05 21:31:00 +0000968 /* signal EOF to align */
969 bdrv_write_compressed(out_bs, 0, NULL, 0);
bellardea2384d2004-08-01 21:59:26 +0000970 } else {
Kevin Wolff2feebb2010-04-14 17:30:35 +0200971 int has_zero_init = bdrv_has_zero_init(out_bs);
972
thsf58c7b32008-06-05 21:53:49 +0000973 sector_num = 0; // total number of sectors converted so far
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200974 nb_sectors = total_sectors - sector_num;
975 local_progress = (float)100 /
Jes Sorensen4ee96412011-05-06 11:39:11 +0200976 (nb_sectors / MIN(nb_sectors, IO_BUF_SIZE / 512));
Jes Sorensen6b837bc2011-03-30 14:16:25 +0200977
bellardea2384d2004-08-01 21:59:26 +0000978 for(;;) {
979 nb_sectors = total_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100980 if (nb_sectors <= 0) {
bellardea2384d2004-08-01 21:59:26 +0000981 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100982 }
983 if (nb_sectors >= (IO_BUF_SIZE / 512)) {
bellardea2384d2004-08-01 21:59:26 +0000984 n = (IO_BUF_SIZE / 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100985 } else {
bellardea2384d2004-08-01 21:59:26 +0000986 n = nb_sectors;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100987 }
balrog926c2d22007-10-31 01:11:44 +0000988
989 while (sector_num - bs_offset >= bs_sectors) {
990 bs_i ++;
991 assert (bs_i < bs_n);
992 bs_offset += bs_sectors;
993 bdrv_get_geometry(bs[bs_i], &bs_sectors);
Blue Swirl0bfcd592010-05-22 08:02:12 +0000994 /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "
995 "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",
balrog926c2d22007-10-31 01:11:44 +0000996 sector_num, bs_i, bs_offset, bs_sectors); */
997 }
998
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100999 if (n > bs_offset + bs_sectors - sector_num) {
balrog926c2d22007-10-31 01:11:44 +00001000 n = bs_offset + bs_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001001 }
balrog926c2d22007-10-31 01:11:44 +00001002
Kevin Wolff2feebb2010-04-14 17:30:35 +02001003 if (has_zero_init) {
Akkarit Sangpetchd0320442009-07-17 10:02:15 +02001004 /* If the output image is being created as a copy on write image,
1005 assume that sectors which are unallocated in the input image
1006 are present in both the output's and input's base images (no
1007 need to copy them). */
1008 if (out_baseimg) {
1009 if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
1010 n, &n1)) {
1011 sector_num += n1;
1012 continue;
1013 }
1014 /* The next 'n1' sectors are allocated in the input image. Copy
1015 only those as they may be followed by unallocated sectors. */
1016 n = n1;
aliguori93c65b42009-04-05 17:40:43 +00001017 }
aliguori93c65b42009-04-05 17:40:43 +00001018 } else {
1019 n1 = n;
thsf58c7b32008-06-05 21:53:49 +00001020 }
1021
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001022 ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
1023 if (ret < 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +01001024 error_report("error while reading sector %" PRId64 ": %s",
1025 sector_num - bs_offset, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001026 goto out;
1027 }
bellardea2384d2004-08-01 21:59:26 +00001028 /* NOTE: at the same time we convert, we do not write zero
1029 sectors to have a chance to compress the image. Ideally, we
1030 should add a specific call to have the info to go faster */
1031 buf1 = buf;
1032 while (n > 0) {
thsf58c7b32008-06-05 21:53:49 +00001033 /* If the output image is being created as a copy on write image,
1034 copy all sectors even the ones containing only NUL bytes,
aliguori93c65b42009-04-05 17:40:43 +00001035 because they may differ from the sectors in the base image.
1036
1037 If the output is to a host device, we also write out
1038 sectors that are entirely 0, since whatever data was
1039 already there is garbage, not 0s. */
Kevin Wolff2feebb2010-04-14 17:30:35 +02001040 if (!has_zero_init || out_baseimg ||
Kevin Wolfa22f1232011-08-26 15:27:13 +02001041 is_allocated_sectors_min(buf1, n, &n1, min_sparse)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001042 ret = bdrv_write(out_bs, sector_num, buf1, n1);
1043 if (ret < 0) {
Stefan Hajnoczi3fba9d82011-08-17 17:41:09 +01001044 error_report("error while writing sector %" PRId64
1045 ": %s", sector_num, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001046 goto out;
1047 }
bellardea2384d2004-08-01 21:59:26 +00001048 }
1049 sector_num += n1;
1050 n -= n1;
1051 buf1 += n1 * 512;
1052 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001053 qemu_progress_print(local_progress, 100);
bellardea2384d2004-08-01 21:59:26 +00001054 }
1055 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001056out:
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001057 qemu_progress_end();
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001058 free_option_parameters(create_options);
1059 free_option_parameters(param);
Kevin Wolfbb1c0592011-08-08 14:09:12 +02001060 qemu_vfree(buf);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001061 if (out_bs) {
1062 bdrv_delete(out_bs);
1063 }
Jes Sorensen31ca34b2010-12-06 15:25:36 +01001064 if (bs) {
1065 for (bs_i = 0; bs_i < bs_n; bs_i++) {
1066 if (bs[bs_i]) {
1067 bdrv_delete(bs[bs_i]);
1068 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001069 }
Anthony Liguori7267c092011-08-20 22:09:37 -05001070 g_free(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001071 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001072 if (ret) {
1073 return 1;
1074 }
bellardea2384d2004-08-01 21:59:26 +00001075 return 0;
1076}
1077
bellard57d1a2b2004-08-03 21:15:11 +00001078
bellardfaea38e2006-08-05 21:31:00 +00001079static void dump_snapshots(BlockDriverState *bs)
1080{
1081 QEMUSnapshotInfo *sn_tab, *sn;
1082 int nb_sns, i;
1083 char buf[256];
1084
1085 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1086 if (nb_sns <= 0)
1087 return;
1088 printf("Snapshot list:\n");
1089 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
1090 for(i = 0; i < nb_sns; i++) {
1091 sn = &sn_tab[i];
1092 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
1093 }
Anthony Liguori7267c092011-08-20 22:09:37 -05001094 g_free(sn_tab);
bellardfaea38e2006-08-05 21:31:00 +00001095}
1096
bellardea2384d2004-08-01 21:59:26 +00001097static int img_info(int argc, char **argv)
1098{
1099 int c;
1100 const char *filename, *fmt;
bellardea2384d2004-08-01 21:59:26 +00001101 BlockDriverState *bs;
1102 char fmt_name[128], size_buf[128], dsize_buf[128];
ths96b8f132007-12-17 01:35:20 +00001103 uint64_t total_sectors;
1104 int64_t allocated_size;
bellard93b6b2a2006-08-01 15:51:11 +00001105 char backing_filename[1024];
1106 char backing_filename2[1024];
bellardfaea38e2006-08-05 21:31:00 +00001107 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +00001108
1109 fmt = NULL;
1110 for(;;) {
1111 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001112 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +00001113 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001114 }
bellardea2384d2004-08-01 21:59:26 +00001115 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001116 case '?':
bellardea2384d2004-08-01 21:59:26 +00001117 case 'h':
1118 help();
1119 break;
1120 case 'f':
1121 fmt = optarg;
1122 break;
1123 }
1124 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001125 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +00001126 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001127 }
bellardea2384d2004-08-01 21:59:26 +00001128 filename = argv[optind++];
1129
Stefan Hajnocziadfe0782010-04-13 10:29:35 +01001130 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001131 if (!bs) {
1132 return 1;
1133 }
bellardea2384d2004-08-01 21:59:26 +00001134 bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
1135 bdrv_get_geometry(bs, &total_sectors);
1136 get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
Fam Zheng4a1d5e12011-07-12 19:56:39 +08001137 allocated_size = bdrv_get_allocated_file_size(bs);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001138 if (allocated_size < 0) {
blueswir1a10ea302008-08-24 10:30:33 +00001139 snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001140 } else {
ths5fafdf22007-09-16 21:08:06 +00001141 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
bellardde167e42005-04-28 21:15:08 +00001142 allocated_size);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001143 }
bellardea2384d2004-08-01 21:59:26 +00001144 printf("image: %s\n"
1145 "file format: %s\n"
bellardec3757d2006-06-14 15:50:07 +00001146 "virtual size: %s (%" PRId64 " bytes)\n"
bellardea2384d2004-08-01 21:59:26 +00001147 "disk size: %s\n",
ths5fafdf22007-09-16 21:08:06 +00001148 filename, fmt_name, size_buf,
bellardec3757d2006-06-14 15:50:07 +00001149 (total_sectors * 512),
bellardea2384d2004-08-01 21:59:26 +00001150 dsize_buf);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001151 if (bdrv_is_encrypted(bs)) {
bellardea2384d2004-08-01 21:59:26 +00001152 printf("encrypted: yes\n");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001153 }
bellardfaea38e2006-08-05 21:31:00 +00001154 if (bdrv_get_info(bs, &bdi) >= 0) {
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001155 if (bdi.cluster_size != 0) {
bellardfaea38e2006-08-05 21:31:00 +00001156 printf("cluster_size: %d\n", bdi.cluster_size);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001157 }
bellardfaea38e2006-08-05 21:31:00 +00001158 }
bellard93b6b2a2006-08-01 15:51:11 +00001159 bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
bellardfaea38e2006-08-05 21:31:00 +00001160 if (backing_filename[0] != '\0') {
bellard93b6b2a2006-08-01 15:51:11 +00001161 path_combine(backing_filename2, sizeof(backing_filename2),
1162 filename, backing_filename);
ths5fafdf22007-09-16 21:08:06 +00001163 printf("backing file: %s (actual path: %s)\n",
bellard93b6b2a2006-08-01 15:51:11 +00001164 backing_filename,
1165 backing_filename2);
bellardfaea38e2006-08-05 21:31:00 +00001166 }
1167 dump_snapshots(bs);
bellardea2384d2004-08-01 21:59:26 +00001168 bdrv_delete(bs);
1169 return 0;
1170}
1171
aliguorif7b4a942009-01-07 17:40:15 +00001172#define SNAPSHOT_LIST 1
1173#define SNAPSHOT_CREATE 2
1174#define SNAPSHOT_APPLY 3
1175#define SNAPSHOT_DELETE 4
1176
Stuart Brady153859b2009-06-07 00:42:17 +01001177static int img_snapshot(int argc, char **argv)
aliguorif7b4a942009-01-07 17:40:15 +00001178{
1179 BlockDriverState *bs;
1180 QEMUSnapshotInfo sn;
1181 char *filename, *snapshot_name = NULL;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001182 int c, ret = 0, bdrv_oflags;
aliguorif7b4a942009-01-07 17:40:15 +00001183 int action = 0;
1184 qemu_timeval tv;
1185
Kevin Wolf710da702011-01-10 12:33:02 +01001186 bdrv_oflags = BDRV_O_FLAGS | BDRV_O_RDWR;
aliguorif7b4a942009-01-07 17:40:15 +00001187 /* Parse commandline parameters */
1188 for(;;) {
1189 c = getopt(argc, argv, "la:c:d:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001190 if (c == -1) {
aliguorif7b4a942009-01-07 17:40:15 +00001191 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001192 }
aliguorif7b4a942009-01-07 17:40:15 +00001193 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001194 case '?':
aliguorif7b4a942009-01-07 17:40:15 +00001195 case 'h':
1196 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001197 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001198 case 'l':
1199 if (action) {
1200 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001201 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001202 }
1203 action = SNAPSHOT_LIST;
Naphtali Spreif5edb012010-01-17 16:48:13 +02001204 bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
aliguorif7b4a942009-01-07 17:40:15 +00001205 break;
1206 case 'a':
1207 if (action) {
1208 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001209 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001210 }
1211 action = SNAPSHOT_APPLY;
1212 snapshot_name = optarg;
1213 break;
1214 case 'c':
1215 if (action) {
1216 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001217 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001218 }
1219 action = SNAPSHOT_CREATE;
1220 snapshot_name = optarg;
1221 break;
1222 case 'd':
1223 if (action) {
1224 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001225 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001226 }
1227 action = SNAPSHOT_DELETE;
1228 snapshot_name = optarg;
1229 break;
1230 }
1231 }
1232
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001233 if (optind >= argc) {
aliguorif7b4a942009-01-07 17:40:15 +00001234 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001235 }
aliguorif7b4a942009-01-07 17:40:15 +00001236 filename = argv[optind++];
1237
1238 /* Open the image */
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001239 bs = bdrv_new_open(filename, NULL, bdrv_oflags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001240 if (!bs) {
1241 return 1;
1242 }
aliguorif7b4a942009-01-07 17:40:15 +00001243
1244 /* Perform the requested action */
1245 switch(action) {
1246 case SNAPSHOT_LIST:
1247 dump_snapshots(bs);
1248 break;
1249
1250 case SNAPSHOT_CREATE:
1251 memset(&sn, 0, sizeof(sn));
1252 pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
1253
1254 qemu_gettimeofday(&tv);
1255 sn.date_sec = tv.tv_sec;
1256 sn.date_nsec = tv.tv_usec * 1000;
1257
1258 ret = bdrv_snapshot_create(bs, &sn);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001259 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001260 error_report("Could not create snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001261 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001262 }
aliguorif7b4a942009-01-07 17:40:15 +00001263 break;
1264
1265 case SNAPSHOT_APPLY:
1266 ret = bdrv_snapshot_goto(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001267 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001268 error_report("Could not apply snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001269 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001270 }
aliguorif7b4a942009-01-07 17:40:15 +00001271 break;
1272
1273 case SNAPSHOT_DELETE:
1274 ret = bdrv_snapshot_delete(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001275 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001276 error_report("Could not delete snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001277 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001278 }
aliguorif7b4a942009-01-07 17:40:15 +00001279 break;
1280 }
1281
1282 /* Cleanup */
1283 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001284 if (ret) {
1285 return 1;
1286 }
Stuart Brady153859b2009-06-07 00:42:17 +01001287 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001288}
1289
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001290static int img_rebase(int argc, char **argv)
1291{
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001292 BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001293 BlockDriver *old_backing_drv, *new_backing_drv;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001294 char *filename;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001295 const char *fmt, *cache, *out_basefmt, *out_baseimg;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001296 int c, flags, ret;
1297 int unsafe = 0;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001298 int progress = 0;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001299
1300 /* Parse commandline parameters */
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001301 fmt = NULL;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001302 cache = BDRV_DEFAULT_CACHE;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001303 out_baseimg = NULL;
1304 out_basefmt = NULL;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001305 for(;;) {
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001306 c = getopt(argc, argv, "uhf:F:b:pt:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001307 if (c == -1) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001308 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001309 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001310 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001311 case '?':
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001312 case 'h':
1313 help();
1314 return 0;
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001315 case 'f':
1316 fmt = optarg;
1317 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001318 case 'F':
1319 out_basefmt = optarg;
1320 break;
1321 case 'b':
1322 out_baseimg = optarg;
1323 break;
1324 case 'u':
1325 unsafe = 1;
1326 break;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001327 case 'p':
1328 progress = 1;
1329 break;
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001330 case 't':
1331 cache = optarg;
1332 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001333 }
1334 }
1335
Anthony Liguori9a9d9db2011-04-13 15:51:47 +01001336 if ((optind >= argc) || (!unsafe && !out_baseimg)) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001337 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001338 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001339 filename = argv[optind++];
1340
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001341 qemu_progress_init(progress, 2.0);
1342 qemu_progress_print(0, 100);
1343
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001344 flags = BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
Stefan Hajnoczic3993cd2011-08-04 12:26:51 +01001345 ret = bdrv_parse_cache_flags(cache, &flags);
Federico Simoncelli661a0f72011-06-20 12:48:19 -04001346 if (ret < 0) {
1347 error_report("Invalid cache option: %s", cache);
1348 return -1;
1349 }
1350
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001351 /*
1352 * Open the images.
1353 *
1354 * Ignore the old backing file for unsafe rebase in case we want to correct
1355 * the reference to a renamed or moved backing file.
1356 */
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001357 bs = bdrv_new_open(filename, fmt, flags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001358 if (!bs) {
1359 return 1;
1360 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001361
1362 /* Find the right drivers for the backing files */
1363 old_backing_drv = NULL;
1364 new_backing_drv = NULL;
1365
1366 if (!unsafe && bs->backing_format[0] != '\0') {
1367 old_backing_drv = bdrv_find_format(bs->backing_format);
1368 if (old_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001369 error_report("Invalid format name: '%s'", bs->backing_format);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001370 ret = -1;
1371 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001372 }
1373 }
1374
1375 if (out_basefmt != NULL) {
1376 new_backing_drv = bdrv_find_format(out_basefmt);
1377 if (new_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001378 error_report("Invalid format name: '%s'", out_basefmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001379 ret = -1;
1380 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001381 }
1382 }
1383
1384 /* For safe rebasing we need to compare old and new backing file */
1385 if (unsafe) {
1386 /* Make the compiler happy */
1387 bs_old_backing = NULL;
1388 bs_new_backing = NULL;
1389 } else {
1390 char backing_name[1024];
1391
1392 bs_old_backing = bdrv_new("old_backing");
1393 bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001394 ret = bdrv_open(bs_old_backing, backing_name, BDRV_O_FLAGS,
1395 old_backing_drv);
1396 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001397 error_report("Could not open old backing file '%s'", backing_name);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001398 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001399 }
1400
1401 bs_new_backing = bdrv_new("new_backing");
Kevin Wolfcdbae852010-08-17 18:58:55 +02001402 ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS,
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001403 new_backing_drv);
1404 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001405 error_report("Could not open new backing file '%s'", out_baseimg);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001406 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001407 }
1408 }
1409
1410 /*
1411 * Check each unallocated cluster in the COW file. If it is unallocated,
1412 * accesses go to the backing file. We must therefore compare this cluster
1413 * in the old and new backing file, and if they differ we need to copy it
1414 * from the old backing file into the COW file.
1415 *
1416 * If qemu-img crashes during this step, no harm is done. The content of
1417 * the image is the same as the original one at any time.
1418 */
1419 if (!unsafe) {
1420 uint64_t num_sectors;
1421 uint64_t sector;
Kevin Wolfcc60e322010-04-29 14:47:48 +02001422 int n;
TeLeMand6771bf2010-02-08 16:20:00 +08001423 uint8_t * buf_old;
1424 uint8_t * buf_new;
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001425 float local_progress;
TeLeMand6771bf2010-02-08 16:20:00 +08001426
Kevin Wolfbb1c0592011-08-08 14:09:12 +02001427 buf_old = qemu_blockalign(bs, IO_BUF_SIZE);
1428 buf_new = qemu_blockalign(bs, IO_BUF_SIZE);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001429
1430 bdrv_get_geometry(bs, &num_sectors);
1431
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001432 local_progress = (float)100 /
Jes Sorensen4ee96412011-05-06 11:39:11 +02001433 (num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512));
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001434 for (sector = 0; sector < num_sectors; sector += n) {
1435
1436 /* How many sectors can we handle with the next read? */
1437 if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
1438 n = (IO_BUF_SIZE / 512);
1439 } else {
1440 n = num_sectors - sector;
1441 }
1442
1443 /* If the cluster is allocated, we don't need to take action */
Kevin Wolfcc60e322010-04-29 14:47:48 +02001444 ret = bdrv_is_allocated(bs, sector, n, &n);
1445 if (ret) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001446 continue;
1447 }
1448
1449 /* Read old and new backing file */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001450 ret = bdrv_read(bs_old_backing, sector, buf_old, n);
1451 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001452 error_report("error while reading from old backing file");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001453 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001454 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001455 ret = bdrv_read(bs_new_backing, sector, buf_new, n);
1456 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001457 error_report("error while reading from new backing file");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001458 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001459 }
1460
1461 /* If they differ, we need to write to the COW file */
1462 uint64_t written = 0;
1463
1464 while (written < n) {
1465 int pnum;
1466
1467 if (compare_sectors(buf_old + written * 512,
Kevin Wolf60b1bd42010-02-17 12:32:59 +01001468 buf_new + written * 512, n - written, &pnum))
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001469 {
1470 ret = bdrv_write(bs, sector + written,
1471 buf_old + written * 512, pnum);
1472 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001473 error_report("Error while writing to COW image: %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001474 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001475 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001476 }
1477 }
1478
1479 written += pnum;
1480 }
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001481 qemu_progress_print(local_progress, 100);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001482 }
TeLeMand6771bf2010-02-08 16:20:00 +08001483
Kevin Wolfbb1c0592011-08-08 14:09:12 +02001484 qemu_vfree(buf_old);
1485 qemu_vfree(buf_new);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001486 }
1487
1488 /*
1489 * Change the backing file. All clusters that are different from the old
1490 * backing file are overwritten in the COW file now, so the visible content
1491 * doesn't change when we switch the backing file.
1492 */
1493 ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
1494 if (ret == -ENOSPC) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001495 error_report("Could not change the backing file to '%s': No "
1496 "space left in the file header", out_baseimg);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001497 } else if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001498 error_report("Could not change the backing file to '%s': %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001499 out_baseimg, strerror(-ret));
1500 }
1501
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001502 qemu_progress_print(100, 0);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001503 /*
1504 * TODO At this point it is possible to check if any clusters that are
1505 * allocated in the COW file are the same in the backing file. If so, they
1506 * could be dropped from the COW file. Don't do this before switching the
1507 * backing file, in case of a crash this would lead to corruption.
1508 */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001509out:
Jes Sorensen6b837bc2011-03-30 14:16:25 +02001510 qemu_progress_end();
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001511 /* Cleanup */
1512 if (!unsafe) {
Kevin Wolfeb863ad2011-03-31 12:39:51 +02001513 if (bs_old_backing != NULL) {
1514 bdrv_delete(bs_old_backing);
1515 }
1516 if (bs_new_backing != NULL) {
1517 bdrv_delete(bs_new_backing);
1518 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001519 }
1520
1521 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001522 if (ret) {
1523 return 1;
1524 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001525 return 0;
1526}
1527
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001528static int img_resize(int argc, char **argv)
1529{
1530 int c, ret, relative;
1531 const char *filename, *fmt, *size;
1532 int64_t n, total_size;
Jes Sorensen2a819982010-12-06 17:08:31 +01001533 BlockDriverState *bs = NULL;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001534 QEMUOptionParameter *param;
1535 QEMUOptionParameter resize_options[] = {
1536 {
1537 .name = BLOCK_OPT_SIZE,
1538 .type = OPT_SIZE,
1539 .help = "Virtual disk size"
1540 },
1541 { NULL }
1542 };
1543
Kevin Wolfe80fec72011-04-29 10:58:12 +02001544 /* Remove size from argv manually so that negative numbers are not treated
1545 * as options by getopt. */
1546 if (argc < 3) {
1547 help();
1548 return 1;
1549 }
1550
1551 size = argv[--argc];
1552
1553 /* Parse getopt arguments */
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001554 fmt = NULL;
1555 for(;;) {
1556 c = getopt(argc, argv, "f:h");
1557 if (c == -1) {
1558 break;
1559 }
1560 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001561 case '?':
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001562 case 'h':
1563 help();
1564 break;
1565 case 'f':
1566 fmt = optarg;
1567 break;
1568 }
1569 }
Kevin Wolfe80fec72011-04-29 10:58:12 +02001570 if (optind >= argc) {
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001571 help();
1572 }
1573 filename = argv[optind++];
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001574
1575 /* Choose grow, shrink, or absolute resize mode */
1576 switch (size[0]) {
1577 case '+':
1578 relative = 1;
1579 size++;
1580 break;
1581 case '-':
1582 relative = -1;
1583 size++;
1584 break;
1585 default:
1586 relative = 0;
1587 break;
1588 }
1589
1590 /* Parse size */
1591 param = parse_option_parameters("", resize_options, NULL);
1592 if (set_option_parameter(param, BLOCK_OPT_SIZE, size)) {
1593 /* Error message already printed when size parsing fails */
Jes Sorensen2a819982010-12-06 17:08:31 +01001594 ret = -1;
1595 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001596 }
1597 n = get_option_parameter(param, BLOCK_OPT_SIZE)->value.n;
1598 free_option_parameters(param);
1599
1600 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001601 if (!bs) {
Jes Sorensen2a819982010-12-06 17:08:31 +01001602 ret = -1;
1603 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001604 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001605
1606 if (relative) {
1607 total_size = bdrv_getlength(bs) + n * relative;
1608 } else {
1609 total_size = n;
1610 }
1611 if (total_size <= 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001612 error_report("New image size must be positive");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001613 ret = -1;
1614 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001615 }
1616
1617 ret = bdrv_truncate(bs, total_size);
1618 switch (ret) {
1619 case 0:
1620 printf("Image resized.\n");
1621 break;
1622 case -ENOTSUP:
Jes Sorensen15654a62010-12-16 14:31:53 +01001623 error_report("This image format does not support resize");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001624 break;
1625 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +01001626 error_report("Image is read-only");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001627 break;
1628 default:
Jes Sorensen15654a62010-12-16 14:31:53 +01001629 error_report("Error resizing image (%d)", -ret);
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001630 break;
1631 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001632out:
Jes Sorensen2a819982010-12-06 17:08:31 +01001633 if (bs) {
1634 bdrv_delete(bs);
1635 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001636 if (ret) {
1637 return 1;
1638 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001639 return 0;
1640}
1641
Anthony Liguoric227f092009-10-01 16:12:16 -05001642static const img_cmd_t img_cmds[] = {
Stuart Brady153859b2009-06-07 00:42:17 +01001643#define DEF(option, callback, arg_string) \
1644 { option, callback },
1645#include "qemu-img-cmds.h"
1646#undef DEF
1647#undef GEN_DOCS
1648 { NULL, NULL, },
1649};
1650
bellardea2384d2004-08-01 21:59:26 +00001651int main(int argc, char **argv)
1652{
Anthony Liguoric227f092009-10-01 16:12:16 -05001653 const img_cmd_t *cmd;
Stuart Brady153859b2009-06-07 00:42:17 +01001654 const char *cmdname;
bellardea2384d2004-08-01 21:59:26 +00001655
Kevin Wolf53f76e52010-12-16 15:10:32 +01001656 error_set_progname(argv[0]);
1657
bellardea2384d2004-08-01 21:59:26 +00001658 bdrv_init();
1659 if (argc < 2)
1660 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001661 cmdname = argv[1];
aurel328f9b1572009-02-09 18:14:31 +00001662 argc--; argv++;
Stuart Brady153859b2009-06-07 00:42:17 +01001663
1664 /* find the command */
1665 for(cmd = img_cmds; cmd->name != NULL; cmd++) {
1666 if (!strcmp(cmdname, cmd->name)) {
1667 return cmd->handler(argc, argv);
1668 }
bellardea2384d2004-08-01 21:59:26 +00001669 }
Stuart Brady153859b2009-06-07 00:42:17 +01001670
1671 /* not found */
1672 help();
bellardea2384d2004-08-01 21:59:26 +00001673 return 0;
1674}