blob: c5a173cb61a93e254d03ebc5619deac5fe9fafad [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"
aliguorif7b4a942009-01-07 17:40:15 +000026#include "osdep.h"
Jes Sorensendc786bc2010-10-26 10:39:23 +020027#include "sysemu.h"
thsec36ba12007-09-16 21:59:02 +000028#include "block_int.h"
aliguori9230eaf2009-03-28 17:55:19 +000029#include <stdio.h>
bellardea2384d2004-08-01 21:59:26 +000030
bellarde8445332006-06-14 15:32:10 +000031#ifdef _WIN32
32#include <windows.h>
33#endif
34
Anthony Liguoric227f092009-10-01 16:12:16 -050035typedef struct img_cmd_t {
Stuart Brady153859b2009-06-07 00:42:17 +010036 const char *name;
37 int (*handler)(int argc, char **argv);
Anthony Liguoric227f092009-10-01 16:12:16 -050038} img_cmd_t;
Stuart Brady153859b2009-06-07 00:42:17 +010039
aurel32137519c2008-11-30 19:12:49 +000040/* Default to cache=writeback as data integrity is not important for qemu-tcg. */
Stefan Hajnocziadfe0782010-04-13 10:29:35 +010041#define BDRV_O_FLAGS BDRV_O_CACHE_WB
aurel32137519c2008-11-30 19:12:49 +000042
Stefan Weil8b7968f2010-09-23 21:28:05 +020043static void GCC_FMT_ATTR(1, 2) error(const char *fmt, ...)
bellardea2384d2004-08-01 21:59:26 +000044{
45 va_list ap;
46 va_start(ap, fmt);
bellard57d1a2b2004-08-03 21:15:11 +000047 fprintf(stderr, "qemu-img: ");
bellardea2384d2004-08-01 21:59:26 +000048 vfprintf(stderr, fmt, ap);
49 fprintf(stderr, "\n");
bellardea2384d2004-08-01 21:59:26 +000050 va_end(ap);
51}
52
53static void format_print(void *opaque, const char *name)
54{
55 printf(" %s", name);
56}
57
blueswir1d2c639d2009-01-24 18:19:25 +000058/* Please keep in synch with qemu-img.texi */
pbrook3f379ab2007-11-11 03:33:13 +000059static void help(void)
bellardea2384d2004-08-01 21:59:26 +000060{
Paolo Bonzinie00291c2010-02-04 16:49:56 +010061 const char *help_msg =
62 "qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fabrice Bellard\n"
malc3f020d72010-02-08 12:04:56 +030063 "usage: qemu-img command [command options]\n"
64 "QEMU disk image utility\n"
65 "\n"
66 "Command syntax:\n"
Stuart Brady153859b2009-06-07 00:42:17 +010067#define DEF(option, callback, arg_string) \
68 " " arg_string "\n"
69#include "qemu-img-cmds.h"
70#undef DEF
71#undef GEN_DOCS
malc3f020d72010-02-08 12:04:56 +030072 "\n"
73 "Command parameters:\n"
74 " 'filename' is a disk image filename\n"
75 " 'fmt' is the disk image format. It is guessed automatically in most cases\n"
76 " 'size' is the disk image size in bytes. Optional suffixes\n"
77 " 'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M)\n"
78 " and T (terabyte, 1024G) are supported. 'b' is ignored.\n"
79 " 'output_filename' is the destination disk image filename\n"
80 " 'output_fmt' is the destination format\n"
81 " 'options' is a comma separated list of format specific options in a\n"
82 " name=value format. Use -o ? for an overview of the options supported by the\n"
83 " used format\n"
84 " '-c' indicates that target image must be compressed (qcow format only)\n"
85 " '-u' enables unsafe rebasing. It is assumed that old and new backing file\n"
86 " match exactly. The image doesn't need a working backing file before\n"
87 " rebasing in this case (useful for renaming the backing file)\n"
88 " '-h' with or without a command shows this help and lists the supported formats\n"
89 "\n"
90 "Parameters to snapshot subcommand:\n"
91 " 'snapshot' is the name of the snapshot to create, apply or delete\n"
92 " '-a' applies a snapshot (revert disk to saved state)\n"
93 " '-c' creates a snapshot\n"
94 " '-d' deletes a snapshot\n"
Paolo Bonzinie00291c2010-02-04 16:49:56 +010095 " '-l' lists all snapshots in the given image\n";
96
97 printf("%s\nSupported formats:", help_msg);
bellardea2384d2004-08-01 21:59:26 +000098 bdrv_iterate_format(format_print, NULL);
99 printf("\n");
100 exit(1);
101}
102
bellardea2384d2004-08-01 21:59:26 +0000103#if defined(WIN32)
104/* XXX: put correct support for win32 */
105static int read_password(char *buf, int buf_size)
106{
107 int c, i;
108 printf("Password: ");
109 fflush(stdout);
110 i = 0;
111 for(;;) {
112 c = getchar();
113 if (c == '\n')
114 break;
115 if (i < (buf_size - 1))
116 buf[i++] = c;
117 }
118 buf[i] = '\0';
119 return 0;
120}
121
122#else
123
124#include <termios.h>
125
126static struct termios oldtty;
127
128static void term_exit(void)
129{
130 tcsetattr (0, TCSANOW, &oldtty);
131}
132
133static void term_init(void)
134{
135 struct termios tty;
136
137 tcgetattr (0, &tty);
138 oldtty = tty;
139
140 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
141 |INLCR|IGNCR|ICRNL|IXON);
142 tty.c_oflag |= OPOST;
143 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
144 tty.c_cflag &= ~(CSIZE|PARENB);
145 tty.c_cflag |= CS8;
146 tty.c_cc[VMIN] = 1;
147 tty.c_cc[VTIME] = 0;
ths3b46e622007-09-17 08:09:54 +0000148
bellardea2384d2004-08-01 21:59:26 +0000149 tcsetattr (0, TCSANOW, &tty);
150
151 atexit(term_exit);
152}
153
pbrook3f379ab2007-11-11 03:33:13 +0000154static int read_password(char *buf, int buf_size)
bellardea2384d2004-08-01 21:59:26 +0000155{
156 uint8_t ch;
157 int i, ret;
158
159 printf("password: ");
160 fflush(stdout);
161 term_init();
162 i = 0;
163 for(;;) {
164 ret = read(0, &ch, 1);
165 if (ret == -1) {
166 if (errno == EAGAIN || errno == EINTR) {
167 continue;
168 } else {
169 ret = -1;
170 break;
171 }
172 } else if (ret == 0) {
173 ret = -1;
174 break;
175 } else {
176 if (ch == '\r') {
177 ret = 0;
178 break;
179 }
180 if (i < (buf_size - 1))
181 buf[i++] = ch;
182 }
183 }
184 term_exit();
185 buf[i] = '\0';
186 printf("\n");
187 return ret;
188}
189#endif
190
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100191static int print_block_option_help(const char *filename, const char *fmt)
192{
193 BlockDriver *drv, *proto_drv;
194 QEMUOptionParameter *create_options = NULL;
195
196 /* Find driver and parse its options */
197 drv = bdrv_find_format(fmt);
198 if (!drv) {
199 error("Unknown file format '%s'", fmt);
200 return 1;
201 }
202
203 proto_drv = bdrv_find_protocol(filename);
204 if (!proto_drv) {
205 error("Unknown protocol '%s'", filename);
206 return 1;
207 }
208
209 create_options = append_option_parameters(create_options,
210 drv->create_options);
211 create_options = append_option_parameters(create_options,
212 proto_drv->create_options);
213 print_option_help(create_options);
214 free_option_parameters(create_options);
215 return 0;
216}
217
bellard75c23802004-08-27 21:28:58 +0000218static BlockDriverState *bdrv_new_open(const char *filename,
Sheng Yang9bc378c2010-01-29 10:15:06 +0800219 const char *fmt,
Stefan Hajnoczif163d072010-04-13 10:29:34 +0100220 int flags)
bellard75c23802004-08-27 21:28:58 +0000221{
222 BlockDriverState *bs;
223 BlockDriver *drv;
224 char password[256];
225
226 bs = bdrv_new("");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900227 if (!bs) {
bellard75c23802004-08-27 21:28:58 +0000228 error("Not enough memory");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900229 goto fail;
230 }
bellard75c23802004-08-27 21:28:58 +0000231 if (fmt) {
232 drv = bdrv_find_format(fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900233 if (!drv) {
bellard75c23802004-08-27 21:28:58 +0000234 error("Unknown file format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900235 goto fail;
236 }
bellard75c23802004-08-27 21:28:58 +0000237 } else {
238 drv = NULL;
239 }
Kevin Wolfd6e90982010-03-31 14:40:27 +0200240 if (bdrv_open(bs, filename, flags, drv) < 0) {
bellard75c23802004-08-27 21:28:58 +0000241 error("Could not open '%s'", filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900242 goto fail;
bellard75c23802004-08-27 21:28:58 +0000243 }
244 if (bdrv_is_encrypted(bs)) {
245 printf("Disk image '%s' is encrypted.\n", filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900246 if (read_password(password, sizeof(password)) < 0) {
bellard75c23802004-08-27 21:28:58 +0000247 error("No password given");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900248 goto fail;
249 }
250 if (bdrv_set_key(bs, password) < 0) {
bellard75c23802004-08-27 21:28:58 +0000251 error("invalid password");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900252 goto fail;
253 }
bellard75c23802004-08-27 21:28:58 +0000254 }
255 return bs;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900256fail:
257 if (bs) {
258 bdrv_delete(bs);
259 }
260 return NULL;
bellard75c23802004-08-27 21:28:58 +0000261}
262
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900263static int add_old_style_options(const char *fmt, QEMUOptionParameter *list,
Jes Sorenseneec77d92010-12-07 17:44:34 +0100264 const char *base_filename,
265 const char *base_fmt)
Kevin Wolfefa84d42009-05-18 16:42:12 +0200266{
Kevin Wolfefa84d42009-05-18 16:42:12 +0200267 if (base_filename) {
268 if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) {
269 error("Backing file not supported for file format '%s'", 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)) {
275 error("Backing file format not supported for file format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900276 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200277 }
278 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900279 return 0;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200280}
281
bellardea2384d2004-08-01 21:59:26 +0000282static int img_create(int argc, char **argv)
283{
Jes Sorenseneec77d92010-12-07 17:44:34 +0100284 int c, ret = 0;
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;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900289 BlockDriver *drv, *proto_drv;
290 QEMUOptionParameter *param = NULL, *create_options = 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':
Jes Sorenseneec77d92010-12-07 17:44:34 +0100313 error("qemu-img: option -e is deprecated, please use \'-o "
314 "encryption\' instead!");
315 return 1;
thsd8871c52007-10-24 16:11:42 +0000316 case '6':
Jes Sorenseneec77d92010-12-07 17:44:34 +0100317 error("qemu-img: option -6 is deprecated, please use \'-o "
318 "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 Sorensen4ac8aac2010-12-06 15:25:38 +0100332 if (options && !strcmp(options, "?")) {
333 ret = print_block_option_help(filename, fmt);
334 goto out;
335 }
336
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200337 /* Find driver and parse its options */
bellardea2384d2004-08-01 21:59:26 +0000338 drv = bdrv_find_format(fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900339 if (!drv) {
bellardea2384d2004-08-01 21:59:26 +0000340 error("Unknown file format '%s'", fmt);
Jes Sorensen2a819982010-12-06 17:08:31 +0100341 ret = -1;
342 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900343 }
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200344
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900345 proto_drv = bdrv_find_protocol(filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900346 if (!proto_drv) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900347 error("Unknown protocol '%s'", filename);
Jes Sorensen2a819982010-12-06 17:08:31 +0100348 ret = -1;
349 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900350 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900351
352 create_options = append_option_parameters(create_options,
353 drv->create_options);
354 create_options = append_option_parameters(create_options,
355 proto_drv->create_options);
356
Kevin Wolf9f566402009-10-28 11:36:07 +0100357 /* Create parameter list with default values */
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900358 param = parse_option_parameters("", create_options, param);
Kevin Wolf9f566402009-10-28 11:36:07 +0100359 set_option_parameter_int(param, BLOCK_OPT_SIZE, -1);
360
361 /* Parse -o options */
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200362 if (options) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900363 param = parse_option_parameters(options, create_options, param);
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200364 if (param == NULL) {
365 error("Invalid options for file format '%s'.", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900366 ret = -1;
367 goto out;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200368 }
bellard75c23802004-08-27 21:28:58 +0000369 }
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200370
371 /* Add size to parameters */
372 if (optind < argc) {
373 set_option_parameter(param, BLOCK_OPT_SIZE, argv[optind++]);
374 }
375
376 /* Add old-style options to parameters */
Jes Sorenseneec77d92010-12-07 17:44:34 +0100377 ret = add_old_style_options(fmt, param, base_filename, base_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900378 if (ret < 0) {
379 goto out;
380 }
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200381
382 // The size for the image must always be specified, with one exception:
383 // If we are using a backing file, we can obtain the size from there
Kevin Wolf9f566402009-10-28 11:36:07 +0100384 if (get_option_parameter(param, BLOCK_OPT_SIZE)->value.n == -1) {
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200385
386 QEMUOptionParameter *backing_file =
387 get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
388 QEMUOptionParameter *backing_fmt =
389 get_option_parameter(param, BLOCK_OPT_BACKING_FMT);
390
391 if (backing_file && backing_file->value.s) {
392 BlockDriverState *bs;
393 uint64_t size;
394 const char *fmt = NULL;
395 char buf[32];
396
397 if (backing_fmt && backing_fmt->value.s) {
398 if (bdrv_find_format(backing_fmt->value.s)) {
399 fmt = backing_fmt->value.s;
400 } else {
401 error("Unknown backing file format '%s'",
402 backing_fmt->value.s);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900403 ret = -1;
404 goto out;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200405 }
406 }
407
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100408 bs = bdrv_new_open(backing_file->value.s, fmt, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900409 if (!bs) {
410 ret = -1;
411 goto out;
412 }
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200413 bdrv_get_geometry(bs, &size);
414 size *= 512;
415 bdrv_delete(bs);
416
417 snprintf(buf, sizeof(buf), "%" PRId64, size);
418 set_option_parameter(param, BLOCK_OPT_SIZE, buf);
419 } else {
420 error("Image creation needs a size parameter");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900421 ret = -1;
422 goto out;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200423 }
424 }
425
426 printf("Formatting '%s', fmt=%s ", filename, fmt);
427 print_option_parameters(param);
428 puts("");
429
430 ret = bdrv_create(drv, filename, param);
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200431
bellardea2384d2004-08-01 21:59:26 +0000432 if (ret < 0) {
433 if (ret == -ENOTSUP) {
bellard3c565212004-09-29 21:29:14 +0000434 error("Formatting or formatting option not supported for file format '%s'", fmt);
aurel326e9ea0c2009-04-15 14:42:46 +0000435 } else if (ret == -EFBIG) {
436 error("The image size is too large for file format '%s'", fmt);
bellardea2384d2004-08-01 21:59:26 +0000437 } else {
Juan Quintela3e7896d2010-03-04 10:00:38 +0100438 error("%s: error while creating %s: %s", filename, fmt, strerror(-ret));
bellardea2384d2004-08-01 21:59:26 +0000439 }
440 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900441out:
Stefan Hajnoczia87a6722010-12-07 09:35:55 +0000442 free_option_parameters(create_options);
443 free_option_parameters(param);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900444 if (ret) {
445 return 1;
446 }
bellardea2384d2004-08-01 21:59:26 +0000447 return 0;
448}
449
Kevin Wolfe076f332010-06-29 11:43:13 +0200450/*
451 * Checks an image for consistency. Exit codes:
452 *
453 * 0 - Check completed, image is good
454 * 1 - Check not completed because of internal errors
455 * 2 - Check completed, image is corrupted
456 * 3 - Check completed, image has leaked clusters, but is good otherwise
457 */
aliguori15859692009-04-21 23:11:53 +0000458static int img_check(int argc, char **argv)
459{
460 int c, ret;
461 const char *filename, *fmt;
aliguori15859692009-04-21 23:11:53 +0000462 BlockDriverState *bs;
Kevin Wolfe076f332010-06-29 11:43:13 +0200463 BdrvCheckResult result;
aliguori15859692009-04-21 23:11:53 +0000464
465 fmt = NULL;
466 for(;;) {
467 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100468 if (c == -1) {
aliguori15859692009-04-21 23:11:53 +0000469 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100470 }
aliguori15859692009-04-21 23:11:53 +0000471 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100472 case '?':
aliguori15859692009-04-21 23:11:53 +0000473 case 'h':
474 help();
475 break;
476 case 'f':
477 fmt = optarg;
478 break;
479 }
480 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100481 if (optind >= argc) {
aliguori15859692009-04-21 23:11:53 +0000482 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100483 }
aliguori15859692009-04-21 23:11:53 +0000484 filename = argv[optind++];
485
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100486 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900487 if (!bs) {
488 return 1;
489 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200490 ret = bdrv_check(bs, &result);
491
492 if (ret == -ENOTSUP) {
aliguori15859692009-04-21 23:11:53 +0000493 error("This image format does not support checks");
Kevin Wolfe076f332010-06-29 11:43:13 +0200494 bdrv_delete(bs);
495 return 1;
496 }
497
498 if (!(result.corruptions || result.leaks || result.check_errors)) {
499 printf("No errors were found on the image.\n");
500 } else {
501 if (result.corruptions) {
502 printf("\n%d errors were found on the image.\n"
503 "Data may be corrupted, or further writes to the image "
504 "may corrupt it.\n",
505 result.corruptions);
aliguori15859692009-04-21 23:11:53 +0000506 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200507
508 if (result.leaks) {
509 printf("\n%d leaked clusters were found on the image.\n"
510 "This means waste of disk space, but no harm to data.\n",
511 result.leaks);
512 }
513
514 if (result.check_errors) {
515 printf("\n%d internal errors have occurred during the check.\n",
516 result.check_errors);
517 }
aliguori15859692009-04-21 23:11:53 +0000518 }
519
520 bdrv_delete(bs);
Kevin Wolfe076f332010-06-29 11:43:13 +0200521
522 if (ret < 0 || result.check_errors) {
523 printf("\nAn error has occurred during the check: %s\n"
524 "The check is not complete and may have missed error.\n",
525 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900526 return 1;
527 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200528
529 if (result.corruptions) {
530 return 2;
531 } else if (result.leaks) {
532 return 3;
533 } else {
534 return 0;
535 }
aliguori15859692009-04-21 23:11:53 +0000536}
537
bellardea2384d2004-08-01 21:59:26 +0000538static int img_commit(int argc, char **argv)
539{
540 int c, ret;
541 const char *filename, *fmt;
bellardea2384d2004-08-01 21:59:26 +0000542 BlockDriverState *bs;
543
544 fmt = NULL;
545 for(;;) {
546 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100547 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000548 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100549 }
bellardea2384d2004-08-01 21:59:26 +0000550 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100551 case '?':
bellardea2384d2004-08-01 21:59:26 +0000552 case 'h':
553 help();
554 break;
555 case 'f':
556 fmt = optarg;
557 break;
558 }
559 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100560 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +0000561 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100562 }
bellardea2384d2004-08-01 21:59:26 +0000563 filename = argv[optind++];
564
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100565 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900566 if (!bs) {
567 return 1;
568 }
bellardea2384d2004-08-01 21:59:26 +0000569 ret = bdrv_commit(bs);
570 switch(ret) {
571 case 0:
572 printf("Image committed.\n");
573 break;
574 case -ENOENT:
575 error("No disk inserted");
576 break;
577 case -EACCES:
578 error("Image is read-only");
579 break;
580 case -ENOTSUP:
581 error("Image is already committed");
582 break;
583 default:
584 error("Error while committing image");
585 break;
586 }
587
588 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900589 if (ret) {
590 return 1;
591 }
bellardea2384d2004-08-01 21:59:26 +0000592 return 0;
593}
594
595static int is_not_zero(const uint8_t *sector, int len)
596{
597 int i;
598 len >>= 2;
599 for(i = 0;i < len; i++) {
600 if (((uint32_t *)sector)[i] != 0)
601 return 1;
602 }
603 return 0;
604}
605
thsf58c7b32008-06-05 21:53:49 +0000606/*
607 * Returns true iff the first sector pointed to by 'buf' contains at least
608 * a non-NUL byte.
609 *
610 * 'pnum' is set to the number of sectors (including and immediately following
611 * the first one) that are known to be in the same allocated/unallocated state.
612 */
bellardea2384d2004-08-01 21:59:26 +0000613static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
614{
615 int v, i;
616
617 if (n <= 0) {
618 *pnum = 0;
619 return 0;
620 }
621 v = is_not_zero(buf, 512);
622 for(i = 1; i < n; i++) {
623 buf += 512;
624 if (v != is_not_zero(buf, 512))
625 break;
626 }
627 *pnum = i;
628 return v;
629}
630
Kevin Wolf3e85c6f2010-01-12 12:55:18 +0100631/*
632 * Compares two buffers sector by sector. Returns 0 if the first sector of both
633 * buffers matches, non-zero otherwise.
634 *
635 * pnum is set to the number of sectors (including and immediately following
636 * the first one) that are known to have the same comparison result
637 */
638static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
639 int *pnum)
640{
641 int res, i;
642
643 if (n <= 0) {
644 *pnum = 0;
645 return 0;
646 }
647
648 res = !!memcmp(buf1, buf2, 512);
649 for(i = 1; i < n; i++) {
650 buf1 += 512;
651 buf2 += 512;
652
653 if (!!memcmp(buf1, buf2, 512) != res) {
654 break;
655 }
656 }
657
658 *pnum = i;
659 return res;
660}
661
Kevin Wolf80ee15a2009-09-15 12:30:43 +0200662#define IO_BUF_SIZE (2 * 1024 * 1024)
bellardea2384d2004-08-01 21:59:26 +0000663
664static int img_convert(int argc, char **argv)
665{
Jes Sorenseneec77d92010-12-07 17:44:34 +0100666 int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;
thsf58c7b32008-06-05 21:53:49 +0000667 const char *fmt, *out_fmt, *out_baseimg, *out_filename;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900668 BlockDriver *drv, *proto_drv;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900669 BlockDriverState **bs = NULL, *out_bs = NULL;
ths96b8f132007-12-17 01:35:20 +0000670 int64_t total_sectors, nb_sectors, sector_num, bs_offset;
671 uint64_t bs_sectors;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900672 uint8_t * buf = NULL;
bellardea2384d2004-08-01 21:59:26 +0000673 const uint8_t *buf1;
bellardfaea38e2006-08-05 21:31:00 +0000674 BlockDriverInfo bdi;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900675 QEMUOptionParameter *param = NULL, *create_options = NULL;
Kevin Wolfa18953f2010-10-14 15:46:04 +0200676 QEMUOptionParameter *out_baseimg_param;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200677 char *options = NULL;
edison51ef6722010-09-21 19:58:41 -0700678 const char *snapshot_name = NULL;
bellardea2384d2004-08-01 21:59:26 +0000679
680 fmt = NULL;
681 out_fmt = "raw";
thsf58c7b32008-06-05 21:53:49 +0000682 out_baseimg = NULL;
Jes Sorenseneec77d92010-12-07 17:44:34 +0100683 compress = 0;
bellardea2384d2004-08-01 21:59:26 +0000684 for(;;) {
edison51ef6722010-09-21 19:58:41 -0700685 c = getopt(argc, argv, "f:O:B:s:hce6o:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100686 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000687 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100688 }
bellardea2384d2004-08-01 21:59:26 +0000689 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100690 case '?':
bellardea2384d2004-08-01 21:59:26 +0000691 case 'h':
692 help();
693 break;
694 case 'f':
695 fmt = optarg;
696 break;
697 case 'O':
698 out_fmt = optarg;
699 break;
thsf58c7b32008-06-05 21:53:49 +0000700 case 'B':
701 out_baseimg = optarg;
702 break;
bellardea2384d2004-08-01 21:59:26 +0000703 case 'c':
Jes Sorenseneec77d92010-12-07 17:44:34 +0100704 compress = 1;
bellardea2384d2004-08-01 21:59:26 +0000705 break;
706 case 'e':
Jes Sorenseneec77d92010-12-07 17:44:34 +0100707 error("qemu-img: option -e is deprecated, please use \'-o "
708 "encryption\' instead!");
709 return 1;
thsec36ba12007-09-16 21:59:02 +0000710 case '6':
Jes Sorenseneec77d92010-12-07 17:44:34 +0100711 error("qemu-img: option -6 is deprecated, please use \'-o "
712 "compat6\' instead!");
713 return 1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200714 case 'o':
715 options = optarg;
716 break;
edison51ef6722010-09-21 19:58:41 -0700717 case 's':
718 snapshot_name = optarg;
719 break;
bellardea2384d2004-08-01 21:59:26 +0000720 }
721 }
ths3b46e622007-09-17 08:09:54 +0000722
balrog926c2d22007-10-31 01:11:44 +0000723 bs_n = argc - optind - 1;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100724 if (bs_n < 1) {
725 help();
726 }
balrog926c2d22007-10-31 01:11:44 +0000727
728 out_filename = argv[argc - 1];
thsf58c7b32008-06-05 21:53:49 +0000729
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100730 if (options && !strcmp(options, "?")) {
731 ret = print_block_option_help(out_filename, out_fmt);
732 goto out;
733 }
734
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900735 if (bs_n > 1 && out_baseimg) {
thsf58c7b32008-06-05 21:53:49 +0000736 error("-B makes no sense when concatenating multiple input images");
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100737 ret = -1;
738 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900739 }
balrog926c2d22007-10-31 01:11:44 +0000740
Jes Sorensen5bdf61f2010-12-06 15:25:35 +0100741 bs = qemu_mallocz(bs_n * sizeof(BlockDriverState *));
balrog926c2d22007-10-31 01:11:44 +0000742
743 total_sectors = 0;
744 for (bs_i = 0; bs_i < bs_n; bs_i++) {
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100745 bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900746 if (!bs[bs_i]) {
balrog926c2d22007-10-31 01:11:44 +0000747 error("Could not open '%s'", argv[optind + bs_i]);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900748 ret = -1;
749 goto out;
750 }
balrog926c2d22007-10-31 01:11:44 +0000751 bdrv_get_geometry(bs[bs_i], &bs_sectors);
752 total_sectors += bs_sectors;
753 }
bellardea2384d2004-08-01 21:59:26 +0000754
edison51ef6722010-09-21 19:58:41 -0700755 if (snapshot_name != NULL) {
756 if (bs_n > 1) {
757 error("No support for concatenating multiple snapshot\n");
758 ret = -1;
759 goto out;
760 }
761 if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
762 error("Failed to load snapshot\n");
763 ret = -1;
764 goto out;
765 }
766 }
767
Kevin Wolfefa84d42009-05-18 16:42:12 +0200768 /* Find driver and parse its options */
bellardea2384d2004-08-01 21:59:26 +0000769 drv = bdrv_find_format(out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900770 if (!drv) {
thsd34dda52007-02-10 22:59:40 +0000771 error("Unknown file format '%s'", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900772 ret = -1;
773 goto out;
774 }
balrog926c2d22007-10-31 01:11:44 +0000775
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900776 proto_drv = bdrv_find_protocol(out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900777 if (!proto_drv) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900778 error("Unknown protocol '%s'", out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900779 ret = -1;
780 goto out;
781 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900782
783 create_options = append_option_parameters(create_options,
784 drv->create_options);
785 create_options = append_option_parameters(create_options,
786 proto_drv->create_options);
Kevin Wolfdb08adf2009-06-04 15:39:38 +0200787
Kevin Wolfefa84d42009-05-18 16:42:12 +0200788 if (options) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900789 param = parse_option_parameters(options, create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200790 if (param == NULL) {
791 error("Invalid options for file format '%s'.", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900792 ret = -1;
793 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200794 }
795 } else {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900796 param = parse_option_parameters("", create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200797 }
798
799 set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
Jes Sorenseneec77d92010-12-07 17:44:34 +0100800 ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900801 if (ret < 0) {
802 goto out;
803 }
Kevin Wolfefa84d42009-05-18 16:42:12 +0200804
Kevin Wolfa18953f2010-10-14 15:46:04 +0200805 /* Get backing file name if -o backing_file was used */
806 out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
807 if (out_baseimg_param) {
808 out_baseimg = out_baseimg_param->value.s;
809 }
810
Kevin Wolfefa84d42009-05-18 16:42:12 +0200811 /* Check if compression is supported */
Jes Sorenseneec77d92010-12-07 17:44:34 +0100812 if (compress) {
Kevin Wolfefa84d42009-05-18 16:42:12 +0200813 QEMUOptionParameter *encryption =
814 get_option_parameter(param, BLOCK_OPT_ENCRYPT);
815
816 if (!drv->bdrv_write_compressed) {
817 error("Compression not supported for this file format");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900818 ret = -1;
819 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200820 }
821
822 if (encryption && encryption->value.n) {
823 error("Compression and encryption not supported at the same time");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900824 ret = -1;
825 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200826 }
827 }
828
829 /* Create the new image */
830 ret = bdrv_create(drv, out_filename, param);
bellardea2384d2004-08-01 21:59:26 +0000831 if (ret < 0) {
832 if (ret == -ENOTSUP) {
aliguori93c65b42009-04-05 17:40:43 +0000833 error("Formatting not supported for file format '%s'", out_fmt);
aurel326e9ea0c2009-04-15 14:42:46 +0000834 } else if (ret == -EFBIG) {
835 error("The image size is too large for file format '%s'", out_fmt);
bellardea2384d2004-08-01 21:59:26 +0000836 } else {
Juan Quintela3e7896d2010-03-04 10:00:38 +0100837 error("%s: error while converting %s: %s", out_filename, out_fmt, strerror(-ret));
bellardea2384d2004-08-01 21:59:26 +0000838 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900839 goto out;
bellardea2384d2004-08-01 21:59:26 +0000840 }
ths3b46e622007-09-17 08:09:54 +0000841
Kevin Wolf1bd8e172010-08-31 13:44:25 +0200842 out_bs = bdrv_new_open(out_filename, out_fmt,
843 BDRV_O_FLAGS | BDRV_O_RDWR | BDRV_O_NO_FLUSH);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900844 if (!out_bs) {
845 ret = -1;
846 goto out;
847 }
bellardea2384d2004-08-01 21:59:26 +0000848
balrog926c2d22007-10-31 01:11:44 +0000849 bs_i = 0;
850 bs_offset = 0;
851 bdrv_get_geometry(bs[0], &bs_sectors);
TeLeMand6771bf2010-02-08 16:20:00 +0800852 buf = qemu_malloc(IO_BUF_SIZE);
balrog926c2d22007-10-31 01:11:44 +0000853
Jes Sorenseneec77d92010-12-07 17:44:34 +0100854 if (compress) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900855 ret = bdrv_get_info(out_bs, &bdi);
856 if (ret < 0) {
bellardfaea38e2006-08-05 21:31:00 +0000857 error("could not get block driver info");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900858 goto out;
859 }
bellardfaea38e2006-08-05 21:31:00 +0000860 cluster_size = bdi.cluster_size;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900861 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
bellardea2384d2004-08-01 21:59:26 +0000862 error("invalid cluster size");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900863 ret = -1;
864 goto out;
865 }
bellardea2384d2004-08-01 21:59:26 +0000866 cluster_sectors = cluster_size >> 9;
867 sector_num = 0;
868 for(;;) {
balrog926c2d22007-10-31 01:11:44 +0000869 int64_t bs_num;
870 int remainder;
871 uint8_t *buf2;
872
bellardea2384d2004-08-01 21:59:26 +0000873 nb_sectors = total_sectors - sector_num;
874 if (nb_sectors <= 0)
875 break;
876 if (nb_sectors >= cluster_sectors)
877 n = cluster_sectors;
878 else
879 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000880
881 bs_num = sector_num - bs_offset;
882 assert (bs_num >= 0);
883 remainder = n;
884 buf2 = buf;
885 while (remainder > 0) {
886 int nlow;
887 while (bs_num == bs_sectors) {
888 bs_i++;
889 assert (bs_i < bs_n);
890 bs_offset += bs_sectors;
891 bdrv_get_geometry(bs[bs_i], &bs_sectors);
892 bs_num = 0;
Blue Swirl0bfcd592010-05-22 08:02:12 +0000893 /* printf("changing part: sector_num=%" PRId64 ", "
894 "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64
895 "\n", sector_num, bs_i, bs_offset, bs_sectors); */
balrog926c2d22007-10-31 01:11:44 +0000896 }
897 assert (bs_num < bs_sectors);
898
899 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
900
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900901 ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
902 if (ret < 0) {
balrog926c2d22007-10-31 01:11:44 +0000903 error("error while reading");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900904 goto out;
905 }
balrog926c2d22007-10-31 01:11:44 +0000906
907 buf2 += nlow * 512;
908 bs_num += nlow;
909
910 remainder -= nlow;
911 }
912 assert (remainder == 0);
913
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100914 if (n < cluster_sectors) {
bellardea2384d2004-08-01 21:59:26 +0000915 memset(buf + n * 512, 0, cluster_size - n * 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100916 }
bellardea2384d2004-08-01 21:59:26 +0000917 if (is_not_zero(buf, cluster_size)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900918 ret = bdrv_write_compressed(out_bs, sector_num, buf,
919 cluster_sectors);
920 if (ret != 0) {
bellardec3757d2006-06-14 15:50:07 +0000921 error("error while compressing sector %" PRId64,
922 sector_num);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900923 goto out;
924 }
bellardea2384d2004-08-01 21:59:26 +0000925 }
926 sector_num += n;
927 }
bellardfaea38e2006-08-05 21:31:00 +0000928 /* signal EOF to align */
929 bdrv_write_compressed(out_bs, 0, NULL, 0);
bellardea2384d2004-08-01 21:59:26 +0000930 } else {
Kevin Wolff2feebb2010-04-14 17:30:35 +0200931 int has_zero_init = bdrv_has_zero_init(out_bs);
932
thsf58c7b32008-06-05 21:53:49 +0000933 sector_num = 0; // total number of sectors converted so far
bellardea2384d2004-08-01 21:59:26 +0000934 for(;;) {
935 nb_sectors = total_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100936 if (nb_sectors <= 0) {
bellardea2384d2004-08-01 21:59:26 +0000937 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100938 }
939 if (nb_sectors >= (IO_BUF_SIZE / 512)) {
bellardea2384d2004-08-01 21:59:26 +0000940 n = (IO_BUF_SIZE / 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100941 } else {
bellardea2384d2004-08-01 21:59:26 +0000942 n = nb_sectors;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100943 }
balrog926c2d22007-10-31 01:11:44 +0000944
945 while (sector_num - bs_offset >= bs_sectors) {
946 bs_i ++;
947 assert (bs_i < bs_n);
948 bs_offset += bs_sectors;
949 bdrv_get_geometry(bs[bs_i], &bs_sectors);
Blue Swirl0bfcd592010-05-22 08:02:12 +0000950 /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "
951 "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",
balrog926c2d22007-10-31 01:11:44 +0000952 sector_num, bs_i, bs_offset, bs_sectors); */
953 }
954
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100955 if (n > bs_offset + bs_sectors - sector_num) {
balrog926c2d22007-10-31 01:11:44 +0000956 n = bs_offset + bs_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100957 }
balrog926c2d22007-10-31 01:11:44 +0000958
Kevin Wolff2feebb2010-04-14 17:30:35 +0200959 if (has_zero_init) {
Akkarit Sangpetchd0320442009-07-17 10:02:15 +0200960 /* If the output image is being created as a copy on write image,
961 assume that sectors which are unallocated in the input image
962 are present in both the output's and input's base images (no
963 need to copy them). */
964 if (out_baseimg) {
965 if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
966 n, &n1)) {
967 sector_num += n1;
968 continue;
969 }
970 /* The next 'n1' sectors are allocated in the input image. Copy
971 only those as they may be followed by unallocated sectors. */
972 n = n1;
aliguori93c65b42009-04-05 17:40:43 +0000973 }
aliguori93c65b42009-04-05 17:40:43 +0000974 } else {
975 n1 = n;
thsf58c7b32008-06-05 21:53:49 +0000976 }
977
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900978 ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
979 if (ret < 0) {
bellardea2384d2004-08-01 21:59:26 +0000980 error("error while reading");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900981 goto out;
982 }
bellardea2384d2004-08-01 21:59:26 +0000983 /* NOTE: at the same time we convert, we do not write zero
984 sectors to have a chance to compress the image. Ideally, we
985 should add a specific call to have the info to go faster */
986 buf1 = buf;
987 while (n > 0) {
thsf58c7b32008-06-05 21:53:49 +0000988 /* If the output image is being created as a copy on write image,
989 copy all sectors even the ones containing only NUL bytes,
aliguori93c65b42009-04-05 17:40:43 +0000990 because they may differ from the sectors in the base image.
991
992 If the output is to a host device, we also write out
993 sectors that are entirely 0, since whatever data was
994 already there is garbage, not 0s. */
Kevin Wolff2feebb2010-04-14 17:30:35 +0200995 if (!has_zero_init || out_baseimg ||
aliguori93c65b42009-04-05 17:40:43 +0000996 is_allocated_sectors(buf1, n, &n1)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900997 ret = bdrv_write(out_bs, sector_num, buf1, n1);
998 if (ret < 0) {
bellardea2384d2004-08-01 21:59:26 +0000999 error("error while writing");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001000 goto out;
1001 }
bellardea2384d2004-08-01 21:59:26 +00001002 }
1003 sector_num += n1;
1004 n -= n1;
1005 buf1 += n1 * 512;
1006 }
1007 }
1008 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001009out:
1010 free_option_parameters(create_options);
1011 free_option_parameters(param);
TeLeMand6771bf2010-02-08 16:20:00 +08001012 qemu_free(buf);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001013 if (out_bs) {
1014 bdrv_delete(out_bs);
1015 }
Jes Sorensen31ca34b2010-12-06 15:25:36 +01001016 if (bs) {
1017 for (bs_i = 0; bs_i < bs_n; bs_i++) {
1018 if (bs[bs_i]) {
1019 bdrv_delete(bs[bs_i]);
1020 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001021 }
Jes Sorensen31ca34b2010-12-06 15:25:36 +01001022 qemu_free(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001023 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001024 if (ret) {
1025 return 1;
1026 }
bellardea2384d2004-08-01 21:59:26 +00001027 return 0;
1028}
1029
bellard57d1a2b2004-08-03 21:15:11 +00001030#ifdef _WIN32
1031static int64_t get_allocated_file_size(const char *filename)
1032{
bellarde8445332006-06-14 15:32:10 +00001033 typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
1034 get_compressed_t get_compressed;
bellard57d1a2b2004-08-03 21:15:11 +00001035 struct _stati64 st;
bellarde8445332006-06-14 15:32:10 +00001036
1037 /* WinNT support GetCompressedFileSize to determine allocate size */
1038 get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
1039 if (get_compressed) {
1040 DWORD high, low;
1041 low = get_compressed(filename, &high);
1042 if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
1043 return (((int64_t) high) << 32) + low;
1044 }
1045
ths5fafdf22007-09-16 21:08:06 +00001046 if (_stati64(filename, &st) < 0)
bellard57d1a2b2004-08-03 21:15:11 +00001047 return -1;
1048 return st.st_size;
1049}
1050#else
1051static int64_t get_allocated_file_size(const char *filename)
1052{
1053 struct stat st;
ths5fafdf22007-09-16 21:08:06 +00001054 if (stat(filename, &st) < 0)
bellard57d1a2b2004-08-03 21:15:11 +00001055 return -1;
1056 return (int64_t)st.st_blocks * 512;
1057}
1058#endif
1059
bellardfaea38e2006-08-05 21:31:00 +00001060static void dump_snapshots(BlockDriverState *bs)
1061{
1062 QEMUSnapshotInfo *sn_tab, *sn;
1063 int nb_sns, i;
1064 char buf[256];
1065
1066 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1067 if (nb_sns <= 0)
1068 return;
1069 printf("Snapshot list:\n");
1070 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
1071 for(i = 0; i < nb_sns; i++) {
1072 sn = &sn_tab[i];
1073 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
1074 }
1075 qemu_free(sn_tab);
1076}
1077
bellardea2384d2004-08-01 21:59:26 +00001078static int img_info(int argc, char **argv)
1079{
1080 int c;
1081 const char *filename, *fmt;
bellardea2384d2004-08-01 21:59:26 +00001082 BlockDriverState *bs;
1083 char fmt_name[128], size_buf[128], dsize_buf[128];
ths96b8f132007-12-17 01:35:20 +00001084 uint64_t total_sectors;
1085 int64_t allocated_size;
bellard93b6b2a2006-08-01 15:51:11 +00001086 char backing_filename[1024];
1087 char backing_filename2[1024];
bellardfaea38e2006-08-05 21:31:00 +00001088 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +00001089
1090 fmt = NULL;
1091 for(;;) {
1092 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001093 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +00001094 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001095 }
bellardea2384d2004-08-01 21:59:26 +00001096 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001097 case '?':
bellardea2384d2004-08-01 21:59:26 +00001098 case 'h':
1099 help();
1100 break;
1101 case 'f':
1102 fmt = optarg;
1103 break;
1104 }
1105 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001106 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +00001107 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001108 }
bellardea2384d2004-08-01 21:59:26 +00001109 filename = argv[optind++];
1110
Stefan Hajnocziadfe0782010-04-13 10:29:35 +01001111 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001112 if (!bs) {
1113 return 1;
1114 }
bellardea2384d2004-08-01 21:59:26 +00001115 bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
1116 bdrv_get_geometry(bs, &total_sectors);
1117 get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
bellard57d1a2b2004-08-03 21:15:11 +00001118 allocated_size = get_allocated_file_size(filename);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001119 if (allocated_size < 0) {
blueswir1a10ea302008-08-24 10:30:33 +00001120 snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001121 } else {
ths5fafdf22007-09-16 21:08:06 +00001122 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
bellardde167e42005-04-28 21:15:08 +00001123 allocated_size);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001124 }
bellardea2384d2004-08-01 21:59:26 +00001125 printf("image: %s\n"
1126 "file format: %s\n"
bellardec3757d2006-06-14 15:50:07 +00001127 "virtual size: %s (%" PRId64 " bytes)\n"
bellardea2384d2004-08-01 21:59:26 +00001128 "disk size: %s\n",
ths5fafdf22007-09-16 21:08:06 +00001129 filename, fmt_name, size_buf,
bellardec3757d2006-06-14 15:50:07 +00001130 (total_sectors * 512),
bellardea2384d2004-08-01 21:59:26 +00001131 dsize_buf);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001132 if (bdrv_is_encrypted(bs)) {
bellardea2384d2004-08-01 21:59:26 +00001133 printf("encrypted: yes\n");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001134 }
bellardfaea38e2006-08-05 21:31:00 +00001135 if (bdrv_get_info(bs, &bdi) >= 0) {
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001136 if (bdi.cluster_size != 0) {
bellardfaea38e2006-08-05 21:31:00 +00001137 printf("cluster_size: %d\n", bdi.cluster_size);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001138 }
bellardfaea38e2006-08-05 21:31:00 +00001139 }
bellard93b6b2a2006-08-01 15:51:11 +00001140 bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
bellardfaea38e2006-08-05 21:31:00 +00001141 if (backing_filename[0] != '\0') {
bellard93b6b2a2006-08-01 15:51:11 +00001142 path_combine(backing_filename2, sizeof(backing_filename2),
1143 filename, backing_filename);
ths5fafdf22007-09-16 21:08:06 +00001144 printf("backing file: %s (actual path: %s)\n",
bellard93b6b2a2006-08-01 15:51:11 +00001145 backing_filename,
1146 backing_filename2);
bellardfaea38e2006-08-05 21:31:00 +00001147 }
1148 dump_snapshots(bs);
bellardea2384d2004-08-01 21:59:26 +00001149 bdrv_delete(bs);
1150 return 0;
1151}
1152
aliguorif7b4a942009-01-07 17:40:15 +00001153#define SNAPSHOT_LIST 1
1154#define SNAPSHOT_CREATE 2
1155#define SNAPSHOT_APPLY 3
1156#define SNAPSHOT_DELETE 4
1157
Stuart Brady153859b2009-06-07 00:42:17 +01001158static int img_snapshot(int argc, char **argv)
aliguorif7b4a942009-01-07 17:40:15 +00001159{
1160 BlockDriverState *bs;
1161 QEMUSnapshotInfo sn;
1162 char *filename, *snapshot_name = NULL;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001163 int c, ret = 0, bdrv_oflags;
aliguorif7b4a942009-01-07 17:40:15 +00001164 int action = 0;
1165 qemu_timeval tv;
1166
Naphtali Spreif5edb012010-01-17 16:48:13 +02001167 bdrv_oflags = BDRV_O_RDWR;
aliguorif7b4a942009-01-07 17:40:15 +00001168 /* Parse commandline parameters */
1169 for(;;) {
1170 c = getopt(argc, argv, "la:c:d:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001171 if (c == -1) {
aliguorif7b4a942009-01-07 17:40:15 +00001172 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001173 }
aliguorif7b4a942009-01-07 17:40:15 +00001174 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001175 case '?':
aliguorif7b4a942009-01-07 17:40:15 +00001176 case 'h':
1177 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001178 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001179 case 'l':
1180 if (action) {
1181 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001182 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001183 }
1184 action = SNAPSHOT_LIST;
Naphtali Spreif5edb012010-01-17 16:48:13 +02001185 bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
aliguorif7b4a942009-01-07 17:40:15 +00001186 break;
1187 case 'a':
1188 if (action) {
1189 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001190 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001191 }
1192 action = SNAPSHOT_APPLY;
1193 snapshot_name = optarg;
1194 break;
1195 case 'c':
1196 if (action) {
1197 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001198 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001199 }
1200 action = SNAPSHOT_CREATE;
1201 snapshot_name = optarg;
1202 break;
1203 case 'd':
1204 if (action) {
1205 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001206 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001207 }
1208 action = SNAPSHOT_DELETE;
1209 snapshot_name = optarg;
1210 break;
1211 }
1212 }
1213
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001214 if (optind >= argc) {
aliguorif7b4a942009-01-07 17:40:15 +00001215 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001216 }
aliguorif7b4a942009-01-07 17:40:15 +00001217 filename = argv[optind++];
1218
1219 /* Open the image */
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001220 bs = bdrv_new_open(filename, NULL, bdrv_oflags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001221 if (!bs) {
1222 return 1;
1223 }
aliguorif7b4a942009-01-07 17:40:15 +00001224
1225 /* Perform the requested action */
1226 switch(action) {
1227 case SNAPSHOT_LIST:
1228 dump_snapshots(bs);
1229 break;
1230
1231 case SNAPSHOT_CREATE:
1232 memset(&sn, 0, sizeof(sn));
1233 pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
1234
1235 qemu_gettimeofday(&tv);
1236 sn.date_sec = tv.tv_sec;
1237 sn.date_nsec = tv.tv_usec * 1000;
1238
1239 ret = bdrv_snapshot_create(bs, &sn);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001240 if (ret) {
aliguorif7b4a942009-01-07 17:40:15 +00001241 error("Could not create snapshot '%s': %d (%s)",
1242 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001243 }
aliguorif7b4a942009-01-07 17:40:15 +00001244 break;
1245
1246 case SNAPSHOT_APPLY:
1247 ret = bdrv_snapshot_goto(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001248 if (ret) {
aliguorif7b4a942009-01-07 17:40:15 +00001249 error("Could not apply snapshot '%s': %d (%s)",
1250 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001251 }
aliguorif7b4a942009-01-07 17:40:15 +00001252 break;
1253
1254 case SNAPSHOT_DELETE:
1255 ret = bdrv_snapshot_delete(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001256 if (ret) {
aliguorif7b4a942009-01-07 17:40:15 +00001257 error("Could not delete snapshot '%s': %d (%s)",
1258 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001259 }
aliguorif7b4a942009-01-07 17:40:15 +00001260 break;
1261 }
1262
1263 /* Cleanup */
1264 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001265 if (ret) {
1266 return 1;
1267 }
Stuart Brady153859b2009-06-07 00:42:17 +01001268 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001269}
1270
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001271static int img_rebase(int argc, char **argv)
1272{
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001273 BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001274 BlockDriver *old_backing_drv, *new_backing_drv;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001275 char *filename;
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001276 const char *fmt, *out_basefmt, *out_baseimg;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001277 int c, flags, ret;
1278 int unsafe = 0;
1279
1280 /* Parse commandline parameters */
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001281 fmt = NULL;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001282 out_baseimg = NULL;
1283 out_basefmt = NULL;
1284
1285 for(;;) {
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001286 c = getopt(argc, argv, "uhf:F:b:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001287 if (c == -1) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001288 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001289 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001290 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001291 case '?':
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001292 case 'h':
1293 help();
1294 return 0;
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001295 case 'f':
1296 fmt = optarg;
1297 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001298 case 'F':
1299 out_basefmt = optarg;
1300 break;
1301 case 'b':
1302 out_baseimg = optarg;
1303 break;
1304 case 'u':
1305 unsafe = 1;
1306 break;
1307 }
1308 }
1309
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001310 if ((optind >= argc) || !out_baseimg) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001311 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001312 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001313 filename = argv[optind++];
1314
1315 /*
1316 * Open the images.
1317 *
1318 * Ignore the old backing file for unsafe rebase in case we want to correct
1319 * the reference to a renamed or moved backing file.
1320 */
Stefan Hajnocziadfe0782010-04-13 10:29:35 +01001321 flags = BDRV_O_FLAGS | BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001322 bs = bdrv_new_open(filename, fmt, flags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001323 if (!bs) {
1324 return 1;
1325 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001326
1327 /* Find the right drivers for the backing files */
1328 old_backing_drv = NULL;
1329 new_backing_drv = NULL;
1330
1331 if (!unsafe && bs->backing_format[0] != '\0') {
1332 old_backing_drv = bdrv_find_format(bs->backing_format);
1333 if (old_backing_drv == NULL) {
1334 error("Invalid format name: '%s'", bs->backing_format);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001335 ret = -1;
1336 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001337 }
1338 }
1339
1340 if (out_basefmt != NULL) {
1341 new_backing_drv = bdrv_find_format(out_basefmt);
1342 if (new_backing_drv == NULL) {
1343 error("Invalid format name: '%s'", out_basefmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001344 ret = -1;
1345 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001346 }
1347 }
1348
1349 /* For safe rebasing we need to compare old and new backing file */
1350 if (unsafe) {
1351 /* Make the compiler happy */
1352 bs_old_backing = NULL;
1353 bs_new_backing = NULL;
1354 } else {
1355 char backing_name[1024];
1356
1357 bs_old_backing = bdrv_new("old_backing");
1358 bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001359 ret = bdrv_open(bs_old_backing, backing_name, BDRV_O_FLAGS,
1360 old_backing_drv);
1361 if (ret) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001362 error("Could not open old backing file '%s'", backing_name);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001363 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001364 }
1365
1366 bs_new_backing = bdrv_new("new_backing");
Kevin Wolfcdbae852010-08-17 18:58:55 +02001367 ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS,
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001368 new_backing_drv);
1369 if (ret) {
Kevin Wolf584771e2010-02-17 12:33:17 +01001370 error("Could not open new backing file '%s'", out_baseimg);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001371 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001372 }
1373 }
1374
1375 /*
1376 * Check each unallocated cluster in the COW file. If it is unallocated,
1377 * accesses go to the backing file. We must therefore compare this cluster
1378 * in the old and new backing file, and if they differ we need to copy it
1379 * from the old backing file into the COW file.
1380 *
1381 * If qemu-img crashes during this step, no harm is done. The content of
1382 * the image is the same as the original one at any time.
1383 */
1384 if (!unsafe) {
1385 uint64_t num_sectors;
1386 uint64_t sector;
Kevin Wolfcc60e322010-04-29 14:47:48 +02001387 int n;
TeLeMand6771bf2010-02-08 16:20:00 +08001388 uint8_t * buf_old;
1389 uint8_t * buf_new;
1390
1391 buf_old = qemu_malloc(IO_BUF_SIZE);
1392 buf_new = qemu_malloc(IO_BUF_SIZE);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001393
1394 bdrv_get_geometry(bs, &num_sectors);
1395
1396 for (sector = 0; sector < num_sectors; sector += n) {
1397
1398 /* How many sectors can we handle with the next read? */
1399 if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
1400 n = (IO_BUF_SIZE / 512);
1401 } else {
1402 n = num_sectors - sector;
1403 }
1404
1405 /* If the cluster is allocated, we don't need to take action */
Kevin Wolfcc60e322010-04-29 14:47:48 +02001406 ret = bdrv_is_allocated(bs, sector, n, &n);
1407 if (ret) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001408 continue;
1409 }
1410
1411 /* Read old and new backing file */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001412 ret = bdrv_read(bs_old_backing, sector, buf_old, n);
1413 if (ret < 0) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001414 error("error while reading from old backing file");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001415 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001416 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001417 ret = bdrv_read(bs_new_backing, sector, buf_new, n);
1418 if (ret < 0) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001419 error("error while reading from new backing file");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001420 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001421 }
1422
1423 /* If they differ, we need to write to the COW file */
1424 uint64_t written = 0;
1425
1426 while (written < n) {
1427 int pnum;
1428
1429 if (compare_sectors(buf_old + written * 512,
Kevin Wolf60b1bd42010-02-17 12:32:59 +01001430 buf_new + written * 512, n - written, &pnum))
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001431 {
1432 ret = bdrv_write(bs, sector + written,
1433 buf_old + written * 512, pnum);
1434 if (ret < 0) {
1435 error("Error while writing to COW image: %s",
1436 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001437 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001438 }
1439 }
1440
1441 written += pnum;
1442 }
1443 }
TeLeMand6771bf2010-02-08 16:20:00 +08001444
1445 qemu_free(buf_old);
1446 qemu_free(buf_new);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001447 }
1448
1449 /*
1450 * Change the backing file. All clusters that are different from the old
1451 * backing file are overwritten in the COW file now, so the visible content
1452 * doesn't change when we switch the backing file.
1453 */
1454 ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
1455 if (ret == -ENOSPC) {
1456 error("Could not change the backing file to '%s': No space left in "
1457 "the file header", out_baseimg);
1458 } else if (ret < 0) {
1459 error("Could not change the backing file to '%s': %s",
1460 out_baseimg, strerror(-ret));
1461 }
1462
1463 /*
1464 * TODO At this point it is possible to check if any clusters that are
1465 * allocated in the COW file are the same in the backing file. If so, they
1466 * could be dropped from the COW file. Don't do this before switching the
1467 * backing file, in case of a crash this would lead to corruption.
1468 */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001469out:
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001470 /* Cleanup */
1471 if (!unsafe) {
1472 bdrv_delete(bs_old_backing);
1473 bdrv_delete(bs_new_backing);
1474 }
1475
1476 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001477 if (ret) {
1478 return 1;
1479 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001480 return 0;
1481}
1482
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001483static int img_resize(int argc, char **argv)
1484{
1485 int c, ret, relative;
1486 const char *filename, *fmt, *size;
1487 int64_t n, total_size;
Jes Sorensen2a819982010-12-06 17:08:31 +01001488 BlockDriverState *bs = NULL;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001489 QEMUOptionParameter *param;
1490 QEMUOptionParameter resize_options[] = {
1491 {
1492 .name = BLOCK_OPT_SIZE,
1493 .type = OPT_SIZE,
1494 .help = "Virtual disk size"
1495 },
1496 { NULL }
1497 };
1498
1499 fmt = NULL;
1500 for(;;) {
1501 c = getopt(argc, argv, "f:h");
1502 if (c == -1) {
1503 break;
1504 }
1505 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001506 case '?':
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001507 case 'h':
1508 help();
1509 break;
1510 case 'f':
1511 fmt = optarg;
1512 break;
1513 }
1514 }
1515 if (optind + 1 >= argc) {
1516 help();
1517 }
1518 filename = argv[optind++];
1519 size = argv[optind++];
1520
1521 /* Choose grow, shrink, or absolute resize mode */
1522 switch (size[0]) {
1523 case '+':
1524 relative = 1;
1525 size++;
1526 break;
1527 case '-':
1528 relative = -1;
1529 size++;
1530 break;
1531 default:
1532 relative = 0;
1533 break;
1534 }
1535
1536 /* Parse size */
1537 param = parse_option_parameters("", resize_options, NULL);
1538 if (set_option_parameter(param, BLOCK_OPT_SIZE, size)) {
1539 /* Error message already printed when size parsing fails */
Jes Sorensen2a819982010-12-06 17:08:31 +01001540 ret = -1;
1541 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001542 }
1543 n = get_option_parameter(param, BLOCK_OPT_SIZE)->value.n;
1544 free_option_parameters(param);
1545
1546 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001547 if (!bs) {
Jes Sorensen2a819982010-12-06 17:08:31 +01001548 ret = -1;
1549 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001550 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001551
1552 if (relative) {
1553 total_size = bdrv_getlength(bs) + n * relative;
1554 } else {
1555 total_size = n;
1556 }
1557 if (total_size <= 0) {
1558 error("New image size must be positive");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001559 ret = -1;
1560 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001561 }
1562
1563 ret = bdrv_truncate(bs, total_size);
1564 switch (ret) {
1565 case 0:
1566 printf("Image resized.\n");
1567 break;
1568 case -ENOTSUP:
1569 error("This image format does not support resize");
1570 break;
1571 case -EACCES:
1572 error("Image is read-only");
1573 break;
1574 default:
1575 error("Error resizing image (%d)", -ret);
1576 break;
1577 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001578out:
Jes Sorensen2a819982010-12-06 17:08:31 +01001579 if (bs) {
1580 bdrv_delete(bs);
1581 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001582 if (ret) {
1583 return 1;
1584 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001585 return 0;
1586}
1587
Anthony Liguoric227f092009-10-01 16:12:16 -05001588static const img_cmd_t img_cmds[] = {
Stuart Brady153859b2009-06-07 00:42:17 +01001589#define DEF(option, callback, arg_string) \
1590 { option, callback },
1591#include "qemu-img-cmds.h"
1592#undef DEF
1593#undef GEN_DOCS
1594 { NULL, NULL, },
1595};
1596
bellardea2384d2004-08-01 21:59:26 +00001597int main(int argc, char **argv)
1598{
Anthony Liguoric227f092009-10-01 16:12:16 -05001599 const img_cmd_t *cmd;
Stuart Brady153859b2009-06-07 00:42:17 +01001600 const char *cmdname;
bellardea2384d2004-08-01 21:59:26 +00001601
1602 bdrv_init();
1603 if (argc < 2)
1604 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001605 cmdname = argv[1];
aurel328f9b1572009-02-09 18:14:31 +00001606 argc--; argv++;
Stuart Brady153859b2009-06-07 00:42:17 +01001607
1608 /* find the command */
1609 for(cmd = img_cmds; cmd->name != NULL; cmd++) {
1610 if (!strcmp(cmdname, cmd->name)) {
1611 return cmd->handler(argc, argv);
1612 }
bellardea2384d2004-08-01 21:59:26 +00001613 }
Stuart Brady153859b2009-06-07 00:42:17 +01001614
1615 /* not found */
1616 help();
bellardea2384d2004-08-01 21:59:26 +00001617 return 0;
1618}