blob: 4a3735811c64a6508760d475583e04d3b77b0f8c [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("");
Kevin Wolfad717132010-12-16 15:37:41 +0100218
bellard75c23802004-08-27 21:28:58 +0000219 if (fmt) {
220 drv = bdrv_find_format(fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900221 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100222 error_report("Unknown file format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900223 goto fail;
224 }
bellard75c23802004-08-27 21:28:58 +0000225 } else {
226 drv = NULL;
227 }
Kevin Wolfd6e90982010-03-31 14:40:27 +0200228 if (bdrv_open(bs, filename, flags, drv) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100229 error_report("Could not open '%s'", filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900230 goto fail;
bellard75c23802004-08-27 21:28:58 +0000231 }
232 if (bdrv_is_encrypted(bs)) {
233 printf("Disk image '%s' is encrypted.\n", filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900234 if (read_password(password, sizeof(password)) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100235 error_report("No password given");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900236 goto fail;
237 }
238 if (bdrv_set_key(bs, password) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100239 error_report("invalid password");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900240 goto fail;
241 }
bellard75c23802004-08-27 21:28:58 +0000242 }
243 return bs;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900244fail:
245 if (bs) {
246 bdrv_delete(bs);
247 }
248 return NULL;
bellard75c23802004-08-27 21:28:58 +0000249}
250
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900251static int add_old_style_options(const char *fmt, QEMUOptionParameter *list,
Jes Sorenseneec77d92010-12-07 17:44:34 +0100252 const char *base_filename,
253 const char *base_fmt)
Kevin Wolfefa84d42009-05-18 16:42:12 +0200254{
Kevin Wolfefa84d42009-05-18 16:42:12 +0200255 if (base_filename) {
256 if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100257 error_report("Backing file not supported for file format '%s'",
258 fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900259 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200260 }
261 }
262 if (base_fmt) {
263 if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100264 error_report("Backing file format not supported for file "
265 "format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900266 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200267 }
268 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900269 return 0;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200270}
271
bellardea2384d2004-08-01 21:59:26 +0000272static int img_create(int argc, char **argv)
273{
Jes Sorenseneec77d92010-12-07 17:44:34 +0100274 int c, ret = 0;
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100275 uint64_t img_size = -1;
bellardea2384d2004-08-01 21:59:26 +0000276 const char *fmt = "raw";
aliguori9230eaf2009-03-28 17:55:19 +0000277 const char *base_fmt = NULL;
bellardea2384d2004-08-01 21:59:26 +0000278 const char *filename;
279 const char *base_filename = NULL;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200280 char *options = NULL;
ths3b46e622007-09-17 08:09:54 +0000281
bellardea2384d2004-08-01 21:59:26 +0000282 for(;;) {
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200283 c = getopt(argc, argv, "F:b:f:he6o:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100284 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000285 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100286 }
bellardea2384d2004-08-01 21:59:26 +0000287 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100288 case '?':
bellardea2384d2004-08-01 21:59:26 +0000289 case 'h':
290 help();
291 break;
aliguori9230eaf2009-03-28 17:55:19 +0000292 case 'F':
293 base_fmt = optarg;
294 break;
bellardea2384d2004-08-01 21:59:26 +0000295 case 'b':
296 base_filename = optarg;
297 break;
298 case 'f':
299 fmt = optarg;
300 break;
301 case 'e':
Jes Sorensen15654a62010-12-16 14:31:53 +0100302 error_report("qemu-img: option -e is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100303 "encryption\' instead!");
304 return 1;
thsd8871c52007-10-24 16:11:42 +0000305 case '6':
Jes Sorensen15654a62010-12-16 14:31:53 +0100306 error_report("qemu-img: option -6 is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100307 "compat6\' instead!");
308 return 1;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200309 case 'o':
310 options = optarg;
311 break;
bellardea2384d2004-08-01 21:59:26 +0000312 }
313 }
aliguori9230eaf2009-03-28 17:55:19 +0000314
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900315 /* Get the filename */
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100316 if (optind >= argc) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900317 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100318 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900319 filename = argv[optind++];
320
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100321 /* Get image size, if specified */
322 if (optind < argc) {
Jes Sorensen70b4f4b2011-01-05 11:41:02 +0100323 int64_t sval;
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100324 sval = strtosz_suffix(argv[optind++], NULL, STRTOSZ_DEFSUFFIX_B);
325 if (sval < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100326 error_report("Invalid image size specified! You may use k, M, G or "
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100327 "T suffixes for ");
Jes Sorensen15654a62010-12-16 14:31:53 +0100328 error_report("kilobytes, megabytes, gigabytes and terabytes.");
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100329 ret = -1;
330 goto out;
331 }
332 img_size = (uint64_t)sval;
333 }
334
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100335 if (options && !strcmp(options, "?")) {
336 ret = print_block_option_help(filename, fmt);
337 goto out;
338 }
339
Jes Sorensenf88e1a42010-12-16 13:52:15 +0100340 ret = bdrv_img_create(filename, fmt, base_filename, base_fmt,
341 options, img_size, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900342out:
343 if (ret) {
344 return 1;
345 }
bellardea2384d2004-08-01 21:59:26 +0000346 return 0;
347}
348
Kevin Wolfe076f332010-06-29 11:43:13 +0200349/*
350 * Checks an image for consistency. Exit codes:
351 *
352 * 0 - Check completed, image is good
353 * 1 - Check not completed because of internal errors
354 * 2 - Check completed, image is corrupted
355 * 3 - Check completed, image has leaked clusters, but is good otherwise
356 */
aliguori15859692009-04-21 23:11:53 +0000357static int img_check(int argc, char **argv)
358{
359 int c, ret;
360 const char *filename, *fmt;
aliguori15859692009-04-21 23:11:53 +0000361 BlockDriverState *bs;
Kevin Wolfe076f332010-06-29 11:43:13 +0200362 BdrvCheckResult result;
aliguori15859692009-04-21 23:11:53 +0000363
364 fmt = NULL;
365 for(;;) {
366 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100367 if (c == -1) {
aliguori15859692009-04-21 23:11:53 +0000368 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100369 }
aliguori15859692009-04-21 23:11:53 +0000370 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100371 case '?':
aliguori15859692009-04-21 23:11:53 +0000372 case 'h':
373 help();
374 break;
375 case 'f':
376 fmt = optarg;
377 break;
378 }
379 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100380 if (optind >= argc) {
aliguori15859692009-04-21 23:11:53 +0000381 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100382 }
aliguori15859692009-04-21 23:11:53 +0000383 filename = argv[optind++];
384
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100385 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900386 if (!bs) {
387 return 1;
388 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200389 ret = bdrv_check(bs, &result);
390
391 if (ret == -ENOTSUP) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100392 error_report("This image format does not support checks");
Kevin Wolfe076f332010-06-29 11:43:13 +0200393 bdrv_delete(bs);
394 return 1;
395 }
396
397 if (!(result.corruptions || result.leaks || result.check_errors)) {
398 printf("No errors were found on the image.\n");
399 } else {
400 if (result.corruptions) {
401 printf("\n%d errors were found on the image.\n"
402 "Data may be corrupted, or further writes to the image "
403 "may corrupt it.\n",
404 result.corruptions);
aliguori15859692009-04-21 23:11:53 +0000405 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200406
407 if (result.leaks) {
408 printf("\n%d leaked clusters were found on the image.\n"
409 "This means waste of disk space, but no harm to data.\n",
410 result.leaks);
411 }
412
413 if (result.check_errors) {
414 printf("\n%d internal errors have occurred during the check.\n",
415 result.check_errors);
416 }
aliguori15859692009-04-21 23:11:53 +0000417 }
418
419 bdrv_delete(bs);
Kevin Wolfe076f332010-06-29 11:43:13 +0200420
421 if (ret < 0 || result.check_errors) {
422 printf("\nAn error has occurred during the check: %s\n"
423 "The check is not complete and may have missed error.\n",
424 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900425 return 1;
426 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200427
428 if (result.corruptions) {
429 return 2;
430 } else if (result.leaks) {
431 return 3;
432 } else {
433 return 0;
434 }
aliguori15859692009-04-21 23:11:53 +0000435}
436
bellardea2384d2004-08-01 21:59:26 +0000437static int img_commit(int argc, char **argv)
438{
439 int c, ret;
440 const char *filename, *fmt;
bellardea2384d2004-08-01 21:59:26 +0000441 BlockDriverState *bs;
442
443 fmt = NULL;
444 for(;;) {
445 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100446 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000447 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100448 }
bellardea2384d2004-08-01 21:59:26 +0000449 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100450 case '?':
bellardea2384d2004-08-01 21:59:26 +0000451 case 'h':
452 help();
453 break;
454 case 'f':
455 fmt = optarg;
456 break;
457 }
458 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100459 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +0000460 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100461 }
bellardea2384d2004-08-01 21:59:26 +0000462 filename = argv[optind++];
463
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100464 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900465 if (!bs) {
466 return 1;
467 }
bellardea2384d2004-08-01 21:59:26 +0000468 ret = bdrv_commit(bs);
469 switch(ret) {
470 case 0:
471 printf("Image committed.\n");
472 break;
473 case -ENOENT:
Jes Sorensen15654a62010-12-16 14:31:53 +0100474 error_report("No disk inserted");
bellardea2384d2004-08-01 21:59:26 +0000475 break;
476 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +0100477 error_report("Image is read-only");
bellardea2384d2004-08-01 21:59:26 +0000478 break;
479 case -ENOTSUP:
Jes Sorensen15654a62010-12-16 14:31:53 +0100480 error_report("Image is already committed");
bellardea2384d2004-08-01 21:59:26 +0000481 break;
482 default:
Jes Sorensen15654a62010-12-16 14:31:53 +0100483 error_report("Error while committing image");
bellardea2384d2004-08-01 21:59:26 +0000484 break;
485 }
486
487 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900488 if (ret) {
489 return 1;
490 }
bellardea2384d2004-08-01 21:59:26 +0000491 return 0;
492}
493
494static int is_not_zero(const uint8_t *sector, int len)
495{
496 int i;
497 len >>= 2;
498 for(i = 0;i < len; i++) {
499 if (((uint32_t *)sector)[i] != 0)
500 return 1;
501 }
502 return 0;
503}
504
thsf58c7b32008-06-05 21:53:49 +0000505/*
506 * Returns true iff the first sector pointed to by 'buf' contains at least
507 * a non-NUL byte.
508 *
509 * 'pnum' is set to the number of sectors (including and immediately following
510 * the first one) that are known to be in the same allocated/unallocated state.
511 */
bellardea2384d2004-08-01 21:59:26 +0000512static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
513{
514 int v, i;
515
516 if (n <= 0) {
517 *pnum = 0;
518 return 0;
519 }
520 v = is_not_zero(buf, 512);
521 for(i = 1; i < n; i++) {
522 buf += 512;
523 if (v != is_not_zero(buf, 512))
524 break;
525 }
526 *pnum = i;
527 return v;
528}
529
Kevin Wolf3e85c6f2010-01-12 12:55:18 +0100530/*
531 * Compares two buffers sector by sector. Returns 0 if the first sector of both
532 * buffers matches, non-zero otherwise.
533 *
534 * pnum is set to the number of sectors (including and immediately following
535 * the first one) that are known to have the same comparison result
536 */
537static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
538 int *pnum)
539{
540 int res, i;
541
542 if (n <= 0) {
543 *pnum = 0;
544 return 0;
545 }
546
547 res = !!memcmp(buf1, buf2, 512);
548 for(i = 1; i < n; i++) {
549 buf1 += 512;
550 buf2 += 512;
551
552 if (!!memcmp(buf1, buf2, 512) != res) {
553 break;
554 }
555 }
556
557 *pnum = i;
558 return res;
559}
560
Kevin Wolf80ee15a2009-09-15 12:30:43 +0200561#define IO_BUF_SIZE (2 * 1024 * 1024)
bellardea2384d2004-08-01 21:59:26 +0000562
563static int img_convert(int argc, char **argv)
564{
Jes Sorenseneec77d92010-12-07 17:44:34 +0100565 int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;
thsf58c7b32008-06-05 21:53:49 +0000566 const char *fmt, *out_fmt, *out_baseimg, *out_filename;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900567 BlockDriver *drv, *proto_drv;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900568 BlockDriverState **bs = NULL, *out_bs = NULL;
ths96b8f132007-12-17 01:35:20 +0000569 int64_t total_sectors, nb_sectors, sector_num, bs_offset;
570 uint64_t bs_sectors;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900571 uint8_t * buf = NULL;
bellardea2384d2004-08-01 21:59:26 +0000572 const uint8_t *buf1;
bellardfaea38e2006-08-05 21:31:00 +0000573 BlockDriverInfo bdi;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900574 QEMUOptionParameter *param = NULL, *create_options = NULL;
Kevin Wolfa18953f2010-10-14 15:46:04 +0200575 QEMUOptionParameter *out_baseimg_param;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200576 char *options = NULL;
edison51ef6722010-09-21 19:58:41 -0700577 const char *snapshot_name = NULL;
bellardea2384d2004-08-01 21:59:26 +0000578
579 fmt = NULL;
580 out_fmt = "raw";
thsf58c7b32008-06-05 21:53:49 +0000581 out_baseimg = NULL;
Jes Sorenseneec77d92010-12-07 17:44:34 +0100582 compress = 0;
bellardea2384d2004-08-01 21:59:26 +0000583 for(;;) {
edison51ef6722010-09-21 19:58:41 -0700584 c = getopt(argc, argv, "f:O:B:s:hce6o:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100585 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000586 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100587 }
bellardea2384d2004-08-01 21:59:26 +0000588 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100589 case '?':
bellardea2384d2004-08-01 21:59:26 +0000590 case 'h':
591 help();
592 break;
593 case 'f':
594 fmt = optarg;
595 break;
596 case 'O':
597 out_fmt = optarg;
598 break;
thsf58c7b32008-06-05 21:53:49 +0000599 case 'B':
600 out_baseimg = optarg;
601 break;
bellardea2384d2004-08-01 21:59:26 +0000602 case 'c':
Jes Sorenseneec77d92010-12-07 17:44:34 +0100603 compress = 1;
bellardea2384d2004-08-01 21:59:26 +0000604 break;
605 case 'e':
Jes Sorensen15654a62010-12-16 14:31:53 +0100606 error_report("qemu-img: option -e is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100607 "encryption\' instead!");
608 return 1;
thsec36ba12007-09-16 21:59:02 +0000609 case '6':
Jes Sorensen15654a62010-12-16 14:31:53 +0100610 error_report("qemu-img: option -6 is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100611 "compat6\' instead!");
612 return 1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200613 case 'o':
614 options = optarg;
615 break;
edison51ef6722010-09-21 19:58:41 -0700616 case 's':
617 snapshot_name = optarg;
618 break;
bellardea2384d2004-08-01 21:59:26 +0000619 }
620 }
ths3b46e622007-09-17 08:09:54 +0000621
balrog926c2d22007-10-31 01:11:44 +0000622 bs_n = argc - optind - 1;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100623 if (bs_n < 1) {
624 help();
625 }
balrog926c2d22007-10-31 01:11:44 +0000626
627 out_filename = argv[argc - 1];
thsf58c7b32008-06-05 21:53:49 +0000628
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100629 if (options && !strcmp(options, "?")) {
630 ret = print_block_option_help(out_filename, out_fmt);
631 goto out;
632 }
633
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900634 if (bs_n > 1 && out_baseimg) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100635 error_report("-B makes no sense when concatenating multiple input "
636 "images");
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100637 ret = -1;
638 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900639 }
balrog926c2d22007-10-31 01:11:44 +0000640
Jes Sorensen5bdf61f2010-12-06 15:25:35 +0100641 bs = qemu_mallocz(bs_n * sizeof(BlockDriverState *));
balrog926c2d22007-10-31 01:11:44 +0000642
643 total_sectors = 0;
644 for (bs_i = 0; bs_i < bs_n; bs_i++) {
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100645 bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900646 if (!bs[bs_i]) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100647 error_report("Could not open '%s'", argv[optind + bs_i]);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900648 ret = -1;
649 goto out;
650 }
balrog926c2d22007-10-31 01:11:44 +0000651 bdrv_get_geometry(bs[bs_i], &bs_sectors);
652 total_sectors += bs_sectors;
653 }
bellardea2384d2004-08-01 21:59:26 +0000654
edison51ef6722010-09-21 19:58:41 -0700655 if (snapshot_name != NULL) {
656 if (bs_n > 1) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100657 error_report("No support for concatenating multiple snapshot\n");
edison51ef6722010-09-21 19:58:41 -0700658 ret = -1;
659 goto out;
660 }
661 if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100662 error_report("Failed to load snapshot\n");
edison51ef6722010-09-21 19:58:41 -0700663 ret = -1;
664 goto out;
665 }
666 }
667
Kevin Wolfefa84d42009-05-18 16:42:12 +0200668 /* Find driver and parse its options */
bellardea2384d2004-08-01 21:59:26 +0000669 drv = bdrv_find_format(out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900670 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100671 error_report("Unknown file format '%s'", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900672 ret = -1;
673 goto out;
674 }
balrog926c2d22007-10-31 01:11:44 +0000675
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900676 proto_drv = bdrv_find_protocol(out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900677 if (!proto_drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100678 error_report("Unknown protocol '%s'", out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900679 ret = -1;
680 goto out;
681 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900682
683 create_options = append_option_parameters(create_options,
684 drv->create_options);
685 create_options = append_option_parameters(create_options,
686 proto_drv->create_options);
Kevin Wolfdb08adf2009-06-04 15:39:38 +0200687
Kevin Wolfefa84d42009-05-18 16:42:12 +0200688 if (options) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900689 param = parse_option_parameters(options, create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200690 if (param == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100691 error_report("Invalid options for file format '%s'.", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900692 ret = -1;
693 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200694 }
695 } else {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900696 param = parse_option_parameters("", create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200697 }
698
699 set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
Jes Sorenseneec77d92010-12-07 17:44:34 +0100700 ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900701 if (ret < 0) {
702 goto out;
703 }
Kevin Wolfefa84d42009-05-18 16:42:12 +0200704
Kevin Wolfa18953f2010-10-14 15:46:04 +0200705 /* Get backing file name if -o backing_file was used */
706 out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
707 if (out_baseimg_param) {
708 out_baseimg = out_baseimg_param->value.s;
709 }
710
Kevin Wolfefa84d42009-05-18 16:42:12 +0200711 /* Check if compression is supported */
Jes Sorenseneec77d92010-12-07 17:44:34 +0100712 if (compress) {
Kevin Wolfefa84d42009-05-18 16:42:12 +0200713 QEMUOptionParameter *encryption =
714 get_option_parameter(param, BLOCK_OPT_ENCRYPT);
715
716 if (!drv->bdrv_write_compressed) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100717 error_report("Compression not supported for this file format");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900718 ret = -1;
719 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200720 }
721
722 if (encryption && encryption->value.n) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100723 error_report("Compression and encryption not supported at "
724 "the same time");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900725 ret = -1;
726 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200727 }
728 }
729
730 /* Create the new image */
731 ret = bdrv_create(drv, out_filename, param);
bellardea2384d2004-08-01 21:59:26 +0000732 if (ret < 0) {
733 if (ret == -ENOTSUP) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100734 error_report("Formatting not supported for file format '%s'",
735 out_fmt);
aurel326e9ea0c2009-04-15 14:42:46 +0000736 } else if (ret == -EFBIG) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100737 error_report("The image size is too large for file format '%s'",
738 out_fmt);
bellardea2384d2004-08-01 21:59:26 +0000739 } else {
Jes Sorensen15654a62010-12-16 14:31:53 +0100740 error_report("%s: error while converting %s: %s",
741 out_filename, out_fmt, strerror(-ret));
bellardea2384d2004-08-01 21:59:26 +0000742 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900743 goto out;
bellardea2384d2004-08-01 21:59:26 +0000744 }
ths3b46e622007-09-17 08:09:54 +0000745
Kevin Wolf1bd8e172010-08-31 13:44:25 +0200746 out_bs = bdrv_new_open(out_filename, out_fmt,
747 BDRV_O_FLAGS | BDRV_O_RDWR | BDRV_O_NO_FLUSH);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900748 if (!out_bs) {
749 ret = -1;
750 goto out;
751 }
bellardea2384d2004-08-01 21:59:26 +0000752
balrog926c2d22007-10-31 01:11:44 +0000753 bs_i = 0;
754 bs_offset = 0;
755 bdrv_get_geometry(bs[0], &bs_sectors);
TeLeMand6771bf2010-02-08 16:20:00 +0800756 buf = qemu_malloc(IO_BUF_SIZE);
balrog926c2d22007-10-31 01:11:44 +0000757
Jes Sorenseneec77d92010-12-07 17:44:34 +0100758 if (compress) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900759 ret = bdrv_get_info(out_bs, &bdi);
760 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100761 error_report("could not get block driver info");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900762 goto out;
763 }
bellardfaea38e2006-08-05 21:31:00 +0000764 cluster_size = bdi.cluster_size;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900765 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100766 error_report("invalid cluster size");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900767 ret = -1;
768 goto out;
769 }
bellardea2384d2004-08-01 21:59:26 +0000770 cluster_sectors = cluster_size >> 9;
771 sector_num = 0;
772 for(;;) {
balrog926c2d22007-10-31 01:11:44 +0000773 int64_t bs_num;
774 int remainder;
775 uint8_t *buf2;
776
bellardea2384d2004-08-01 21:59:26 +0000777 nb_sectors = total_sectors - sector_num;
778 if (nb_sectors <= 0)
779 break;
780 if (nb_sectors >= cluster_sectors)
781 n = cluster_sectors;
782 else
783 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000784
785 bs_num = sector_num - bs_offset;
786 assert (bs_num >= 0);
787 remainder = n;
788 buf2 = buf;
789 while (remainder > 0) {
790 int nlow;
791 while (bs_num == bs_sectors) {
792 bs_i++;
793 assert (bs_i < bs_n);
794 bs_offset += bs_sectors;
795 bdrv_get_geometry(bs[bs_i], &bs_sectors);
796 bs_num = 0;
Blue Swirl0bfcd592010-05-22 08:02:12 +0000797 /* printf("changing part: sector_num=%" PRId64 ", "
798 "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64
799 "\n", sector_num, bs_i, bs_offset, bs_sectors); */
balrog926c2d22007-10-31 01:11:44 +0000800 }
801 assert (bs_num < bs_sectors);
802
803 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
804
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900805 ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
806 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100807 error_report("error while reading");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900808 goto out;
809 }
balrog926c2d22007-10-31 01:11:44 +0000810
811 buf2 += nlow * 512;
812 bs_num += nlow;
813
814 remainder -= nlow;
815 }
816 assert (remainder == 0);
817
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100818 if (n < cluster_sectors) {
bellardea2384d2004-08-01 21:59:26 +0000819 memset(buf + n * 512, 0, cluster_size - n * 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100820 }
bellardea2384d2004-08-01 21:59:26 +0000821 if (is_not_zero(buf, cluster_size)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900822 ret = bdrv_write_compressed(out_bs, sector_num, buf,
823 cluster_sectors);
824 if (ret != 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100825 error_report("error while compressing sector %" PRId64,
bellardec3757d2006-06-14 15:50:07 +0000826 sector_num);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900827 goto out;
828 }
bellardea2384d2004-08-01 21:59:26 +0000829 }
830 sector_num += n;
831 }
bellardfaea38e2006-08-05 21:31:00 +0000832 /* signal EOF to align */
833 bdrv_write_compressed(out_bs, 0, NULL, 0);
bellardea2384d2004-08-01 21:59:26 +0000834 } else {
Kevin Wolff2feebb2010-04-14 17:30:35 +0200835 int has_zero_init = bdrv_has_zero_init(out_bs);
836
thsf58c7b32008-06-05 21:53:49 +0000837 sector_num = 0; // total number of sectors converted so far
bellardea2384d2004-08-01 21:59:26 +0000838 for(;;) {
839 nb_sectors = total_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100840 if (nb_sectors <= 0) {
bellardea2384d2004-08-01 21:59:26 +0000841 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100842 }
843 if (nb_sectors >= (IO_BUF_SIZE / 512)) {
bellardea2384d2004-08-01 21:59:26 +0000844 n = (IO_BUF_SIZE / 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100845 } else {
bellardea2384d2004-08-01 21:59:26 +0000846 n = nb_sectors;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100847 }
balrog926c2d22007-10-31 01:11:44 +0000848
849 while (sector_num - bs_offset >= bs_sectors) {
850 bs_i ++;
851 assert (bs_i < bs_n);
852 bs_offset += bs_sectors;
853 bdrv_get_geometry(bs[bs_i], &bs_sectors);
Blue Swirl0bfcd592010-05-22 08:02:12 +0000854 /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "
855 "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",
balrog926c2d22007-10-31 01:11:44 +0000856 sector_num, bs_i, bs_offset, bs_sectors); */
857 }
858
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100859 if (n > bs_offset + bs_sectors - sector_num) {
balrog926c2d22007-10-31 01:11:44 +0000860 n = bs_offset + bs_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100861 }
balrog926c2d22007-10-31 01:11:44 +0000862
Kevin Wolff2feebb2010-04-14 17:30:35 +0200863 if (has_zero_init) {
Akkarit Sangpetchd0320442009-07-17 10:02:15 +0200864 /* If the output image is being created as a copy on write image,
865 assume that sectors which are unallocated in the input image
866 are present in both the output's and input's base images (no
867 need to copy them). */
868 if (out_baseimg) {
869 if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
870 n, &n1)) {
871 sector_num += n1;
872 continue;
873 }
874 /* The next 'n1' sectors are allocated in the input image. Copy
875 only those as they may be followed by unallocated sectors. */
876 n = n1;
aliguori93c65b42009-04-05 17:40:43 +0000877 }
aliguori93c65b42009-04-05 17:40:43 +0000878 } else {
879 n1 = n;
thsf58c7b32008-06-05 21:53:49 +0000880 }
881
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900882 ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
883 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100884 error_report("error while reading");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900885 goto out;
886 }
bellardea2384d2004-08-01 21:59:26 +0000887 /* NOTE: at the same time we convert, we do not write zero
888 sectors to have a chance to compress the image. Ideally, we
889 should add a specific call to have the info to go faster */
890 buf1 = buf;
891 while (n > 0) {
thsf58c7b32008-06-05 21:53:49 +0000892 /* If the output image is being created as a copy on write image,
893 copy all sectors even the ones containing only NUL bytes,
aliguori93c65b42009-04-05 17:40:43 +0000894 because they may differ from the sectors in the base image.
895
896 If the output is to a host device, we also write out
897 sectors that are entirely 0, since whatever data was
898 already there is garbage, not 0s. */
Kevin Wolff2feebb2010-04-14 17:30:35 +0200899 if (!has_zero_init || out_baseimg ||
aliguori93c65b42009-04-05 17:40:43 +0000900 is_allocated_sectors(buf1, n, &n1)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900901 ret = bdrv_write(out_bs, sector_num, buf1, n1);
902 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100903 error_report("error while writing");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900904 goto out;
905 }
bellardea2384d2004-08-01 21:59:26 +0000906 }
907 sector_num += n1;
908 n -= n1;
909 buf1 += n1 * 512;
910 }
911 }
912 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900913out:
914 free_option_parameters(create_options);
915 free_option_parameters(param);
TeLeMand6771bf2010-02-08 16:20:00 +0800916 qemu_free(buf);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900917 if (out_bs) {
918 bdrv_delete(out_bs);
919 }
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100920 if (bs) {
921 for (bs_i = 0; bs_i < bs_n; bs_i++) {
922 if (bs[bs_i]) {
923 bdrv_delete(bs[bs_i]);
924 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900925 }
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100926 qemu_free(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900927 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900928 if (ret) {
929 return 1;
930 }
bellardea2384d2004-08-01 21:59:26 +0000931 return 0;
932}
933
bellard57d1a2b2004-08-03 21:15:11 +0000934#ifdef _WIN32
935static int64_t get_allocated_file_size(const char *filename)
936{
bellarde8445332006-06-14 15:32:10 +0000937 typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
938 get_compressed_t get_compressed;
bellard57d1a2b2004-08-03 21:15:11 +0000939 struct _stati64 st;
bellarde8445332006-06-14 15:32:10 +0000940
941 /* WinNT support GetCompressedFileSize to determine allocate size */
942 get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
943 if (get_compressed) {
944 DWORD high, low;
945 low = get_compressed(filename, &high);
946 if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
947 return (((int64_t) high) << 32) + low;
948 }
949
ths5fafdf22007-09-16 21:08:06 +0000950 if (_stati64(filename, &st) < 0)
bellard57d1a2b2004-08-03 21:15:11 +0000951 return -1;
952 return st.st_size;
953}
954#else
955static int64_t get_allocated_file_size(const char *filename)
956{
957 struct stat st;
ths5fafdf22007-09-16 21:08:06 +0000958 if (stat(filename, &st) < 0)
bellard57d1a2b2004-08-03 21:15:11 +0000959 return -1;
960 return (int64_t)st.st_blocks * 512;
961}
962#endif
963
bellardfaea38e2006-08-05 21:31:00 +0000964static void dump_snapshots(BlockDriverState *bs)
965{
966 QEMUSnapshotInfo *sn_tab, *sn;
967 int nb_sns, i;
968 char buf[256];
969
970 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
971 if (nb_sns <= 0)
972 return;
973 printf("Snapshot list:\n");
974 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
975 for(i = 0; i < nb_sns; i++) {
976 sn = &sn_tab[i];
977 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
978 }
979 qemu_free(sn_tab);
980}
981
bellardea2384d2004-08-01 21:59:26 +0000982static int img_info(int argc, char **argv)
983{
984 int c;
985 const char *filename, *fmt;
bellardea2384d2004-08-01 21:59:26 +0000986 BlockDriverState *bs;
987 char fmt_name[128], size_buf[128], dsize_buf[128];
ths96b8f132007-12-17 01:35:20 +0000988 uint64_t total_sectors;
989 int64_t allocated_size;
bellard93b6b2a2006-08-01 15:51:11 +0000990 char backing_filename[1024];
991 char backing_filename2[1024];
bellardfaea38e2006-08-05 21:31:00 +0000992 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +0000993
994 fmt = NULL;
995 for(;;) {
996 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100997 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000998 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100999 }
bellardea2384d2004-08-01 21:59:26 +00001000 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001001 case '?':
bellardea2384d2004-08-01 21:59:26 +00001002 case 'h':
1003 help();
1004 break;
1005 case 'f':
1006 fmt = optarg;
1007 break;
1008 }
1009 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001010 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +00001011 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001012 }
bellardea2384d2004-08-01 21:59:26 +00001013 filename = argv[optind++];
1014
Stefan Hajnocziadfe0782010-04-13 10:29:35 +01001015 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001016 if (!bs) {
1017 return 1;
1018 }
bellardea2384d2004-08-01 21:59:26 +00001019 bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
1020 bdrv_get_geometry(bs, &total_sectors);
1021 get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
bellard57d1a2b2004-08-03 21:15:11 +00001022 allocated_size = get_allocated_file_size(filename);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001023 if (allocated_size < 0) {
blueswir1a10ea302008-08-24 10:30:33 +00001024 snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001025 } else {
ths5fafdf22007-09-16 21:08:06 +00001026 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
bellardde167e42005-04-28 21:15:08 +00001027 allocated_size);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001028 }
bellardea2384d2004-08-01 21:59:26 +00001029 printf("image: %s\n"
1030 "file format: %s\n"
bellardec3757d2006-06-14 15:50:07 +00001031 "virtual size: %s (%" PRId64 " bytes)\n"
bellardea2384d2004-08-01 21:59:26 +00001032 "disk size: %s\n",
ths5fafdf22007-09-16 21:08:06 +00001033 filename, fmt_name, size_buf,
bellardec3757d2006-06-14 15:50:07 +00001034 (total_sectors * 512),
bellardea2384d2004-08-01 21:59:26 +00001035 dsize_buf);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001036 if (bdrv_is_encrypted(bs)) {
bellardea2384d2004-08-01 21:59:26 +00001037 printf("encrypted: yes\n");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001038 }
bellardfaea38e2006-08-05 21:31:00 +00001039 if (bdrv_get_info(bs, &bdi) >= 0) {
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001040 if (bdi.cluster_size != 0) {
bellardfaea38e2006-08-05 21:31:00 +00001041 printf("cluster_size: %d\n", bdi.cluster_size);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001042 }
bellardfaea38e2006-08-05 21:31:00 +00001043 }
bellard93b6b2a2006-08-01 15:51:11 +00001044 bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
bellardfaea38e2006-08-05 21:31:00 +00001045 if (backing_filename[0] != '\0') {
bellard93b6b2a2006-08-01 15:51:11 +00001046 path_combine(backing_filename2, sizeof(backing_filename2),
1047 filename, backing_filename);
ths5fafdf22007-09-16 21:08:06 +00001048 printf("backing file: %s (actual path: %s)\n",
bellard93b6b2a2006-08-01 15:51:11 +00001049 backing_filename,
1050 backing_filename2);
bellardfaea38e2006-08-05 21:31:00 +00001051 }
1052 dump_snapshots(bs);
bellardea2384d2004-08-01 21:59:26 +00001053 bdrv_delete(bs);
1054 return 0;
1055}
1056
aliguorif7b4a942009-01-07 17:40:15 +00001057#define SNAPSHOT_LIST 1
1058#define SNAPSHOT_CREATE 2
1059#define SNAPSHOT_APPLY 3
1060#define SNAPSHOT_DELETE 4
1061
Stuart Brady153859b2009-06-07 00:42:17 +01001062static int img_snapshot(int argc, char **argv)
aliguorif7b4a942009-01-07 17:40:15 +00001063{
1064 BlockDriverState *bs;
1065 QEMUSnapshotInfo sn;
1066 char *filename, *snapshot_name = NULL;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001067 int c, ret = 0, bdrv_oflags;
aliguorif7b4a942009-01-07 17:40:15 +00001068 int action = 0;
1069 qemu_timeval tv;
1070
Kevin Wolf710da702011-01-10 12:33:02 +01001071 bdrv_oflags = BDRV_O_FLAGS | BDRV_O_RDWR;
aliguorif7b4a942009-01-07 17:40:15 +00001072 /* Parse commandline parameters */
1073 for(;;) {
1074 c = getopt(argc, argv, "la:c:d:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001075 if (c == -1) {
aliguorif7b4a942009-01-07 17:40:15 +00001076 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001077 }
aliguorif7b4a942009-01-07 17:40:15 +00001078 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001079 case '?':
aliguorif7b4a942009-01-07 17:40:15 +00001080 case 'h':
1081 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001082 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001083 case 'l':
1084 if (action) {
1085 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001086 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001087 }
1088 action = SNAPSHOT_LIST;
Naphtali Spreif5edb012010-01-17 16:48:13 +02001089 bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
aliguorif7b4a942009-01-07 17:40:15 +00001090 break;
1091 case 'a':
1092 if (action) {
1093 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001094 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001095 }
1096 action = SNAPSHOT_APPLY;
1097 snapshot_name = optarg;
1098 break;
1099 case 'c':
1100 if (action) {
1101 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001102 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001103 }
1104 action = SNAPSHOT_CREATE;
1105 snapshot_name = optarg;
1106 break;
1107 case 'd':
1108 if (action) {
1109 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001110 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001111 }
1112 action = SNAPSHOT_DELETE;
1113 snapshot_name = optarg;
1114 break;
1115 }
1116 }
1117
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001118 if (optind >= argc) {
aliguorif7b4a942009-01-07 17:40:15 +00001119 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001120 }
aliguorif7b4a942009-01-07 17:40:15 +00001121 filename = argv[optind++];
1122
1123 /* Open the image */
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001124 bs = bdrv_new_open(filename, NULL, bdrv_oflags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001125 if (!bs) {
1126 return 1;
1127 }
aliguorif7b4a942009-01-07 17:40:15 +00001128
1129 /* Perform the requested action */
1130 switch(action) {
1131 case SNAPSHOT_LIST:
1132 dump_snapshots(bs);
1133 break;
1134
1135 case SNAPSHOT_CREATE:
1136 memset(&sn, 0, sizeof(sn));
1137 pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
1138
1139 qemu_gettimeofday(&tv);
1140 sn.date_sec = tv.tv_sec;
1141 sn.date_nsec = tv.tv_usec * 1000;
1142
1143 ret = bdrv_snapshot_create(bs, &sn);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001144 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001145 error_report("Could not create snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001146 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001147 }
aliguorif7b4a942009-01-07 17:40:15 +00001148 break;
1149
1150 case SNAPSHOT_APPLY:
1151 ret = bdrv_snapshot_goto(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001152 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001153 error_report("Could not apply snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001154 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001155 }
aliguorif7b4a942009-01-07 17:40:15 +00001156 break;
1157
1158 case SNAPSHOT_DELETE:
1159 ret = bdrv_snapshot_delete(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001160 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001161 error_report("Could not delete snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001162 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001163 }
aliguorif7b4a942009-01-07 17:40:15 +00001164 break;
1165 }
1166
1167 /* Cleanup */
1168 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001169 if (ret) {
1170 return 1;
1171 }
Stuart Brady153859b2009-06-07 00:42:17 +01001172 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001173}
1174
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001175static int img_rebase(int argc, char **argv)
1176{
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001177 BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001178 BlockDriver *old_backing_drv, *new_backing_drv;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001179 char *filename;
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001180 const char *fmt, *out_basefmt, *out_baseimg;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001181 int c, flags, ret;
1182 int unsafe = 0;
1183
1184 /* Parse commandline parameters */
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001185 fmt = NULL;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001186 out_baseimg = NULL;
1187 out_basefmt = NULL;
1188
1189 for(;;) {
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001190 c = getopt(argc, argv, "uhf:F:b:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001191 if (c == -1) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001192 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001193 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001194 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001195 case '?':
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001196 case 'h':
1197 help();
1198 return 0;
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001199 case 'f':
1200 fmt = optarg;
1201 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001202 case 'F':
1203 out_basefmt = optarg;
1204 break;
1205 case 'b':
1206 out_baseimg = optarg;
1207 break;
1208 case 'u':
1209 unsafe = 1;
1210 break;
1211 }
1212 }
1213
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001214 if ((optind >= argc) || !out_baseimg) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001215 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001216 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001217 filename = argv[optind++];
1218
1219 /*
1220 * Open the images.
1221 *
1222 * Ignore the old backing file for unsafe rebase in case we want to correct
1223 * the reference to a renamed or moved backing file.
1224 */
Stefan Hajnocziadfe0782010-04-13 10:29:35 +01001225 flags = BDRV_O_FLAGS | BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001226 bs = bdrv_new_open(filename, fmt, flags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001227 if (!bs) {
1228 return 1;
1229 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001230
1231 /* Find the right drivers for the backing files */
1232 old_backing_drv = NULL;
1233 new_backing_drv = NULL;
1234
1235 if (!unsafe && bs->backing_format[0] != '\0') {
1236 old_backing_drv = bdrv_find_format(bs->backing_format);
1237 if (old_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001238 error_report("Invalid format name: '%s'", bs->backing_format);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001239 ret = -1;
1240 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001241 }
1242 }
1243
1244 if (out_basefmt != NULL) {
1245 new_backing_drv = bdrv_find_format(out_basefmt);
1246 if (new_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001247 error_report("Invalid format name: '%s'", out_basefmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001248 ret = -1;
1249 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001250 }
1251 }
1252
1253 /* For safe rebasing we need to compare old and new backing file */
1254 if (unsafe) {
1255 /* Make the compiler happy */
1256 bs_old_backing = NULL;
1257 bs_new_backing = NULL;
1258 } else {
1259 char backing_name[1024];
1260
1261 bs_old_backing = bdrv_new("old_backing");
1262 bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001263 ret = bdrv_open(bs_old_backing, backing_name, BDRV_O_FLAGS,
1264 old_backing_drv);
1265 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001266 error_report("Could not open old backing file '%s'", backing_name);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001267 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001268 }
1269
1270 bs_new_backing = bdrv_new("new_backing");
Kevin Wolfcdbae852010-08-17 18:58:55 +02001271 ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS,
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001272 new_backing_drv);
1273 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001274 error_report("Could not open new backing file '%s'", out_baseimg);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001275 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001276 }
1277 }
1278
1279 /*
1280 * Check each unallocated cluster in the COW file. If it is unallocated,
1281 * accesses go to the backing file. We must therefore compare this cluster
1282 * in the old and new backing file, and if they differ we need to copy it
1283 * from the old backing file into the COW file.
1284 *
1285 * If qemu-img crashes during this step, no harm is done. The content of
1286 * the image is the same as the original one at any time.
1287 */
1288 if (!unsafe) {
1289 uint64_t num_sectors;
1290 uint64_t sector;
Kevin Wolfcc60e322010-04-29 14:47:48 +02001291 int n;
TeLeMand6771bf2010-02-08 16:20:00 +08001292 uint8_t * buf_old;
1293 uint8_t * buf_new;
1294
1295 buf_old = qemu_malloc(IO_BUF_SIZE);
1296 buf_new = qemu_malloc(IO_BUF_SIZE);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001297
1298 bdrv_get_geometry(bs, &num_sectors);
1299
1300 for (sector = 0; sector < num_sectors; sector += n) {
1301
1302 /* How many sectors can we handle with the next read? */
1303 if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
1304 n = (IO_BUF_SIZE / 512);
1305 } else {
1306 n = num_sectors - sector;
1307 }
1308
1309 /* If the cluster is allocated, we don't need to take action */
Kevin Wolfcc60e322010-04-29 14:47:48 +02001310 ret = bdrv_is_allocated(bs, sector, n, &n);
1311 if (ret) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001312 continue;
1313 }
1314
1315 /* Read old and new backing file */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001316 ret = bdrv_read(bs_old_backing, sector, buf_old, n);
1317 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001318 error_report("error while reading from old backing file");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001319 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001320 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001321 ret = bdrv_read(bs_new_backing, sector, buf_new, n);
1322 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001323 error_report("error while reading from new backing file");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001324 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001325 }
1326
1327 /* If they differ, we need to write to the COW file */
1328 uint64_t written = 0;
1329
1330 while (written < n) {
1331 int pnum;
1332
1333 if (compare_sectors(buf_old + written * 512,
Kevin Wolf60b1bd42010-02-17 12:32:59 +01001334 buf_new + written * 512, n - written, &pnum))
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001335 {
1336 ret = bdrv_write(bs, sector + written,
1337 buf_old + written * 512, pnum);
1338 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001339 error_report("Error while writing to COW image: %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001340 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001341 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001342 }
1343 }
1344
1345 written += pnum;
1346 }
1347 }
TeLeMand6771bf2010-02-08 16:20:00 +08001348
1349 qemu_free(buf_old);
1350 qemu_free(buf_new);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001351 }
1352
1353 /*
1354 * Change the backing file. All clusters that are different from the old
1355 * backing file are overwritten in the COW file now, so the visible content
1356 * doesn't change when we switch the backing file.
1357 */
1358 ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
1359 if (ret == -ENOSPC) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001360 error_report("Could not change the backing file to '%s': No "
1361 "space left in the file header", out_baseimg);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001362 } else if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001363 error_report("Could not change the backing file to '%s': %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001364 out_baseimg, strerror(-ret));
1365 }
1366
1367 /*
1368 * TODO At this point it is possible to check if any clusters that are
1369 * allocated in the COW file are the same in the backing file. If so, they
1370 * could be dropped from the COW file. Don't do this before switching the
1371 * backing file, in case of a crash this would lead to corruption.
1372 */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001373out:
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001374 /* Cleanup */
1375 if (!unsafe) {
1376 bdrv_delete(bs_old_backing);
1377 bdrv_delete(bs_new_backing);
1378 }
1379
1380 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001381 if (ret) {
1382 return 1;
1383 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001384 return 0;
1385}
1386
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001387static int img_resize(int argc, char **argv)
1388{
1389 int c, ret, relative;
1390 const char *filename, *fmt, *size;
1391 int64_t n, total_size;
Jes Sorensen2a819982010-12-06 17:08:31 +01001392 BlockDriverState *bs = NULL;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001393 QEMUOptionParameter *param;
1394 QEMUOptionParameter resize_options[] = {
1395 {
1396 .name = BLOCK_OPT_SIZE,
1397 .type = OPT_SIZE,
1398 .help = "Virtual disk size"
1399 },
1400 { NULL }
1401 };
1402
1403 fmt = NULL;
1404 for(;;) {
1405 c = getopt(argc, argv, "f:h");
1406 if (c == -1) {
1407 break;
1408 }
1409 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001410 case '?':
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001411 case 'h':
1412 help();
1413 break;
1414 case 'f':
1415 fmt = optarg;
1416 break;
1417 }
1418 }
1419 if (optind + 1 >= argc) {
1420 help();
1421 }
1422 filename = argv[optind++];
1423 size = argv[optind++];
1424
1425 /* Choose grow, shrink, or absolute resize mode */
1426 switch (size[0]) {
1427 case '+':
1428 relative = 1;
1429 size++;
1430 break;
1431 case '-':
1432 relative = -1;
1433 size++;
1434 break;
1435 default:
1436 relative = 0;
1437 break;
1438 }
1439
1440 /* Parse size */
1441 param = parse_option_parameters("", resize_options, NULL);
1442 if (set_option_parameter(param, BLOCK_OPT_SIZE, size)) {
1443 /* Error message already printed when size parsing fails */
Jes Sorensen2a819982010-12-06 17:08:31 +01001444 ret = -1;
1445 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001446 }
1447 n = get_option_parameter(param, BLOCK_OPT_SIZE)->value.n;
1448 free_option_parameters(param);
1449
1450 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001451 if (!bs) {
Jes Sorensen2a819982010-12-06 17:08:31 +01001452 ret = -1;
1453 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001454 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001455
1456 if (relative) {
1457 total_size = bdrv_getlength(bs) + n * relative;
1458 } else {
1459 total_size = n;
1460 }
1461 if (total_size <= 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001462 error_report("New image size must be positive");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001463 ret = -1;
1464 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001465 }
1466
1467 ret = bdrv_truncate(bs, total_size);
1468 switch (ret) {
1469 case 0:
1470 printf("Image resized.\n");
1471 break;
1472 case -ENOTSUP:
Jes Sorensen15654a62010-12-16 14:31:53 +01001473 error_report("This image format does not support resize");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001474 break;
1475 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +01001476 error_report("Image is read-only");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001477 break;
1478 default:
Jes Sorensen15654a62010-12-16 14:31:53 +01001479 error_report("Error resizing image (%d)", -ret);
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001480 break;
1481 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001482out:
Jes Sorensen2a819982010-12-06 17:08:31 +01001483 if (bs) {
1484 bdrv_delete(bs);
1485 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001486 if (ret) {
1487 return 1;
1488 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001489 return 0;
1490}
1491
Anthony Liguoric227f092009-10-01 16:12:16 -05001492static const img_cmd_t img_cmds[] = {
Stuart Brady153859b2009-06-07 00:42:17 +01001493#define DEF(option, callback, arg_string) \
1494 { option, callback },
1495#include "qemu-img-cmds.h"
1496#undef DEF
1497#undef GEN_DOCS
1498 { NULL, NULL, },
1499};
1500
bellardea2384d2004-08-01 21:59:26 +00001501int main(int argc, char **argv)
1502{
Anthony Liguoric227f092009-10-01 16:12:16 -05001503 const img_cmd_t *cmd;
Stuart Brady153859b2009-06-07 00:42:17 +01001504 const char *cmdname;
bellardea2384d2004-08-01 21:59:26 +00001505
Kevin Wolf53f76e52010-12-16 15:10:32 +01001506 error_set_progname(argv[0]);
1507
bellardea2384d2004-08-01 21:59:26 +00001508 bdrv_init();
1509 if (argc < 2)
1510 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001511 cmdname = argv[1];
aurel328f9b1572009-02-09 18:14:31 +00001512 argc--; argv++;
Stuart Brady153859b2009-06-07 00:42:17 +01001513
1514 /* find the command */
1515 for(cmd = img_cmds; cmd->name != NULL; cmd++) {
1516 if (!strcmp(cmdname, cmd->name)) {
1517 return cmd->handler(argc, argv);
1518 }
bellardea2384d2004-08-01 21:59:26 +00001519 }
Stuart Brady153859b2009-06-07 00:42:17 +01001520
1521 /* not found */
1522 help();
bellardea2384d2004-08-01 21:59:26 +00001523 return 0;
1524}