blob: 6fd52e9e94278997635fe57208a0939ac8126a60 [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,
Kevin Wolfefa84d42009-05-18 16:42:12 +0200264 int flags, const char *base_filename, const char *base_fmt)
265{
266 if (flags & BLOCK_FLAG_ENCRYPT) {
267 if (set_option_parameter(list, BLOCK_OPT_ENCRYPT, "on")) {
268 error("Encryption not supported for file format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900269 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200270 }
271 }
272 if (flags & BLOCK_FLAG_COMPAT6) {
273 if (set_option_parameter(list, BLOCK_OPT_COMPAT6, "on")) {
274 error("VMDK version 6 not supported for file format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900275 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200276 }
277 }
278
279 if (base_filename) {
280 if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) {
281 error("Backing file not supported for file format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900282 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200283 }
284 }
285 if (base_fmt) {
286 if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {
287 error("Backing file format not supported for file format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900288 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200289 }
290 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900291 return 0;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200292}
293
bellardea2384d2004-08-01 21:59:26 +0000294static int img_create(int argc, char **argv)
295{
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900296 int c, ret = 0, flags;
bellardea2384d2004-08-01 21:59:26 +0000297 const char *fmt = "raw";
aliguori9230eaf2009-03-28 17:55:19 +0000298 const char *base_fmt = NULL;
bellardea2384d2004-08-01 21:59:26 +0000299 const char *filename;
300 const char *base_filename = NULL;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900301 BlockDriver *drv, *proto_drv;
302 QEMUOptionParameter *param = NULL, *create_options = NULL;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200303 char *options = NULL;
ths3b46e622007-09-17 08:09:54 +0000304
thsec36ba12007-09-16 21:59:02 +0000305 flags = 0;
bellardea2384d2004-08-01 21:59:26 +0000306 for(;;) {
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200307 c = getopt(argc, argv, "F:b:f:he6o:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100308 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000309 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100310 }
bellardea2384d2004-08-01 21:59:26 +0000311 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100312 case '?':
bellardea2384d2004-08-01 21:59:26 +0000313 case 'h':
314 help();
315 break;
aliguori9230eaf2009-03-28 17:55:19 +0000316 case 'F':
317 base_fmt = optarg;
318 break;
bellardea2384d2004-08-01 21:59:26 +0000319 case 'b':
320 base_filename = optarg;
321 break;
322 case 'f':
323 fmt = optarg;
324 break;
325 case 'e':
thsec36ba12007-09-16 21:59:02 +0000326 flags |= BLOCK_FLAG_ENCRYPT;
bellardea2384d2004-08-01 21:59:26 +0000327 break;
thsd8871c52007-10-24 16:11:42 +0000328 case '6':
thsec36ba12007-09-16 21:59:02 +0000329 flags |= BLOCK_FLAG_COMPAT6;
thsd8871c52007-10-24 16:11:42 +0000330 break;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200331 case 'o':
332 options = optarg;
333 break;
bellardea2384d2004-08-01 21:59:26 +0000334 }
335 }
aliguori9230eaf2009-03-28 17:55:19 +0000336
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900337 /* Get the filename */
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100338 if (optind >= argc) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900339 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100340 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900341 filename = argv[optind++];
342
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100343 if (options && !strcmp(options, "?")) {
344 ret = print_block_option_help(filename, fmt);
345 goto out;
346 }
347
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200348 /* Find driver and parse its options */
bellardea2384d2004-08-01 21:59:26 +0000349 drv = bdrv_find_format(fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900350 if (!drv) {
bellardea2384d2004-08-01 21:59:26 +0000351 error("Unknown file format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900352 return 1;
353 }
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200354
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900355 proto_drv = bdrv_find_protocol(filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900356 if (!proto_drv) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900357 error("Unknown protocol '%s'", filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900358 return 1;
359 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900360
361 create_options = append_option_parameters(create_options,
362 drv->create_options);
363 create_options = append_option_parameters(create_options,
364 proto_drv->create_options);
365
Kevin Wolf9f566402009-10-28 11:36:07 +0100366 /* Create parameter list with default values */
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900367 param = parse_option_parameters("", create_options, param);
Kevin Wolf9f566402009-10-28 11:36:07 +0100368 set_option_parameter_int(param, BLOCK_OPT_SIZE, -1);
369
370 /* Parse -o options */
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200371 if (options) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900372 param = parse_option_parameters(options, create_options, param);
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200373 if (param == NULL) {
374 error("Invalid options for file format '%s'.", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900375 ret = -1;
376 goto out;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200377 }
bellard75c23802004-08-27 21:28:58 +0000378 }
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200379
380 /* Add size to parameters */
381 if (optind < argc) {
382 set_option_parameter(param, BLOCK_OPT_SIZE, argv[optind++]);
383 }
384
385 /* Add old-style options to parameters */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900386 ret = add_old_style_options(fmt, param, flags, base_filename, base_fmt);
387 if (ret < 0) {
388 goto out;
389 }
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200390
391 // The size for the image must always be specified, with one exception:
392 // If we are using a backing file, we can obtain the size from there
Kevin Wolf9f566402009-10-28 11:36:07 +0100393 if (get_option_parameter(param, BLOCK_OPT_SIZE)->value.n == -1) {
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200394
395 QEMUOptionParameter *backing_file =
396 get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
397 QEMUOptionParameter *backing_fmt =
398 get_option_parameter(param, BLOCK_OPT_BACKING_FMT);
399
400 if (backing_file && backing_file->value.s) {
401 BlockDriverState *bs;
402 uint64_t size;
403 const char *fmt = NULL;
404 char buf[32];
405
406 if (backing_fmt && backing_fmt->value.s) {
407 if (bdrv_find_format(backing_fmt->value.s)) {
408 fmt = backing_fmt->value.s;
409 } else {
410 error("Unknown backing file format '%s'",
411 backing_fmt->value.s);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900412 ret = -1;
413 goto out;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200414 }
415 }
416
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100417 bs = bdrv_new_open(backing_file->value.s, fmt, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900418 if (!bs) {
419 ret = -1;
420 goto out;
421 }
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200422 bdrv_get_geometry(bs, &size);
423 size *= 512;
424 bdrv_delete(bs);
425
426 snprintf(buf, sizeof(buf), "%" PRId64, size);
427 set_option_parameter(param, BLOCK_OPT_SIZE, buf);
428 } else {
429 error("Image creation needs a size parameter");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900430 ret = -1;
431 goto out;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200432 }
433 }
434
435 printf("Formatting '%s', fmt=%s ", filename, fmt);
436 print_option_parameters(param);
437 puts("");
438
439 ret = bdrv_create(drv, filename, param);
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900440 free_option_parameters(create_options);
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200441 free_option_parameters(param);
442
bellardea2384d2004-08-01 21:59:26 +0000443 if (ret < 0) {
444 if (ret == -ENOTSUP) {
bellard3c565212004-09-29 21:29:14 +0000445 error("Formatting or formatting option not supported for file format '%s'", fmt);
aurel326e9ea0c2009-04-15 14:42:46 +0000446 } else if (ret == -EFBIG) {
447 error("The image size is too large for file format '%s'", fmt);
bellardea2384d2004-08-01 21:59:26 +0000448 } else {
Juan Quintela3e7896d2010-03-04 10:00:38 +0100449 error("%s: error while creating %s: %s", filename, fmt, strerror(-ret));
bellardea2384d2004-08-01 21:59:26 +0000450 }
451 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900452out:
453 if (ret) {
454 return 1;
455 }
bellardea2384d2004-08-01 21:59:26 +0000456 return 0;
457}
458
Kevin Wolfe076f332010-06-29 11:43:13 +0200459/*
460 * Checks an image for consistency. Exit codes:
461 *
462 * 0 - Check completed, image is good
463 * 1 - Check not completed because of internal errors
464 * 2 - Check completed, image is corrupted
465 * 3 - Check completed, image has leaked clusters, but is good otherwise
466 */
aliguori15859692009-04-21 23:11:53 +0000467static int img_check(int argc, char **argv)
468{
469 int c, ret;
470 const char *filename, *fmt;
aliguori15859692009-04-21 23:11:53 +0000471 BlockDriverState *bs;
Kevin Wolfe076f332010-06-29 11:43:13 +0200472 BdrvCheckResult result;
aliguori15859692009-04-21 23:11:53 +0000473
474 fmt = NULL;
475 for(;;) {
476 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100477 if (c == -1) {
aliguori15859692009-04-21 23:11:53 +0000478 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100479 }
aliguori15859692009-04-21 23:11:53 +0000480 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100481 case '?':
aliguori15859692009-04-21 23:11:53 +0000482 case 'h':
483 help();
484 break;
485 case 'f':
486 fmt = optarg;
487 break;
488 }
489 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100490 if (optind >= argc) {
aliguori15859692009-04-21 23:11:53 +0000491 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100492 }
aliguori15859692009-04-21 23:11:53 +0000493 filename = argv[optind++];
494
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100495 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900496 if (!bs) {
497 return 1;
498 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200499 ret = bdrv_check(bs, &result);
500
501 if (ret == -ENOTSUP) {
aliguori15859692009-04-21 23:11:53 +0000502 error("This image format does not support checks");
Kevin Wolfe076f332010-06-29 11:43:13 +0200503 bdrv_delete(bs);
504 return 1;
505 }
506
507 if (!(result.corruptions || result.leaks || result.check_errors)) {
508 printf("No errors were found on the image.\n");
509 } else {
510 if (result.corruptions) {
511 printf("\n%d errors were found on the image.\n"
512 "Data may be corrupted, or further writes to the image "
513 "may corrupt it.\n",
514 result.corruptions);
aliguori15859692009-04-21 23:11:53 +0000515 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200516
517 if (result.leaks) {
518 printf("\n%d leaked clusters were found on the image.\n"
519 "This means waste of disk space, but no harm to data.\n",
520 result.leaks);
521 }
522
523 if (result.check_errors) {
524 printf("\n%d internal errors have occurred during the check.\n",
525 result.check_errors);
526 }
aliguori15859692009-04-21 23:11:53 +0000527 }
528
529 bdrv_delete(bs);
Kevin Wolfe076f332010-06-29 11:43:13 +0200530
531 if (ret < 0 || result.check_errors) {
532 printf("\nAn error has occurred during the check: %s\n"
533 "The check is not complete and may have missed error.\n",
534 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900535 return 1;
536 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200537
538 if (result.corruptions) {
539 return 2;
540 } else if (result.leaks) {
541 return 3;
542 } else {
543 return 0;
544 }
aliguori15859692009-04-21 23:11:53 +0000545}
546
bellardea2384d2004-08-01 21:59:26 +0000547static int img_commit(int argc, char **argv)
548{
549 int c, ret;
550 const char *filename, *fmt;
bellardea2384d2004-08-01 21:59:26 +0000551 BlockDriverState *bs;
552
553 fmt = NULL;
554 for(;;) {
555 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100556 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000557 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100558 }
bellardea2384d2004-08-01 21:59:26 +0000559 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100560 case '?':
bellardea2384d2004-08-01 21:59:26 +0000561 case 'h':
562 help();
563 break;
564 case 'f':
565 fmt = optarg;
566 break;
567 }
568 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100569 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +0000570 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100571 }
bellardea2384d2004-08-01 21:59:26 +0000572 filename = argv[optind++];
573
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100574 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900575 if (!bs) {
576 return 1;
577 }
bellardea2384d2004-08-01 21:59:26 +0000578 ret = bdrv_commit(bs);
579 switch(ret) {
580 case 0:
581 printf("Image committed.\n");
582 break;
583 case -ENOENT:
584 error("No disk inserted");
585 break;
586 case -EACCES:
587 error("Image is read-only");
588 break;
589 case -ENOTSUP:
590 error("Image is already committed");
591 break;
592 default:
593 error("Error while committing image");
594 break;
595 }
596
597 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900598 if (ret) {
599 return 1;
600 }
bellardea2384d2004-08-01 21:59:26 +0000601 return 0;
602}
603
604static int is_not_zero(const uint8_t *sector, int len)
605{
606 int i;
607 len >>= 2;
608 for(i = 0;i < len; i++) {
609 if (((uint32_t *)sector)[i] != 0)
610 return 1;
611 }
612 return 0;
613}
614
thsf58c7b32008-06-05 21:53:49 +0000615/*
616 * Returns true iff the first sector pointed to by 'buf' contains at least
617 * a non-NUL byte.
618 *
619 * 'pnum' is set to the number of sectors (including and immediately following
620 * the first one) that are known to be in the same allocated/unallocated state.
621 */
bellardea2384d2004-08-01 21:59:26 +0000622static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
623{
624 int v, i;
625
626 if (n <= 0) {
627 *pnum = 0;
628 return 0;
629 }
630 v = is_not_zero(buf, 512);
631 for(i = 1; i < n; i++) {
632 buf += 512;
633 if (v != is_not_zero(buf, 512))
634 break;
635 }
636 *pnum = i;
637 return v;
638}
639
Kevin Wolf3e85c6f2010-01-12 12:55:18 +0100640/*
641 * Compares two buffers sector by sector. Returns 0 if the first sector of both
642 * buffers matches, non-zero otherwise.
643 *
644 * pnum is set to the number of sectors (including and immediately following
645 * the first one) that are known to have the same comparison result
646 */
647static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
648 int *pnum)
649{
650 int res, i;
651
652 if (n <= 0) {
653 *pnum = 0;
654 return 0;
655 }
656
657 res = !!memcmp(buf1, buf2, 512);
658 for(i = 1; i < n; i++) {
659 buf1 += 512;
660 buf2 += 512;
661
662 if (!!memcmp(buf1, buf2, 512) != res) {
663 break;
664 }
665 }
666
667 *pnum = i;
668 return res;
669}
670
Kevin Wolf80ee15a2009-09-15 12:30:43 +0200671#define IO_BUF_SIZE (2 * 1024 * 1024)
bellardea2384d2004-08-01 21:59:26 +0000672
673static int img_convert(int argc, char **argv)
674{
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900675 int c, ret = 0, n, n1, bs_n, bs_i, flags, cluster_size, cluster_sectors;
thsf58c7b32008-06-05 21:53:49 +0000676 const char *fmt, *out_fmt, *out_baseimg, *out_filename;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900677 BlockDriver *drv, *proto_drv;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900678 BlockDriverState **bs = NULL, *out_bs = NULL;
ths96b8f132007-12-17 01:35:20 +0000679 int64_t total_sectors, nb_sectors, sector_num, bs_offset;
680 uint64_t bs_sectors;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900681 uint8_t * buf = NULL;
bellardea2384d2004-08-01 21:59:26 +0000682 const uint8_t *buf1;
bellardfaea38e2006-08-05 21:31:00 +0000683 BlockDriverInfo bdi;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900684 QEMUOptionParameter *param = NULL, *create_options = NULL;
Kevin Wolfa18953f2010-10-14 15:46:04 +0200685 QEMUOptionParameter *out_baseimg_param;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200686 char *options = NULL;
edison51ef6722010-09-21 19:58:41 -0700687 const char *snapshot_name = NULL;
bellardea2384d2004-08-01 21:59:26 +0000688
689 fmt = NULL;
690 out_fmt = "raw";
thsf58c7b32008-06-05 21:53:49 +0000691 out_baseimg = NULL;
thsec36ba12007-09-16 21:59:02 +0000692 flags = 0;
bellardea2384d2004-08-01 21:59:26 +0000693 for(;;) {
edison51ef6722010-09-21 19:58:41 -0700694 c = getopt(argc, argv, "f:O:B:s:hce6o:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100695 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000696 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100697 }
bellardea2384d2004-08-01 21:59:26 +0000698 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100699 case '?':
bellardea2384d2004-08-01 21:59:26 +0000700 case 'h':
701 help();
702 break;
703 case 'f':
704 fmt = optarg;
705 break;
706 case 'O':
707 out_fmt = optarg;
708 break;
thsf58c7b32008-06-05 21:53:49 +0000709 case 'B':
710 out_baseimg = optarg;
711 break;
bellardea2384d2004-08-01 21:59:26 +0000712 case 'c':
thsec36ba12007-09-16 21:59:02 +0000713 flags |= BLOCK_FLAG_COMPRESS;
bellardea2384d2004-08-01 21:59:26 +0000714 break;
715 case 'e':
thsec36ba12007-09-16 21:59:02 +0000716 flags |= BLOCK_FLAG_ENCRYPT;
717 break;
718 case '6':
719 flags |= BLOCK_FLAG_COMPAT6;
bellardea2384d2004-08-01 21:59:26 +0000720 break;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200721 case 'o':
722 options = optarg;
723 break;
edison51ef6722010-09-21 19:58:41 -0700724 case 's':
725 snapshot_name = optarg;
726 break;
bellardea2384d2004-08-01 21:59:26 +0000727 }
728 }
ths3b46e622007-09-17 08:09:54 +0000729
balrog926c2d22007-10-31 01:11:44 +0000730 bs_n = argc - optind - 1;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100731 if (bs_n < 1) {
732 help();
733 }
balrog926c2d22007-10-31 01:11:44 +0000734
735 out_filename = argv[argc - 1];
thsf58c7b32008-06-05 21:53:49 +0000736
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100737 if (options && !strcmp(options, "?")) {
738 ret = print_block_option_help(out_filename, out_fmt);
739 goto out;
740 }
741
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900742 if (bs_n > 1 && out_baseimg) {
thsf58c7b32008-06-05 21:53:49 +0000743 error("-B makes no sense when concatenating multiple input images");
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100744 ret = -1;
745 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900746 }
balrog926c2d22007-10-31 01:11:44 +0000747
Jes Sorensen5bdf61f2010-12-06 15:25:35 +0100748 bs = qemu_mallocz(bs_n * sizeof(BlockDriverState *));
balrog926c2d22007-10-31 01:11:44 +0000749
750 total_sectors = 0;
751 for (bs_i = 0; bs_i < bs_n; bs_i++) {
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100752 bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900753 if (!bs[bs_i]) {
balrog926c2d22007-10-31 01:11:44 +0000754 error("Could not open '%s'", argv[optind + bs_i]);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900755 ret = -1;
756 goto out;
757 }
balrog926c2d22007-10-31 01:11:44 +0000758 bdrv_get_geometry(bs[bs_i], &bs_sectors);
759 total_sectors += bs_sectors;
760 }
bellardea2384d2004-08-01 21:59:26 +0000761
edison51ef6722010-09-21 19:58:41 -0700762 if (snapshot_name != NULL) {
763 if (bs_n > 1) {
764 error("No support for concatenating multiple snapshot\n");
765 ret = -1;
766 goto out;
767 }
768 if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
769 error("Failed to load snapshot\n");
770 ret = -1;
771 goto out;
772 }
773 }
774
Kevin Wolfefa84d42009-05-18 16:42:12 +0200775 /* Find driver and parse its options */
bellardea2384d2004-08-01 21:59:26 +0000776 drv = bdrv_find_format(out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900777 if (!drv) {
thsd34dda52007-02-10 22:59:40 +0000778 error("Unknown file format '%s'", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900779 ret = -1;
780 goto out;
781 }
balrog926c2d22007-10-31 01:11:44 +0000782
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900783 proto_drv = bdrv_find_protocol(out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900784 if (!proto_drv) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900785 error("Unknown protocol '%s'", out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900786 ret = -1;
787 goto out;
788 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900789
790 create_options = append_option_parameters(create_options,
791 drv->create_options);
792 create_options = append_option_parameters(create_options,
793 proto_drv->create_options);
Kevin Wolfdb08adf2009-06-04 15:39:38 +0200794
Kevin Wolfefa84d42009-05-18 16:42:12 +0200795 if (options) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900796 param = parse_option_parameters(options, create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200797 if (param == NULL) {
798 error("Invalid options for file format '%s'.", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900799 ret = -1;
800 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200801 }
802 } else {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900803 param = parse_option_parameters("", create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200804 }
805
806 set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900807 ret = add_old_style_options(out_fmt, param, flags, out_baseimg, NULL);
808 if (ret < 0) {
809 goto out;
810 }
Kevin Wolfefa84d42009-05-18 16:42:12 +0200811
Kevin Wolfa18953f2010-10-14 15:46:04 +0200812 /* Get backing file name if -o backing_file was used */
813 out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
814 if (out_baseimg_param) {
815 out_baseimg = out_baseimg_param->value.s;
816 }
817
Kevin Wolfefa84d42009-05-18 16:42:12 +0200818 /* Check if compression is supported */
819 if (flags & BLOCK_FLAG_COMPRESS) {
820 QEMUOptionParameter *encryption =
821 get_option_parameter(param, BLOCK_OPT_ENCRYPT);
822
823 if (!drv->bdrv_write_compressed) {
824 error("Compression not supported for this file format");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900825 ret = -1;
826 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200827 }
828
829 if (encryption && encryption->value.n) {
830 error("Compression and encryption not supported at the same time");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900831 ret = -1;
832 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200833 }
834 }
835
836 /* Create the new image */
837 ret = bdrv_create(drv, out_filename, param);
bellardea2384d2004-08-01 21:59:26 +0000838 if (ret < 0) {
839 if (ret == -ENOTSUP) {
aliguori93c65b42009-04-05 17:40:43 +0000840 error("Formatting not supported for file format '%s'", out_fmt);
aurel326e9ea0c2009-04-15 14:42:46 +0000841 } else if (ret == -EFBIG) {
842 error("The image size is too large for file format '%s'", out_fmt);
bellardea2384d2004-08-01 21:59:26 +0000843 } else {
Juan Quintela3e7896d2010-03-04 10:00:38 +0100844 error("%s: error while converting %s: %s", out_filename, out_fmt, strerror(-ret));
bellardea2384d2004-08-01 21:59:26 +0000845 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900846 goto out;
bellardea2384d2004-08-01 21:59:26 +0000847 }
ths3b46e622007-09-17 08:09:54 +0000848
Kevin Wolf1bd8e172010-08-31 13:44:25 +0200849 out_bs = bdrv_new_open(out_filename, out_fmt,
850 BDRV_O_FLAGS | BDRV_O_RDWR | BDRV_O_NO_FLUSH);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900851 if (!out_bs) {
852 ret = -1;
853 goto out;
854 }
bellardea2384d2004-08-01 21:59:26 +0000855
balrog926c2d22007-10-31 01:11:44 +0000856 bs_i = 0;
857 bs_offset = 0;
858 bdrv_get_geometry(bs[0], &bs_sectors);
TeLeMand6771bf2010-02-08 16:20:00 +0800859 buf = qemu_malloc(IO_BUF_SIZE);
balrog926c2d22007-10-31 01:11:44 +0000860
861 if (flags & BLOCK_FLAG_COMPRESS) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900862 ret = bdrv_get_info(out_bs, &bdi);
863 if (ret < 0) {
bellardfaea38e2006-08-05 21:31:00 +0000864 error("could not get block driver info");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900865 goto out;
866 }
bellardfaea38e2006-08-05 21:31:00 +0000867 cluster_size = bdi.cluster_size;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900868 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
bellardea2384d2004-08-01 21:59:26 +0000869 error("invalid cluster size");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900870 ret = -1;
871 goto out;
872 }
bellardea2384d2004-08-01 21:59:26 +0000873 cluster_sectors = cluster_size >> 9;
874 sector_num = 0;
875 for(;;) {
balrog926c2d22007-10-31 01:11:44 +0000876 int64_t bs_num;
877 int remainder;
878 uint8_t *buf2;
879
bellardea2384d2004-08-01 21:59:26 +0000880 nb_sectors = total_sectors - sector_num;
881 if (nb_sectors <= 0)
882 break;
883 if (nb_sectors >= cluster_sectors)
884 n = cluster_sectors;
885 else
886 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000887
888 bs_num = sector_num - bs_offset;
889 assert (bs_num >= 0);
890 remainder = n;
891 buf2 = buf;
892 while (remainder > 0) {
893 int nlow;
894 while (bs_num == bs_sectors) {
895 bs_i++;
896 assert (bs_i < bs_n);
897 bs_offset += bs_sectors;
898 bdrv_get_geometry(bs[bs_i], &bs_sectors);
899 bs_num = 0;
Blue Swirl0bfcd592010-05-22 08:02:12 +0000900 /* printf("changing part: sector_num=%" PRId64 ", "
901 "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64
902 "\n", sector_num, bs_i, bs_offset, bs_sectors); */
balrog926c2d22007-10-31 01:11:44 +0000903 }
904 assert (bs_num < bs_sectors);
905
906 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
907
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900908 ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
909 if (ret < 0) {
balrog926c2d22007-10-31 01:11:44 +0000910 error("error while reading");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900911 goto out;
912 }
balrog926c2d22007-10-31 01:11:44 +0000913
914 buf2 += nlow * 512;
915 bs_num += nlow;
916
917 remainder -= nlow;
918 }
919 assert (remainder == 0);
920
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100921 if (n < cluster_sectors) {
bellardea2384d2004-08-01 21:59:26 +0000922 memset(buf + n * 512, 0, cluster_size - n * 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100923 }
bellardea2384d2004-08-01 21:59:26 +0000924 if (is_not_zero(buf, cluster_size)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900925 ret = bdrv_write_compressed(out_bs, sector_num, buf,
926 cluster_sectors);
927 if (ret != 0) {
bellardec3757d2006-06-14 15:50:07 +0000928 error("error while compressing sector %" PRId64,
929 sector_num);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900930 goto out;
931 }
bellardea2384d2004-08-01 21:59:26 +0000932 }
933 sector_num += n;
934 }
bellardfaea38e2006-08-05 21:31:00 +0000935 /* signal EOF to align */
936 bdrv_write_compressed(out_bs, 0, NULL, 0);
bellardea2384d2004-08-01 21:59:26 +0000937 } else {
Kevin Wolff2feebb2010-04-14 17:30:35 +0200938 int has_zero_init = bdrv_has_zero_init(out_bs);
939
thsf58c7b32008-06-05 21:53:49 +0000940 sector_num = 0; // total number of sectors converted so far
bellardea2384d2004-08-01 21:59:26 +0000941 for(;;) {
942 nb_sectors = total_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100943 if (nb_sectors <= 0) {
bellardea2384d2004-08-01 21:59:26 +0000944 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100945 }
946 if (nb_sectors >= (IO_BUF_SIZE / 512)) {
bellardea2384d2004-08-01 21:59:26 +0000947 n = (IO_BUF_SIZE / 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100948 } else {
bellardea2384d2004-08-01 21:59:26 +0000949 n = nb_sectors;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100950 }
balrog926c2d22007-10-31 01:11:44 +0000951
952 while (sector_num - bs_offset >= bs_sectors) {
953 bs_i ++;
954 assert (bs_i < bs_n);
955 bs_offset += bs_sectors;
956 bdrv_get_geometry(bs[bs_i], &bs_sectors);
Blue Swirl0bfcd592010-05-22 08:02:12 +0000957 /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "
958 "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",
balrog926c2d22007-10-31 01:11:44 +0000959 sector_num, bs_i, bs_offset, bs_sectors); */
960 }
961
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100962 if (n > bs_offset + bs_sectors - sector_num) {
balrog926c2d22007-10-31 01:11:44 +0000963 n = bs_offset + bs_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100964 }
balrog926c2d22007-10-31 01:11:44 +0000965
Kevin Wolff2feebb2010-04-14 17:30:35 +0200966 if (has_zero_init) {
Akkarit Sangpetchd0320442009-07-17 10:02:15 +0200967 /* If the output image is being created as a copy on write image,
968 assume that sectors which are unallocated in the input image
969 are present in both the output's and input's base images (no
970 need to copy them). */
971 if (out_baseimg) {
972 if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
973 n, &n1)) {
974 sector_num += n1;
975 continue;
976 }
977 /* The next 'n1' sectors are allocated in the input image. Copy
978 only those as they may be followed by unallocated sectors. */
979 n = n1;
aliguori93c65b42009-04-05 17:40:43 +0000980 }
aliguori93c65b42009-04-05 17:40:43 +0000981 } else {
982 n1 = n;
thsf58c7b32008-06-05 21:53:49 +0000983 }
984
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900985 ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
986 if (ret < 0) {
bellardea2384d2004-08-01 21:59:26 +0000987 error("error while reading");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900988 goto out;
989 }
bellardea2384d2004-08-01 21:59:26 +0000990 /* NOTE: at the same time we convert, we do not write zero
991 sectors to have a chance to compress the image. Ideally, we
992 should add a specific call to have the info to go faster */
993 buf1 = buf;
994 while (n > 0) {
thsf58c7b32008-06-05 21:53:49 +0000995 /* If the output image is being created as a copy on write image,
996 copy all sectors even the ones containing only NUL bytes,
aliguori93c65b42009-04-05 17:40:43 +0000997 because they may differ from the sectors in the base image.
998
999 If the output is to a host device, we also write out
1000 sectors that are entirely 0, since whatever data was
1001 already there is garbage, not 0s. */
Kevin Wolff2feebb2010-04-14 17:30:35 +02001002 if (!has_zero_init || out_baseimg ||
aliguori93c65b42009-04-05 17:40:43 +00001003 is_allocated_sectors(buf1, n, &n1)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001004 ret = bdrv_write(out_bs, sector_num, buf1, n1);
1005 if (ret < 0) {
bellardea2384d2004-08-01 21:59:26 +00001006 error("error while writing");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001007 goto out;
1008 }
bellardea2384d2004-08-01 21:59:26 +00001009 }
1010 sector_num += n1;
1011 n -= n1;
1012 buf1 += n1 * 512;
1013 }
1014 }
1015 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001016out:
1017 free_option_parameters(create_options);
1018 free_option_parameters(param);
TeLeMand6771bf2010-02-08 16:20:00 +08001019 qemu_free(buf);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001020 if (out_bs) {
1021 bdrv_delete(out_bs);
1022 }
Jes Sorensen31ca34b2010-12-06 15:25:36 +01001023 if (bs) {
1024 for (bs_i = 0; bs_i < bs_n; bs_i++) {
1025 if (bs[bs_i]) {
1026 bdrv_delete(bs[bs_i]);
1027 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001028 }
Jes Sorensen31ca34b2010-12-06 15:25:36 +01001029 qemu_free(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001030 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001031 if (ret) {
1032 return 1;
1033 }
bellardea2384d2004-08-01 21:59:26 +00001034 return 0;
1035}
1036
bellard57d1a2b2004-08-03 21:15:11 +00001037#ifdef _WIN32
1038static int64_t get_allocated_file_size(const char *filename)
1039{
bellarde8445332006-06-14 15:32:10 +00001040 typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
1041 get_compressed_t get_compressed;
bellard57d1a2b2004-08-03 21:15:11 +00001042 struct _stati64 st;
bellarde8445332006-06-14 15:32:10 +00001043
1044 /* WinNT support GetCompressedFileSize to determine allocate size */
1045 get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
1046 if (get_compressed) {
1047 DWORD high, low;
1048 low = get_compressed(filename, &high);
1049 if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
1050 return (((int64_t) high) << 32) + low;
1051 }
1052
ths5fafdf22007-09-16 21:08:06 +00001053 if (_stati64(filename, &st) < 0)
bellard57d1a2b2004-08-03 21:15:11 +00001054 return -1;
1055 return st.st_size;
1056}
1057#else
1058static int64_t get_allocated_file_size(const char *filename)
1059{
1060 struct stat st;
ths5fafdf22007-09-16 21:08:06 +00001061 if (stat(filename, &st) < 0)
bellard57d1a2b2004-08-03 21:15:11 +00001062 return -1;
1063 return (int64_t)st.st_blocks * 512;
1064}
1065#endif
1066
bellardfaea38e2006-08-05 21:31:00 +00001067static void dump_snapshots(BlockDriverState *bs)
1068{
1069 QEMUSnapshotInfo *sn_tab, *sn;
1070 int nb_sns, i;
1071 char buf[256];
1072
1073 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1074 if (nb_sns <= 0)
1075 return;
1076 printf("Snapshot list:\n");
1077 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
1078 for(i = 0; i < nb_sns; i++) {
1079 sn = &sn_tab[i];
1080 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
1081 }
1082 qemu_free(sn_tab);
1083}
1084
bellardea2384d2004-08-01 21:59:26 +00001085static int img_info(int argc, char **argv)
1086{
1087 int c;
1088 const char *filename, *fmt;
bellardea2384d2004-08-01 21:59:26 +00001089 BlockDriverState *bs;
1090 char fmt_name[128], size_buf[128], dsize_buf[128];
ths96b8f132007-12-17 01:35:20 +00001091 uint64_t total_sectors;
1092 int64_t allocated_size;
bellard93b6b2a2006-08-01 15:51:11 +00001093 char backing_filename[1024];
1094 char backing_filename2[1024];
bellardfaea38e2006-08-05 21:31:00 +00001095 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +00001096
1097 fmt = NULL;
1098 for(;;) {
1099 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001100 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +00001101 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001102 }
bellardea2384d2004-08-01 21:59:26 +00001103 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001104 case '?':
bellardea2384d2004-08-01 21:59:26 +00001105 case 'h':
1106 help();
1107 break;
1108 case 'f':
1109 fmt = optarg;
1110 break;
1111 }
1112 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001113 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +00001114 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001115 }
bellardea2384d2004-08-01 21:59:26 +00001116 filename = argv[optind++];
1117
Stefan Hajnocziadfe0782010-04-13 10:29:35 +01001118 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001119 if (!bs) {
1120 return 1;
1121 }
bellardea2384d2004-08-01 21:59:26 +00001122 bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
1123 bdrv_get_geometry(bs, &total_sectors);
1124 get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
bellard57d1a2b2004-08-03 21:15:11 +00001125 allocated_size = get_allocated_file_size(filename);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001126 if (allocated_size < 0) {
blueswir1a10ea302008-08-24 10:30:33 +00001127 snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001128 } else {
ths5fafdf22007-09-16 21:08:06 +00001129 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
bellardde167e42005-04-28 21:15:08 +00001130 allocated_size);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001131 }
bellardea2384d2004-08-01 21:59:26 +00001132 printf("image: %s\n"
1133 "file format: %s\n"
bellardec3757d2006-06-14 15:50:07 +00001134 "virtual size: %s (%" PRId64 " bytes)\n"
bellardea2384d2004-08-01 21:59:26 +00001135 "disk size: %s\n",
ths5fafdf22007-09-16 21:08:06 +00001136 filename, fmt_name, size_buf,
bellardec3757d2006-06-14 15:50:07 +00001137 (total_sectors * 512),
bellardea2384d2004-08-01 21:59:26 +00001138 dsize_buf);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001139 if (bdrv_is_encrypted(bs)) {
bellardea2384d2004-08-01 21:59:26 +00001140 printf("encrypted: yes\n");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001141 }
bellardfaea38e2006-08-05 21:31:00 +00001142 if (bdrv_get_info(bs, &bdi) >= 0) {
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001143 if (bdi.cluster_size != 0) {
bellardfaea38e2006-08-05 21:31:00 +00001144 printf("cluster_size: %d\n", bdi.cluster_size);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001145 }
bellardfaea38e2006-08-05 21:31:00 +00001146 }
bellard93b6b2a2006-08-01 15:51:11 +00001147 bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
bellardfaea38e2006-08-05 21:31:00 +00001148 if (backing_filename[0] != '\0') {
bellard93b6b2a2006-08-01 15:51:11 +00001149 path_combine(backing_filename2, sizeof(backing_filename2),
1150 filename, backing_filename);
ths5fafdf22007-09-16 21:08:06 +00001151 printf("backing file: %s (actual path: %s)\n",
bellard93b6b2a2006-08-01 15:51:11 +00001152 backing_filename,
1153 backing_filename2);
bellardfaea38e2006-08-05 21:31:00 +00001154 }
1155 dump_snapshots(bs);
bellardea2384d2004-08-01 21:59:26 +00001156 bdrv_delete(bs);
1157 return 0;
1158}
1159
aliguorif7b4a942009-01-07 17:40:15 +00001160#define SNAPSHOT_LIST 1
1161#define SNAPSHOT_CREATE 2
1162#define SNAPSHOT_APPLY 3
1163#define SNAPSHOT_DELETE 4
1164
Stuart Brady153859b2009-06-07 00:42:17 +01001165static int img_snapshot(int argc, char **argv)
aliguorif7b4a942009-01-07 17:40:15 +00001166{
1167 BlockDriverState *bs;
1168 QEMUSnapshotInfo sn;
1169 char *filename, *snapshot_name = NULL;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001170 int c, ret = 0, bdrv_oflags;
aliguorif7b4a942009-01-07 17:40:15 +00001171 int action = 0;
1172 qemu_timeval tv;
1173
Naphtali Spreif5edb012010-01-17 16:48:13 +02001174 bdrv_oflags = BDRV_O_RDWR;
aliguorif7b4a942009-01-07 17:40:15 +00001175 /* Parse commandline parameters */
1176 for(;;) {
1177 c = getopt(argc, argv, "la:c:d:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001178 if (c == -1) {
aliguorif7b4a942009-01-07 17:40:15 +00001179 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001180 }
aliguorif7b4a942009-01-07 17:40:15 +00001181 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001182 case '?':
aliguorif7b4a942009-01-07 17:40:15 +00001183 case 'h':
1184 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001185 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001186 case 'l':
1187 if (action) {
1188 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001189 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001190 }
1191 action = SNAPSHOT_LIST;
Naphtali Spreif5edb012010-01-17 16:48:13 +02001192 bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
aliguorif7b4a942009-01-07 17:40:15 +00001193 break;
1194 case 'a':
1195 if (action) {
1196 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001197 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001198 }
1199 action = SNAPSHOT_APPLY;
1200 snapshot_name = optarg;
1201 break;
1202 case 'c':
1203 if (action) {
1204 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001205 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001206 }
1207 action = SNAPSHOT_CREATE;
1208 snapshot_name = optarg;
1209 break;
1210 case 'd':
1211 if (action) {
1212 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001213 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001214 }
1215 action = SNAPSHOT_DELETE;
1216 snapshot_name = optarg;
1217 break;
1218 }
1219 }
1220
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001221 if (optind >= argc) {
aliguorif7b4a942009-01-07 17:40:15 +00001222 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001223 }
aliguorif7b4a942009-01-07 17:40:15 +00001224 filename = argv[optind++];
1225
1226 /* Open the image */
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001227 bs = bdrv_new_open(filename, NULL, bdrv_oflags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001228 if (!bs) {
1229 return 1;
1230 }
aliguorif7b4a942009-01-07 17:40:15 +00001231
1232 /* Perform the requested action */
1233 switch(action) {
1234 case SNAPSHOT_LIST:
1235 dump_snapshots(bs);
1236 break;
1237
1238 case SNAPSHOT_CREATE:
1239 memset(&sn, 0, sizeof(sn));
1240 pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
1241
1242 qemu_gettimeofday(&tv);
1243 sn.date_sec = tv.tv_sec;
1244 sn.date_nsec = tv.tv_usec * 1000;
1245
1246 ret = bdrv_snapshot_create(bs, &sn);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001247 if (ret) {
aliguorif7b4a942009-01-07 17:40:15 +00001248 error("Could not create snapshot '%s': %d (%s)",
1249 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001250 }
aliguorif7b4a942009-01-07 17:40:15 +00001251 break;
1252
1253 case SNAPSHOT_APPLY:
1254 ret = bdrv_snapshot_goto(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001255 if (ret) {
aliguorif7b4a942009-01-07 17:40:15 +00001256 error("Could not apply snapshot '%s': %d (%s)",
1257 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001258 }
aliguorif7b4a942009-01-07 17:40:15 +00001259 break;
1260
1261 case SNAPSHOT_DELETE:
1262 ret = bdrv_snapshot_delete(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001263 if (ret) {
aliguorif7b4a942009-01-07 17:40:15 +00001264 error("Could not delete snapshot '%s': %d (%s)",
1265 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001266 }
aliguorif7b4a942009-01-07 17:40:15 +00001267 break;
1268 }
1269
1270 /* Cleanup */
1271 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001272 if (ret) {
1273 return 1;
1274 }
Stuart Brady153859b2009-06-07 00:42:17 +01001275 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001276}
1277
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001278static int img_rebase(int argc, char **argv)
1279{
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001280 BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001281 BlockDriver *old_backing_drv, *new_backing_drv;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001282 char *filename;
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001283 const char *fmt, *out_basefmt, *out_baseimg;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001284 int c, flags, ret;
1285 int unsafe = 0;
1286
1287 /* Parse commandline parameters */
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001288 fmt = NULL;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001289 out_baseimg = NULL;
1290 out_basefmt = NULL;
1291
1292 for(;;) {
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001293 c = getopt(argc, argv, "uhf:F:b:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001294 if (c == -1) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001295 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001296 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001297 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001298 case '?':
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001299 case 'h':
1300 help();
1301 return 0;
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001302 case 'f':
1303 fmt = optarg;
1304 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001305 case 'F':
1306 out_basefmt = optarg;
1307 break;
1308 case 'b':
1309 out_baseimg = optarg;
1310 break;
1311 case 'u':
1312 unsafe = 1;
1313 break;
1314 }
1315 }
1316
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001317 if ((optind >= argc) || !out_baseimg) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001318 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001319 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001320 filename = argv[optind++];
1321
1322 /*
1323 * Open the images.
1324 *
1325 * Ignore the old backing file for unsafe rebase in case we want to correct
1326 * the reference to a renamed or moved backing file.
1327 */
Stefan Hajnocziadfe0782010-04-13 10:29:35 +01001328 flags = BDRV_O_FLAGS | BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001329 bs = bdrv_new_open(filename, fmt, flags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001330 if (!bs) {
1331 return 1;
1332 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001333
1334 /* Find the right drivers for the backing files */
1335 old_backing_drv = NULL;
1336 new_backing_drv = NULL;
1337
1338 if (!unsafe && bs->backing_format[0] != '\0') {
1339 old_backing_drv = bdrv_find_format(bs->backing_format);
1340 if (old_backing_drv == NULL) {
1341 error("Invalid format name: '%s'", bs->backing_format);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001342 ret = -1;
1343 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001344 }
1345 }
1346
1347 if (out_basefmt != NULL) {
1348 new_backing_drv = bdrv_find_format(out_basefmt);
1349 if (new_backing_drv == NULL) {
1350 error("Invalid format name: '%s'", out_basefmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001351 ret = -1;
1352 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001353 }
1354 }
1355
1356 /* For safe rebasing we need to compare old and new backing file */
1357 if (unsafe) {
1358 /* Make the compiler happy */
1359 bs_old_backing = NULL;
1360 bs_new_backing = NULL;
1361 } else {
1362 char backing_name[1024];
1363
1364 bs_old_backing = bdrv_new("old_backing");
1365 bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001366 ret = bdrv_open(bs_old_backing, backing_name, BDRV_O_FLAGS,
1367 old_backing_drv);
1368 if (ret) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001369 error("Could not open old backing file '%s'", backing_name);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001370 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001371 }
1372
1373 bs_new_backing = bdrv_new("new_backing");
Kevin Wolfcdbae852010-08-17 18:58:55 +02001374 ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS,
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001375 new_backing_drv);
1376 if (ret) {
Kevin Wolf584771e2010-02-17 12:33:17 +01001377 error("Could not open new backing file '%s'", out_baseimg);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001378 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001379 }
1380 }
1381
1382 /*
1383 * Check each unallocated cluster in the COW file. If it is unallocated,
1384 * accesses go to the backing file. We must therefore compare this cluster
1385 * in the old and new backing file, and if they differ we need to copy it
1386 * from the old backing file into the COW file.
1387 *
1388 * If qemu-img crashes during this step, no harm is done. The content of
1389 * the image is the same as the original one at any time.
1390 */
1391 if (!unsafe) {
1392 uint64_t num_sectors;
1393 uint64_t sector;
Kevin Wolfcc60e322010-04-29 14:47:48 +02001394 int n;
TeLeMand6771bf2010-02-08 16:20:00 +08001395 uint8_t * buf_old;
1396 uint8_t * buf_new;
1397
1398 buf_old = qemu_malloc(IO_BUF_SIZE);
1399 buf_new = qemu_malloc(IO_BUF_SIZE);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001400
1401 bdrv_get_geometry(bs, &num_sectors);
1402
1403 for (sector = 0; sector < num_sectors; sector += n) {
1404
1405 /* How many sectors can we handle with the next read? */
1406 if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
1407 n = (IO_BUF_SIZE / 512);
1408 } else {
1409 n = num_sectors - sector;
1410 }
1411
1412 /* If the cluster is allocated, we don't need to take action */
Kevin Wolfcc60e322010-04-29 14:47:48 +02001413 ret = bdrv_is_allocated(bs, sector, n, &n);
1414 if (ret) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001415 continue;
1416 }
1417
1418 /* Read old and new backing file */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001419 ret = bdrv_read(bs_old_backing, sector, buf_old, n);
1420 if (ret < 0) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001421 error("error while reading from old backing file");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001422 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001423 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001424 ret = bdrv_read(bs_new_backing, sector, buf_new, n);
1425 if (ret < 0) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001426 error("error while reading from new backing file");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001427 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001428 }
1429
1430 /* If they differ, we need to write to the COW file */
1431 uint64_t written = 0;
1432
1433 while (written < n) {
1434 int pnum;
1435
1436 if (compare_sectors(buf_old + written * 512,
Kevin Wolf60b1bd42010-02-17 12:32:59 +01001437 buf_new + written * 512, n - written, &pnum))
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001438 {
1439 ret = bdrv_write(bs, sector + written,
1440 buf_old + written * 512, pnum);
1441 if (ret < 0) {
1442 error("Error while writing to COW image: %s",
1443 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001444 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001445 }
1446 }
1447
1448 written += pnum;
1449 }
1450 }
TeLeMand6771bf2010-02-08 16:20:00 +08001451
1452 qemu_free(buf_old);
1453 qemu_free(buf_new);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001454 }
1455
1456 /*
1457 * Change the backing file. All clusters that are different from the old
1458 * backing file are overwritten in the COW file now, so the visible content
1459 * doesn't change when we switch the backing file.
1460 */
1461 ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
1462 if (ret == -ENOSPC) {
1463 error("Could not change the backing file to '%s': No space left in "
1464 "the file header", out_baseimg);
1465 } else if (ret < 0) {
1466 error("Could not change the backing file to '%s': %s",
1467 out_baseimg, strerror(-ret));
1468 }
1469
1470 /*
1471 * TODO At this point it is possible to check if any clusters that are
1472 * allocated in the COW file are the same in the backing file. If so, they
1473 * could be dropped from the COW file. Don't do this before switching the
1474 * backing file, in case of a crash this would lead to corruption.
1475 */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001476out:
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001477 /* Cleanup */
1478 if (!unsafe) {
1479 bdrv_delete(bs_old_backing);
1480 bdrv_delete(bs_new_backing);
1481 }
1482
1483 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001484 if (ret) {
1485 return 1;
1486 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001487 return 0;
1488}
1489
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001490static int img_resize(int argc, char **argv)
1491{
1492 int c, ret, relative;
1493 const char *filename, *fmt, *size;
1494 int64_t n, total_size;
1495 BlockDriverState *bs;
1496 QEMUOptionParameter *param;
1497 QEMUOptionParameter resize_options[] = {
1498 {
1499 .name = BLOCK_OPT_SIZE,
1500 .type = OPT_SIZE,
1501 .help = "Virtual disk size"
1502 },
1503 { NULL }
1504 };
1505
1506 fmt = NULL;
1507 for(;;) {
1508 c = getopt(argc, argv, "f:h");
1509 if (c == -1) {
1510 break;
1511 }
1512 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001513 case '?':
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001514 case 'h':
1515 help();
1516 break;
1517 case 'f':
1518 fmt = optarg;
1519 break;
1520 }
1521 }
1522 if (optind + 1 >= argc) {
1523 help();
1524 }
1525 filename = argv[optind++];
1526 size = argv[optind++];
1527
1528 /* Choose grow, shrink, or absolute resize mode */
1529 switch (size[0]) {
1530 case '+':
1531 relative = 1;
1532 size++;
1533 break;
1534 case '-':
1535 relative = -1;
1536 size++;
1537 break;
1538 default:
1539 relative = 0;
1540 break;
1541 }
1542
1543 /* Parse size */
1544 param = parse_option_parameters("", resize_options, NULL);
1545 if (set_option_parameter(param, BLOCK_OPT_SIZE, size)) {
1546 /* Error message already printed when size parsing fails */
1547 exit(1);
1548 }
1549 n = get_option_parameter(param, BLOCK_OPT_SIZE)->value.n;
1550 free_option_parameters(param);
1551
1552 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001553 if (!bs) {
1554 return 1;
1555 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001556
1557 if (relative) {
1558 total_size = bdrv_getlength(bs) + n * relative;
1559 } else {
1560 total_size = n;
1561 }
1562 if (total_size <= 0) {
1563 error("New image size must be positive");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001564 ret = -1;
1565 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001566 }
1567
1568 ret = bdrv_truncate(bs, total_size);
1569 switch (ret) {
1570 case 0:
1571 printf("Image resized.\n");
1572 break;
1573 case -ENOTSUP:
1574 error("This image format does not support resize");
1575 break;
1576 case -EACCES:
1577 error("Image is read-only");
1578 break;
1579 default:
1580 error("Error resizing image (%d)", -ret);
1581 break;
1582 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001583out:
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001584 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001585 if (ret) {
1586 return 1;
1587 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001588 return 0;
1589}
1590
Anthony Liguoric227f092009-10-01 16:12:16 -05001591static const img_cmd_t img_cmds[] = {
Stuart Brady153859b2009-06-07 00:42:17 +01001592#define DEF(option, callback, arg_string) \
1593 { option, callback },
1594#include "qemu-img-cmds.h"
1595#undef DEF
1596#undef GEN_DOCS
1597 { NULL, NULL, },
1598};
1599
bellardea2384d2004-08-01 21:59:26 +00001600int main(int argc, char **argv)
1601{
Anthony Liguoric227f092009-10-01 16:12:16 -05001602 const img_cmd_t *cmd;
Stuart Brady153859b2009-06-07 00:42:17 +01001603 const char *cmdname;
bellardea2384d2004-08-01 21:59:26 +00001604
1605 bdrv_init();
1606 if (argc < 2)
1607 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001608 cmdname = argv[1];
aurel328f9b1572009-02-09 18:14:31 +00001609 argc--; argv++;
Stuart Brady153859b2009-06-07 00:42:17 +01001610
1611 /* find the command */
1612 for(cmd = img_cmds; cmd->name != NULL; cmd++) {
1613 if (!strcmp(cmdname, cmd->name)) {
1614 return cmd->handler(argc, argv);
1615 }
bellardea2384d2004-08-01 21:59:26 +00001616 }
Stuart Brady153859b2009-06-07 00:42:17 +01001617
1618 /* not found */
1619 help();
bellardea2384d2004-08-01 21:59:26 +00001620 return 0;
1621}