blob: 50cfdda6d590d19da9739ff6298d6c95adf8d209 [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:");
bellardea2384d2004-08-01 21:59:26 +0000308 if (c == -1)
309 break;
310 switch(c) {
311 case 'h':
312 help();
313 break;
aliguori9230eaf2009-03-28 17:55:19 +0000314 case 'F':
315 base_fmt = optarg;
316 break;
bellardea2384d2004-08-01 21:59:26 +0000317 case 'b':
318 base_filename = optarg;
319 break;
320 case 'f':
321 fmt = optarg;
322 break;
323 case 'e':
thsec36ba12007-09-16 21:59:02 +0000324 flags |= BLOCK_FLAG_ENCRYPT;
bellardea2384d2004-08-01 21:59:26 +0000325 break;
thsd8871c52007-10-24 16:11:42 +0000326 case '6':
thsec36ba12007-09-16 21:59:02 +0000327 flags |= BLOCK_FLAG_COMPAT6;
thsd8871c52007-10-24 16:11:42 +0000328 break;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200329 case 'o':
330 options = optarg;
331 break;
bellardea2384d2004-08-01 21:59:26 +0000332 }
333 }
aliguori9230eaf2009-03-28 17:55:19 +0000334
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900335 /* Get the filename */
336 if (optind >= argc)
337 help();
338 filename = argv[optind++];
339
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100340 if (options && !strcmp(options, "?")) {
341 ret = print_block_option_help(filename, fmt);
342 goto out;
343 }
344
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200345 /* Find driver and parse its options */
bellardea2384d2004-08-01 21:59:26 +0000346 drv = bdrv_find_format(fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900347 if (!drv) {
bellardea2384d2004-08-01 21:59:26 +0000348 error("Unknown file format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900349 return 1;
350 }
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200351
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900352 proto_drv = bdrv_find_protocol(filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900353 if (!proto_drv) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900354 error("Unknown protocol '%s'", filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900355 return 1;
356 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900357
358 create_options = append_option_parameters(create_options,
359 drv->create_options);
360 create_options = append_option_parameters(create_options,
361 proto_drv->create_options);
362
Kevin Wolf9f566402009-10-28 11:36:07 +0100363 /* Create parameter list with default values */
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900364 param = parse_option_parameters("", create_options, param);
Kevin Wolf9f566402009-10-28 11:36:07 +0100365 set_option_parameter_int(param, BLOCK_OPT_SIZE, -1);
366
367 /* Parse -o options */
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200368 if (options) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900369 param = parse_option_parameters(options, create_options, param);
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200370 if (param == NULL) {
371 error("Invalid options for file format '%s'.", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900372 ret = -1;
373 goto out;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200374 }
bellard75c23802004-08-27 21:28:58 +0000375 }
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200376
377 /* Add size to parameters */
378 if (optind < argc) {
379 set_option_parameter(param, BLOCK_OPT_SIZE, argv[optind++]);
380 }
381
382 /* Add old-style options to parameters */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900383 ret = add_old_style_options(fmt, param, flags, base_filename, base_fmt);
384 if (ret < 0) {
385 goto out;
386 }
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200387
388 // The size for the image must always be specified, with one exception:
389 // If we are using a backing file, we can obtain the size from there
Kevin Wolf9f566402009-10-28 11:36:07 +0100390 if (get_option_parameter(param, BLOCK_OPT_SIZE)->value.n == -1) {
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200391
392 QEMUOptionParameter *backing_file =
393 get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
394 QEMUOptionParameter *backing_fmt =
395 get_option_parameter(param, BLOCK_OPT_BACKING_FMT);
396
397 if (backing_file && backing_file->value.s) {
398 BlockDriverState *bs;
399 uint64_t size;
400 const char *fmt = NULL;
401 char buf[32];
402
403 if (backing_fmt && backing_fmt->value.s) {
404 if (bdrv_find_format(backing_fmt->value.s)) {
405 fmt = backing_fmt->value.s;
406 } else {
407 error("Unknown backing file format '%s'",
408 backing_fmt->value.s);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900409 ret = -1;
410 goto out;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200411 }
412 }
413
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100414 bs = bdrv_new_open(backing_file->value.s, fmt, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900415 if (!bs) {
416 ret = -1;
417 goto out;
418 }
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200419 bdrv_get_geometry(bs, &size);
420 size *= 512;
421 bdrv_delete(bs);
422
423 snprintf(buf, sizeof(buf), "%" PRId64, size);
424 set_option_parameter(param, BLOCK_OPT_SIZE, buf);
425 } else {
426 error("Image creation needs a size parameter");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900427 ret = -1;
428 goto out;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200429 }
430 }
431
432 printf("Formatting '%s', fmt=%s ", filename, fmt);
433 print_option_parameters(param);
434 puts("");
435
436 ret = bdrv_create(drv, filename, param);
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900437 free_option_parameters(create_options);
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200438 free_option_parameters(param);
439
bellardea2384d2004-08-01 21:59:26 +0000440 if (ret < 0) {
441 if (ret == -ENOTSUP) {
bellard3c565212004-09-29 21:29:14 +0000442 error("Formatting or formatting option not supported for file format '%s'", fmt);
aurel326e9ea0c2009-04-15 14:42:46 +0000443 } else if (ret == -EFBIG) {
444 error("The image size is too large for file format '%s'", fmt);
bellardea2384d2004-08-01 21:59:26 +0000445 } else {
Juan Quintela3e7896d2010-03-04 10:00:38 +0100446 error("%s: error while creating %s: %s", filename, fmt, strerror(-ret));
bellardea2384d2004-08-01 21:59:26 +0000447 }
448 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900449out:
450 if (ret) {
451 return 1;
452 }
bellardea2384d2004-08-01 21:59:26 +0000453 return 0;
454}
455
Kevin Wolfe076f332010-06-29 11:43:13 +0200456/*
457 * Checks an image for consistency. Exit codes:
458 *
459 * 0 - Check completed, image is good
460 * 1 - Check not completed because of internal errors
461 * 2 - Check completed, image is corrupted
462 * 3 - Check completed, image has leaked clusters, but is good otherwise
463 */
aliguori15859692009-04-21 23:11:53 +0000464static int img_check(int argc, char **argv)
465{
466 int c, ret;
467 const char *filename, *fmt;
aliguori15859692009-04-21 23:11:53 +0000468 BlockDriverState *bs;
Kevin Wolfe076f332010-06-29 11:43:13 +0200469 BdrvCheckResult result;
aliguori15859692009-04-21 23:11:53 +0000470
471 fmt = NULL;
472 for(;;) {
473 c = getopt(argc, argv, "f:h");
474 if (c == -1)
475 break;
476 switch(c) {
477 case 'h':
478 help();
479 break;
480 case 'f':
481 fmt = optarg;
482 break;
483 }
484 }
485 if (optind >= argc)
486 help();
487 filename = argv[optind++];
488
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100489 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900490 if (!bs) {
491 return 1;
492 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200493 ret = bdrv_check(bs, &result);
494
495 if (ret == -ENOTSUP) {
aliguori15859692009-04-21 23:11:53 +0000496 error("This image format does not support checks");
Kevin Wolfe076f332010-06-29 11:43:13 +0200497 bdrv_delete(bs);
498 return 1;
499 }
500
501 if (!(result.corruptions || result.leaks || result.check_errors)) {
502 printf("No errors were found on the image.\n");
503 } else {
504 if (result.corruptions) {
505 printf("\n%d errors were found on the image.\n"
506 "Data may be corrupted, or further writes to the image "
507 "may corrupt it.\n",
508 result.corruptions);
aliguori15859692009-04-21 23:11:53 +0000509 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200510
511 if (result.leaks) {
512 printf("\n%d leaked clusters were found on the image.\n"
513 "This means waste of disk space, but no harm to data.\n",
514 result.leaks);
515 }
516
517 if (result.check_errors) {
518 printf("\n%d internal errors have occurred during the check.\n",
519 result.check_errors);
520 }
aliguori15859692009-04-21 23:11:53 +0000521 }
522
523 bdrv_delete(bs);
Kevin Wolfe076f332010-06-29 11:43:13 +0200524
525 if (ret < 0 || result.check_errors) {
526 printf("\nAn error has occurred during the check: %s\n"
527 "The check is not complete and may have missed error.\n",
528 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900529 return 1;
530 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200531
532 if (result.corruptions) {
533 return 2;
534 } else if (result.leaks) {
535 return 3;
536 } else {
537 return 0;
538 }
aliguori15859692009-04-21 23:11:53 +0000539}
540
bellardea2384d2004-08-01 21:59:26 +0000541static int img_commit(int argc, char **argv)
542{
543 int c, ret;
544 const char *filename, *fmt;
bellardea2384d2004-08-01 21:59:26 +0000545 BlockDriverState *bs;
546
547 fmt = NULL;
548 for(;;) {
549 c = getopt(argc, argv, "f:h");
550 if (c == -1)
551 break;
552 switch(c) {
553 case 'h':
554 help();
555 break;
556 case 'f':
557 fmt = optarg;
558 break;
559 }
560 }
ths5fafdf22007-09-16 21:08:06 +0000561 if (optind >= argc)
bellardea2384d2004-08-01 21:59:26 +0000562 help();
563 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{
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900666 int c, ret = 0, n, n1, bs_n, bs_i, flags, 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;
thsec36ba12007-09-16 21:59:02 +0000683 flags = 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:");
bellardea2384d2004-08-01 21:59:26 +0000686 if (c == -1)
687 break;
688 switch(c) {
689 case 'h':
690 help();
691 break;
692 case 'f':
693 fmt = optarg;
694 break;
695 case 'O':
696 out_fmt = optarg;
697 break;
thsf58c7b32008-06-05 21:53:49 +0000698 case 'B':
699 out_baseimg = optarg;
700 break;
bellardea2384d2004-08-01 21:59:26 +0000701 case 'c':
thsec36ba12007-09-16 21:59:02 +0000702 flags |= BLOCK_FLAG_COMPRESS;
bellardea2384d2004-08-01 21:59:26 +0000703 break;
704 case 'e':
thsec36ba12007-09-16 21:59:02 +0000705 flags |= BLOCK_FLAG_ENCRYPT;
706 break;
707 case '6':
708 flags |= BLOCK_FLAG_COMPAT6;
bellardea2384d2004-08-01 21:59:26 +0000709 break;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200710 case 'o':
711 options = optarg;
712 break;
edison51ef6722010-09-21 19:58:41 -0700713 case 's':
714 snapshot_name = optarg;
715 break;
bellardea2384d2004-08-01 21:59:26 +0000716 }
717 }
ths3b46e622007-09-17 08:09:54 +0000718
balrog926c2d22007-10-31 01:11:44 +0000719 bs_n = argc - optind - 1;
720 if (bs_n < 1) help();
721
722 out_filename = argv[argc - 1];
thsf58c7b32008-06-05 21:53:49 +0000723
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100724 if (options && !strcmp(options, "?")) {
725 ret = print_block_option_help(out_filename, out_fmt);
726 goto out;
727 }
728
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900729 if (bs_n > 1 && out_baseimg) {
thsf58c7b32008-06-05 21:53:49 +0000730 error("-B makes no sense when concatenating multiple input images");
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100731 ret = -1;
732 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900733 }
balrog926c2d22007-10-31 01:11:44 +0000734
Jes Sorensen5bdf61f2010-12-06 15:25:35 +0100735 bs = qemu_mallocz(bs_n * sizeof(BlockDriverState *));
balrog926c2d22007-10-31 01:11:44 +0000736
737 total_sectors = 0;
738 for (bs_i = 0; bs_i < bs_n; bs_i++) {
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100739 bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900740 if (!bs[bs_i]) {
balrog926c2d22007-10-31 01:11:44 +0000741 error("Could not open '%s'", argv[optind + bs_i]);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900742 ret = -1;
743 goto out;
744 }
balrog926c2d22007-10-31 01:11:44 +0000745 bdrv_get_geometry(bs[bs_i], &bs_sectors);
746 total_sectors += bs_sectors;
747 }
bellardea2384d2004-08-01 21:59:26 +0000748
edison51ef6722010-09-21 19:58:41 -0700749 if (snapshot_name != NULL) {
750 if (bs_n > 1) {
751 error("No support for concatenating multiple snapshot\n");
752 ret = -1;
753 goto out;
754 }
755 if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
756 error("Failed to load snapshot\n");
757 ret = -1;
758 goto out;
759 }
760 }
761
Kevin Wolfefa84d42009-05-18 16:42:12 +0200762 /* Find driver and parse its options */
bellardea2384d2004-08-01 21:59:26 +0000763 drv = bdrv_find_format(out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900764 if (!drv) {
thsd34dda52007-02-10 22:59:40 +0000765 error("Unknown file format '%s'", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900766 ret = -1;
767 goto out;
768 }
balrog926c2d22007-10-31 01:11:44 +0000769
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900770 proto_drv = bdrv_find_protocol(out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900771 if (!proto_drv) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900772 error("Unknown protocol '%s'", out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900773 ret = -1;
774 goto out;
775 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900776
777 create_options = append_option_parameters(create_options,
778 drv->create_options);
779 create_options = append_option_parameters(create_options,
780 proto_drv->create_options);
Kevin Wolfdb08adf2009-06-04 15:39:38 +0200781
Kevin Wolfefa84d42009-05-18 16:42:12 +0200782 if (options) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900783 param = parse_option_parameters(options, create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200784 if (param == NULL) {
785 error("Invalid options for file format '%s'.", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900786 ret = -1;
787 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200788 }
789 } else {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900790 param = parse_option_parameters("", create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200791 }
792
793 set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900794 ret = add_old_style_options(out_fmt, param, flags, out_baseimg, NULL);
795 if (ret < 0) {
796 goto out;
797 }
Kevin Wolfefa84d42009-05-18 16:42:12 +0200798
Kevin Wolfa18953f2010-10-14 15:46:04 +0200799 /* Get backing file name if -o backing_file was used */
800 out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
801 if (out_baseimg_param) {
802 out_baseimg = out_baseimg_param->value.s;
803 }
804
Kevin Wolfefa84d42009-05-18 16:42:12 +0200805 /* Check if compression is supported */
806 if (flags & BLOCK_FLAG_COMPRESS) {
807 QEMUOptionParameter *encryption =
808 get_option_parameter(param, BLOCK_OPT_ENCRYPT);
809
810 if (!drv->bdrv_write_compressed) {
811 error("Compression not supported for this file format");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900812 ret = -1;
813 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200814 }
815
816 if (encryption && encryption->value.n) {
817 error("Compression and encryption not supported at the same time");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900818 ret = -1;
819 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200820 }
821 }
822
823 /* Create the new image */
824 ret = bdrv_create(drv, out_filename, param);
bellardea2384d2004-08-01 21:59:26 +0000825 if (ret < 0) {
826 if (ret == -ENOTSUP) {
aliguori93c65b42009-04-05 17:40:43 +0000827 error("Formatting not supported for file format '%s'", out_fmt);
aurel326e9ea0c2009-04-15 14:42:46 +0000828 } else if (ret == -EFBIG) {
829 error("The image size is too large for file format '%s'", out_fmt);
bellardea2384d2004-08-01 21:59:26 +0000830 } else {
Juan Quintela3e7896d2010-03-04 10:00:38 +0100831 error("%s: error while converting %s: %s", out_filename, out_fmt, strerror(-ret));
bellardea2384d2004-08-01 21:59:26 +0000832 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900833 goto out;
bellardea2384d2004-08-01 21:59:26 +0000834 }
ths3b46e622007-09-17 08:09:54 +0000835
Kevin Wolf1bd8e172010-08-31 13:44:25 +0200836 out_bs = bdrv_new_open(out_filename, out_fmt,
837 BDRV_O_FLAGS | BDRV_O_RDWR | BDRV_O_NO_FLUSH);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900838 if (!out_bs) {
839 ret = -1;
840 goto out;
841 }
bellardea2384d2004-08-01 21:59:26 +0000842
balrog926c2d22007-10-31 01:11:44 +0000843 bs_i = 0;
844 bs_offset = 0;
845 bdrv_get_geometry(bs[0], &bs_sectors);
TeLeMand6771bf2010-02-08 16:20:00 +0800846 buf = qemu_malloc(IO_BUF_SIZE);
balrog926c2d22007-10-31 01:11:44 +0000847
848 if (flags & BLOCK_FLAG_COMPRESS) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900849 ret = bdrv_get_info(out_bs, &bdi);
850 if (ret < 0) {
bellardfaea38e2006-08-05 21:31:00 +0000851 error("could not get block driver info");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900852 goto out;
853 }
bellardfaea38e2006-08-05 21:31:00 +0000854 cluster_size = bdi.cluster_size;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900855 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
bellardea2384d2004-08-01 21:59:26 +0000856 error("invalid cluster size");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900857 ret = -1;
858 goto out;
859 }
bellardea2384d2004-08-01 21:59:26 +0000860 cluster_sectors = cluster_size >> 9;
861 sector_num = 0;
862 for(;;) {
balrog926c2d22007-10-31 01:11:44 +0000863 int64_t bs_num;
864 int remainder;
865 uint8_t *buf2;
866
bellardea2384d2004-08-01 21:59:26 +0000867 nb_sectors = total_sectors - sector_num;
868 if (nb_sectors <= 0)
869 break;
870 if (nb_sectors >= cluster_sectors)
871 n = cluster_sectors;
872 else
873 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000874
875 bs_num = sector_num - bs_offset;
876 assert (bs_num >= 0);
877 remainder = n;
878 buf2 = buf;
879 while (remainder > 0) {
880 int nlow;
881 while (bs_num == bs_sectors) {
882 bs_i++;
883 assert (bs_i < bs_n);
884 bs_offset += bs_sectors;
885 bdrv_get_geometry(bs[bs_i], &bs_sectors);
886 bs_num = 0;
Blue Swirl0bfcd592010-05-22 08:02:12 +0000887 /* printf("changing part: sector_num=%" PRId64 ", "
888 "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64
889 "\n", sector_num, bs_i, bs_offset, bs_sectors); */
balrog926c2d22007-10-31 01:11:44 +0000890 }
891 assert (bs_num < bs_sectors);
892
893 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
894
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900895 ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
896 if (ret < 0) {
balrog926c2d22007-10-31 01:11:44 +0000897 error("error while reading");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900898 goto out;
899 }
balrog926c2d22007-10-31 01:11:44 +0000900
901 buf2 += nlow * 512;
902 bs_num += nlow;
903
904 remainder -= nlow;
905 }
906 assert (remainder == 0);
907
bellardea2384d2004-08-01 21:59:26 +0000908 if (n < cluster_sectors)
909 memset(buf + n * 512, 0, cluster_size - n * 512);
910 if (is_not_zero(buf, cluster_size)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900911 ret = bdrv_write_compressed(out_bs, sector_num, buf,
912 cluster_sectors);
913 if (ret != 0) {
bellardec3757d2006-06-14 15:50:07 +0000914 error("error while compressing sector %" PRId64,
915 sector_num);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900916 goto out;
917 }
bellardea2384d2004-08-01 21:59:26 +0000918 }
919 sector_num += n;
920 }
bellardfaea38e2006-08-05 21:31:00 +0000921 /* signal EOF to align */
922 bdrv_write_compressed(out_bs, 0, NULL, 0);
bellardea2384d2004-08-01 21:59:26 +0000923 } else {
Kevin Wolff2feebb2010-04-14 17:30:35 +0200924 int has_zero_init = bdrv_has_zero_init(out_bs);
925
thsf58c7b32008-06-05 21:53:49 +0000926 sector_num = 0; // total number of sectors converted so far
bellardea2384d2004-08-01 21:59:26 +0000927 for(;;) {
928 nb_sectors = total_sectors - sector_num;
929 if (nb_sectors <= 0)
930 break;
931 if (nb_sectors >= (IO_BUF_SIZE / 512))
932 n = (IO_BUF_SIZE / 512);
933 else
934 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000935
936 while (sector_num - bs_offset >= bs_sectors) {
937 bs_i ++;
938 assert (bs_i < bs_n);
939 bs_offset += bs_sectors;
940 bdrv_get_geometry(bs[bs_i], &bs_sectors);
Blue Swirl0bfcd592010-05-22 08:02:12 +0000941 /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "
942 "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",
balrog926c2d22007-10-31 01:11:44 +0000943 sector_num, bs_i, bs_offset, bs_sectors); */
944 }
945
946 if (n > bs_offset + bs_sectors - sector_num)
947 n = bs_offset + bs_sectors - sector_num;
948
Kevin Wolff2feebb2010-04-14 17:30:35 +0200949 if (has_zero_init) {
Akkarit Sangpetchd0320442009-07-17 10:02:15 +0200950 /* If the output image is being created as a copy on write image,
951 assume that sectors which are unallocated in the input image
952 are present in both the output's and input's base images (no
953 need to copy them). */
954 if (out_baseimg) {
955 if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
956 n, &n1)) {
957 sector_num += n1;
958 continue;
959 }
960 /* The next 'n1' sectors are allocated in the input image. Copy
961 only those as they may be followed by unallocated sectors. */
962 n = n1;
aliguori93c65b42009-04-05 17:40:43 +0000963 }
aliguori93c65b42009-04-05 17:40:43 +0000964 } else {
965 n1 = n;
thsf58c7b32008-06-05 21:53:49 +0000966 }
967
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900968 ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
969 if (ret < 0) {
bellardea2384d2004-08-01 21:59:26 +0000970 error("error while reading");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900971 goto out;
972 }
bellardea2384d2004-08-01 21:59:26 +0000973 /* NOTE: at the same time we convert, we do not write zero
974 sectors to have a chance to compress the image. Ideally, we
975 should add a specific call to have the info to go faster */
976 buf1 = buf;
977 while (n > 0) {
thsf58c7b32008-06-05 21:53:49 +0000978 /* If the output image is being created as a copy on write image,
979 copy all sectors even the ones containing only NUL bytes,
aliguori93c65b42009-04-05 17:40:43 +0000980 because they may differ from the sectors in the base image.
981
982 If the output is to a host device, we also write out
983 sectors that are entirely 0, since whatever data was
984 already there is garbage, not 0s. */
Kevin Wolff2feebb2010-04-14 17:30:35 +0200985 if (!has_zero_init || out_baseimg ||
aliguori93c65b42009-04-05 17:40:43 +0000986 is_allocated_sectors(buf1, n, &n1)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900987 ret = bdrv_write(out_bs, sector_num, buf1, n1);
988 if (ret < 0) {
bellardea2384d2004-08-01 21:59:26 +0000989 error("error while writing");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900990 goto out;
991 }
bellardea2384d2004-08-01 21:59:26 +0000992 }
993 sector_num += n1;
994 n -= n1;
995 buf1 += n1 * 512;
996 }
997 }
998 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900999out:
1000 free_option_parameters(create_options);
1001 free_option_parameters(param);
TeLeMand6771bf2010-02-08 16:20:00 +08001002 qemu_free(buf);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001003 if (out_bs) {
1004 bdrv_delete(out_bs);
1005 }
Jes Sorensen31ca34b2010-12-06 15:25:36 +01001006 if (bs) {
1007 for (bs_i = 0; bs_i < bs_n; bs_i++) {
1008 if (bs[bs_i]) {
1009 bdrv_delete(bs[bs_i]);
1010 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001011 }
Jes Sorensen31ca34b2010-12-06 15:25:36 +01001012 qemu_free(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001013 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001014 if (ret) {
1015 return 1;
1016 }
bellardea2384d2004-08-01 21:59:26 +00001017 return 0;
1018}
1019
bellard57d1a2b2004-08-03 21:15:11 +00001020#ifdef _WIN32
1021static int64_t get_allocated_file_size(const char *filename)
1022{
bellarde8445332006-06-14 15:32:10 +00001023 typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
1024 get_compressed_t get_compressed;
bellard57d1a2b2004-08-03 21:15:11 +00001025 struct _stati64 st;
bellarde8445332006-06-14 15:32:10 +00001026
1027 /* WinNT support GetCompressedFileSize to determine allocate size */
1028 get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
1029 if (get_compressed) {
1030 DWORD high, low;
1031 low = get_compressed(filename, &high);
1032 if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
1033 return (((int64_t) high) << 32) + low;
1034 }
1035
ths5fafdf22007-09-16 21:08:06 +00001036 if (_stati64(filename, &st) < 0)
bellard57d1a2b2004-08-03 21:15:11 +00001037 return -1;
1038 return st.st_size;
1039}
1040#else
1041static int64_t get_allocated_file_size(const char *filename)
1042{
1043 struct stat st;
ths5fafdf22007-09-16 21:08:06 +00001044 if (stat(filename, &st) < 0)
bellard57d1a2b2004-08-03 21:15:11 +00001045 return -1;
1046 return (int64_t)st.st_blocks * 512;
1047}
1048#endif
1049
bellardfaea38e2006-08-05 21:31:00 +00001050static void dump_snapshots(BlockDriverState *bs)
1051{
1052 QEMUSnapshotInfo *sn_tab, *sn;
1053 int nb_sns, i;
1054 char buf[256];
1055
1056 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1057 if (nb_sns <= 0)
1058 return;
1059 printf("Snapshot list:\n");
1060 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
1061 for(i = 0; i < nb_sns; i++) {
1062 sn = &sn_tab[i];
1063 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
1064 }
1065 qemu_free(sn_tab);
1066}
1067
bellardea2384d2004-08-01 21:59:26 +00001068static int img_info(int argc, char **argv)
1069{
1070 int c;
1071 const char *filename, *fmt;
bellardea2384d2004-08-01 21:59:26 +00001072 BlockDriverState *bs;
1073 char fmt_name[128], size_buf[128], dsize_buf[128];
ths96b8f132007-12-17 01:35:20 +00001074 uint64_t total_sectors;
1075 int64_t allocated_size;
bellard93b6b2a2006-08-01 15:51:11 +00001076 char backing_filename[1024];
1077 char backing_filename2[1024];
bellardfaea38e2006-08-05 21:31:00 +00001078 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +00001079
1080 fmt = NULL;
1081 for(;;) {
1082 c = getopt(argc, argv, "f:h");
1083 if (c == -1)
1084 break;
1085 switch(c) {
1086 case 'h':
1087 help();
1088 break;
1089 case 'f':
1090 fmt = optarg;
1091 break;
1092 }
1093 }
ths5fafdf22007-09-16 21:08:06 +00001094 if (optind >= argc)
bellardea2384d2004-08-01 21:59:26 +00001095 help();
1096 filename = argv[optind++];
1097
Stefan Hajnocziadfe0782010-04-13 10:29:35 +01001098 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001099 if (!bs) {
1100 return 1;
1101 }
bellardea2384d2004-08-01 21:59:26 +00001102 bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
1103 bdrv_get_geometry(bs, &total_sectors);
1104 get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
bellard57d1a2b2004-08-03 21:15:11 +00001105 allocated_size = get_allocated_file_size(filename);
1106 if (allocated_size < 0)
blueswir1a10ea302008-08-24 10:30:33 +00001107 snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
bellardde167e42005-04-28 21:15:08 +00001108 else
ths5fafdf22007-09-16 21:08:06 +00001109 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
bellardde167e42005-04-28 21:15:08 +00001110 allocated_size);
bellardea2384d2004-08-01 21:59:26 +00001111 printf("image: %s\n"
1112 "file format: %s\n"
bellardec3757d2006-06-14 15:50:07 +00001113 "virtual size: %s (%" PRId64 " bytes)\n"
bellardea2384d2004-08-01 21:59:26 +00001114 "disk size: %s\n",
ths5fafdf22007-09-16 21:08:06 +00001115 filename, fmt_name, size_buf,
bellardec3757d2006-06-14 15:50:07 +00001116 (total_sectors * 512),
bellardea2384d2004-08-01 21:59:26 +00001117 dsize_buf);
1118 if (bdrv_is_encrypted(bs))
1119 printf("encrypted: yes\n");
bellardfaea38e2006-08-05 21:31:00 +00001120 if (bdrv_get_info(bs, &bdi) >= 0) {
ths5fafdf22007-09-16 21:08:06 +00001121 if (bdi.cluster_size != 0)
bellardfaea38e2006-08-05 21:31:00 +00001122 printf("cluster_size: %d\n", bdi.cluster_size);
1123 }
bellard93b6b2a2006-08-01 15:51:11 +00001124 bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
bellardfaea38e2006-08-05 21:31:00 +00001125 if (backing_filename[0] != '\0') {
bellard93b6b2a2006-08-01 15:51:11 +00001126 path_combine(backing_filename2, sizeof(backing_filename2),
1127 filename, backing_filename);
ths5fafdf22007-09-16 21:08:06 +00001128 printf("backing file: %s (actual path: %s)\n",
bellard93b6b2a2006-08-01 15:51:11 +00001129 backing_filename,
1130 backing_filename2);
bellardfaea38e2006-08-05 21:31:00 +00001131 }
1132 dump_snapshots(bs);
bellardea2384d2004-08-01 21:59:26 +00001133 bdrv_delete(bs);
1134 return 0;
1135}
1136
aliguorif7b4a942009-01-07 17:40:15 +00001137#define SNAPSHOT_LIST 1
1138#define SNAPSHOT_CREATE 2
1139#define SNAPSHOT_APPLY 3
1140#define SNAPSHOT_DELETE 4
1141
Stuart Brady153859b2009-06-07 00:42:17 +01001142static int img_snapshot(int argc, char **argv)
aliguorif7b4a942009-01-07 17:40:15 +00001143{
1144 BlockDriverState *bs;
1145 QEMUSnapshotInfo sn;
1146 char *filename, *snapshot_name = NULL;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001147 int c, ret = 0, bdrv_oflags;
aliguorif7b4a942009-01-07 17:40:15 +00001148 int action = 0;
1149 qemu_timeval tv;
1150
Naphtali Spreif5edb012010-01-17 16:48:13 +02001151 bdrv_oflags = BDRV_O_RDWR;
aliguorif7b4a942009-01-07 17:40:15 +00001152 /* Parse commandline parameters */
1153 for(;;) {
1154 c = getopt(argc, argv, "la:c:d:h");
1155 if (c == -1)
1156 break;
1157 switch(c) {
1158 case 'h':
1159 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001160 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001161 case 'l':
1162 if (action) {
1163 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001164 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001165 }
1166 action = SNAPSHOT_LIST;
Naphtali Spreif5edb012010-01-17 16:48:13 +02001167 bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
aliguorif7b4a942009-01-07 17:40:15 +00001168 break;
1169 case 'a':
1170 if (action) {
1171 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001172 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001173 }
1174 action = SNAPSHOT_APPLY;
1175 snapshot_name = optarg;
1176 break;
1177 case 'c':
1178 if (action) {
1179 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001180 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001181 }
1182 action = SNAPSHOT_CREATE;
1183 snapshot_name = optarg;
1184 break;
1185 case 'd':
1186 if (action) {
1187 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001188 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001189 }
1190 action = SNAPSHOT_DELETE;
1191 snapshot_name = optarg;
1192 break;
1193 }
1194 }
1195
1196 if (optind >= argc)
1197 help();
1198 filename = argv[optind++];
1199
1200 /* Open the image */
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001201 bs = bdrv_new_open(filename, NULL, bdrv_oflags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001202 if (!bs) {
1203 return 1;
1204 }
aliguorif7b4a942009-01-07 17:40:15 +00001205
1206 /* Perform the requested action */
1207 switch(action) {
1208 case SNAPSHOT_LIST:
1209 dump_snapshots(bs);
1210 break;
1211
1212 case SNAPSHOT_CREATE:
1213 memset(&sn, 0, sizeof(sn));
1214 pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
1215
1216 qemu_gettimeofday(&tv);
1217 sn.date_sec = tv.tv_sec;
1218 sn.date_nsec = tv.tv_usec * 1000;
1219
1220 ret = bdrv_snapshot_create(bs, &sn);
1221 if (ret)
1222 error("Could not create snapshot '%s': %d (%s)",
1223 snapshot_name, ret, strerror(-ret));
1224 break;
1225
1226 case SNAPSHOT_APPLY:
1227 ret = bdrv_snapshot_goto(bs, snapshot_name);
1228 if (ret)
1229 error("Could not apply snapshot '%s': %d (%s)",
1230 snapshot_name, ret, strerror(-ret));
1231 break;
1232
1233 case SNAPSHOT_DELETE:
1234 ret = bdrv_snapshot_delete(bs, snapshot_name);
1235 if (ret)
1236 error("Could not delete snapshot '%s': %d (%s)",
1237 snapshot_name, ret, strerror(-ret));
1238 break;
1239 }
1240
1241 /* Cleanup */
1242 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001243 if (ret) {
1244 return 1;
1245 }
Stuart Brady153859b2009-06-07 00:42:17 +01001246 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001247}
1248
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001249static int img_rebase(int argc, char **argv)
1250{
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001251 BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001252 BlockDriver *old_backing_drv, *new_backing_drv;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001253 char *filename;
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001254 const char *fmt, *out_basefmt, *out_baseimg;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001255 int c, flags, ret;
1256 int unsafe = 0;
1257
1258 /* Parse commandline parameters */
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001259 fmt = NULL;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001260 out_baseimg = NULL;
1261 out_basefmt = NULL;
1262
1263 for(;;) {
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001264 c = getopt(argc, argv, "uhf:F:b:");
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001265 if (c == -1)
1266 break;
1267 switch(c) {
1268 case 'h':
1269 help();
1270 return 0;
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001271 case 'f':
1272 fmt = optarg;
1273 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001274 case 'F':
1275 out_basefmt = optarg;
1276 break;
1277 case 'b':
1278 out_baseimg = optarg;
1279 break;
1280 case 'u':
1281 unsafe = 1;
1282 break;
1283 }
1284 }
1285
1286 if ((optind >= argc) || !out_baseimg)
1287 help();
1288 filename = argv[optind++];
1289
1290 /*
1291 * Open the images.
1292 *
1293 * Ignore the old backing file for unsafe rebase in case we want to correct
1294 * the reference to a renamed or moved backing file.
1295 */
Stefan Hajnocziadfe0782010-04-13 10:29:35 +01001296 flags = BDRV_O_FLAGS | BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001297 bs = bdrv_new_open(filename, fmt, flags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001298 if (!bs) {
1299 return 1;
1300 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001301
1302 /* Find the right drivers for the backing files */
1303 old_backing_drv = NULL;
1304 new_backing_drv = NULL;
1305
1306 if (!unsafe && bs->backing_format[0] != '\0') {
1307 old_backing_drv = bdrv_find_format(bs->backing_format);
1308 if (old_backing_drv == NULL) {
1309 error("Invalid format name: '%s'", bs->backing_format);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001310 ret = -1;
1311 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001312 }
1313 }
1314
1315 if (out_basefmt != NULL) {
1316 new_backing_drv = bdrv_find_format(out_basefmt);
1317 if (new_backing_drv == NULL) {
1318 error("Invalid format name: '%s'", out_basefmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001319 ret = -1;
1320 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001321 }
1322 }
1323
1324 /* For safe rebasing we need to compare old and new backing file */
1325 if (unsafe) {
1326 /* Make the compiler happy */
1327 bs_old_backing = NULL;
1328 bs_new_backing = NULL;
1329 } else {
1330 char backing_name[1024];
1331
1332 bs_old_backing = bdrv_new("old_backing");
1333 bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001334 ret = bdrv_open(bs_old_backing, backing_name, BDRV_O_FLAGS,
1335 old_backing_drv);
1336 if (ret) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001337 error("Could not open old backing file '%s'", backing_name);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001338 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001339 }
1340
1341 bs_new_backing = bdrv_new("new_backing");
Kevin Wolfcdbae852010-08-17 18:58:55 +02001342 ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS,
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001343 new_backing_drv);
1344 if (ret) {
Kevin Wolf584771e2010-02-17 12:33:17 +01001345 error("Could not open new backing file '%s'", out_baseimg);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001346 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001347 }
1348 }
1349
1350 /*
1351 * Check each unallocated cluster in the COW file. If it is unallocated,
1352 * accesses go to the backing file. We must therefore compare this cluster
1353 * in the old and new backing file, and if they differ we need to copy it
1354 * from the old backing file into the COW file.
1355 *
1356 * If qemu-img crashes during this step, no harm is done. The content of
1357 * the image is the same as the original one at any time.
1358 */
1359 if (!unsafe) {
1360 uint64_t num_sectors;
1361 uint64_t sector;
Kevin Wolfcc60e322010-04-29 14:47:48 +02001362 int n;
TeLeMand6771bf2010-02-08 16:20:00 +08001363 uint8_t * buf_old;
1364 uint8_t * buf_new;
1365
1366 buf_old = qemu_malloc(IO_BUF_SIZE);
1367 buf_new = qemu_malloc(IO_BUF_SIZE);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001368
1369 bdrv_get_geometry(bs, &num_sectors);
1370
1371 for (sector = 0; sector < num_sectors; sector += n) {
1372
1373 /* How many sectors can we handle with the next read? */
1374 if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
1375 n = (IO_BUF_SIZE / 512);
1376 } else {
1377 n = num_sectors - sector;
1378 }
1379
1380 /* If the cluster is allocated, we don't need to take action */
Kevin Wolfcc60e322010-04-29 14:47:48 +02001381 ret = bdrv_is_allocated(bs, sector, n, &n);
1382 if (ret) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001383 continue;
1384 }
1385
1386 /* Read old and new backing file */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001387 ret = bdrv_read(bs_old_backing, sector, buf_old, n);
1388 if (ret < 0) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001389 error("error while reading from old backing file");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001390 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001391 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001392 ret = bdrv_read(bs_new_backing, sector, buf_new, n);
1393 if (ret < 0) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001394 error("error while reading from new backing file");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001395 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001396 }
1397
1398 /* If they differ, we need to write to the COW file */
1399 uint64_t written = 0;
1400
1401 while (written < n) {
1402 int pnum;
1403
1404 if (compare_sectors(buf_old + written * 512,
Kevin Wolf60b1bd42010-02-17 12:32:59 +01001405 buf_new + written * 512, n - written, &pnum))
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001406 {
1407 ret = bdrv_write(bs, sector + written,
1408 buf_old + written * 512, pnum);
1409 if (ret < 0) {
1410 error("Error while writing to COW image: %s",
1411 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001412 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001413 }
1414 }
1415
1416 written += pnum;
1417 }
1418 }
TeLeMand6771bf2010-02-08 16:20:00 +08001419
1420 qemu_free(buf_old);
1421 qemu_free(buf_new);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001422 }
1423
1424 /*
1425 * Change the backing file. All clusters that are different from the old
1426 * backing file are overwritten in the COW file now, so the visible content
1427 * doesn't change when we switch the backing file.
1428 */
1429 ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
1430 if (ret == -ENOSPC) {
1431 error("Could not change the backing file to '%s': No space left in "
1432 "the file header", out_baseimg);
1433 } else if (ret < 0) {
1434 error("Could not change the backing file to '%s': %s",
1435 out_baseimg, strerror(-ret));
1436 }
1437
1438 /*
1439 * TODO At this point it is possible to check if any clusters that are
1440 * allocated in the COW file are the same in the backing file. If so, they
1441 * could be dropped from the COW file. Don't do this before switching the
1442 * backing file, in case of a crash this would lead to corruption.
1443 */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001444out:
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001445 /* Cleanup */
1446 if (!unsafe) {
1447 bdrv_delete(bs_old_backing);
1448 bdrv_delete(bs_new_backing);
1449 }
1450
1451 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001452 if (ret) {
1453 return 1;
1454 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001455 return 0;
1456}
1457
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001458static int img_resize(int argc, char **argv)
1459{
1460 int c, ret, relative;
1461 const char *filename, *fmt, *size;
1462 int64_t n, total_size;
1463 BlockDriverState *bs;
1464 QEMUOptionParameter *param;
1465 QEMUOptionParameter resize_options[] = {
1466 {
1467 .name = BLOCK_OPT_SIZE,
1468 .type = OPT_SIZE,
1469 .help = "Virtual disk size"
1470 },
1471 { NULL }
1472 };
1473
1474 fmt = NULL;
1475 for(;;) {
1476 c = getopt(argc, argv, "f:h");
1477 if (c == -1) {
1478 break;
1479 }
1480 switch(c) {
1481 case 'h':
1482 help();
1483 break;
1484 case 'f':
1485 fmt = optarg;
1486 break;
1487 }
1488 }
1489 if (optind + 1 >= argc) {
1490 help();
1491 }
1492 filename = argv[optind++];
1493 size = argv[optind++];
1494
1495 /* Choose grow, shrink, or absolute resize mode */
1496 switch (size[0]) {
1497 case '+':
1498 relative = 1;
1499 size++;
1500 break;
1501 case '-':
1502 relative = -1;
1503 size++;
1504 break;
1505 default:
1506 relative = 0;
1507 break;
1508 }
1509
1510 /* Parse size */
1511 param = parse_option_parameters("", resize_options, NULL);
1512 if (set_option_parameter(param, BLOCK_OPT_SIZE, size)) {
1513 /* Error message already printed when size parsing fails */
1514 exit(1);
1515 }
1516 n = get_option_parameter(param, BLOCK_OPT_SIZE)->value.n;
1517 free_option_parameters(param);
1518
1519 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001520 if (!bs) {
1521 return 1;
1522 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001523
1524 if (relative) {
1525 total_size = bdrv_getlength(bs) + n * relative;
1526 } else {
1527 total_size = n;
1528 }
1529 if (total_size <= 0) {
1530 error("New image size must be positive");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001531 ret = -1;
1532 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001533 }
1534
1535 ret = bdrv_truncate(bs, total_size);
1536 switch (ret) {
1537 case 0:
1538 printf("Image resized.\n");
1539 break;
1540 case -ENOTSUP:
1541 error("This image format does not support resize");
1542 break;
1543 case -EACCES:
1544 error("Image is read-only");
1545 break;
1546 default:
1547 error("Error resizing image (%d)", -ret);
1548 break;
1549 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001550out:
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001551 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001552 if (ret) {
1553 return 1;
1554 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001555 return 0;
1556}
1557
Anthony Liguoric227f092009-10-01 16:12:16 -05001558static const img_cmd_t img_cmds[] = {
Stuart Brady153859b2009-06-07 00:42:17 +01001559#define DEF(option, callback, arg_string) \
1560 { option, callback },
1561#include "qemu-img-cmds.h"
1562#undef DEF
1563#undef GEN_DOCS
1564 { NULL, NULL, },
1565};
1566
bellardea2384d2004-08-01 21:59:26 +00001567int main(int argc, char **argv)
1568{
Anthony Liguoric227f092009-10-01 16:12:16 -05001569 const img_cmd_t *cmd;
Stuart Brady153859b2009-06-07 00:42:17 +01001570 const char *cmdname;
bellardea2384d2004-08-01 21:59:26 +00001571
1572 bdrv_init();
1573 if (argc < 2)
1574 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001575 cmdname = argv[1];
aurel328f9b1572009-02-09 18:14:31 +00001576 argc--; argv++;
Stuart Brady153859b2009-06-07 00:42:17 +01001577
1578 /* find the command */
1579 for(cmd = img_cmds; cmd->name != NULL; cmd++) {
1580 if (!strcmp(cmdname, cmd->name)) {
1581 return cmd->handler(argc, argv);
1582 }
bellardea2384d2004-08-01 21:59:26 +00001583 }
Stuart Brady153859b2009-06-07 00:42:17 +01001584
1585 /* not found */
1586 help();
bellardea2384d2004-08-01 21:59:26 +00001587 return 0;
1588}