blob: 0b871d842c03b711984f771b3e15e19f338e06e8 [file] [log] [blame]
bellardea2384d2004-08-01 21:59:26 +00001/*
bellardfb43f4d2006-08-07 21:34:46 +00002 * QEMU disk image utility
ths5fafdf22007-09-16 21:08:06 +00003 *
bellard68d0f702008-01-06 17:21:48 +00004 * Copyright (c) 2003-2008 Fabrice Bellard
ths5fafdf22007-09-16 21:08:06 +00005 *
bellardea2384d2004-08-01 21:59:26 +00006 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
pbrookfaf07962007-11-11 02:51:17 +000024#include "qemu-common.h"
Kevin Wolf9ea2ea72009-05-18 16:42:11 +020025#include "qemu-option.h"
Kevin Wolf53f76e52010-12-16 15:10:32 +010026#include "qemu-error.h"
aliguorif7b4a942009-01-07 17:40:15 +000027#include "osdep.h"
Jes Sorensendc786bc2010-10-26 10:39:23 +020028#include "sysemu.h"
thsec36ba12007-09-16 21:59:02 +000029#include "block_int.h"
aliguori9230eaf2009-03-28 17:55:19 +000030#include <stdio.h>
bellardea2384d2004-08-01 21:59:26 +000031
bellarde8445332006-06-14 15:32:10 +000032#ifdef _WIN32
33#include <windows.h>
34#endif
35
Anthony Liguoric227f092009-10-01 16:12:16 -050036typedef struct img_cmd_t {
Stuart Brady153859b2009-06-07 00:42:17 +010037 const char *name;
38 int (*handler)(int argc, char **argv);
Anthony Liguoric227f092009-10-01 16:12:16 -050039} img_cmd_t;
Stuart Brady153859b2009-06-07 00:42:17 +010040
aurel32137519c2008-11-30 19:12:49 +000041/* Default to cache=writeback as data integrity is not important for qemu-tcg. */
Stefan Hajnocziadfe0782010-04-13 10:29:35 +010042#define BDRV_O_FLAGS BDRV_O_CACHE_WB
aurel32137519c2008-11-30 19:12:49 +000043
bellardea2384d2004-08-01 21:59:26 +000044static void format_print(void *opaque, const char *name)
45{
46 printf(" %s", name);
47}
48
blueswir1d2c639d2009-01-24 18:19:25 +000049/* Please keep in synch with qemu-img.texi */
pbrook3f379ab2007-11-11 03:33:13 +000050static void help(void)
bellardea2384d2004-08-01 21:59:26 +000051{
Paolo Bonzinie00291c2010-02-04 16:49:56 +010052 const char *help_msg =
53 "qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fabrice Bellard\n"
malc3f020d72010-02-08 12:04:56 +030054 "usage: qemu-img command [command options]\n"
55 "QEMU disk image utility\n"
56 "\n"
57 "Command syntax:\n"
Stuart Brady153859b2009-06-07 00:42:17 +010058#define DEF(option, callback, arg_string) \
59 " " arg_string "\n"
60#include "qemu-img-cmds.h"
61#undef DEF
62#undef GEN_DOCS
malc3f020d72010-02-08 12:04:56 +030063 "\n"
64 "Command parameters:\n"
65 " 'filename' is a disk image filename\n"
66 " 'fmt' is the disk image format. It is guessed automatically in most cases\n"
67 " 'size' is the disk image size in bytes. Optional suffixes\n"
68 " 'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M)\n"
69 " and T (terabyte, 1024G) are supported. 'b' is ignored.\n"
70 " 'output_filename' is the destination disk image filename\n"
71 " 'output_fmt' is the destination format\n"
72 " 'options' is a comma separated list of format specific options in a\n"
73 " name=value format. Use -o ? for an overview of the options supported by the\n"
74 " used format\n"
75 " '-c' indicates that target image must be compressed (qcow format only)\n"
76 " '-u' enables unsafe rebasing. It is assumed that old and new backing file\n"
77 " match exactly. The image doesn't need a working backing file before\n"
78 " rebasing in this case (useful for renaming the backing file)\n"
79 " '-h' with or without a command shows this help and lists the supported formats\n"
80 "\n"
81 "Parameters to snapshot subcommand:\n"
82 " 'snapshot' is the name of the snapshot to create, apply or delete\n"
83 " '-a' applies a snapshot (revert disk to saved state)\n"
84 " '-c' creates a snapshot\n"
85 " '-d' deletes a snapshot\n"
Paolo Bonzinie00291c2010-02-04 16:49:56 +010086 " '-l' lists all snapshots in the given image\n";
87
88 printf("%s\nSupported formats:", help_msg);
bellardea2384d2004-08-01 21:59:26 +000089 bdrv_iterate_format(format_print, NULL);
90 printf("\n");
91 exit(1);
92}
93
bellardea2384d2004-08-01 21:59:26 +000094#if defined(WIN32)
95/* XXX: put correct support for win32 */
96static int read_password(char *buf, int buf_size)
97{
98 int c, i;
99 printf("Password: ");
100 fflush(stdout);
101 i = 0;
102 for(;;) {
103 c = getchar();
104 if (c == '\n')
105 break;
106 if (i < (buf_size - 1))
107 buf[i++] = c;
108 }
109 buf[i] = '\0';
110 return 0;
111}
112
113#else
114
115#include <termios.h>
116
117static struct termios oldtty;
118
119static void term_exit(void)
120{
121 tcsetattr (0, TCSANOW, &oldtty);
122}
123
124static void term_init(void)
125{
126 struct termios tty;
127
128 tcgetattr (0, &tty);
129 oldtty = tty;
130
131 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
132 |INLCR|IGNCR|ICRNL|IXON);
133 tty.c_oflag |= OPOST;
134 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
135 tty.c_cflag &= ~(CSIZE|PARENB);
136 tty.c_cflag |= CS8;
137 tty.c_cc[VMIN] = 1;
138 tty.c_cc[VTIME] = 0;
ths3b46e622007-09-17 08:09:54 +0000139
bellardea2384d2004-08-01 21:59:26 +0000140 tcsetattr (0, TCSANOW, &tty);
141
142 atexit(term_exit);
143}
144
pbrook3f379ab2007-11-11 03:33:13 +0000145static int read_password(char *buf, int buf_size)
bellardea2384d2004-08-01 21:59:26 +0000146{
147 uint8_t ch;
148 int i, ret;
149
150 printf("password: ");
151 fflush(stdout);
152 term_init();
153 i = 0;
154 for(;;) {
155 ret = read(0, &ch, 1);
156 if (ret == -1) {
157 if (errno == EAGAIN || errno == EINTR) {
158 continue;
159 } else {
160 ret = -1;
161 break;
162 }
163 } else if (ret == 0) {
164 ret = -1;
165 break;
166 } else {
167 if (ch == '\r') {
168 ret = 0;
169 break;
170 }
171 if (i < (buf_size - 1))
172 buf[i++] = ch;
173 }
174 }
175 term_exit();
176 buf[i] = '\0';
177 printf("\n");
178 return ret;
179}
180#endif
181
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100182static int print_block_option_help(const char *filename, const char *fmt)
183{
184 BlockDriver *drv, *proto_drv;
185 QEMUOptionParameter *create_options = NULL;
186
187 /* Find driver and parse its options */
188 drv = bdrv_find_format(fmt);
189 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100190 error_report("Unknown file format '%s'", fmt);
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100191 return 1;
192 }
193
194 proto_drv = bdrv_find_protocol(filename);
195 if (!proto_drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100196 error_report("Unknown protocol '%s'", filename);
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100197 return 1;
198 }
199
200 create_options = append_option_parameters(create_options,
201 drv->create_options);
202 create_options = append_option_parameters(create_options,
203 proto_drv->create_options);
204 print_option_help(create_options);
205 free_option_parameters(create_options);
206 return 0;
207}
208
bellard75c23802004-08-27 21:28:58 +0000209static BlockDriverState *bdrv_new_open(const char *filename,
Sheng Yang9bc378c2010-01-29 10:15:06 +0800210 const char *fmt,
Stefan Hajnoczif163d072010-04-13 10:29:34 +0100211 int flags)
bellard75c23802004-08-27 21:28:58 +0000212{
213 BlockDriverState *bs;
214 BlockDriver *drv;
215 char password[256];
216
217 bs = bdrv_new("");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900218 if (!bs) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100219 error_report("Not enough memory");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900220 goto fail;
221 }
bellard75c23802004-08-27 21:28:58 +0000222 if (fmt) {
223 drv = bdrv_find_format(fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900224 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100225 error_report("Unknown file format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900226 goto fail;
227 }
bellard75c23802004-08-27 21:28:58 +0000228 } else {
229 drv = NULL;
230 }
Kevin Wolfd6e90982010-03-31 14:40:27 +0200231 if (bdrv_open(bs, filename, flags, drv) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100232 error_report("Could not open '%s'", filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900233 goto fail;
bellard75c23802004-08-27 21:28:58 +0000234 }
235 if (bdrv_is_encrypted(bs)) {
236 printf("Disk image '%s' is encrypted.\n", filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900237 if (read_password(password, sizeof(password)) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100238 error_report("No password given");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900239 goto fail;
240 }
241 if (bdrv_set_key(bs, password) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100242 error_report("invalid password");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900243 goto fail;
244 }
bellard75c23802004-08-27 21:28:58 +0000245 }
246 return bs;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900247fail:
248 if (bs) {
249 bdrv_delete(bs);
250 }
251 return NULL;
bellard75c23802004-08-27 21:28:58 +0000252}
253
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900254static int add_old_style_options(const char *fmt, QEMUOptionParameter *list,
Jes Sorenseneec77d92010-12-07 17:44:34 +0100255 const char *base_filename,
256 const char *base_fmt)
Kevin Wolfefa84d42009-05-18 16:42:12 +0200257{
Kevin Wolfefa84d42009-05-18 16:42:12 +0200258 if (base_filename) {
259 if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100260 error_report("Backing file not supported for file format '%s'",
261 fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900262 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200263 }
264 }
265 if (base_fmt) {
266 if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100267 error_report("Backing file format not supported for file "
268 "format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900269 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200270 }
271 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900272 return 0;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200273}
274
bellardea2384d2004-08-01 21:59:26 +0000275static int img_create(int argc, char **argv)
276{
Jes Sorenseneec77d92010-12-07 17:44:34 +0100277 int c, ret = 0;
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100278 uint64_t img_size = -1;
bellardea2384d2004-08-01 21:59:26 +0000279 const char *fmt = "raw";
aliguori9230eaf2009-03-28 17:55:19 +0000280 const char *base_fmt = NULL;
bellardea2384d2004-08-01 21:59:26 +0000281 const char *filename;
282 const char *base_filename = NULL;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200283 char *options = NULL;
ths3b46e622007-09-17 08:09:54 +0000284
bellardea2384d2004-08-01 21:59:26 +0000285 for(;;) {
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200286 c = getopt(argc, argv, "F:b:f:he6o:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100287 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000288 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100289 }
bellardea2384d2004-08-01 21:59:26 +0000290 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100291 case '?':
bellardea2384d2004-08-01 21:59:26 +0000292 case 'h':
293 help();
294 break;
aliguori9230eaf2009-03-28 17:55:19 +0000295 case 'F':
296 base_fmt = optarg;
297 break;
bellardea2384d2004-08-01 21:59:26 +0000298 case 'b':
299 base_filename = optarg;
300 break;
301 case 'f':
302 fmt = optarg;
303 break;
304 case 'e':
Jes Sorensen15654a62010-12-16 14:31:53 +0100305 error_report("qemu-img: option -e is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100306 "encryption\' instead!");
307 return 1;
thsd8871c52007-10-24 16:11:42 +0000308 case '6':
Jes Sorensen15654a62010-12-16 14:31:53 +0100309 error_report("qemu-img: option -6 is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100310 "compat6\' instead!");
311 return 1;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200312 case 'o':
313 options = optarg;
314 break;
bellardea2384d2004-08-01 21:59:26 +0000315 }
316 }
aliguori9230eaf2009-03-28 17:55:19 +0000317
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900318 /* Get the filename */
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100319 if (optind >= argc) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900320 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100321 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900322 filename = argv[optind++];
323
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100324 /* Get image size, if specified */
325 if (optind < argc) {
326 ssize_t sval;
327 sval = strtosz_suffix(argv[optind++], NULL, STRTOSZ_DEFSUFFIX_B);
328 if (sval < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100329 error_report("Invalid image size specified! You may use k, M, G or "
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100330 "T suffixes for ");
Jes Sorensen15654a62010-12-16 14:31:53 +0100331 error_report("kilobytes, megabytes, gigabytes and terabytes.");
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100332 ret = -1;
333 goto out;
334 }
335 img_size = (uint64_t)sval;
336 }
337
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100338 if (options && !strcmp(options, "?")) {
339 ret = print_block_option_help(filename, fmt);
340 goto out;
341 }
342
Jes Sorensenf88e1a42010-12-16 13:52:15 +0100343 ret = bdrv_img_create(filename, fmt, base_filename, base_fmt,
344 options, img_size, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900345out:
346 if (ret) {
347 return 1;
348 }
bellardea2384d2004-08-01 21:59:26 +0000349 return 0;
350}
351
Kevin Wolfe076f332010-06-29 11:43:13 +0200352/*
353 * Checks an image for consistency. Exit codes:
354 *
355 * 0 - Check completed, image is good
356 * 1 - Check not completed because of internal errors
357 * 2 - Check completed, image is corrupted
358 * 3 - Check completed, image has leaked clusters, but is good otherwise
359 */
aliguori15859692009-04-21 23:11:53 +0000360static int img_check(int argc, char **argv)
361{
362 int c, ret;
363 const char *filename, *fmt;
aliguori15859692009-04-21 23:11:53 +0000364 BlockDriverState *bs;
Kevin Wolfe076f332010-06-29 11:43:13 +0200365 BdrvCheckResult result;
aliguori15859692009-04-21 23:11:53 +0000366
367 fmt = NULL;
368 for(;;) {
369 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100370 if (c == -1) {
aliguori15859692009-04-21 23:11:53 +0000371 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100372 }
aliguori15859692009-04-21 23:11:53 +0000373 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100374 case '?':
aliguori15859692009-04-21 23:11:53 +0000375 case 'h':
376 help();
377 break;
378 case 'f':
379 fmt = optarg;
380 break;
381 }
382 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100383 if (optind >= argc) {
aliguori15859692009-04-21 23:11:53 +0000384 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100385 }
aliguori15859692009-04-21 23:11:53 +0000386 filename = argv[optind++];
387
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100388 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900389 if (!bs) {
390 return 1;
391 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200392 ret = bdrv_check(bs, &result);
393
394 if (ret == -ENOTSUP) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100395 error_report("This image format does not support checks");
Kevin Wolfe076f332010-06-29 11:43:13 +0200396 bdrv_delete(bs);
397 return 1;
398 }
399
400 if (!(result.corruptions || result.leaks || result.check_errors)) {
401 printf("No errors were found on the image.\n");
402 } else {
403 if (result.corruptions) {
404 printf("\n%d errors were found on the image.\n"
405 "Data may be corrupted, or further writes to the image "
406 "may corrupt it.\n",
407 result.corruptions);
aliguori15859692009-04-21 23:11:53 +0000408 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200409
410 if (result.leaks) {
411 printf("\n%d leaked clusters were found on the image.\n"
412 "This means waste of disk space, but no harm to data.\n",
413 result.leaks);
414 }
415
416 if (result.check_errors) {
417 printf("\n%d internal errors have occurred during the check.\n",
418 result.check_errors);
419 }
aliguori15859692009-04-21 23:11:53 +0000420 }
421
422 bdrv_delete(bs);
Kevin Wolfe076f332010-06-29 11:43:13 +0200423
424 if (ret < 0 || result.check_errors) {
425 printf("\nAn error has occurred during the check: %s\n"
426 "The check is not complete and may have missed error.\n",
427 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900428 return 1;
429 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200430
431 if (result.corruptions) {
432 return 2;
433 } else if (result.leaks) {
434 return 3;
435 } else {
436 return 0;
437 }
aliguori15859692009-04-21 23:11:53 +0000438}
439
bellardea2384d2004-08-01 21:59:26 +0000440static int img_commit(int argc, char **argv)
441{
442 int c, ret;
443 const char *filename, *fmt;
bellardea2384d2004-08-01 21:59:26 +0000444 BlockDriverState *bs;
445
446 fmt = NULL;
447 for(;;) {
448 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100449 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000450 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100451 }
bellardea2384d2004-08-01 21:59:26 +0000452 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100453 case '?':
bellardea2384d2004-08-01 21:59:26 +0000454 case 'h':
455 help();
456 break;
457 case 'f':
458 fmt = optarg;
459 break;
460 }
461 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100462 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +0000463 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100464 }
bellardea2384d2004-08-01 21:59:26 +0000465 filename = argv[optind++];
466
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100467 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900468 if (!bs) {
469 return 1;
470 }
bellardea2384d2004-08-01 21:59:26 +0000471 ret = bdrv_commit(bs);
472 switch(ret) {
473 case 0:
474 printf("Image committed.\n");
475 break;
476 case -ENOENT:
Jes Sorensen15654a62010-12-16 14:31:53 +0100477 error_report("No disk inserted");
bellardea2384d2004-08-01 21:59:26 +0000478 break;
479 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +0100480 error_report("Image is read-only");
bellardea2384d2004-08-01 21:59:26 +0000481 break;
482 case -ENOTSUP:
Jes Sorensen15654a62010-12-16 14:31:53 +0100483 error_report("Image is already committed");
bellardea2384d2004-08-01 21:59:26 +0000484 break;
485 default:
Jes Sorensen15654a62010-12-16 14:31:53 +0100486 error_report("Error while committing image");
bellardea2384d2004-08-01 21:59:26 +0000487 break;
488 }
489
490 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900491 if (ret) {
492 return 1;
493 }
bellardea2384d2004-08-01 21:59:26 +0000494 return 0;
495}
496
497static int is_not_zero(const uint8_t *sector, int len)
498{
499 int i;
500 len >>= 2;
501 for(i = 0;i < len; i++) {
502 if (((uint32_t *)sector)[i] != 0)
503 return 1;
504 }
505 return 0;
506}
507
thsf58c7b32008-06-05 21:53:49 +0000508/*
509 * Returns true iff the first sector pointed to by 'buf' contains at least
510 * a non-NUL byte.
511 *
512 * 'pnum' is set to the number of sectors (including and immediately following
513 * the first one) that are known to be in the same allocated/unallocated state.
514 */
bellardea2384d2004-08-01 21:59:26 +0000515static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
516{
517 int v, i;
518
519 if (n <= 0) {
520 *pnum = 0;
521 return 0;
522 }
523 v = is_not_zero(buf, 512);
524 for(i = 1; i < n; i++) {
525 buf += 512;
526 if (v != is_not_zero(buf, 512))
527 break;
528 }
529 *pnum = i;
530 return v;
531}
532
Kevin Wolf3e85c6f2010-01-12 12:55:18 +0100533/*
534 * Compares two buffers sector by sector. Returns 0 if the first sector of both
535 * buffers matches, non-zero otherwise.
536 *
537 * pnum is set to the number of sectors (including and immediately following
538 * the first one) that are known to have the same comparison result
539 */
540static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
541 int *pnum)
542{
543 int res, i;
544
545 if (n <= 0) {
546 *pnum = 0;
547 return 0;
548 }
549
550 res = !!memcmp(buf1, buf2, 512);
551 for(i = 1; i < n; i++) {
552 buf1 += 512;
553 buf2 += 512;
554
555 if (!!memcmp(buf1, buf2, 512) != res) {
556 break;
557 }
558 }
559
560 *pnum = i;
561 return res;
562}
563
Kevin Wolf80ee15a2009-09-15 12:30:43 +0200564#define IO_BUF_SIZE (2 * 1024 * 1024)
bellardea2384d2004-08-01 21:59:26 +0000565
566static int img_convert(int argc, char **argv)
567{
Jes Sorenseneec77d92010-12-07 17:44:34 +0100568 int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;
thsf58c7b32008-06-05 21:53:49 +0000569 const char *fmt, *out_fmt, *out_baseimg, *out_filename;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900570 BlockDriver *drv, *proto_drv;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900571 BlockDriverState **bs = NULL, *out_bs = NULL;
ths96b8f132007-12-17 01:35:20 +0000572 int64_t total_sectors, nb_sectors, sector_num, bs_offset;
573 uint64_t bs_sectors;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900574 uint8_t * buf = NULL;
bellardea2384d2004-08-01 21:59:26 +0000575 const uint8_t *buf1;
bellardfaea38e2006-08-05 21:31:00 +0000576 BlockDriverInfo bdi;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900577 QEMUOptionParameter *param = NULL, *create_options = NULL;
Kevin Wolfa18953f2010-10-14 15:46:04 +0200578 QEMUOptionParameter *out_baseimg_param;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200579 char *options = NULL;
edison51ef6722010-09-21 19:58:41 -0700580 const char *snapshot_name = NULL;
bellardea2384d2004-08-01 21:59:26 +0000581
582 fmt = NULL;
583 out_fmt = "raw";
thsf58c7b32008-06-05 21:53:49 +0000584 out_baseimg = NULL;
Jes Sorenseneec77d92010-12-07 17:44:34 +0100585 compress = 0;
bellardea2384d2004-08-01 21:59:26 +0000586 for(;;) {
edison51ef6722010-09-21 19:58:41 -0700587 c = getopt(argc, argv, "f:O:B:s:hce6o:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100588 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000589 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100590 }
bellardea2384d2004-08-01 21:59:26 +0000591 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100592 case '?':
bellardea2384d2004-08-01 21:59:26 +0000593 case 'h':
594 help();
595 break;
596 case 'f':
597 fmt = optarg;
598 break;
599 case 'O':
600 out_fmt = optarg;
601 break;
thsf58c7b32008-06-05 21:53:49 +0000602 case 'B':
603 out_baseimg = optarg;
604 break;
bellardea2384d2004-08-01 21:59:26 +0000605 case 'c':
Jes Sorenseneec77d92010-12-07 17:44:34 +0100606 compress = 1;
bellardea2384d2004-08-01 21:59:26 +0000607 break;
608 case 'e':
Jes Sorensen15654a62010-12-16 14:31:53 +0100609 error_report("qemu-img: option -e is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100610 "encryption\' instead!");
611 return 1;
thsec36ba12007-09-16 21:59:02 +0000612 case '6':
Jes Sorensen15654a62010-12-16 14:31:53 +0100613 error_report("qemu-img: option -6 is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100614 "compat6\' instead!");
615 return 1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200616 case 'o':
617 options = optarg;
618 break;
edison51ef6722010-09-21 19:58:41 -0700619 case 's':
620 snapshot_name = optarg;
621 break;
bellardea2384d2004-08-01 21:59:26 +0000622 }
623 }
ths3b46e622007-09-17 08:09:54 +0000624
balrog926c2d22007-10-31 01:11:44 +0000625 bs_n = argc - optind - 1;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100626 if (bs_n < 1) {
627 help();
628 }
balrog926c2d22007-10-31 01:11:44 +0000629
630 out_filename = argv[argc - 1];
thsf58c7b32008-06-05 21:53:49 +0000631
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100632 if (options && !strcmp(options, "?")) {
633 ret = print_block_option_help(out_filename, out_fmt);
634 goto out;
635 }
636
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900637 if (bs_n > 1 && out_baseimg) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100638 error_report("-B makes no sense when concatenating multiple input "
639 "images");
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100640 ret = -1;
641 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900642 }
balrog926c2d22007-10-31 01:11:44 +0000643
Jes Sorensen5bdf61f2010-12-06 15:25:35 +0100644 bs = qemu_mallocz(bs_n * sizeof(BlockDriverState *));
balrog926c2d22007-10-31 01:11:44 +0000645
646 total_sectors = 0;
647 for (bs_i = 0; bs_i < bs_n; bs_i++) {
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100648 bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900649 if (!bs[bs_i]) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100650 error_report("Could not open '%s'", argv[optind + bs_i]);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900651 ret = -1;
652 goto out;
653 }
balrog926c2d22007-10-31 01:11:44 +0000654 bdrv_get_geometry(bs[bs_i], &bs_sectors);
655 total_sectors += bs_sectors;
656 }
bellardea2384d2004-08-01 21:59:26 +0000657
edison51ef6722010-09-21 19:58:41 -0700658 if (snapshot_name != NULL) {
659 if (bs_n > 1) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100660 error_report("No support for concatenating multiple snapshot\n");
edison51ef6722010-09-21 19:58:41 -0700661 ret = -1;
662 goto out;
663 }
664 if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100665 error_report("Failed to load snapshot\n");
edison51ef6722010-09-21 19:58:41 -0700666 ret = -1;
667 goto out;
668 }
669 }
670
Kevin Wolfefa84d42009-05-18 16:42:12 +0200671 /* Find driver and parse its options */
bellardea2384d2004-08-01 21:59:26 +0000672 drv = bdrv_find_format(out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900673 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100674 error_report("Unknown file format '%s'", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900675 ret = -1;
676 goto out;
677 }
balrog926c2d22007-10-31 01:11:44 +0000678
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900679 proto_drv = bdrv_find_protocol(out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900680 if (!proto_drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100681 error_report("Unknown protocol '%s'", out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900682 ret = -1;
683 goto out;
684 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900685
686 create_options = append_option_parameters(create_options,
687 drv->create_options);
688 create_options = append_option_parameters(create_options,
689 proto_drv->create_options);
Kevin Wolfdb08adf2009-06-04 15:39:38 +0200690
Kevin Wolfefa84d42009-05-18 16:42:12 +0200691 if (options) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900692 param = parse_option_parameters(options, create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200693 if (param == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100694 error_report("Invalid options for file format '%s'.", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900695 ret = -1;
696 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200697 }
698 } else {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900699 param = parse_option_parameters("", create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200700 }
701
702 set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
Jes Sorenseneec77d92010-12-07 17:44:34 +0100703 ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900704 if (ret < 0) {
705 goto out;
706 }
Kevin Wolfefa84d42009-05-18 16:42:12 +0200707
Kevin Wolfa18953f2010-10-14 15:46:04 +0200708 /* Get backing file name if -o backing_file was used */
709 out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
710 if (out_baseimg_param) {
711 out_baseimg = out_baseimg_param->value.s;
712 }
713
Kevin Wolfefa84d42009-05-18 16:42:12 +0200714 /* Check if compression is supported */
Jes Sorenseneec77d92010-12-07 17:44:34 +0100715 if (compress) {
Kevin Wolfefa84d42009-05-18 16:42:12 +0200716 QEMUOptionParameter *encryption =
717 get_option_parameter(param, BLOCK_OPT_ENCRYPT);
718
719 if (!drv->bdrv_write_compressed) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100720 error_report("Compression not supported for this file format");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900721 ret = -1;
722 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200723 }
724
725 if (encryption && encryption->value.n) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100726 error_report("Compression and encryption not supported at "
727 "the same time");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900728 ret = -1;
729 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200730 }
731 }
732
733 /* Create the new image */
734 ret = bdrv_create(drv, out_filename, param);
bellardea2384d2004-08-01 21:59:26 +0000735 if (ret < 0) {
736 if (ret == -ENOTSUP) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100737 error_report("Formatting not supported for file format '%s'",
738 out_fmt);
aurel326e9ea0c2009-04-15 14:42:46 +0000739 } else if (ret == -EFBIG) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100740 error_report("The image size is too large for file format '%s'",
741 out_fmt);
bellardea2384d2004-08-01 21:59:26 +0000742 } else {
Jes Sorensen15654a62010-12-16 14:31:53 +0100743 error_report("%s: error while converting %s: %s",
744 out_filename, out_fmt, strerror(-ret));
bellardea2384d2004-08-01 21:59:26 +0000745 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900746 goto out;
bellardea2384d2004-08-01 21:59:26 +0000747 }
ths3b46e622007-09-17 08:09:54 +0000748
Kevin Wolf1bd8e172010-08-31 13:44:25 +0200749 out_bs = bdrv_new_open(out_filename, out_fmt,
750 BDRV_O_FLAGS | BDRV_O_RDWR | BDRV_O_NO_FLUSH);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900751 if (!out_bs) {
752 ret = -1;
753 goto out;
754 }
bellardea2384d2004-08-01 21:59:26 +0000755
balrog926c2d22007-10-31 01:11:44 +0000756 bs_i = 0;
757 bs_offset = 0;
758 bdrv_get_geometry(bs[0], &bs_sectors);
TeLeMand6771bf2010-02-08 16:20:00 +0800759 buf = qemu_malloc(IO_BUF_SIZE);
balrog926c2d22007-10-31 01:11:44 +0000760
Jes Sorenseneec77d92010-12-07 17:44:34 +0100761 if (compress) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900762 ret = bdrv_get_info(out_bs, &bdi);
763 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100764 error_report("could not get block driver info");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900765 goto out;
766 }
bellardfaea38e2006-08-05 21:31:00 +0000767 cluster_size = bdi.cluster_size;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900768 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100769 error_report("invalid cluster size");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900770 ret = -1;
771 goto out;
772 }
bellardea2384d2004-08-01 21:59:26 +0000773 cluster_sectors = cluster_size >> 9;
774 sector_num = 0;
775 for(;;) {
balrog926c2d22007-10-31 01:11:44 +0000776 int64_t bs_num;
777 int remainder;
778 uint8_t *buf2;
779
bellardea2384d2004-08-01 21:59:26 +0000780 nb_sectors = total_sectors - sector_num;
781 if (nb_sectors <= 0)
782 break;
783 if (nb_sectors >= cluster_sectors)
784 n = cluster_sectors;
785 else
786 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000787
788 bs_num = sector_num - bs_offset;
789 assert (bs_num >= 0);
790 remainder = n;
791 buf2 = buf;
792 while (remainder > 0) {
793 int nlow;
794 while (bs_num == bs_sectors) {
795 bs_i++;
796 assert (bs_i < bs_n);
797 bs_offset += bs_sectors;
798 bdrv_get_geometry(bs[bs_i], &bs_sectors);
799 bs_num = 0;
Blue Swirl0bfcd592010-05-22 08:02:12 +0000800 /* printf("changing part: sector_num=%" PRId64 ", "
801 "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64
802 "\n", sector_num, bs_i, bs_offset, bs_sectors); */
balrog926c2d22007-10-31 01:11:44 +0000803 }
804 assert (bs_num < bs_sectors);
805
806 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
807
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900808 ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
809 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100810 error_report("error while reading");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900811 goto out;
812 }
balrog926c2d22007-10-31 01:11:44 +0000813
814 buf2 += nlow * 512;
815 bs_num += nlow;
816
817 remainder -= nlow;
818 }
819 assert (remainder == 0);
820
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100821 if (n < cluster_sectors) {
bellardea2384d2004-08-01 21:59:26 +0000822 memset(buf + n * 512, 0, cluster_size - n * 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100823 }
bellardea2384d2004-08-01 21:59:26 +0000824 if (is_not_zero(buf, cluster_size)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900825 ret = bdrv_write_compressed(out_bs, sector_num, buf,
826 cluster_sectors);
827 if (ret != 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100828 error_report("error while compressing sector %" PRId64,
bellardec3757d2006-06-14 15:50:07 +0000829 sector_num);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900830 goto out;
831 }
bellardea2384d2004-08-01 21:59:26 +0000832 }
833 sector_num += n;
834 }
bellardfaea38e2006-08-05 21:31:00 +0000835 /* signal EOF to align */
836 bdrv_write_compressed(out_bs, 0, NULL, 0);
bellardea2384d2004-08-01 21:59:26 +0000837 } else {
Kevin Wolff2feebb2010-04-14 17:30:35 +0200838 int has_zero_init = bdrv_has_zero_init(out_bs);
839
thsf58c7b32008-06-05 21:53:49 +0000840 sector_num = 0; // total number of sectors converted so far
bellardea2384d2004-08-01 21:59:26 +0000841 for(;;) {
842 nb_sectors = total_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100843 if (nb_sectors <= 0) {
bellardea2384d2004-08-01 21:59:26 +0000844 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100845 }
846 if (nb_sectors >= (IO_BUF_SIZE / 512)) {
bellardea2384d2004-08-01 21:59:26 +0000847 n = (IO_BUF_SIZE / 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100848 } else {
bellardea2384d2004-08-01 21:59:26 +0000849 n = nb_sectors;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100850 }
balrog926c2d22007-10-31 01:11:44 +0000851
852 while (sector_num - bs_offset >= bs_sectors) {
853 bs_i ++;
854 assert (bs_i < bs_n);
855 bs_offset += bs_sectors;
856 bdrv_get_geometry(bs[bs_i], &bs_sectors);
Blue Swirl0bfcd592010-05-22 08:02:12 +0000857 /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "
858 "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",
balrog926c2d22007-10-31 01:11:44 +0000859 sector_num, bs_i, bs_offset, bs_sectors); */
860 }
861
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100862 if (n > bs_offset + bs_sectors - sector_num) {
balrog926c2d22007-10-31 01:11:44 +0000863 n = bs_offset + bs_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100864 }
balrog926c2d22007-10-31 01:11:44 +0000865
Kevin Wolff2feebb2010-04-14 17:30:35 +0200866 if (has_zero_init) {
Akkarit Sangpetchd0320442009-07-17 10:02:15 +0200867 /* If the output image is being created as a copy on write image,
868 assume that sectors which are unallocated in the input image
869 are present in both the output's and input's base images (no
870 need to copy them). */
871 if (out_baseimg) {
872 if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
873 n, &n1)) {
874 sector_num += n1;
875 continue;
876 }
877 /* The next 'n1' sectors are allocated in the input image. Copy
878 only those as they may be followed by unallocated sectors. */
879 n = n1;
aliguori93c65b42009-04-05 17:40:43 +0000880 }
aliguori93c65b42009-04-05 17:40:43 +0000881 } else {
882 n1 = n;
thsf58c7b32008-06-05 21:53:49 +0000883 }
884
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900885 ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
886 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100887 error_report("error while reading");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900888 goto out;
889 }
bellardea2384d2004-08-01 21:59:26 +0000890 /* NOTE: at the same time we convert, we do not write zero
891 sectors to have a chance to compress the image. Ideally, we
892 should add a specific call to have the info to go faster */
893 buf1 = buf;
894 while (n > 0) {
thsf58c7b32008-06-05 21:53:49 +0000895 /* If the output image is being created as a copy on write image,
896 copy all sectors even the ones containing only NUL bytes,
aliguori93c65b42009-04-05 17:40:43 +0000897 because they may differ from the sectors in the base image.
898
899 If the output is to a host device, we also write out
900 sectors that are entirely 0, since whatever data was
901 already there is garbage, not 0s. */
Kevin Wolff2feebb2010-04-14 17:30:35 +0200902 if (!has_zero_init || out_baseimg ||
aliguori93c65b42009-04-05 17:40:43 +0000903 is_allocated_sectors(buf1, n, &n1)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900904 ret = bdrv_write(out_bs, sector_num, buf1, n1);
905 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100906 error_report("error while writing");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900907 goto out;
908 }
bellardea2384d2004-08-01 21:59:26 +0000909 }
910 sector_num += n1;
911 n -= n1;
912 buf1 += n1 * 512;
913 }
914 }
915 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900916out:
917 free_option_parameters(create_options);
918 free_option_parameters(param);
TeLeMand6771bf2010-02-08 16:20:00 +0800919 qemu_free(buf);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900920 if (out_bs) {
921 bdrv_delete(out_bs);
922 }
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100923 if (bs) {
924 for (bs_i = 0; bs_i < bs_n; bs_i++) {
925 if (bs[bs_i]) {
926 bdrv_delete(bs[bs_i]);
927 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900928 }
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100929 qemu_free(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900930 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900931 if (ret) {
932 return 1;
933 }
bellardea2384d2004-08-01 21:59:26 +0000934 return 0;
935}
936
bellard57d1a2b2004-08-03 21:15:11 +0000937#ifdef _WIN32
938static int64_t get_allocated_file_size(const char *filename)
939{
bellarde8445332006-06-14 15:32:10 +0000940 typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
941 get_compressed_t get_compressed;
bellard57d1a2b2004-08-03 21:15:11 +0000942 struct _stati64 st;
bellarde8445332006-06-14 15:32:10 +0000943
944 /* WinNT support GetCompressedFileSize to determine allocate size */
945 get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
946 if (get_compressed) {
947 DWORD high, low;
948 low = get_compressed(filename, &high);
949 if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
950 return (((int64_t) high) << 32) + low;
951 }
952
ths5fafdf22007-09-16 21:08:06 +0000953 if (_stati64(filename, &st) < 0)
bellard57d1a2b2004-08-03 21:15:11 +0000954 return -1;
955 return st.st_size;
956}
957#else
958static int64_t get_allocated_file_size(const char *filename)
959{
960 struct stat st;
ths5fafdf22007-09-16 21:08:06 +0000961 if (stat(filename, &st) < 0)
bellard57d1a2b2004-08-03 21:15:11 +0000962 return -1;
963 return (int64_t)st.st_blocks * 512;
964}
965#endif
966
bellardfaea38e2006-08-05 21:31:00 +0000967static void dump_snapshots(BlockDriverState *bs)
968{
969 QEMUSnapshotInfo *sn_tab, *sn;
970 int nb_sns, i;
971 char buf[256];
972
973 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
974 if (nb_sns <= 0)
975 return;
976 printf("Snapshot list:\n");
977 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
978 for(i = 0; i < nb_sns; i++) {
979 sn = &sn_tab[i];
980 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
981 }
982 qemu_free(sn_tab);
983}
984
bellardea2384d2004-08-01 21:59:26 +0000985static int img_info(int argc, char **argv)
986{
987 int c;
988 const char *filename, *fmt;
bellardea2384d2004-08-01 21:59:26 +0000989 BlockDriverState *bs;
990 char fmt_name[128], size_buf[128], dsize_buf[128];
ths96b8f132007-12-17 01:35:20 +0000991 uint64_t total_sectors;
992 int64_t allocated_size;
bellard93b6b2a2006-08-01 15:51:11 +0000993 char backing_filename[1024];
994 char backing_filename2[1024];
bellardfaea38e2006-08-05 21:31:00 +0000995 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +0000996
997 fmt = NULL;
998 for(;;) {
999 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001000 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +00001001 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001002 }
bellardea2384d2004-08-01 21:59:26 +00001003 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001004 case '?':
bellardea2384d2004-08-01 21:59:26 +00001005 case 'h':
1006 help();
1007 break;
1008 case 'f':
1009 fmt = optarg;
1010 break;
1011 }
1012 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001013 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +00001014 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001015 }
bellardea2384d2004-08-01 21:59:26 +00001016 filename = argv[optind++];
1017
Stefan Hajnocziadfe0782010-04-13 10:29:35 +01001018 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001019 if (!bs) {
1020 return 1;
1021 }
bellardea2384d2004-08-01 21:59:26 +00001022 bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
1023 bdrv_get_geometry(bs, &total_sectors);
1024 get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
bellard57d1a2b2004-08-03 21:15:11 +00001025 allocated_size = get_allocated_file_size(filename);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001026 if (allocated_size < 0) {
blueswir1a10ea302008-08-24 10:30:33 +00001027 snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001028 } else {
ths5fafdf22007-09-16 21:08:06 +00001029 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
bellardde167e42005-04-28 21:15:08 +00001030 allocated_size);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001031 }
bellardea2384d2004-08-01 21:59:26 +00001032 printf("image: %s\n"
1033 "file format: %s\n"
bellardec3757d2006-06-14 15:50:07 +00001034 "virtual size: %s (%" PRId64 " bytes)\n"
bellardea2384d2004-08-01 21:59:26 +00001035 "disk size: %s\n",
ths5fafdf22007-09-16 21:08:06 +00001036 filename, fmt_name, size_buf,
bellardec3757d2006-06-14 15:50:07 +00001037 (total_sectors * 512),
bellardea2384d2004-08-01 21:59:26 +00001038 dsize_buf);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001039 if (bdrv_is_encrypted(bs)) {
bellardea2384d2004-08-01 21:59:26 +00001040 printf("encrypted: yes\n");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001041 }
bellardfaea38e2006-08-05 21:31:00 +00001042 if (bdrv_get_info(bs, &bdi) >= 0) {
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001043 if (bdi.cluster_size != 0) {
bellardfaea38e2006-08-05 21:31:00 +00001044 printf("cluster_size: %d\n", bdi.cluster_size);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001045 }
bellardfaea38e2006-08-05 21:31:00 +00001046 }
bellard93b6b2a2006-08-01 15:51:11 +00001047 bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
bellardfaea38e2006-08-05 21:31:00 +00001048 if (backing_filename[0] != '\0') {
bellard93b6b2a2006-08-01 15:51:11 +00001049 path_combine(backing_filename2, sizeof(backing_filename2),
1050 filename, backing_filename);
ths5fafdf22007-09-16 21:08:06 +00001051 printf("backing file: %s (actual path: %s)\n",
bellard93b6b2a2006-08-01 15:51:11 +00001052 backing_filename,
1053 backing_filename2);
bellardfaea38e2006-08-05 21:31:00 +00001054 }
1055 dump_snapshots(bs);
bellardea2384d2004-08-01 21:59:26 +00001056 bdrv_delete(bs);
1057 return 0;
1058}
1059
aliguorif7b4a942009-01-07 17:40:15 +00001060#define SNAPSHOT_LIST 1
1061#define SNAPSHOT_CREATE 2
1062#define SNAPSHOT_APPLY 3
1063#define SNAPSHOT_DELETE 4
1064
Stuart Brady153859b2009-06-07 00:42:17 +01001065static int img_snapshot(int argc, char **argv)
aliguorif7b4a942009-01-07 17:40:15 +00001066{
1067 BlockDriverState *bs;
1068 QEMUSnapshotInfo sn;
1069 char *filename, *snapshot_name = NULL;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001070 int c, ret = 0, bdrv_oflags;
aliguorif7b4a942009-01-07 17:40:15 +00001071 int action = 0;
1072 qemu_timeval tv;
1073
Naphtali Spreif5edb012010-01-17 16:48:13 +02001074 bdrv_oflags = BDRV_O_RDWR;
aliguorif7b4a942009-01-07 17:40:15 +00001075 /* Parse commandline parameters */
1076 for(;;) {
1077 c = getopt(argc, argv, "la:c:d:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001078 if (c == -1) {
aliguorif7b4a942009-01-07 17:40:15 +00001079 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001080 }
aliguorif7b4a942009-01-07 17:40:15 +00001081 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001082 case '?':
aliguorif7b4a942009-01-07 17:40:15 +00001083 case 'h':
1084 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001085 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001086 case 'l':
1087 if (action) {
1088 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001089 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001090 }
1091 action = SNAPSHOT_LIST;
Naphtali Spreif5edb012010-01-17 16:48:13 +02001092 bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
aliguorif7b4a942009-01-07 17:40:15 +00001093 break;
1094 case 'a':
1095 if (action) {
1096 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001097 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001098 }
1099 action = SNAPSHOT_APPLY;
1100 snapshot_name = optarg;
1101 break;
1102 case 'c':
1103 if (action) {
1104 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001105 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001106 }
1107 action = SNAPSHOT_CREATE;
1108 snapshot_name = optarg;
1109 break;
1110 case 'd':
1111 if (action) {
1112 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001113 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001114 }
1115 action = SNAPSHOT_DELETE;
1116 snapshot_name = optarg;
1117 break;
1118 }
1119 }
1120
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001121 if (optind >= argc) {
aliguorif7b4a942009-01-07 17:40:15 +00001122 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001123 }
aliguorif7b4a942009-01-07 17:40:15 +00001124 filename = argv[optind++];
1125
1126 /* Open the image */
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001127 bs = bdrv_new_open(filename, NULL, bdrv_oflags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001128 if (!bs) {
1129 return 1;
1130 }
aliguorif7b4a942009-01-07 17:40:15 +00001131
1132 /* Perform the requested action */
1133 switch(action) {
1134 case SNAPSHOT_LIST:
1135 dump_snapshots(bs);
1136 break;
1137
1138 case SNAPSHOT_CREATE:
1139 memset(&sn, 0, sizeof(sn));
1140 pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
1141
1142 qemu_gettimeofday(&tv);
1143 sn.date_sec = tv.tv_sec;
1144 sn.date_nsec = tv.tv_usec * 1000;
1145
1146 ret = bdrv_snapshot_create(bs, &sn);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001147 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001148 error_report("Could not create snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001149 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001150 }
aliguorif7b4a942009-01-07 17:40:15 +00001151 break;
1152
1153 case SNAPSHOT_APPLY:
1154 ret = bdrv_snapshot_goto(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001155 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001156 error_report("Could not apply snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001157 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001158 }
aliguorif7b4a942009-01-07 17:40:15 +00001159 break;
1160
1161 case SNAPSHOT_DELETE:
1162 ret = bdrv_snapshot_delete(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001163 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001164 error_report("Could not delete snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001165 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001166 }
aliguorif7b4a942009-01-07 17:40:15 +00001167 break;
1168 }
1169
1170 /* Cleanup */
1171 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001172 if (ret) {
1173 return 1;
1174 }
Stuart Brady153859b2009-06-07 00:42:17 +01001175 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001176}
1177
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001178static int img_rebase(int argc, char **argv)
1179{
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001180 BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001181 BlockDriver *old_backing_drv, *new_backing_drv;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001182 char *filename;
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001183 const char *fmt, *out_basefmt, *out_baseimg;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001184 int c, flags, ret;
1185 int unsafe = 0;
1186
1187 /* Parse commandline parameters */
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001188 fmt = NULL;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001189 out_baseimg = NULL;
1190 out_basefmt = NULL;
1191
1192 for(;;) {
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001193 c = getopt(argc, argv, "uhf:F:b:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001194 if (c == -1) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001195 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001196 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001197 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001198 case '?':
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001199 case 'h':
1200 help();
1201 return 0;
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001202 case 'f':
1203 fmt = optarg;
1204 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001205 case 'F':
1206 out_basefmt = optarg;
1207 break;
1208 case 'b':
1209 out_baseimg = optarg;
1210 break;
1211 case 'u':
1212 unsafe = 1;
1213 break;
1214 }
1215 }
1216
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001217 if ((optind >= argc) || !out_baseimg) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001218 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001219 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001220 filename = argv[optind++];
1221
1222 /*
1223 * Open the images.
1224 *
1225 * Ignore the old backing file for unsafe rebase in case we want to correct
1226 * the reference to a renamed or moved backing file.
1227 */
Stefan Hajnocziadfe0782010-04-13 10:29:35 +01001228 flags = BDRV_O_FLAGS | BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001229 bs = bdrv_new_open(filename, fmt, flags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001230 if (!bs) {
1231 return 1;
1232 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001233
1234 /* Find the right drivers for the backing files */
1235 old_backing_drv = NULL;
1236 new_backing_drv = NULL;
1237
1238 if (!unsafe && bs->backing_format[0] != '\0') {
1239 old_backing_drv = bdrv_find_format(bs->backing_format);
1240 if (old_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001241 error_report("Invalid format name: '%s'", bs->backing_format);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001242 ret = -1;
1243 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001244 }
1245 }
1246
1247 if (out_basefmt != NULL) {
1248 new_backing_drv = bdrv_find_format(out_basefmt);
1249 if (new_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001250 error_report("Invalid format name: '%s'", out_basefmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001251 ret = -1;
1252 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001253 }
1254 }
1255
1256 /* For safe rebasing we need to compare old and new backing file */
1257 if (unsafe) {
1258 /* Make the compiler happy */
1259 bs_old_backing = NULL;
1260 bs_new_backing = NULL;
1261 } else {
1262 char backing_name[1024];
1263
1264 bs_old_backing = bdrv_new("old_backing");
1265 bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001266 ret = bdrv_open(bs_old_backing, backing_name, BDRV_O_FLAGS,
1267 old_backing_drv);
1268 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001269 error_report("Could not open old backing file '%s'", backing_name);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001270 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001271 }
1272
1273 bs_new_backing = bdrv_new("new_backing");
Kevin Wolfcdbae852010-08-17 18:58:55 +02001274 ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS,
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001275 new_backing_drv);
1276 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001277 error_report("Could not open new backing file '%s'", out_baseimg);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001278 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001279 }
1280 }
1281
1282 /*
1283 * Check each unallocated cluster in the COW file. If it is unallocated,
1284 * accesses go to the backing file. We must therefore compare this cluster
1285 * in the old and new backing file, and if they differ we need to copy it
1286 * from the old backing file into the COW file.
1287 *
1288 * If qemu-img crashes during this step, no harm is done. The content of
1289 * the image is the same as the original one at any time.
1290 */
1291 if (!unsafe) {
1292 uint64_t num_sectors;
1293 uint64_t sector;
Kevin Wolfcc60e322010-04-29 14:47:48 +02001294 int n;
TeLeMand6771bf2010-02-08 16:20:00 +08001295 uint8_t * buf_old;
1296 uint8_t * buf_new;
1297
1298 buf_old = qemu_malloc(IO_BUF_SIZE);
1299 buf_new = qemu_malloc(IO_BUF_SIZE);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001300
1301 bdrv_get_geometry(bs, &num_sectors);
1302
1303 for (sector = 0; sector < num_sectors; sector += n) {
1304
1305 /* How many sectors can we handle with the next read? */
1306 if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
1307 n = (IO_BUF_SIZE / 512);
1308 } else {
1309 n = num_sectors - sector;
1310 }
1311
1312 /* If the cluster is allocated, we don't need to take action */
Kevin Wolfcc60e322010-04-29 14:47:48 +02001313 ret = bdrv_is_allocated(bs, sector, n, &n);
1314 if (ret) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001315 continue;
1316 }
1317
1318 /* Read old and new backing file */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001319 ret = bdrv_read(bs_old_backing, sector, buf_old, n);
1320 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001321 error_report("error while reading from old backing file");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001322 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001323 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001324 ret = bdrv_read(bs_new_backing, sector, buf_new, n);
1325 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001326 error_report("error while reading from new backing file");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001327 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001328 }
1329
1330 /* If they differ, we need to write to the COW file */
1331 uint64_t written = 0;
1332
1333 while (written < n) {
1334 int pnum;
1335
1336 if (compare_sectors(buf_old + written * 512,
Kevin Wolf60b1bd42010-02-17 12:32:59 +01001337 buf_new + written * 512, n - written, &pnum))
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001338 {
1339 ret = bdrv_write(bs, sector + written,
1340 buf_old + written * 512, pnum);
1341 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001342 error_report("Error while writing to COW image: %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001343 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001344 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001345 }
1346 }
1347
1348 written += pnum;
1349 }
1350 }
TeLeMand6771bf2010-02-08 16:20:00 +08001351
1352 qemu_free(buf_old);
1353 qemu_free(buf_new);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001354 }
1355
1356 /*
1357 * Change the backing file. All clusters that are different from the old
1358 * backing file are overwritten in the COW file now, so the visible content
1359 * doesn't change when we switch the backing file.
1360 */
1361 ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
1362 if (ret == -ENOSPC) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001363 error_report("Could not change the backing file to '%s': No "
1364 "space left in the file header", out_baseimg);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001365 } else if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001366 error_report("Could not change the backing file to '%s': %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001367 out_baseimg, strerror(-ret));
1368 }
1369
1370 /*
1371 * TODO At this point it is possible to check if any clusters that are
1372 * allocated in the COW file are the same in the backing file. If so, they
1373 * could be dropped from the COW file. Don't do this before switching the
1374 * backing file, in case of a crash this would lead to corruption.
1375 */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001376out:
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001377 /* Cleanup */
1378 if (!unsafe) {
1379 bdrv_delete(bs_old_backing);
1380 bdrv_delete(bs_new_backing);
1381 }
1382
1383 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001384 if (ret) {
1385 return 1;
1386 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001387 return 0;
1388}
1389
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001390static int img_resize(int argc, char **argv)
1391{
1392 int c, ret, relative;
1393 const char *filename, *fmt, *size;
1394 int64_t n, total_size;
Jes Sorensen2a819982010-12-06 17:08:31 +01001395 BlockDriverState *bs = NULL;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001396 QEMUOptionParameter *param;
1397 QEMUOptionParameter resize_options[] = {
1398 {
1399 .name = BLOCK_OPT_SIZE,
1400 .type = OPT_SIZE,
1401 .help = "Virtual disk size"
1402 },
1403 { NULL }
1404 };
1405
1406 fmt = NULL;
1407 for(;;) {
1408 c = getopt(argc, argv, "f:h");
1409 if (c == -1) {
1410 break;
1411 }
1412 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001413 case '?':
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001414 case 'h':
1415 help();
1416 break;
1417 case 'f':
1418 fmt = optarg;
1419 break;
1420 }
1421 }
1422 if (optind + 1 >= argc) {
1423 help();
1424 }
1425 filename = argv[optind++];
1426 size = argv[optind++];
1427
1428 /* Choose grow, shrink, or absolute resize mode */
1429 switch (size[0]) {
1430 case '+':
1431 relative = 1;
1432 size++;
1433 break;
1434 case '-':
1435 relative = -1;
1436 size++;
1437 break;
1438 default:
1439 relative = 0;
1440 break;
1441 }
1442
1443 /* Parse size */
1444 param = parse_option_parameters("", resize_options, NULL);
1445 if (set_option_parameter(param, BLOCK_OPT_SIZE, size)) {
1446 /* Error message already printed when size parsing fails */
Jes Sorensen2a819982010-12-06 17:08:31 +01001447 ret = -1;
1448 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001449 }
1450 n = get_option_parameter(param, BLOCK_OPT_SIZE)->value.n;
1451 free_option_parameters(param);
1452
1453 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001454 if (!bs) {
Jes Sorensen2a819982010-12-06 17:08:31 +01001455 ret = -1;
1456 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001457 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001458
1459 if (relative) {
1460 total_size = bdrv_getlength(bs) + n * relative;
1461 } else {
1462 total_size = n;
1463 }
1464 if (total_size <= 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001465 error_report("New image size must be positive");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001466 ret = -1;
1467 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001468 }
1469
1470 ret = bdrv_truncate(bs, total_size);
1471 switch (ret) {
1472 case 0:
1473 printf("Image resized.\n");
1474 break;
1475 case -ENOTSUP:
Jes Sorensen15654a62010-12-16 14:31:53 +01001476 error_report("This image format does not support resize");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001477 break;
1478 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +01001479 error_report("Image is read-only");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001480 break;
1481 default:
Jes Sorensen15654a62010-12-16 14:31:53 +01001482 error_report("Error resizing image (%d)", -ret);
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001483 break;
1484 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001485out:
Jes Sorensen2a819982010-12-06 17:08:31 +01001486 if (bs) {
1487 bdrv_delete(bs);
1488 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001489 if (ret) {
1490 return 1;
1491 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001492 return 0;
1493}
1494
Anthony Liguoric227f092009-10-01 16:12:16 -05001495static const img_cmd_t img_cmds[] = {
Stuart Brady153859b2009-06-07 00:42:17 +01001496#define DEF(option, callback, arg_string) \
1497 { option, callback },
1498#include "qemu-img-cmds.h"
1499#undef DEF
1500#undef GEN_DOCS
1501 { NULL, NULL, },
1502};
1503
bellardea2384d2004-08-01 21:59:26 +00001504int main(int argc, char **argv)
1505{
Anthony Liguoric227f092009-10-01 16:12:16 -05001506 const img_cmd_t *cmd;
Stuart Brady153859b2009-06-07 00:42:17 +01001507 const char *cmdname;
bellardea2384d2004-08-01 21:59:26 +00001508
Kevin Wolf53f76e52010-12-16 15:10:32 +01001509 error_set_progname(argv[0]);
1510
bellardea2384d2004-08-01 21:59:26 +00001511 bdrv_init();
1512 if (argc < 2)
1513 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001514 cmdname = argv[1];
aurel328f9b1572009-02-09 18:14:31 +00001515 argc--; argv++;
Stuart Brady153859b2009-06-07 00:42:17 +01001516
1517 /* find the command */
1518 for(cmd = img_cmds; cmd->name != NULL; cmd++) {
1519 if (!strcmp(cmdname, cmd->name)) {
1520 return cmd->handler(argc, argv);
1521 }
bellardea2384d2004-08-01 21:59:26 +00001522 }
Stuart Brady153859b2009-06-07 00:42:17 +01001523
1524 /* not found */
1525 help();
bellardea2384d2004-08-01 21:59:26 +00001526 return 0;
1527}