blob: 7e3cc4cbd5cc57086703227a4121af11db722e48 [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];
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100216 int ret;
bellard75c23802004-08-27 21:28:58 +0000217
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100218 bs = bdrv_new("image");
Kevin Wolfad717132010-12-16 15:37:41 +0100219
bellard75c23802004-08-27 21:28:58 +0000220 if (fmt) {
221 drv = bdrv_find_format(fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900222 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100223 error_report("Unknown file format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900224 goto fail;
225 }
bellard75c23802004-08-27 21:28:58 +0000226 } else {
227 drv = NULL;
228 }
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100229
230 ret = bdrv_open(bs, filename, flags, drv);
231 if (ret < 0) {
232 error_report("Could not open '%s': %s", filename, strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900233 goto fail;
bellard75c23802004-08-27 21:28:58 +0000234 }
Kevin Wolfb9eaf9e2011-02-09 11:25:53 +0100235
bellard75c23802004-08-27 21:28:58 +0000236 if (bdrv_is_encrypted(bs)) {
237 printf("Disk image '%s' is encrypted.\n", filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900238 if (read_password(password, sizeof(password)) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100239 error_report("No password given");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900240 goto fail;
241 }
242 if (bdrv_set_key(bs, password) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100243 error_report("invalid password");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900244 goto fail;
245 }
bellard75c23802004-08-27 21:28:58 +0000246 }
247 return bs;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900248fail:
249 if (bs) {
250 bdrv_delete(bs);
251 }
252 return NULL;
bellard75c23802004-08-27 21:28:58 +0000253}
254
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900255static int add_old_style_options(const char *fmt, QEMUOptionParameter *list,
Jes Sorenseneec77d92010-12-07 17:44:34 +0100256 const char *base_filename,
257 const char *base_fmt)
Kevin Wolfefa84d42009-05-18 16:42:12 +0200258{
Kevin Wolfefa84d42009-05-18 16:42:12 +0200259 if (base_filename) {
260 if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100261 error_report("Backing file not supported for file format '%s'",
262 fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900263 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200264 }
265 }
266 if (base_fmt) {
267 if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100268 error_report("Backing file format not supported for file "
269 "format '%s'", fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900270 return -1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200271 }
272 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900273 return 0;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200274}
275
bellardea2384d2004-08-01 21:59:26 +0000276static int img_create(int argc, char **argv)
277{
Jes Sorenseneec77d92010-12-07 17:44:34 +0100278 int c, ret = 0;
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100279 uint64_t img_size = -1;
bellardea2384d2004-08-01 21:59:26 +0000280 const char *fmt = "raw";
aliguori9230eaf2009-03-28 17:55:19 +0000281 const char *base_fmt = NULL;
bellardea2384d2004-08-01 21:59:26 +0000282 const char *filename;
283 const char *base_filename = NULL;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200284 char *options = NULL;
ths3b46e622007-09-17 08:09:54 +0000285
bellardea2384d2004-08-01 21:59:26 +0000286 for(;;) {
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200287 c = getopt(argc, argv, "F:b:f:he6o:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100288 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000289 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100290 }
bellardea2384d2004-08-01 21:59:26 +0000291 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100292 case '?':
bellardea2384d2004-08-01 21:59:26 +0000293 case 'h':
294 help();
295 break;
aliguori9230eaf2009-03-28 17:55:19 +0000296 case 'F':
297 base_fmt = optarg;
298 break;
bellardea2384d2004-08-01 21:59:26 +0000299 case 'b':
300 base_filename = optarg;
301 break;
302 case 'f':
303 fmt = optarg;
304 break;
305 case 'e':
Jes Sorensen15654a62010-12-16 14:31:53 +0100306 error_report("qemu-img: option -e is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100307 "encryption\' instead!");
308 return 1;
thsd8871c52007-10-24 16:11:42 +0000309 case '6':
Jes Sorensen15654a62010-12-16 14:31:53 +0100310 error_report("qemu-img: option -6 is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100311 "compat6\' instead!");
312 return 1;
Kevin Wolf9ea2ea72009-05-18 16:42:11 +0200313 case 'o':
314 options = optarg;
315 break;
bellardea2384d2004-08-01 21:59:26 +0000316 }
317 }
aliguori9230eaf2009-03-28 17:55:19 +0000318
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900319 /* Get the filename */
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100320 if (optind >= argc) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900321 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100322 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900323 filename = argv[optind++];
324
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100325 /* Get image size, if specified */
326 if (optind < argc) {
Jes Sorensen70b4f4b2011-01-05 11:41:02 +0100327 int64_t sval;
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100328 sval = strtosz_suffix(argv[optind++], NULL, STRTOSZ_DEFSUFFIX_B);
329 if (sval < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100330 error_report("Invalid image size specified! You may use k, M, G or "
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100331 "T suffixes for ");
Jes Sorensen15654a62010-12-16 14:31:53 +0100332 error_report("kilobytes, megabytes, gigabytes and terabytes.");
Jes Sorensen1da7cfb2010-12-09 14:17:25 +0100333 ret = -1;
334 goto out;
335 }
336 img_size = (uint64_t)sval;
337 }
338
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100339 if (options && !strcmp(options, "?")) {
340 ret = print_block_option_help(filename, fmt);
341 goto out;
342 }
343
Jes Sorensenf88e1a42010-12-16 13:52:15 +0100344 ret = bdrv_img_create(filename, fmt, base_filename, base_fmt,
345 options, img_size, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900346out:
347 if (ret) {
348 return 1;
349 }
bellardea2384d2004-08-01 21:59:26 +0000350 return 0;
351}
352
Kevin Wolfe076f332010-06-29 11:43:13 +0200353/*
354 * Checks an image for consistency. Exit codes:
355 *
356 * 0 - Check completed, image is good
357 * 1 - Check not completed because of internal errors
358 * 2 - Check completed, image is corrupted
359 * 3 - Check completed, image has leaked clusters, but is good otherwise
360 */
aliguori15859692009-04-21 23:11:53 +0000361static int img_check(int argc, char **argv)
362{
363 int c, ret;
364 const char *filename, *fmt;
aliguori15859692009-04-21 23:11:53 +0000365 BlockDriverState *bs;
Kevin Wolfe076f332010-06-29 11:43:13 +0200366 BdrvCheckResult result;
aliguori15859692009-04-21 23:11:53 +0000367
368 fmt = NULL;
369 for(;;) {
370 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100371 if (c == -1) {
aliguori15859692009-04-21 23:11:53 +0000372 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100373 }
aliguori15859692009-04-21 23:11:53 +0000374 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100375 case '?':
aliguori15859692009-04-21 23:11:53 +0000376 case 'h':
377 help();
378 break;
379 case 'f':
380 fmt = optarg;
381 break;
382 }
383 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100384 if (optind >= argc) {
aliguori15859692009-04-21 23:11:53 +0000385 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100386 }
aliguori15859692009-04-21 23:11:53 +0000387 filename = argv[optind++];
388
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100389 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900390 if (!bs) {
391 return 1;
392 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200393 ret = bdrv_check(bs, &result);
394
395 if (ret == -ENOTSUP) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100396 error_report("This image format does not support checks");
Kevin Wolfe076f332010-06-29 11:43:13 +0200397 bdrv_delete(bs);
398 return 1;
399 }
400
401 if (!(result.corruptions || result.leaks || result.check_errors)) {
402 printf("No errors were found on the image.\n");
403 } else {
404 if (result.corruptions) {
405 printf("\n%d errors were found on the image.\n"
406 "Data may be corrupted, or further writes to the image "
407 "may corrupt it.\n",
408 result.corruptions);
aliguori15859692009-04-21 23:11:53 +0000409 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200410
411 if (result.leaks) {
412 printf("\n%d leaked clusters were found on the image.\n"
413 "This means waste of disk space, but no harm to data.\n",
414 result.leaks);
415 }
416
417 if (result.check_errors) {
418 printf("\n%d internal errors have occurred during the check.\n",
419 result.check_errors);
420 }
aliguori15859692009-04-21 23:11:53 +0000421 }
422
423 bdrv_delete(bs);
Kevin Wolfe076f332010-06-29 11:43:13 +0200424
425 if (ret < 0 || result.check_errors) {
426 printf("\nAn error has occurred during the check: %s\n"
427 "The check is not complete and may have missed error.\n",
428 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900429 return 1;
430 }
Kevin Wolfe076f332010-06-29 11:43:13 +0200431
432 if (result.corruptions) {
433 return 2;
434 } else if (result.leaks) {
435 return 3;
436 } else {
437 return 0;
438 }
aliguori15859692009-04-21 23:11:53 +0000439}
440
bellardea2384d2004-08-01 21:59:26 +0000441static int img_commit(int argc, char **argv)
442{
443 int c, ret;
444 const char *filename, *fmt;
bellardea2384d2004-08-01 21:59:26 +0000445 BlockDriverState *bs;
446
447 fmt = NULL;
448 for(;;) {
449 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100450 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000451 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100452 }
bellardea2384d2004-08-01 21:59:26 +0000453 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100454 case '?':
bellardea2384d2004-08-01 21:59:26 +0000455 case 'h':
456 help();
457 break;
458 case 'f':
459 fmt = optarg;
460 break;
461 }
462 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100463 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +0000464 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100465 }
bellardea2384d2004-08-01 21:59:26 +0000466 filename = argv[optind++];
467
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100468 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900469 if (!bs) {
470 return 1;
471 }
bellardea2384d2004-08-01 21:59:26 +0000472 ret = bdrv_commit(bs);
473 switch(ret) {
474 case 0:
475 printf("Image committed.\n");
476 break;
477 case -ENOENT:
Jes Sorensen15654a62010-12-16 14:31:53 +0100478 error_report("No disk inserted");
bellardea2384d2004-08-01 21:59:26 +0000479 break;
480 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +0100481 error_report("Image is read-only");
bellardea2384d2004-08-01 21:59:26 +0000482 break;
483 case -ENOTSUP:
Jes Sorensen15654a62010-12-16 14:31:53 +0100484 error_report("Image is already committed");
bellardea2384d2004-08-01 21:59:26 +0000485 break;
486 default:
Jes Sorensen15654a62010-12-16 14:31:53 +0100487 error_report("Error while committing image");
bellardea2384d2004-08-01 21:59:26 +0000488 break;
489 }
490
491 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900492 if (ret) {
493 return 1;
494 }
bellardea2384d2004-08-01 21:59:26 +0000495 return 0;
496}
497
498static int is_not_zero(const uint8_t *sector, int len)
499{
500 int i;
501 len >>= 2;
502 for(i = 0;i < len; i++) {
503 if (((uint32_t *)sector)[i] != 0)
504 return 1;
505 }
506 return 0;
507}
508
thsf58c7b32008-06-05 21:53:49 +0000509/*
510 * Returns true iff the first sector pointed to by 'buf' contains at least
511 * a non-NUL byte.
512 *
513 * 'pnum' is set to the number of sectors (including and immediately following
514 * the first one) that are known to be in the same allocated/unallocated state.
515 */
bellardea2384d2004-08-01 21:59:26 +0000516static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
517{
518 int v, i;
519
520 if (n <= 0) {
521 *pnum = 0;
522 return 0;
523 }
524 v = is_not_zero(buf, 512);
525 for(i = 1; i < n; i++) {
526 buf += 512;
527 if (v != is_not_zero(buf, 512))
528 break;
529 }
530 *pnum = i;
531 return v;
532}
533
Kevin Wolf3e85c6f2010-01-12 12:55:18 +0100534/*
535 * Compares two buffers sector by sector. Returns 0 if the first sector of both
536 * buffers matches, non-zero otherwise.
537 *
538 * pnum is set to the number of sectors (including and immediately following
539 * the first one) that are known to have the same comparison result
540 */
541static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
542 int *pnum)
543{
544 int res, i;
545
546 if (n <= 0) {
547 *pnum = 0;
548 return 0;
549 }
550
551 res = !!memcmp(buf1, buf2, 512);
552 for(i = 1; i < n; i++) {
553 buf1 += 512;
554 buf2 += 512;
555
556 if (!!memcmp(buf1, buf2, 512) != res) {
557 break;
558 }
559 }
560
561 *pnum = i;
562 return res;
563}
564
Kevin Wolf80ee15a2009-09-15 12:30:43 +0200565#define IO_BUF_SIZE (2 * 1024 * 1024)
bellardea2384d2004-08-01 21:59:26 +0000566
567static int img_convert(int argc, char **argv)
568{
Jes Sorenseneec77d92010-12-07 17:44:34 +0100569 int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;
thsf58c7b32008-06-05 21:53:49 +0000570 const char *fmt, *out_fmt, *out_baseimg, *out_filename;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900571 BlockDriver *drv, *proto_drv;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900572 BlockDriverState **bs = NULL, *out_bs = NULL;
ths96b8f132007-12-17 01:35:20 +0000573 int64_t total_sectors, nb_sectors, sector_num, bs_offset;
574 uint64_t bs_sectors;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900575 uint8_t * buf = NULL;
bellardea2384d2004-08-01 21:59:26 +0000576 const uint8_t *buf1;
bellardfaea38e2006-08-05 21:31:00 +0000577 BlockDriverInfo bdi;
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900578 QEMUOptionParameter *param = NULL, *create_options = NULL;
Kevin Wolfa18953f2010-10-14 15:46:04 +0200579 QEMUOptionParameter *out_baseimg_param;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200580 char *options = NULL;
edison51ef6722010-09-21 19:58:41 -0700581 const char *snapshot_name = NULL;
bellardea2384d2004-08-01 21:59:26 +0000582
583 fmt = NULL;
584 out_fmt = "raw";
thsf58c7b32008-06-05 21:53:49 +0000585 out_baseimg = NULL;
Jes Sorenseneec77d92010-12-07 17:44:34 +0100586 compress = 0;
bellardea2384d2004-08-01 21:59:26 +0000587 for(;;) {
edison51ef6722010-09-21 19:58:41 -0700588 c = getopt(argc, argv, "f:O:B:s:hce6o:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100589 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +0000590 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100591 }
bellardea2384d2004-08-01 21:59:26 +0000592 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +0100593 case '?':
bellardea2384d2004-08-01 21:59:26 +0000594 case 'h':
595 help();
596 break;
597 case 'f':
598 fmt = optarg;
599 break;
600 case 'O':
601 out_fmt = optarg;
602 break;
thsf58c7b32008-06-05 21:53:49 +0000603 case 'B':
604 out_baseimg = optarg;
605 break;
bellardea2384d2004-08-01 21:59:26 +0000606 case 'c':
Jes Sorenseneec77d92010-12-07 17:44:34 +0100607 compress = 1;
bellardea2384d2004-08-01 21:59:26 +0000608 break;
609 case 'e':
Jes Sorensen15654a62010-12-16 14:31:53 +0100610 error_report("qemu-img: option -e is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100611 "encryption\' instead!");
612 return 1;
thsec36ba12007-09-16 21:59:02 +0000613 case '6':
Jes Sorensen15654a62010-12-16 14:31:53 +0100614 error_report("qemu-img: option -6 is deprecated, please use \'-o "
Jes Sorenseneec77d92010-12-07 17:44:34 +0100615 "compat6\' instead!");
616 return 1;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200617 case 'o':
618 options = optarg;
619 break;
edison51ef6722010-09-21 19:58:41 -0700620 case 's':
621 snapshot_name = optarg;
622 break;
bellardea2384d2004-08-01 21:59:26 +0000623 }
624 }
ths3b46e622007-09-17 08:09:54 +0000625
balrog926c2d22007-10-31 01:11:44 +0000626 bs_n = argc - optind - 1;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100627 if (bs_n < 1) {
628 help();
629 }
balrog926c2d22007-10-31 01:11:44 +0000630
631 out_filename = argv[argc - 1];
thsf58c7b32008-06-05 21:53:49 +0000632
Jes Sorensen4ac8aac2010-12-06 15:25:38 +0100633 if (options && !strcmp(options, "?")) {
634 ret = print_block_option_help(out_filename, out_fmt);
635 goto out;
636 }
637
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900638 if (bs_n > 1 && out_baseimg) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100639 error_report("-B makes no sense when concatenating multiple input "
640 "images");
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100641 ret = -1;
642 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900643 }
balrog926c2d22007-10-31 01:11:44 +0000644
Jes Sorensen5bdf61f2010-12-06 15:25:35 +0100645 bs = qemu_mallocz(bs_n * sizeof(BlockDriverState *));
balrog926c2d22007-10-31 01:11:44 +0000646
647 total_sectors = 0;
648 for (bs_i = 0; bs_i < bs_n; bs_i++) {
Stefan Hajnocziadfe0782010-04-13 10:29:35 +0100649 bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900650 if (!bs[bs_i]) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100651 error_report("Could not open '%s'", argv[optind + bs_i]);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900652 ret = -1;
653 goto out;
654 }
balrog926c2d22007-10-31 01:11:44 +0000655 bdrv_get_geometry(bs[bs_i], &bs_sectors);
656 total_sectors += bs_sectors;
657 }
bellardea2384d2004-08-01 21:59:26 +0000658
edison51ef6722010-09-21 19:58:41 -0700659 if (snapshot_name != NULL) {
660 if (bs_n > 1) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100661 error_report("No support for concatenating multiple snapshot\n");
edison51ef6722010-09-21 19:58:41 -0700662 ret = -1;
663 goto out;
664 }
665 if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100666 error_report("Failed to load snapshot\n");
edison51ef6722010-09-21 19:58:41 -0700667 ret = -1;
668 goto out;
669 }
670 }
671
Kevin Wolfefa84d42009-05-18 16:42:12 +0200672 /* Find driver and parse its options */
bellardea2384d2004-08-01 21:59:26 +0000673 drv = bdrv_find_format(out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900674 if (!drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100675 error_report("Unknown file format '%s'", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900676 ret = -1;
677 goto out;
678 }
balrog926c2d22007-10-31 01:11:44 +0000679
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900680 proto_drv = bdrv_find_protocol(out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900681 if (!proto_drv) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100682 error_report("Unknown protocol '%s'", out_filename);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900683 ret = -1;
684 goto out;
685 }
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900686
687 create_options = append_option_parameters(create_options,
688 drv->create_options);
689 create_options = append_option_parameters(create_options,
690 proto_drv->create_options);
Kevin Wolfdb08adf2009-06-04 15:39:38 +0200691
Kevin Wolfefa84d42009-05-18 16:42:12 +0200692 if (options) {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900693 param = parse_option_parameters(options, create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200694 if (param == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100695 error_report("Invalid options for file format '%s'.", out_fmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900696 ret = -1;
697 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200698 }
699 } else {
MORITA Kazutakab50cbab2010-05-26 11:35:36 +0900700 param = parse_option_parameters("", create_options, param);
Kevin Wolfefa84d42009-05-18 16:42:12 +0200701 }
702
703 set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
Jes Sorenseneec77d92010-12-07 17:44:34 +0100704 ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900705 if (ret < 0) {
706 goto out;
707 }
Kevin Wolfefa84d42009-05-18 16:42:12 +0200708
Kevin Wolfa18953f2010-10-14 15:46:04 +0200709 /* Get backing file name if -o backing_file was used */
710 out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
711 if (out_baseimg_param) {
712 out_baseimg = out_baseimg_param->value.s;
713 }
714
Kevin Wolfefa84d42009-05-18 16:42:12 +0200715 /* Check if compression is supported */
Jes Sorenseneec77d92010-12-07 17:44:34 +0100716 if (compress) {
Kevin Wolfefa84d42009-05-18 16:42:12 +0200717 QEMUOptionParameter *encryption =
718 get_option_parameter(param, BLOCK_OPT_ENCRYPT);
719
720 if (!drv->bdrv_write_compressed) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100721 error_report("Compression not supported for this file format");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900722 ret = -1;
723 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200724 }
725
726 if (encryption && encryption->value.n) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100727 error_report("Compression and encryption not supported at "
728 "the same time");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900729 ret = -1;
730 goto out;
Kevin Wolfefa84d42009-05-18 16:42:12 +0200731 }
732 }
733
734 /* Create the new image */
735 ret = bdrv_create(drv, out_filename, param);
bellardea2384d2004-08-01 21:59:26 +0000736 if (ret < 0) {
737 if (ret == -ENOTSUP) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100738 error_report("Formatting not supported for file format '%s'",
739 out_fmt);
aurel326e9ea0c2009-04-15 14:42:46 +0000740 } else if (ret == -EFBIG) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100741 error_report("The image size is too large for file format '%s'",
742 out_fmt);
bellardea2384d2004-08-01 21:59:26 +0000743 } else {
Jes Sorensen15654a62010-12-16 14:31:53 +0100744 error_report("%s: error while converting %s: %s",
745 out_filename, out_fmt, strerror(-ret));
bellardea2384d2004-08-01 21:59:26 +0000746 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900747 goto out;
bellardea2384d2004-08-01 21:59:26 +0000748 }
ths3b46e622007-09-17 08:09:54 +0000749
Kevin Wolf1bd8e172010-08-31 13:44:25 +0200750 out_bs = bdrv_new_open(out_filename, out_fmt,
751 BDRV_O_FLAGS | BDRV_O_RDWR | BDRV_O_NO_FLUSH);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900752 if (!out_bs) {
753 ret = -1;
754 goto out;
755 }
bellardea2384d2004-08-01 21:59:26 +0000756
balrog926c2d22007-10-31 01:11:44 +0000757 bs_i = 0;
758 bs_offset = 0;
759 bdrv_get_geometry(bs[0], &bs_sectors);
TeLeMand6771bf2010-02-08 16:20:00 +0800760 buf = qemu_malloc(IO_BUF_SIZE);
balrog926c2d22007-10-31 01:11:44 +0000761
Jes Sorenseneec77d92010-12-07 17:44:34 +0100762 if (compress) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900763 ret = bdrv_get_info(out_bs, &bdi);
764 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100765 error_report("could not get block driver info");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900766 goto out;
767 }
bellardfaea38e2006-08-05 21:31:00 +0000768 cluster_size = bdi.cluster_size;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900769 if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100770 error_report("invalid cluster size");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900771 ret = -1;
772 goto out;
773 }
bellardea2384d2004-08-01 21:59:26 +0000774 cluster_sectors = cluster_size >> 9;
775 sector_num = 0;
776 for(;;) {
balrog926c2d22007-10-31 01:11:44 +0000777 int64_t bs_num;
778 int remainder;
779 uint8_t *buf2;
780
bellardea2384d2004-08-01 21:59:26 +0000781 nb_sectors = total_sectors - sector_num;
782 if (nb_sectors <= 0)
783 break;
784 if (nb_sectors >= cluster_sectors)
785 n = cluster_sectors;
786 else
787 n = nb_sectors;
balrog926c2d22007-10-31 01:11:44 +0000788
789 bs_num = sector_num - bs_offset;
790 assert (bs_num >= 0);
791 remainder = n;
792 buf2 = buf;
793 while (remainder > 0) {
794 int nlow;
795 while (bs_num == bs_sectors) {
796 bs_i++;
797 assert (bs_i < bs_n);
798 bs_offset += bs_sectors;
799 bdrv_get_geometry(bs[bs_i], &bs_sectors);
800 bs_num = 0;
Blue Swirl0bfcd592010-05-22 08:02:12 +0000801 /* printf("changing part: sector_num=%" PRId64 ", "
802 "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64
803 "\n", sector_num, bs_i, bs_offset, bs_sectors); */
balrog926c2d22007-10-31 01:11:44 +0000804 }
805 assert (bs_num < bs_sectors);
806
807 nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
808
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900809 ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
810 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100811 error_report("error while reading");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900812 goto out;
813 }
balrog926c2d22007-10-31 01:11:44 +0000814
815 buf2 += nlow * 512;
816 bs_num += nlow;
817
818 remainder -= nlow;
819 }
820 assert (remainder == 0);
821
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100822 if (n < cluster_sectors) {
bellardea2384d2004-08-01 21:59:26 +0000823 memset(buf + n * 512, 0, cluster_size - n * 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100824 }
bellardea2384d2004-08-01 21:59:26 +0000825 if (is_not_zero(buf, cluster_size)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900826 ret = bdrv_write_compressed(out_bs, sector_num, buf,
827 cluster_sectors);
828 if (ret != 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100829 error_report("error while compressing sector %" PRId64,
bellardec3757d2006-06-14 15:50:07 +0000830 sector_num);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900831 goto out;
832 }
bellardea2384d2004-08-01 21:59:26 +0000833 }
834 sector_num += n;
835 }
bellardfaea38e2006-08-05 21:31:00 +0000836 /* signal EOF to align */
837 bdrv_write_compressed(out_bs, 0, NULL, 0);
bellardea2384d2004-08-01 21:59:26 +0000838 } else {
Kevin Wolff2feebb2010-04-14 17:30:35 +0200839 int has_zero_init = bdrv_has_zero_init(out_bs);
840
thsf58c7b32008-06-05 21:53:49 +0000841 sector_num = 0; // total number of sectors converted so far
bellardea2384d2004-08-01 21:59:26 +0000842 for(;;) {
843 nb_sectors = total_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100844 if (nb_sectors <= 0) {
bellardea2384d2004-08-01 21:59:26 +0000845 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100846 }
847 if (nb_sectors >= (IO_BUF_SIZE / 512)) {
bellardea2384d2004-08-01 21:59:26 +0000848 n = (IO_BUF_SIZE / 512);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100849 } else {
bellardea2384d2004-08-01 21:59:26 +0000850 n = nb_sectors;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100851 }
balrog926c2d22007-10-31 01:11:44 +0000852
853 while (sector_num - bs_offset >= bs_sectors) {
854 bs_i ++;
855 assert (bs_i < bs_n);
856 bs_offset += bs_sectors;
857 bdrv_get_geometry(bs[bs_i], &bs_sectors);
Blue Swirl0bfcd592010-05-22 08:02:12 +0000858 /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "
859 "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",
balrog926c2d22007-10-31 01:11:44 +0000860 sector_num, bs_i, bs_offset, bs_sectors); */
861 }
862
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100863 if (n > bs_offset + bs_sectors - sector_num) {
balrog926c2d22007-10-31 01:11:44 +0000864 n = bs_offset + bs_sectors - sector_num;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +0100865 }
balrog926c2d22007-10-31 01:11:44 +0000866
Kevin Wolff2feebb2010-04-14 17:30:35 +0200867 if (has_zero_init) {
Akkarit Sangpetchd0320442009-07-17 10:02:15 +0200868 /* If the output image is being created as a copy on write image,
869 assume that sectors which are unallocated in the input image
870 are present in both the output's and input's base images (no
871 need to copy them). */
872 if (out_baseimg) {
873 if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
874 n, &n1)) {
875 sector_num += n1;
876 continue;
877 }
878 /* The next 'n1' sectors are allocated in the input image. Copy
879 only those as they may be followed by unallocated sectors. */
880 n = n1;
aliguori93c65b42009-04-05 17:40:43 +0000881 }
aliguori93c65b42009-04-05 17:40:43 +0000882 } else {
883 n1 = n;
thsf58c7b32008-06-05 21:53:49 +0000884 }
885
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900886 ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
887 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100888 error_report("error while reading");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900889 goto out;
890 }
bellardea2384d2004-08-01 21:59:26 +0000891 /* NOTE: at the same time we convert, we do not write zero
892 sectors to have a chance to compress the image. Ideally, we
893 should add a specific call to have the info to go faster */
894 buf1 = buf;
895 while (n > 0) {
thsf58c7b32008-06-05 21:53:49 +0000896 /* If the output image is being created as a copy on write image,
897 copy all sectors even the ones containing only NUL bytes,
aliguori93c65b42009-04-05 17:40:43 +0000898 because they may differ from the sectors in the base image.
899
900 If the output is to a host device, we also write out
901 sectors that are entirely 0, since whatever data was
902 already there is garbage, not 0s. */
Kevin Wolff2feebb2010-04-14 17:30:35 +0200903 if (!has_zero_init || out_baseimg ||
aliguori93c65b42009-04-05 17:40:43 +0000904 is_allocated_sectors(buf1, n, &n1)) {
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900905 ret = bdrv_write(out_bs, sector_num, buf1, n1);
906 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +0100907 error_report("error while writing");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900908 goto out;
909 }
bellardea2384d2004-08-01 21:59:26 +0000910 }
911 sector_num += n1;
912 n -= n1;
913 buf1 += n1 * 512;
914 }
915 }
916 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900917out:
918 free_option_parameters(create_options);
919 free_option_parameters(param);
TeLeMand6771bf2010-02-08 16:20:00 +0800920 qemu_free(buf);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900921 if (out_bs) {
922 bdrv_delete(out_bs);
923 }
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100924 if (bs) {
925 for (bs_i = 0; bs_i < bs_n; bs_i++) {
926 if (bs[bs_i]) {
927 bdrv_delete(bs[bs_i]);
928 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900929 }
Jes Sorensen31ca34b2010-12-06 15:25:36 +0100930 qemu_free(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900931 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +0900932 if (ret) {
933 return 1;
934 }
bellardea2384d2004-08-01 21:59:26 +0000935 return 0;
936}
937
bellard57d1a2b2004-08-03 21:15:11 +0000938#ifdef _WIN32
939static int64_t get_allocated_file_size(const char *filename)
940{
bellarde8445332006-06-14 15:32:10 +0000941 typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
942 get_compressed_t get_compressed;
bellard57d1a2b2004-08-03 21:15:11 +0000943 struct _stati64 st;
bellarde8445332006-06-14 15:32:10 +0000944
945 /* WinNT support GetCompressedFileSize to determine allocate size */
946 get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
947 if (get_compressed) {
948 DWORD high, low;
949 low = get_compressed(filename, &high);
950 if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
951 return (((int64_t) high) << 32) + low;
952 }
953
ths5fafdf22007-09-16 21:08:06 +0000954 if (_stati64(filename, &st) < 0)
bellard57d1a2b2004-08-03 21:15:11 +0000955 return -1;
956 return st.st_size;
957}
958#else
959static int64_t get_allocated_file_size(const char *filename)
960{
961 struct stat st;
ths5fafdf22007-09-16 21:08:06 +0000962 if (stat(filename, &st) < 0)
bellard57d1a2b2004-08-03 21:15:11 +0000963 return -1;
964 return (int64_t)st.st_blocks * 512;
965}
966#endif
967
bellardfaea38e2006-08-05 21:31:00 +0000968static void dump_snapshots(BlockDriverState *bs)
969{
970 QEMUSnapshotInfo *sn_tab, *sn;
971 int nb_sns, i;
972 char buf[256];
973
974 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
975 if (nb_sns <= 0)
976 return;
977 printf("Snapshot list:\n");
978 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
979 for(i = 0; i < nb_sns; i++) {
980 sn = &sn_tab[i];
981 printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
982 }
983 qemu_free(sn_tab);
984}
985
bellardea2384d2004-08-01 21:59:26 +0000986static int img_info(int argc, char **argv)
987{
988 int c;
989 const char *filename, *fmt;
bellardea2384d2004-08-01 21:59:26 +0000990 BlockDriverState *bs;
991 char fmt_name[128], size_buf[128], dsize_buf[128];
ths96b8f132007-12-17 01:35:20 +0000992 uint64_t total_sectors;
993 int64_t allocated_size;
bellard93b6b2a2006-08-01 15:51:11 +0000994 char backing_filename[1024];
995 char backing_filename2[1024];
bellardfaea38e2006-08-05 21:31:00 +0000996 BlockDriverInfo bdi;
bellardea2384d2004-08-01 21:59:26 +0000997
998 fmt = NULL;
999 for(;;) {
1000 c = getopt(argc, argv, "f:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001001 if (c == -1) {
bellardea2384d2004-08-01 21:59:26 +00001002 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001003 }
bellardea2384d2004-08-01 21:59:26 +00001004 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001005 case '?':
bellardea2384d2004-08-01 21:59:26 +00001006 case 'h':
1007 help();
1008 break;
1009 case 'f':
1010 fmt = optarg;
1011 break;
1012 }
1013 }
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001014 if (optind >= argc) {
bellardea2384d2004-08-01 21:59:26 +00001015 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001016 }
bellardea2384d2004-08-01 21:59:26 +00001017 filename = argv[optind++];
1018
Stefan Hajnocziadfe0782010-04-13 10:29:35 +01001019 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001020 if (!bs) {
1021 return 1;
1022 }
bellardea2384d2004-08-01 21:59:26 +00001023 bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
1024 bdrv_get_geometry(bs, &total_sectors);
1025 get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
bellard57d1a2b2004-08-03 21:15:11 +00001026 allocated_size = get_allocated_file_size(filename);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001027 if (allocated_size < 0) {
blueswir1a10ea302008-08-24 10:30:33 +00001028 snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001029 } else {
ths5fafdf22007-09-16 21:08:06 +00001030 get_human_readable_size(dsize_buf, sizeof(dsize_buf),
bellardde167e42005-04-28 21:15:08 +00001031 allocated_size);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001032 }
bellardea2384d2004-08-01 21:59:26 +00001033 printf("image: %s\n"
1034 "file format: %s\n"
bellardec3757d2006-06-14 15:50:07 +00001035 "virtual size: %s (%" PRId64 " bytes)\n"
bellardea2384d2004-08-01 21:59:26 +00001036 "disk size: %s\n",
ths5fafdf22007-09-16 21:08:06 +00001037 filename, fmt_name, size_buf,
bellardec3757d2006-06-14 15:50:07 +00001038 (total_sectors * 512),
bellardea2384d2004-08-01 21:59:26 +00001039 dsize_buf);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001040 if (bdrv_is_encrypted(bs)) {
bellardea2384d2004-08-01 21:59:26 +00001041 printf("encrypted: yes\n");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001042 }
bellardfaea38e2006-08-05 21:31:00 +00001043 if (bdrv_get_info(bs, &bdi) >= 0) {
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001044 if (bdi.cluster_size != 0) {
bellardfaea38e2006-08-05 21:31:00 +00001045 printf("cluster_size: %d\n", bdi.cluster_size);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001046 }
bellardfaea38e2006-08-05 21:31:00 +00001047 }
bellard93b6b2a2006-08-01 15:51:11 +00001048 bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
bellardfaea38e2006-08-05 21:31:00 +00001049 if (backing_filename[0] != '\0') {
bellard93b6b2a2006-08-01 15:51:11 +00001050 path_combine(backing_filename2, sizeof(backing_filename2),
1051 filename, backing_filename);
ths5fafdf22007-09-16 21:08:06 +00001052 printf("backing file: %s (actual path: %s)\n",
bellard93b6b2a2006-08-01 15:51:11 +00001053 backing_filename,
1054 backing_filename2);
bellardfaea38e2006-08-05 21:31:00 +00001055 }
1056 dump_snapshots(bs);
bellardea2384d2004-08-01 21:59:26 +00001057 bdrv_delete(bs);
1058 return 0;
1059}
1060
aliguorif7b4a942009-01-07 17:40:15 +00001061#define SNAPSHOT_LIST 1
1062#define SNAPSHOT_CREATE 2
1063#define SNAPSHOT_APPLY 3
1064#define SNAPSHOT_DELETE 4
1065
Stuart Brady153859b2009-06-07 00:42:17 +01001066static int img_snapshot(int argc, char **argv)
aliguorif7b4a942009-01-07 17:40:15 +00001067{
1068 BlockDriverState *bs;
1069 QEMUSnapshotInfo sn;
1070 char *filename, *snapshot_name = NULL;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001071 int c, ret = 0, bdrv_oflags;
aliguorif7b4a942009-01-07 17:40:15 +00001072 int action = 0;
1073 qemu_timeval tv;
1074
Kevin Wolf710da702011-01-10 12:33:02 +01001075 bdrv_oflags = BDRV_O_FLAGS | BDRV_O_RDWR;
aliguorif7b4a942009-01-07 17:40:15 +00001076 /* Parse commandline parameters */
1077 for(;;) {
1078 c = getopt(argc, argv, "la:c:d:h");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001079 if (c == -1) {
aliguorif7b4a942009-01-07 17:40:15 +00001080 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001081 }
aliguorif7b4a942009-01-07 17:40:15 +00001082 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001083 case '?':
aliguorif7b4a942009-01-07 17:40:15 +00001084 case 'h':
1085 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001086 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001087 case 'l':
1088 if (action) {
1089 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001090 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001091 }
1092 action = SNAPSHOT_LIST;
Naphtali Spreif5edb012010-01-17 16:48:13 +02001093 bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
aliguorif7b4a942009-01-07 17:40:15 +00001094 break;
1095 case 'a':
1096 if (action) {
1097 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001098 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001099 }
1100 action = SNAPSHOT_APPLY;
1101 snapshot_name = optarg;
1102 break;
1103 case 'c':
1104 if (action) {
1105 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001106 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001107 }
1108 action = SNAPSHOT_CREATE;
1109 snapshot_name = optarg;
1110 break;
1111 case 'd':
1112 if (action) {
1113 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001114 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001115 }
1116 action = SNAPSHOT_DELETE;
1117 snapshot_name = optarg;
1118 break;
1119 }
1120 }
1121
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001122 if (optind >= argc) {
aliguorif7b4a942009-01-07 17:40:15 +00001123 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001124 }
aliguorif7b4a942009-01-07 17:40:15 +00001125 filename = argv[optind++];
1126
1127 /* Open the image */
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001128 bs = bdrv_new_open(filename, NULL, bdrv_oflags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001129 if (!bs) {
1130 return 1;
1131 }
aliguorif7b4a942009-01-07 17:40:15 +00001132
1133 /* Perform the requested action */
1134 switch(action) {
1135 case SNAPSHOT_LIST:
1136 dump_snapshots(bs);
1137 break;
1138
1139 case SNAPSHOT_CREATE:
1140 memset(&sn, 0, sizeof(sn));
1141 pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
1142
1143 qemu_gettimeofday(&tv);
1144 sn.date_sec = tv.tv_sec;
1145 sn.date_nsec = tv.tv_usec * 1000;
1146
1147 ret = bdrv_snapshot_create(bs, &sn);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001148 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001149 error_report("Could not create snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001150 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001151 }
aliguorif7b4a942009-01-07 17:40:15 +00001152 break;
1153
1154 case SNAPSHOT_APPLY:
1155 ret = bdrv_snapshot_goto(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001156 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001157 error_report("Could not apply snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001158 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001159 }
aliguorif7b4a942009-01-07 17:40:15 +00001160 break;
1161
1162 case SNAPSHOT_DELETE:
1163 ret = bdrv_snapshot_delete(bs, snapshot_name);
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001164 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001165 error_report("Could not delete snapshot '%s': %d (%s)",
aliguorif7b4a942009-01-07 17:40:15 +00001166 snapshot_name, ret, strerror(-ret));
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001167 }
aliguorif7b4a942009-01-07 17:40:15 +00001168 break;
1169 }
1170
1171 /* Cleanup */
1172 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001173 if (ret) {
1174 return 1;
1175 }
Stuart Brady153859b2009-06-07 00:42:17 +01001176 return 0;
aliguorif7b4a942009-01-07 17:40:15 +00001177}
1178
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001179static int img_rebase(int argc, char **argv)
1180{
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001181 BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001182 BlockDriver *old_backing_drv, *new_backing_drv;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001183 char *filename;
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001184 const char *fmt, *out_basefmt, *out_baseimg;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001185 int c, flags, ret;
1186 int unsafe = 0;
1187
1188 /* Parse commandline parameters */
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001189 fmt = NULL;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001190 out_baseimg = NULL;
1191 out_basefmt = NULL;
1192
1193 for(;;) {
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001194 c = getopt(argc, argv, "uhf:F:b:");
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001195 if (c == -1) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001196 break;
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001197 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001198 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001199 case '?':
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001200 case 'h':
1201 help();
1202 return 0;
Kevin Wolfe53dbee2010-03-02 12:14:31 +01001203 case 'f':
1204 fmt = optarg;
1205 break;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001206 case 'F':
1207 out_basefmt = optarg;
1208 break;
1209 case 'b':
1210 out_baseimg = optarg;
1211 break;
1212 case 'u':
1213 unsafe = 1;
1214 break;
1215 }
1216 }
1217
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001218 if ((optind >= argc) || !out_baseimg) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001219 help();
Jes Sorensenb8fb60d2010-12-06 15:25:39 +01001220 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001221 filename = argv[optind++];
1222
1223 /*
1224 * Open the images.
1225 *
1226 * Ignore the old backing file for unsafe rebase in case we want to correct
1227 * the reference to a renamed or moved backing file.
1228 */
Stefan Hajnocziadfe0782010-04-13 10:29:35 +01001229 flags = BDRV_O_FLAGS | BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
Stefan Hajnoczif163d072010-04-13 10:29:34 +01001230 bs = bdrv_new_open(filename, fmt, flags);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001231 if (!bs) {
1232 return 1;
1233 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001234
1235 /* Find the right drivers for the backing files */
1236 old_backing_drv = NULL;
1237 new_backing_drv = NULL;
1238
1239 if (!unsafe && bs->backing_format[0] != '\0') {
1240 old_backing_drv = bdrv_find_format(bs->backing_format);
1241 if (old_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001242 error_report("Invalid format name: '%s'", bs->backing_format);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001243 ret = -1;
1244 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001245 }
1246 }
1247
1248 if (out_basefmt != NULL) {
1249 new_backing_drv = bdrv_find_format(out_basefmt);
1250 if (new_backing_drv == NULL) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001251 error_report("Invalid format name: '%s'", out_basefmt);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001252 ret = -1;
1253 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001254 }
1255 }
1256
1257 /* For safe rebasing we need to compare old and new backing file */
1258 if (unsafe) {
1259 /* Make the compiler happy */
1260 bs_old_backing = NULL;
1261 bs_new_backing = NULL;
1262 } else {
1263 char backing_name[1024];
1264
1265 bs_old_backing = bdrv_new("old_backing");
1266 bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001267 ret = bdrv_open(bs_old_backing, backing_name, BDRV_O_FLAGS,
1268 old_backing_drv);
1269 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001270 error_report("Could not open old backing file '%s'", backing_name);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001271 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001272 }
1273
1274 bs_new_backing = bdrv_new("new_backing");
Kevin Wolfcdbae852010-08-17 18:58:55 +02001275 ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS,
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001276 new_backing_drv);
1277 if (ret) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001278 error_report("Could not open new backing file '%s'", out_baseimg);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001279 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001280 }
1281 }
1282
1283 /*
1284 * Check each unallocated cluster in the COW file. If it is unallocated,
1285 * accesses go to the backing file. We must therefore compare this cluster
1286 * in the old and new backing file, and if they differ we need to copy it
1287 * from the old backing file into the COW file.
1288 *
1289 * If qemu-img crashes during this step, no harm is done. The content of
1290 * the image is the same as the original one at any time.
1291 */
1292 if (!unsafe) {
1293 uint64_t num_sectors;
1294 uint64_t sector;
Kevin Wolfcc60e322010-04-29 14:47:48 +02001295 int n;
TeLeMand6771bf2010-02-08 16:20:00 +08001296 uint8_t * buf_old;
1297 uint8_t * buf_new;
1298
1299 buf_old = qemu_malloc(IO_BUF_SIZE);
1300 buf_new = qemu_malloc(IO_BUF_SIZE);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001301
1302 bdrv_get_geometry(bs, &num_sectors);
1303
1304 for (sector = 0; sector < num_sectors; sector += n) {
1305
1306 /* How many sectors can we handle with the next read? */
1307 if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
1308 n = (IO_BUF_SIZE / 512);
1309 } else {
1310 n = num_sectors - sector;
1311 }
1312
1313 /* If the cluster is allocated, we don't need to take action */
Kevin Wolfcc60e322010-04-29 14:47:48 +02001314 ret = bdrv_is_allocated(bs, sector, n, &n);
1315 if (ret) {
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001316 continue;
1317 }
1318
1319 /* Read old and new backing file */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001320 ret = bdrv_read(bs_old_backing, sector, buf_old, n);
1321 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001322 error_report("error while reading from old backing file");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001323 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001324 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001325 ret = bdrv_read(bs_new_backing, sector, buf_new, n);
1326 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001327 error_report("error while reading from new backing file");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001328 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001329 }
1330
1331 /* If they differ, we need to write to the COW file */
1332 uint64_t written = 0;
1333
1334 while (written < n) {
1335 int pnum;
1336
1337 if (compare_sectors(buf_old + written * 512,
Kevin Wolf60b1bd42010-02-17 12:32:59 +01001338 buf_new + written * 512, n - written, &pnum))
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001339 {
1340 ret = bdrv_write(bs, sector + written,
1341 buf_old + written * 512, pnum);
1342 if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001343 error_report("Error while writing to COW image: %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001344 strerror(-ret));
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001345 goto out;
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001346 }
1347 }
1348
1349 written += pnum;
1350 }
1351 }
TeLeMand6771bf2010-02-08 16:20:00 +08001352
1353 qemu_free(buf_old);
1354 qemu_free(buf_new);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001355 }
1356
1357 /*
1358 * Change the backing file. All clusters that are different from the old
1359 * backing file are overwritten in the COW file now, so the visible content
1360 * doesn't change when we switch the backing file.
1361 */
1362 ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
1363 if (ret == -ENOSPC) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001364 error_report("Could not change the backing file to '%s': No "
1365 "space left in the file header", out_baseimg);
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001366 } else if (ret < 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001367 error_report("Could not change the backing file to '%s': %s",
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001368 out_baseimg, strerror(-ret));
1369 }
1370
1371 /*
1372 * TODO At this point it is possible to check if any clusters that are
1373 * allocated in the COW file are the same in the backing file. If so, they
1374 * could be dropped from the COW file. Don't do this before switching the
1375 * backing file, in case of a crash this would lead to corruption.
1376 */
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001377out:
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001378 /* Cleanup */
1379 if (!unsafe) {
1380 bdrv_delete(bs_old_backing);
1381 bdrv_delete(bs_new_backing);
1382 }
1383
1384 bdrv_delete(bs);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001385 if (ret) {
1386 return 1;
1387 }
Kevin Wolf3e85c6f2010-01-12 12:55:18 +01001388 return 0;
1389}
1390
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001391static int img_resize(int argc, char **argv)
1392{
1393 int c, ret, relative;
1394 const char *filename, *fmt, *size;
1395 int64_t n, total_size;
Jes Sorensen2a819982010-12-06 17:08:31 +01001396 BlockDriverState *bs = NULL;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001397 QEMUOptionParameter *param;
1398 QEMUOptionParameter resize_options[] = {
1399 {
1400 .name = BLOCK_OPT_SIZE,
1401 .type = OPT_SIZE,
1402 .help = "Virtual disk size"
1403 },
1404 { NULL }
1405 };
1406
1407 fmt = NULL;
1408 for(;;) {
1409 c = getopt(argc, argv, "f:h");
1410 if (c == -1) {
1411 break;
1412 }
1413 switch(c) {
Jes Sorensenef873942010-12-06 15:25:40 +01001414 case '?':
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001415 case 'h':
1416 help();
1417 break;
1418 case 'f':
1419 fmt = optarg;
1420 break;
1421 }
1422 }
1423 if (optind + 1 >= argc) {
1424 help();
1425 }
1426 filename = argv[optind++];
1427 size = argv[optind++];
1428
1429 /* Choose grow, shrink, or absolute resize mode */
1430 switch (size[0]) {
1431 case '+':
1432 relative = 1;
1433 size++;
1434 break;
1435 case '-':
1436 relative = -1;
1437 size++;
1438 break;
1439 default:
1440 relative = 0;
1441 break;
1442 }
1443
1444 /* Parse size */
1445 param = parse_option_parameters("", resize_options, NULL);
1446 if (set_option_parameter(param, BLOCK_OPT_SIZE, size)) {
1447 /* Error message already printed when size parsing fails */
Jes Sorensen2a819982010-12-06 17:08:31 +01001448 ret = -1;
1449 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001450 }
1451 n = get_option_parameter(param, BLOCK_OPT_SIZE)->value.n;
1452 free_option_parameters(param);
1453
1454 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001455 if (!bs) {
Jes Sorensen2a819982010-12-06 17:08:31 +01001456 ret = -1;
1457 goto out;
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001458 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001459
1460 if (relative) {
1461 total_size = bdrv_getlength(bs) + n * relative;
1462 } else {
1463 total_size = n;
1464 }
1465 if (total_size <= 0) {
Jes Sorensen15654a62010-12-16 14:31:53 +01001466 error_report("New image size must be positive");
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001467 ret = -1;
1468 goto out;
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001469 }
1470
1471 ret = bdrv_truncate(bs, total_size);
1472 switch (ret) {
1473 case 0:
1474 printf("Image resized.\n");
1475 break;
1476 case -ENOTSUP:
Jes Sorensen15654a62010-12-16 14:31:53 +01001477 error_report("This image format does not support resize");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001478 break;
1479 case -EACCES:
Jes Sorensen15654a62010-12-16 14:31:53 +01001480 error_report("Image is read-only");
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001481 break;
1482 default:
Jes Sorensen15654a62010-12-16 14:31:53 +01001483 error_report("Error resizing image (%d)", -ret);
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001484 break;
1485 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001486out:
Jes Sorensen2a819982010-12-06 17:08:31 +01001487 if (bs) {
1488 bdrv_delete(bs);
1489 }
MORITA Kazutakac2abcce2010-06-21 04:26:35 +09001490 if (ret) {
1491 return 1;
1492 }
Stefan Hajnocziae6b0ed2010-04-24 09:12:12 +01001493 return 0;
1494}
1495
Anthony Liguoric227f092009-10-01 16:12:16 -05001496static const img_cmd_t img_cmds[] = {
Stuart Brady153859b2009-06-07 00:42:17 +01001497#define DEF(option, callback, arg_string) \
1498 { option, callback },
1499#include "qemu-img-cmds.h"
1500#undef DEF
1501#undef GEN_DOCS
1502 { NULL, NULL, },
1503};
1504
bellardea2384d2004-08-01 21:59:26 +00001505int main(int argc, char **argv)
1506{
Anthony Liguoric227f092009-10-01 16:12:16 -05001507 const img_cmd_t *cmd;
Stuart Brady153859b2009-06-07 00:42:17 +01001508 const char *cmdname;
bellardea2384d2004-08-01 21:59:26 +00001509
Kevin Wolf53f76e52010-12-16 15:10:32 +01001510 error_set_progname(argv[0]);
1511
bellardea2384d2004-08-01 21:59:26 +00001512 bdrv_init();
1513 if (argc < 2)
1514 help();
Stuart Brady153859b2009-06-07 00:42:17 +01001515 cmdname = argv[1];
aurel328f9b1572009-02-09 18:14:31 +00001516 argc--; argv++;
Stuart Brady153859b2009-06-07 00:42:17 +01001517
1518 /* find the command */
1519 for(cmd = img_cmds; cmd->name != NULL; cmd++) {
1520 if (!strcmp(cmdname, cmd->name)) {
1521 return cmd->handler(argc, argv);
1522 }
bellardea2384d2004-08-01 21:59:26 +00001523 }
Stuart Brady153859b2009-06-07 00:42:17 +01001524
1525 /* not found */
1526 help();
bellardea2384d2004-08-01 21:59:26 +00001527 return 0;
1528}