Statistics
| Branch: | Revision:

root / qemu-img.c @ 6b837bc4

History | View | Annotate | Download (42.7 kB)

1 ea2384d3 bellard
/*
2 fb43f4dd bellard
 * QEMU disk image utility
3 5fafdf24 ths
 *
4 68d0f70e bellard
 * Copyright (c) 2003-2008 Fabrice Bellard
5 5fafdf24 ths
 *
6 ea2384d3 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 ea2384d3 bellard
 * of this software and associated documentation files (the "Software"), to deal
8 ea2384d3 bellard
 * in the Software without restriction, including without limitation the rights
9 ea2384d3 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 ea2384d3 bellard
 * copies of the Software, and to permit persons to whom the Software is
11 ea2384d3 bellard
 * furnished to do so, subject to the following conditions:
12 ea2384d3 bellard
 *
13 ea2384d3 bellard
 * The above copyright notice and this permission notice shall be included in
14 ea2384d3 bellard
 * all copies or substantial portions of the Software.
15 ea2384d3 bellard
 *
16 ea2384d3 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 ea2384d3 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 ea2384d3 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 ea2384d3 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 ea2384d3 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 ea2384d3 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 ea2384d3 bellard
 * THE SOFTWARE.
23 ea2384d3 bellard
 */
24 faf07963 pbrook
#include "qemu-common.h"
25 9ea2ea71 Kevin Wolf
#include "qemu-option.h"
26 53f76e58 Kevin Wolf
#include "qemu-error.h"
27 f7b4a940 aliguori
#include "osdep.h"
28 dc786bc9 Jes Sorensen
#include "sysemu.h"
29 ec36ba14 ths
#include "block_int.h"
30 9230eaf6 aliguori
#include <stdio.h>
31 ea2384d3 bellard
32 e8445331 bellard
#ifdef _WIN32
33 e8445331 bellard
#include <windows.h>
34 e8445331 bellard
#endif
35 e8445331 bellard
36 c227f099 Anthony Liguori
typedef struct img_cmd_t {
37 153859be Stuart Brady
    const char *name;
38 153859be Stuart Brady
    int (*handler)(int argc, char **argv);
39 c227f099 Anthony Liguori
} img_cmd_t;
40 153859be Stuart Brady
41 137519ce aurel32
/* Default to cache=writeback as data integrity is not important for qemu-tcg. */
42 adfe078e Stefan Hajnoczi
#define BDRV_O_FLAGS BDRV_O_CACHE_WB
43 137519ce aurel32
44 ea2384d3 bellard
static void format_print(void *opaque, const char *name)
45 ea2384d3 bellard
{
46 ea2384d3 bellard
    printf(" %s", name);
47 ea2384d3 bellard
}
48 ea2384d3 bellard
49 d2c639d6 blueswir1
/* Please keep in synch with qemu-img.texi */
50 3f379ab1 pbrook
static void help(void)
51 ea2384d3 bellard
{
52 e00291c0 Paolo Bonzini
    const char *help_msg =
53 e00291c0 Paolo Bonzini
           "qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fabrice Bellard\n"
54 3f020d70 malc
           "usage: qemu-img command [command options]\n"
55 3f020d70 malc
           "QEMU disk image utility\n"
56 3f020d70 malc
           "\n"
57 3f020d70 malc
           "Command syntax:\n"
58 153859be Stuart Brady
#define DEF(option, callback, arg_string)        \
59 153859be Stuart Brady
           "  " arg_string "\n"
60 153859be Stuart Brady
#include "qemu-img-cmds.h"
61 153859be Stuart Brady
#undef DEF
62 153859be Stuart Brady
#undef GEN_DOCS
63 3f020d70 malc
           "\n"
64 3f020d70 malc
           "Command parameters:\n"
65 3f020d70 malc
           "  'filename' is a disk image filename\n"
66 3f020d70 malc
           "  'fmt' is the disk image format. It is guessed automatically in most cases\n"
67 3f020d70 malc
           "  'size' is the disk image size in bytes. Optional suffixes\n"
68 3f020d70 malc
           "    'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M)\n"
69 3f020d70 malc
           "    and T (terabyte, 1024G) are supported. 'b' is ignored.\n"
70 3f020d70 malc
           "  'output_filename' is the destination disk image filename\n"
71 3f020d70 malc
           "  'output_fmt' is the destination format\n"
72 3f020d70 malc
           "  'options' is a comma separated list of format specific options in a\n"
73 3f020d70 malc
           "    name=value format. Use -o ? for an overview of the options supported by the\n"
74 3f020d70 malc
           "    used format\n"
75 3f020d70 malc
           "  '-c' indicates that target image must be compressed (qcow format only)\n"
76 3f020d70 malc
           "  '-u' enables unsafe rebasing. It is assumed that old and new backing file\n"
77 3f020d70 malc
           "       match exactly. The image doesn't need a working backing file before\n"
78 3f020d70 malc
           "       rebasing in this case (useful for renaming the backing file)\n"
79 3f020d70 malc
           "  '-h' with or without a command shows this help and lists the supported formats\n"
80 6b837bc4 Jes Sorensen
           "  '-p' show progress of command (only certain commands)\n"
81 3f020d70 malc
           "\n"
82 3f020d70 malc
           "Parameters to snapshot subcommand:\n"
83 3f020d70 malc
           "  'snapshot' is the name of the snapshot to create, apply or delete\n"
84 3f020d70 malc
           "  '-a' applies a snapshot (revert disk to saved state)\n"
85 3f020d70 malc
           "  '-c' creates a snapshot\n"
86 3f020d70 malc
           "  '-d' deletes a snapshot\n"
87 e00291c0 Paolo Bonzini
           "  '-l' lists all snapshots in the given image\n";
88 e00291c0 Paolo Bonzini
89 e00291c0 Paolo Bonzini
    printf("%s\nSupported formats:", help_msg);
90 ea2384d3 bellard
    bdrv_iterate_format(format_print, NULL);
91 ea2384d3 bellard
    printf("\n");
92 ea2384d3 bellard
    exit(1);
93 ea2384d3 bellard
}
94 ea2384d3 bellard
95 ea2384d3 bellard
#if defined(WIN32)
96 ea2384d3 bellard
/* XXX: put correct support for win32 */
97 ea2384d3 bellard
static int read_password(char *buf, int buf_size)
98 ea2384d3 bellard
{
99 ea2384d3 bellard
    int c, i;
100 ea2384d3 bellard
    printf("Password: ");
101 ea2384d3 bellard
    fflush(stdout);
102 ea2384d3 bellard
    i = 0;
103 ea2384d3 bellard
    for(;;) {
104 ea2384d3 bellard
        c = getchar();
105 ea2384d3 bellard
        if (c == '\n')
106 ea2384d3 bellard
            break;
107 ea2384d3 bellard
        if (i < (buf_size - 1))
108 ea2384d3 bellard
            buf[i++] = c;
109 ea2384d3 bellard
    }
110 ea2384d3 bellard
    buf[i] = '\0';
111 ea2384d3 bellard
    return 0;
112 ea2384d3 bellard
}
113 ea2384d3 bellard
114 ea2384d3 bellard
#else
115 ea2384d3 bellard
116 ea2384d3 bellard
#include <termios.h>
117 ea2384d3 bellard
118 ea2384d3 bellard
static struct termios oldtty;
119 ea2384d3 bellard
120 ea2384d3 bellard
static void term_exit(void)
121 ea2384d3 bellard
{
122 ea2384d3 bellard
    tcsetattr (0, TCSANOW, &oldtty);
123 ea2384d3 bellard
}
124 ea2384d3 bellard
125 ea2384d3 bellard
static void term_init(void)
126 ea2384d3 bellard
{
127 ea2384d3 bellard
    struct termios tty;
128 ea2384d3 bellard
129 ea2384d3 bellard
    tcgetattr (0, &tty);
130 ea2384d3 bellard
    oldtty = tty;
131 ea2384d3 bellard
132 ea2384d3 bellard
    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
133 ea2384d3 bellard
                          |INLCR|IGNCR|ICRNL|IXON);
134 ea2384d3 bellard
    tty.c_oflag |= OPOST;
135 ea2384d3 bellard
    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
136 ea2384d3 bellard
    tty.c_cflag &= ~(CSIZE|PARENB);
137 ea2384d3 bellard
    tty.c_cflag |= CS8;
138 ea2384d3 bellard
    tty.c_cc[VMIN] = 1;
139 ea2384d3 bellard
    tty.c_cc[VTIME] = 0;
140 3b46e624 ths
141 ea2384d3 bellard
    tcsetattr (0, TCSANOW, &tty);
142 ea2384d3 bellard
143 ea2384d3 bellard
    atexit(term_exit);
144 ea2384d3 bellard
}
145 ea2384d3 bellard
146 3f379ab1 pbrook
static int read_password(char *buf, int buf_size)
147 ea2384d3 bellard
{
148 ea2384d3 bellard
    uint8_t ch;
149 ea2384d3 bellard
    int i, ret;
150 ea2384d3 bellard
151 ea2384d3 bellard
    printf("password: ");
152 ea2384d3 bellard
    fflush(stdout);
153 ea2384d3 bellard
    term_init();
154 ea2384d3 bellard
    i = 0;
155 ea2384d3 bellard
    for(;;) {
156 ea2384d3 bellard
        ret = read(0, &ch, 1);
157 ea2384d3 bellard
        if (ret == -1) {
158 ea2384d3 bellard
            if (errno == EAGAIN || errno == EINTR) {
159 ea2384d3 bellard
                continue;
160 ea2384d3 bellard
            } else {
161 ea2384d3 bellard
                ret = -1;
162 ea2384d3 bellard
                break;
163 ea2384d3 bellard
            }
164 ea2384d3 bellard
        } else if (ret == 0) {
165 ea2384d3 bellard
            ret = -1;
166 ea2384d3 bellard
            break;
167 ea2384d3 bellard
        } else {
168 ea2384d3 bellard
            if (ch == '\r') {
169 ea2384d3 bellard
                ret = 0;
170 ea2384d3 bellard
                break;
171 ea2384d3 bellard
            }
172 ea2384d3 bellard
            if (i < (buf_size - 1))
173 ea2384d3 bellard
                buf[i++] = ch;
174 ea2384d3 bellard
        }
175 ea2384d3 bellard
    }
176 ea2384d3 bellard
    term_exit();
177 ea2384d3 bellard
    buf[i] = '\0';
178 ea2384d3 bellard
    printf("\n");
179 ea2384d3 bellard
    return ret;
180 ea2384d3 bellard
}
181 ea2384d3 bellard
#endif
182 ea2384d3 bellard
183 4ac8aacd Jes Sorensen
static int print_block_option_help(const char *filename, const char *fmt)
184 4ac8aacd Jes Sorensen
{
185 4ac8aacd Jes Sorensen
    BlockDriver *drv, *proto_drv;
186 4ac8aacd Jes Sorensen
    QEMUOptionParameter *create_options = NULL;
187 4ac8aacd Jes Sorensen
188 4ac8aacd Jes Sorensen
    /* Find driver and parse its options */
189 4ac8aacd Jes Sorensen
    drv = bdrv_find_format(fmt);
190 4ac8aacd Jes Sorensen
    if (!drv) {
191 15654a6d Jes Sorensen
        error_report("Unknown file format '%s'", fmt);
192 4ac8aacd Jes Sorensen
        return 1;
193 4ac8aacd Jes Sorensen
    }
194 4ac8aacd Jes Sorensen
195 4ac8aacd Jes Sorensen
    proto_drv = bdrv_find_protocol(filename);
196 4ac8aacd Jes Sorensen
    if (!proto_drv) {
197 15654a6d Jes Sorensen
        error_report("Unknown protocol '%s'", filename);
198 4ac8aacd Jes Sorensen
        return 1;
199 4ac8aacd Jes Sorensen
    }
200 4ac8aacd Jes Sorensen
201 4ac8aacd Jes Sorensen
    create_options = append_option_parameters(create_options,
202 4ac8aacd Jes Sorensen
                                              drv->create_options);
203 4ac8aacd Jes Sorensen
    create_options = append_option_parameters(create_options,
204 4ac8aacd Jes Sorensen
                                              proto_drv->create_options);
205 4ac8aacd Jes Sorensen
    print_option_help(create_options);
206 4ac8aacd Jes Sorensen
    free_option_parameters(create_options);
207 4ac8aacd Jes Sorensen
    return 0;
208 4ac8aacd Jes Sorensen
}
209 4ac8aacd Jes Sorensen
210 75c23805 bellard
static BlockDriverState *bdrv_new_open(const char *filename,
211 9bc378c1 Sheng Yang
                                       const char *fmt,
212 f163d073 Stefan Hajnoczi
                                       int flags)
213 75c23805 bellard
{
214 75c23805 bellard
    BlockDriverState *bs;
215 75c23805 bellard
    BlockDriver *drv;
216 75c23805 bellard
    char password[256];
217 b9eaf9ec Kevin Wolf
    int ret;
218 75c23805 bellard
219 b9eaf9ec Kevin Wolf
    bs = bdrv_new("image");
220 ad717139 Kevin Wolf
221 75c23805 bellard
    if (fmt) {
222 75c23805 bellard
        drv = bdrv_find_format(fmt);
223 c2abccec MORITA Kazutaka
        if (!drv) {
224 15654a6d Jes Sorensen
            error_report("Unknown file format '%s'", fmt);
225 c2abccec MORITA Kazutaka
            goto fail;
226 c2abccec MORITA Kazutaka
        }
227 75c23805 bellard
    } else {
228 75c23805 bellard
        drv = NULL;
229 75c23805 bellard
    }
230 b9eaf9ec Kevin Wolf
231 b9eaf9ec Kevin Wolf
    ret = bdrv_open(bs, filename, flags, drv);
232 b9eaf9ec Kevin Wolf
    if (ret < 0) {
233 b9eaf9ec Kevin Wolf
        error_report("Could not open '%s': %s", filename, strerror(-ret));
234 c2abccec MORITA Kazutaka
        goto fail;
235 75c23805 bellard
    }
236 b9eaf9ec Kevin Wolf
237 75c23805 bellard
    if (bdrv_is_encrypted(bs)) {
238 75c23805 bellard
        printf("Disk image '%s' is encrypted.\n", filename);
239 c2abccec MORITA Kazutaka
        if (read_password(password, sizeof(password)) < 0) {
240 15654a6d Jes Sorensen
            error_report("No password given");
241 c2abccec MORITA Kazutaka
            goto fail;
242 c2abccec MORITA Kazutaka
        }
243 c2abccec MORITA Kazutaka
        if (bdrv_set_key(bs, password) < 0) {
244 15654a6d Jes Sorensen
            error_report("invalid password");
245 c2abccec MORITA Kazutaka
            goto fail;
246 c2abccec MORITA Kazutaka
        }
247 75c23805 bellard
    }
248 75c23805 bellard
    return bs;
249 c2abccec MORITA Kazutaka
fail:
250 c2abccec MORITA Kazutaka
    if (bs) {
251 c2abccec MORITA Kazutaka
        bdrv_delete(bs);
252 c2abccec MORITA Kazutaka
    }
253 c2abccec MORITA Kazutaka
    return NULL;
254 75c23805 bellard
}
255 75c23805 bellard
256 c2abccec MORITA Kazutaka
static int add_old_style_options(const char *fmt, QEMUOptionParameter *list,
257 eec77d9e Jes Sorensen
                                 const char *base_filename,
258 eec77d9e Jes Sorensen
                                 const char *base_fmt)
259 efa84d43 Kevin Wolf
{
260 efa84d43 Kevin Wolf
    if (base_filename) {
261 efa84d43 Kevin Wolf
        if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) {
262 15654a6d Jes Sorensen
            error_report("Backing file not supported for file format '%s'",
263 15654a6d Jes Sorensen
                         fmt);
264 c2abccec MORITA Kazutaka
            return -1;
265 efa84d43 Kevin Wolf
        }
266 efa84d43 Kevin Wolf
    }
267 efa84d43 Kevin Wolf
    if (base_fmt) {
268 efa84d43 Kevin Wolf
        if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {
269 15654a6d Jes Sorensen
            error_report("Backing file format not supported for file "
270 15654a6d Jes Sorensen
                         "format '%s'", fmt);
271 c2abccec MORITA Kazutaka
            return -1;
272 efa84d43 Kevin Wolf
        }
273 efa84d43 Kevin Wolf
    }
274 c2abccec MORITA Kazutaka
    return 0;
275 efa84d43 Kevin Wolf
}
276 efa84d43 Kevin Wolf
277 ea2384d3 bellard
static int img_create(int argc, char **argv)
278 ea2384d3 bellard
{
279 eec77d9e Jes Sorensen
    int c, ret = 0;
280 1da7cfbd Jes Sorensen
    uint64_t img_size = -1;
281 ea2384d3 bellard
    const char *fmt = "raw";
282 9230eaf6 aliguori
    const char *base_fmt = NULL;
283 ea2384d3 bellard
    const char *filename;
284 ea2384d3 bellard
    const char *base_filename = NULL;
285 9ea2ea71 Kevin Wolf
    char *options = NULL;
286 3b46e624 ths
287 ea2384d3 bellard
    for(;;) {
288 9ea2ea71 Kevin Wolf
        c = getopt(argc, argv, "F:b:f:he6o:");
289 b8fb60da Jes Sorensen
        if (c == -1) {
290 ea2384d3 bellard
            break;
291 b8fb60da Jes Sorensen
        }
292 ea2384d3 bellard
        switch(c) {
293 ef87394c Jes Sorensen
        case '?':
294 ea2384d3 bellard
        case 'h':
295 ea2384d3 bellard
            help();
296 ea2384d3 bellard
            break;
297 9230eaf6 aliguori
        case 'F':
298 9230eaf6 aliguori
            base_fmt = optarg;
299 9230eaf6 aliguori
            break;
300 ea2384d3 bellard
        case 'b':
301 ea2384d3 bellard
            base_filename = optarg;
302 ea2384d3 bellard
            break;
303 ea2384d3 bellard
        case 'f':
304 ea2384d3 bellard
            fmt = optarg;
305 ea2384d3 bellard
            break;
306 ea2384d3 bellard
        case 'e':
307 15654a6d Jes Sorensen
            error_report("qemu-img: option -e is deprecated, please use \'-o "
308 eec77d9e Jes Sorensen
                  "encryption\' instead!");
309 eec77d9e Jes Sorensen
            return 1;
310 d8871c5a ths
        case '6':
311 15654a6d Jes Sorensen
            error_report("qemu-img: option -6 is deprecated, please use \'-o "
312 eec77d9e Jes Sorensen
                  "compat6\' instead!");
313 eec77d9e Jes Sorensen
            return 1;
314 9ea2ea71 Kevin Wolf
        case 'o':
315 9ea2ea71 Kevin Wolf
            options = optarg;
316 9ea2ea71 Kevin Wolf
            break;
317 ea2384d3 bellard
        }
318 ea2384d3 bellard
    }
319 9230eaf6 aliguori
320 b50cbabc MORITA Kazutaka
    /* Get the filename */
321 b8fb60da Jes Sorensen
    if (optind >= argc) {
322 b50cbabc MORITA Kazutaka
        help();
323 b8fb60da Jes Sorensen
    }
324 b50cbabc MORITA Kazutaka
    filename = argv[optind++];
325 b50cbabc MORITA Kazutaka
326 1da7cfbd Jes Sorensen
    /* Get image size, if specified */
327 1da7cfbd Jes Sorensen
    if (optind < argc) {
328 70b4f4bb Jes Sorensen
        int64_t sval;
329 1da7cfbd Jes Sorensen
        sval = strtosz_suffix(argv[optind++], NULL, STRTOSZ_DEFSUFFIX_B);
330 1da7cfbd Jes Sorensen
        if (sval < 0) {
331 15654a6d Jes Sorensen
            error_report("Invalid image size specified! You may use k, M, G or "
332 1da7cfbd Jes Sorensen
                  "T suffixes for ");
333 15654a6d Jes Sorensen
            error_report("kilobytes, megabytes, gigabytes and terabytes.");
334 1da7cfbd Jes Sorensen
            ret = -1;
335 1da7cfbd Jes Sorensen
            goto out;
336 1da7cfbd Jes Sorensen
        }
337 1da7cfbd Jes Sorensen
        img_size = (uint64_t)sval;
338 1da7cfbd Jes Sorensen
    }
339 1da7cfbd Jes Sorensen
340 4ac8aacd Jes Sorensen
    if (options && !strcmp(options, "?")) {
341 4ac8aacd Jes Sorensen
        ret = print_block_option_help(filename, fmt);
342 4ac8aacd Jes Sorensen
        goto out;
343 4ac8aacd Jes Sorensen
    }
344 4ac8aacd Jes Sorensen
345 f88e1a42 Jes Sorensen
    ret = bdrv_img_create(filename, fmt, base_filename, base_fmt,
346 f88e1a42 Jes Sorensen
                          options, img_size, BDRV_O_FLAGS);
347 c2abccec MORITA Kazutaka
out:
348 c2abccec MORITA Kazutaka
    if (ret) {
349 c2abccec MORITA Kazutaka
        return 1;
350 c2abccec MORITA Kazutaka
    }
351 ea2384d3 bellard
    return 0;
352 ea2384d3 bellard
}
353 ea2384d3 bellard
354 e076f338 Kevin Wolf
/*
355 e076f338 Kevin Wolf
 * Checks an image for consistency. Exit codes:
356 e076f338 Kevin Wolf
 *
357 e076f338 Kevin Wolf
 * 0 - Check completed, image is good
358 e076f338 Kevin Wolf
 * 1 - Check not completed because of internal errors
359 e076f338 Kevin Wolf
 * 2 - Check completed, image is corrupted
360 e076f338 Kevin Wolf
 * 3 - Check completed, image has leaked clusters, but is good otherwise
361 e076f338 Kevin Wolf
 */
362 1585969c aliguori
static int img_check(int argc, char **argv)
363 1585969c aliguori
{
364 1585969c aliguori
    int c, ret;
365 1585969c aliguori
    const char *filename, *fmt;
366 1585969c aliguori
    BlockDriverState *bs;
367 e076f338 Kevin Wolf
    BdrvCheckResult result;
368 1585969c aliguori
369 1585969c aliguori
    fmt = NULL;
370 1585969c aliguori
    for(;;) {
371 1585969c aliguori
        c = getopt(argc, argv, "f:h");
372 b8fb60da Jes Sorensen
        if (c == -1) {
373 1585969c aliguori
            break;
374 b8fb60da Jes Sorensen
        }
375 1585969c aliguori
        switch(c) {
376 ef87394c Jes Sorensen
        case '?':
377 1585969c aliguori
        case 'h':
378 1585969c aliguori
            help();
379 1585969c aliguori
            break;
380 1585969c aliguori
        case 'f':
381 1585969c aliguori
            fmt = optarg;
382 1585969c aliguori
            break;
383 1585969c aliguori
        }
384 1585969c aliguori
    }
385 b8fb60da Jes Sorensen
    if (optind >= argc) {
386 1585969c aliguori
        help();
387 b8fb60da Jes Sorensen
    }
388 1585969c aliguori
    filename = argv[optind++];
389 1585969c aliguori
390 adfe078e Stefan Hajnoczi
    bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS);
391 c2abccec MORITA Kazutaka
    if (!bs) {
392 c2abccec MORITA Kazutaka
        return 1;
393 c2abccec MORITA Kazutaka
    }
394 e076f338 Kevin Wolf
    ret = bdrv_check(bs, &result);
395 e076f338 Kevin Wolf
396 e076f338 Kevin Wolf
    if (ret == -ENOTSUP) {
397 15654a6d Jes Sorensen
        error_report("This image format does not support checks");
398 e076f338 Kevin Wolf
        bdrv_delete(bs);
399 e076f338 Kevin Wolf
        return 1;
400 e076f338 Kevin Wolf
    }
401 e076f338 Kevin Wolf
402 e076f338 Kevin Wolf
    if (!(result.corruptions || result.leaks || result.check_errors)) {
403 e076f338 Kevin Wolf
        printf("No errors were found on the image.\n");
404 e076f338 Kevin Wolf
    } else {
405 e076f338 Kevin Wolf
        if (result.corruptions) {
406 e076f338 Kevin Wolf
            printf("\n%d errors were found on the image.\n"
407 e076f338 Kevin Wolf
                "Data may be corrupted, or further writes to the image "
408 e076f338 Kevin Wolf
                "may corrupt it.\n",
409 e076f338 Kevin Wolf
                result.corruptions);
410 e076f338 Kevin Wolf
        }
411 e076f338 Kevin Wolf
412 e076f338 Kevin Wolf
        if (result.leaks) {
413 e076f338 Kevin Wolf
            printf("\n%d leaked clusters were found on the image.\n"
414 e076f338 Kevin Wolf
                "This means waste of disk space, but no harm to data.\n",
415 e076f338 Kevin Wolf
                result.leaks);
416 e076f338 Kevin Wolf
        }
417 e076f338 Kevin Wolf
418 e076f338 Kevin Wolf
        if (result.check_errors) {
419 e076f338 Kevin Wolf
            printf("\n%d internal errors have occurred during the check.\n",
420 e076f338 Kevin Wolf
                result.check_errors);
421 1585969c aliguori
        }
422 1585969c aliguori
    }
423 1585969c aliguori
424 1585969c aliguori
    bdrv_delete(bs);
425 e076f338 Kevin Wolf
426 e076f338 Kevin Wolf
    if (ret < 0 || result.check_errors) {
427 e076f338 Kevin Wolf
        printf("\nAn error has occurred during the check: %s\n"
428 e076f338 Kevin Wolf
            "The check is not complete and may have missed error.\n",
429 e076f338 Kevin Wolf
            strerror(-ret));
430 c2abccec MORITA Kazutaka
        return 1;
431 c2abccec MORITA Kazutaka
    }
432 e076f338 Kevin Wolf
433 e076f338 Kevin Wolf
    if (result.corruptions) {
434 e076f338 Kevin Wolf
        return 2;
435 e076f338 Kevin Wolf
    } else if (result.leaks) {
436 e076f338 Kevin Wolf
        return 3;
437 e076f338 Kevin Wolf
    } else {
438 e076f338 Kevin Wolf
        return 0;
439 e076f338 Kevin Wolf
    }
440 1585969c aliguori
}
441 1585969c aliguori
442 ea2384d3 bellard
static int img_commit(int argc, char **argv)
443 ea2384d3 bellard
{
444 ea2384d3 bellard
    int c, ret;
445 ea2384d3 bellard
    const char *filename, *fmt;
446 ea2384d3 bellard
    BlockDriverState *bs;
447 ea2384d3 bellard
448 ea2384d3 bellard
    fmt = NULL;
449 ea2384d3 bellard
    for(;;) {
450 ea2384d3 bellard
        c = getopt(argc, argv, "f:h");
451 b8fb60da Jes Sorensen
        if (c == -1) {
452 ea2384d3 bellard
            break;
453 b8fb60da Jes Sorensen
        }
454 ea2384d3 bellard
        switch(c) {
455 ef87394c Jes Sorensen
        case '?':
456 ea2384d3 bellard
        case 'h':
457 ea2384d3 bellard
            help();
458 ea2384d3 bellard
            break;
459 ea2384d3 bellard
        case 'f':
460 ea2384d3 bellard
            fmt = optarg;
461 ea2384d3 bellard
            break;
462 ea2384d3 bellard
        }
463 ea2384d3 bellard
    }
464 b8fb60da Jes Sorensen
    if (optind >= argc) {
465 ea2384d3 bellard
        help();
466 b8fb60da Jes Sorensen
    }
467 ea2384d3 bellard
    filename = argv[optind++];
468 ea2384d3 bellard
469 adfe078e Stefan Hajnoczi
    bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
470 c2abccec MORITA Kazutaka
    if (!bs) {
471 c2abccec MORITA Kazutaka
        return 1;
472 c2abccec MORITA Kazutaka
    }
473 ea2384d3 bellard
    ret = bdrv_commit(bs);
474 ea2384d3 bellard
    switch(ret) {
475 ea2384d3 bellard
    case 0:
476 ea2384d3 bellard
        printf("Image committed.\n");
477 ea2384d3 bellard
        break;
478 ea2384d3 bellard
    case -ENOENT:
479 15654a6d Jes Sorensen
        error_report("No disk inserted");
480 ea2384d3 bellard
        break;
481 ea2384d3 bellard
    case -EACCES:
482 15654a6d Jes Sorensen
        error_report("Image is read-only");
483 ea2384d3 bellard
        break;
484 ea2384d3 bellard
    case -ENOTSUP:
485 15654a6d Jes Sorensen
        error_report("Image is already committed");
486 ea2384d3 bellard
        break;
487 ea2384d3 bellard
    default:
488 15654a6d Jes Sorensen
        error_report("Error while committing image");
489 ea2384d3 bellard
        break;
490 ea2384d3 bellard
    }
491 ea2384d3 bellard
492 ea2384d3 bellard
    bdrv_delete(bs);
493 c2abccec MORITA Kazutaka
    if (ret) {
494 c2abccec MORITA Kazutaka
        return 1;
495 c2abccec MORITA Kazutaka
    }
496 ea2384d3 bellard
    return 0;
497 ea2384d3 bellard
}
498 ea2384d3 bellard
499 ea2384d3 bellard
static int is_not_zero(const uint8_t *sector, int len)
500 ea2384d3 bellard
{
501 ea2384d3 bellard
    int i;
502 ea2384d3 bellard
    len >>= 2;
503 ea2384d3 bellard
    for(i = 0;i < len; i++) {
504 ea2384d3 bellard
        if (((uint32_t *)sector)[i] != 0)
505 ea2384d3 bellard
            return 1;
506 ea2384d3 bellard
    }
507 ea2384d3 bellard
    return 0;
508 ea2384d3 bellard
}
509 ea2384d3 bellard
510 f58c7b35 ths
/*
511 f58c7b35 ths
 * Returns true iff the first sector pointed to by 'buf' contains at least
512 f58c7b35 ths
 * a non-NUL byte.
513 f58c7b35 ths
 *
514 f58c7b35 ths
 * 'pnum' is set to the number of sectors (including and immediately following
515 f58c7b35 ths
 * the first one) that are known to be in the same allocated/unallocated state.
516 f58c7b35 ths
 */
517 ea2384d3 bellard
static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
518 ea2384d3 bellard
{
519 ea2384d3 bellard
    int v, i;
520 ea2384d3 bellard
521 ea2384d3 bellard
    if (n <= 0) {
522 ea2384d3 bellard
        *pnum = 0;
523 ea2384d3 bellard
        return 0;
524 ea2384d3 bellard
    }
525 ea2384d3 bellard
    v = is_not_zero(buf, 512);
526 ea2384d3 bellard
    for(i = 1; i < n; i++) {
527 ea2384d3 bellard
        buf += 512;
528 ea2384d3 bellard
        if (v != is_not_zero(buf, 512))
529 ea2384d3 bellard
            break;
530 ea2384d3 bellard
    }
531 ea2384d3 bellard
    *pnum = i;
532 ea2384d3 bellard
    return v;
533 ea2384d3 bellard
}
534 ea2384d3 bellard
535 3e85c6fd Kevin Wolf
/*
536 3e85c6fd Kevin Wolf
 * Compares two buffers sector by sector. Returns 0 if the first sector of both
537 3e85c6fd Kevin Wolf
 * buffers matches, non-zero otherwise.
538 3e85c6fd Kevin Wolf
 *
539 3e85c6fd Kevin Wolf
 * pnum is set to the number of sectors (including and immediately following
540 3e85c6fd Kevin Wolf
 * the first one) that are known to have the same comparison result
541 3e85c6fd Kevin Wolf
 */
542 3e85c6fd Kevin Wolf
static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
543 3e85c6fd Kevin Wolf
    int *pnum)
544 3e85c6fd Kevin Wolf
{
545 3e85c6fd Kevin Wolf
    int res, i;
546 3e85c6fd Kevin Wolf
547 3e85c6fd Kevin Wolf
    if (n <= 0) {
548 3e85c6fd Kevin Wolf
        *pnum = 0;
549 3e85c6fd Kevin Wolf
        return 0;
550 3e85c6fd Kevin Wolf
    }
551 3e85c6fd Kevin Wolf
552 3e85c6fd Kevin Wolf
    res = !!memcmp(buf1, buf2, 512);
553 3e85c6fd Kevin Wolf
    for(i = 1; i < n; i++) {
554 3e85c6fd Kevin Wolf
        buf1 += 512;
555 3e85c6fd Kevin Wolf
        buf2 += 512;
556 3e85c6fd Kevin Wolf
557 3e85c6fd Kevin Wolf
        if (!!memcmp(buf1, buf2, 512) != res) {
558 3e85c6fd Kevin Wolf
            break;
559 3e85c6fd Kevin Wolf
        }
560 3e85c6fd Kevin Wolf
    }
561 3e85c6fd Kevin Wolf
562 3e85c6fd Kevin Wolf
    *pnum = i;
563 3e85c6fd Kevin Wolf
    return res;
564 3e85c6fd Kevin Wolf
}
565 3e85c6fd Kevin Wolf
566 80ee15a6 Kevin Wolf
#define IO_BUF_SIZE (2 * 1024 * 1024)
567 ea2384d3 bellard
568 ea2384d3 bellard
static int img_convert(int argc, char **argv)
569 ea2384d3 bellard
{
570 eec77d9e Jes Sorensen
    int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;
571 6b837bc4 Jes Sorensen
    int progress = 0;
572 f58c7b35 ths
    const char *fmt, *out_fmt, *out_baseimg, *out_filename;
573 b50cbabc MORITA Kazutaka
    BlockDriver *drv, *proto_drv;
574 c2abccec MORITA Kazutaka
    BlockDriverState **bs = NULL, *out_bs = NULL;
575 96b8f136 ths
    int64_t total_sectors, nb_sectors, sector_num, bs_offset;
576 96b8f136 ths
    uint64_t bs_sectors;
577 c2abccec MORITA Kazutaka
    uint8_t * buf = NULL;
578 ea2384d3 bellard
    const uint8_t *buf1;
579 faea38e7 bellard
    BlockDriverInfo bdi;
580 b50cbabc MORITA Kazutaka
    QEMUOptionParameter *param = NULL, *create_options = NULL;
581 a18953fb Kevin Wolf
    QEMUOptionParameter *out_baseimg_param;
582 efa84d43 Kevin Wolf
    char *options = NULL;
583 51ef6727 edison
    const char *snapshot_name = NULL;
584 6b837bc4 Jes Sorensen
    float local_progress;
585 ea2384d3 bellard
586 ea2384d3 bellard
    fmt = NULL;
587 ea2384d3 bellard
    out_fmt = "raw";
588 f58c7b35 ths
    out_baseimg = NULL;
589 eec77d9e Jes Sorensen
    compress = 0;
590 ea2384d3 bellard
    for(;;) {
591 6b837bc4 Jes Sorensen
        c = getopt(argc, argv, "f:O:B:s:hce6o:p");
592 b8fb60da Jes Sorensen
        if (c == -1) {
593 ea2384d3 bellard
            break;
594 b8fb60da Jes Sorensen
        }
595 ea2384d3 bellard
        switch(c) {
596 ef87394c Jes Sorensen
        case '?':
597 ea2384d3 bellard
        case 'h':
598 ea2384d3 bellard
            help();
599 ea2384d3 bellard
            break;
600 ea2384d3 bellard
        case 'f':
601 ea2384d3 bellard
            fmt = optarg;
602 ea2384d3 bellard
            break;
603 ea2384d3 bellard
        case 'O':
604 ea2384d3 bellard
            out_fmt = optarg;
605 ea2384d3 bellard
            break;
606 f58c7b35 ths
        case 'B':
607 f58c7b35 ths
            out_baseimg = optarg;
608 f58c7b35 ths
            break;
609 ea2384d3 bellard
        case 'c':
610 eec77d9e Jes Sorensen
            compress = 1;
611 ea2384d3 bellard
            break;
612 ea2384d3 bellard
        case 'e':
613 15654a6d Jes Sorensen
            error_report("qemu-img: option -e is deprecated, please use \'-o "
614 eec77d9e Jes Sorensen
                  "encryption\' instead!");
615 eec77d9e Jes Sorensen
            return 1;
616 ec36ba14 ths
        case '6':
617 15654a6d Jes Sorensen
            error_report("qemu-img: option -6 is deprecated, please use \'-o "
618 eec77d9e Jes Sorensen
                  "compat6\' instead!");
619 eec77d9e Jes Sorensen
            return 1;
620 efa84d43 Kevin Wolf
        case 'o':
621 efa84d43 Kevin Wolf
            options = optarg;
622 efa84d43 Kevin Wolf
            break;
623 51ef6727 edison
        case 's':
624 51ef6727 edison
            snapshot_name = optarg;
625 51ef6727 edison
            break;
626 6b837bc4 Jes Sorensen
        case 'p':
627 6b837bc4 Jes Sorensen
            progress = 1;
628 6b837bc4 Jes Sorensen
            break;
629 ea2384d3 bellard
        }
630 ea2384d3 bellard
    }
631 3b46e624 ths
632 926c2d23 balrog
    bs_n = argc - optind - 1;
633 b8fb60da Jes Sorensen
    if (bs_n < 1) {
634 b8fb60da Jes Sorensen
        help();
635 b8fb60da Jes Sorensen
    }
636 926c2d23 balrog
637 926c2d23 balrog
    out_filename = argv[argc - 1];
638 f58c7b35 ths
639 4ac8aacd Jes Sorensen
    if (options && !strcmp(options, "?")) {
640 4ac8aacd Jes Sorensen
        ret = print_block_option_help(out_filename, out_fmt);
641 4ac8aacd Jes Sorensen
        goto out;
642 4ac8aacd Jes Sorensen
    }
643 4ac8aacd Jes Sorensen
644 c2abccec MORITA Kazutaka
    if (bs_n > 1 && out_baseimg) {
645 15654a6d Jes Sorensen
        error_report("-B makes no sense when concatenating multiple input "
646 15654a6d Jes Sorensen
                     "images");
647 31ca34b8 Jes Sorensen
        ret = -1;
648 31ca34b8 Jes Sorensen
        goto out;
649 c2abccec MORITA Kazutaka
    }
650 926c2d23 balrog
        
651 6b837bc4 Jes Sorensen
    qemu_progress_init(progress, 2.0);
652 6b837bc4 Jes Sorensen
    qemu_progress_print(0, 100);
653 6b837bc4 Jes Sorensen
654 5bdf61fd Jes Sorensen
    bs = qemu_mallocz(bs_n * sizeof(BlockDriverState *));
655 926c2d23 balrog
656 926c2d23 balrog
    total_sectors = 0;
657 926c2d23 balrog
    for (bs_i = 0; bs_i < bs_n; bs_i++) {
658 adfe078e Stefan Hajnoczi
        bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS);
659 c2abccec MORITA Kazutaka
        if (!bs[bs_i]) {
660 15654a6d Jes Sorensen
            error_report("Could not open '%s'", argv[optind + bs_i]);
661 c2abccec MORITA Kazutaka
            ret = -1;
662 c2abccec MORITA Kazutaka
            goto out;
663 c2abccec MORITA Kazutaka
        }
664 926c2d23 balrog
        bdrv_get_geometry(bs[bs_i], &bs_sectors);
665 926c2d23 balrog
        total_sectors += bs_sectors;
666 926c2d23 balrog
    }
667 ea2384d3 bellard
668 51ef6727 edison
    if (snapshot_name != NULL) {
669 51ef6727 edison
        if (bs_n > 1) {
670 15654a6d Jes Sorensen
            error_report("No support for concatenating multiple snapshot\n");
671 51ef6727 edison
            ret = -1;
672 51ef6727 edison
            goto out;
673 51ef6727 edison
        }
674 51ef6727 edison
        if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
675 15654a6d Jes Sorensen
            error_report("Failed to load snapshot\n");
676 51ef6727 edison
            ret = -1;
677 51ef6727 edison
            goto out;
678 51ef6727 edison
        }
679 51ef6727 edison
    }
680 51ef6727 edison
681 efa84d43 Kevin Wolf
    /* Find driver and parse its options */
682 ea2384d3 bellard
    drv = bdrv_find_format(out_fmt);
683 c2abccec MORITA Kazutaka
    if (!drv) {
684 15654a6d Jes Sorensen
        error_report("Unknown file format '%s'", out_fmt);
685 c2abccec MORITA Kazutaka
        ret = -1;
686 c2abccec MORITA Kazutaka
        goto out;
687 c2abccec MORITA Kazutaka
    }
688 efa84d43 Kevin Wolf
689 b50cbabc MORITA Kazutaka
    proto_drv = bdrv_find_protocol(out_filename);
690 c2abccec MORITA Kazutaka
    if (!proto_drv) {
691 15654a6d Jes Sorensen
        error_report("Unknown protocol '%s'", out_filename);
692 c2abccec MORITA Kazutaka
        ret = -1;
693 c2abccec MORITA Kazutaka
        goto out;
694 c2abccec MORITA Kazutaka
    }
695 b50cbabc MORITA Kazutaka
696 b50cbabc MORITA Kazutaka
    create_options = append_option_parameters(create_options,
697 b50cbabc MORITA Kazutaka
                                              drv->create_options);
698 b50cbabc MORITA Kazutaka
    create_options = append_option_parameters(create_options,
699 b50cbabc MORITA Kazutaka
                                              proto_drv->create_options);
700 db08adf5 Kevin Wolf
701 efa84d43 Kevin Wolf
    if (options) {
702 b50cbabc MORITA Kazutaka
        param = parse_option_parameters(options, create_options, param);
703 efa84d43 Kevin Wolf
        if (param == NULL) {
704 15654a6d Jes Sorensen
            error_report("Invalid options for file format '%s'.", out_fmt);
705 c2abccec MORITA Kazutaka
            ret = -1;
706 c2abccec MORITA Kazutaka
            goto out;
707 efa84d43 Kevin Wolf
        }
708 efa84d43 Kevin Wolf
    } else {
709 b50cbabc MORITA Kazutaka
        param = parse_option_parameters("", create_options, param);
710 efa84d43 Kevin Wolf
    }
711 efa84d43 Kevin Wolf
712 efa84d43 Kevin Wolf
    set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
713 eec77d9e Jes Sorensen
    ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);
714 c2abccec MORITA Kazutaka
    if (ret < 0) {
715 c2abccec MORITA Kazutaka
        goto out;
716 c2abccec MORITA Kazutaka
    }
717 efa84d43 Kevin Wolf
718 a18953fb Kevin Wolf
    /* Get backing file name if -o backing_file was used */
719 a18953fb Kevin Wolf
    out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
720 a18953fb Kevin Wolf
    if (out_baseimg_param) {
721 a18953fb Kevin Wolf
        out_baseimg = out_baseimg_param->value.s;
722 a18953fb Kevin Wolf
    }
723 a18953fb Kevin Wolf
724 efa84d43 Kevin Wolf
    /* Check if compression is supported */
725 eec77d9e Jes Sorensen
    if (compress) {
726 efa84d43 Kevin Wolf
        QEMUOptionParameter *encryption =
727 efa84d43 Kevin Wolf
            get_option_parameter(param, BLOCK_OPT_ENCRYPT);
728 efa84d43 Kevin Wolf
729 efa84d43 Kevin Wolf
        if (!drv->bdrv_write_compressed) {
730 15654a6d Jes Sorensen
            error_report("Compression not supported for this file format");
731 c2abccec MORITA Kazutaka
            ret = -1;
732 c2abccec MORITA Kazutaka
            goto out;
733 efa84d43 Kevin Wolf
        }
734 efa84d43 Kevin Wolf
735 efa84d43 Kevin Wolf
        if (encryption && encryption->value.n) {
736 15654a6d Jes Sorensen
            error_report("Compression and encryption not supported at "
737 15654a6d Jes Sorensen
                         "the same time");
738 c2abccec MORITA Kazutaka
            ret = -1;
739 c2abccec MORITA Kazutaka
            goto out;
740 efa84d43 Kevin Wolf
        }
741 efa84d43 Kevin Wolf
    }
742 efa84d43 Kevin Wolf
743 efa84d43 Kevin Wolf
    /* Create the new image */
744 efa84d43 Kevin Wolf
    ret = bdrv_create(drv, out_filename, param);
745 ea2384d3 bellard
    if (ret < 0) {
746 ea2384d3 bellard
        if (ret == -ENOTSUP) {
747 15654a6d Jes Sorensen
            error_report("Formatting not supported for file format '%s'",
748 15654a6d Jes Sorensen
                         out_fmt);
749 6e9ea0c0 aurel32
        } else if (ret == -EFBIG) {
750 15654a6d Jes Sorensen
            error_report("The image size is too large for file format '%s'",
751 15654a6d Jes Sorensen
                         out_fmt);
752 ea2384d3 bellard
        } else {
753 15654a6d Jes Sorensen
            error_report("%s: error while converting %s: %s",
754 15654a6d Jes Sorensen
                         out_filename, out_fmt, strerror(-ret));
755 ea2384d3 bellard
        }
756 c2abccec MORITA Kazutaka
        goto out;
757 ea2384d3 bellard
    }
758 3b46e624 ths
759 1bd8e175 Kevin Wolf
    out_bs = bdrv_new_open(out_filename, out_fmt,
760 1bd8e175 Kevin Wolf
        BDRV_O_FLAGS | BDRV_O_RDWR | BDRV_O_NO_FLUSH);
761 c2abccec MORITA Kazutaka
    if (!out_bs) {
762 c2abccec MORITA Kazutaka
        ret = -1;
763 c2abccec MORITA Kazutaka
        goto out;
764 c2abccec MORITA Kazutaka
    }
765 ea2384d3 bellard
766 926c2d23 balrog
    bs_i = 0;
767 926c2d23 balrog
    bs_offset = 0;
768 926c2d23 balrog
    bdrv_get_geometry(bs[0], &bs_sectors);
769 d6771bfa TeLeMan
    buf = qemu_malloc(IO_BUF_SIZE);
770 926c2d23 balrog
771 eec77d9e Jes Sorensen
    if (compress) {
772 c2abccec MORITA Kazutaka
        ret = bdrv_get_info(out_bs, &bdi);
773 c2abccec MORITA Kazutaka
        if (ret < 0) {
774 15654a6d Jes Sorensen
            error_report("could not get block driver info");
775 c2abccec MORITA Kazutaka
            goto out;
776 c2abccec MORITA Kazutaka
        }
777 faea38e7 bellard
        cluster_size = bdi.cluster_size;
778 c2abccec MORITA Kazutaka
        if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
779 15654a6d Jes Sorensen
            error_report("invalid cluster size");
780 c2abccec MORITA Kazutaka
            ret = -1;
781 c2abccec MORITA Kazutaka
            goto out;
782 c2abccec MORITA Kazutaka
        }
783 ea2384d3 bellard
        cluster_sectors = cluster_size >> 9;
784 ea2384d3 bellard
        sector_num = 0;
785 6b837bc4 Jes Sorensen
786 6b837bc4 Jes Sorensen
        nb_sectors = total_sectors;
787 6b837bc4 Jes Sorensen
        local_progress = (float)100 /
788 6b837bc4 Jes Sorensen
            (nb_sectors / MIN(nb_sectors, (cluster_sectors)));
789 6b837bc4 Jes Sorensen
790 ea2384d3 bellard
        for(;;) {
791 926c2d23 balrog
            int64_t bs_num;
792 926c2d23 balrog
            int remainder;
793 926c2d23 balrog
            uint8_t *buf2;
794 926c2d23 balrog
795 ea2384d3 bellard
            nb_sectors = total_sectors - sector_num;
796 ea2384d3 bellard
            if (nb_sectors <= 0)
797 ea2384d3 bellard
                break;
798 ea2384d3 bellard
            if (nb_sectors >= cluster_sectors)
799 ea2384d3 bellard
                n = cluster_sectors;
800 ea2384d3 bellard
            else
801 ea2384d3 bellard
                n = nb_sectors;
802 926c2d23 balrog
803 926c2d23 balrog
            bs_num = sector_num - bs_offset;
804 926c2d23 balrog
            assert (bs_num >= 0);
805 926c2d23 balrog
            remainder = n;
806 926c2d23 balrog
            buf2 = buf;
807 926c2d23 balrog
            while (remainder > 0) {
808 926c2d23 balrog
                int nlow;
809 926c2d23 balrog
                while (bs_num == bs_sectors) {
810 926c2d23 balrog
                    bs_i++;
811 926c2d23 balrog
                    assert (bs_i < bs_n);
812 926c2d23 balrog
                    bs_offset += bs_sectors;
813 926c2d23 balrog
                    bdrv_get_geometry(bs[bs_i], &bs_sectors);
814 926c2d23 balrog
                    bs_num = 0;
815 0bfcd599 Blue Swirl
                    /* printf("changing part: sector_num=%" PRId64 ", "
816 0bfcd599 Blue Swirl
                       "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64
817 0bfcd599 Blue Swirl
                       "\n", sector_num, bs_i, bs_offset, bs_sectors); */
818 926c2d23 balrog
                }
819 926c2d23 balrog
                assert (bs_num < bs_sectors);
820 926c2d23 balrog
821 926c2d23 balrog
                nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
822 926c2d23 balrog
823 c2abccec MORITA Kazutaka
                ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
824 c2abccec MORITA Kazutaka
                if (ret < 0) {
825 15654a6d Jes Sorensen
                    error_report("error while reading");
826 c2abccec MORITA Kazutaka
                    goto out;
827 c2abccec MORITA Kazutaka
                }
828 926c2d23 balrog
829 926c2d23 balrog
                buf2 += nlow * 512;
830 926c2d23 balrog
                bs_num += nlow;
831 926c2d23 balrog
832 926c2d23 balrog
                remainder -= nlow;
833 926c2d23 balrog
            }
834 926c2d23 balrog
            assert (remainder == 0);
835 926c2d23 balrog
836 b8fb60da Jes Sorensen
            if (n < cluster_sectors) {
837 ea2384d3 bellard
                memset(buf + n * 512, 0, cluster_size - n * 512);
838 b8fb60da Jes Sorensen
            }
839 ea2384d3 bellard
            if (is_not_zero(buf, cluster_size)) {
840 c2abccec MORITA Kazutaka
                ret = bdrv_write_compressed(out_bs, sector_num, buf,
841 c2abccec MORITA Kazutaka
                                            cluster_sectors);
842 c2abccec MORITA Kazutaka
                if (ret != 0) {
843 15654a6d Jes Sorensen
                    error_report("error while compressing sector %" PRId64,
844 ec3757de bellard
                          sector_num);
845 c2abccec MORITA Kazutaka
                    goto out;
846 c2abccec MORITA Kazutaka
                }
847 ea2384d3 bellard
            }
848 ea2384d3 bellard
            sector_num += n;
849 6b837bc4 Jes Sorensen
            qemu_progress_print(local_progress, 100);
850 ea2384d3 bellard
        }
851 faea38e7 bellard
        /* signal EOF to align */
852 faea38e7 bellard
        bdrv_write_compressed(out_bs, 0, NULL, 0);
853 ea2384d3 bellard
    } else {
854 f2feebbd Kevin Wolf
        int has_zero_init = bdrv_has_zero_init(out_bs);
855 f2feebbd Kevin Wolf
856 f58c7b35 ths
        sector_num = 0; // total number of sectors converted so far
857 6b837bc4 Jes Sorensen
        nb_sectors = total_sectors - sector_num;
858 6b837bc4 Jes Sorensen
        local_progress = (float)100 /
859 6b837bc4 Jes Sorensen
            (nb_sectors / MIN(nb_sectors, (IO_BUF_SIZE / 512)));
860 6b837bc4 Jes Sorensen
861 ea2384d3 bellard
        for(;;) {
862 ea2384d3 bellard
            nb_sectors = total_sectors - sector_num;
863 b8fb60da Jes Sorensen
            if (nb_sectors <= 0) {
864 ea2384d3 bellard
                break;
865 b8fb60da Jes Sorensen
            }
866 b8fb60da Jes Sorensen
            if (nb_sectors >= (IO_BUF_SIZE / 512)) {
867 ea2384d3 bellard
                n = (IO_BUF_SIZE / 512);
868 b8fb60da Jes Sorensen
            } else {
869 ea2384d3 bellard
                n = nb_sectors;
870 b8fb60da Jes Sorensen
            }
871 926c2d23 balrog
872 926c2d23 balrog
            while (sector_num - bs_offset >= bs_sectors) {
873 926c2d23 balrog
                bs_i ++;
874 926c2d23 balrog
                assert (bs_i < bs_n);
875 926c2d23 balrog
                bs_offset += bs_sectors;
876 926c2d23 balrog
                bdrv_get_geometry(bs[bs_i], &bs_sectors);
877 0bfcd599 Blue Swirl
                /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "
878 0bfcd599 Blue Swirl
                  "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",
879 926c2d23 balrog
                   sector_num, bs_i, bs_offset, bs_sectors); */
880 926c2d23 balrog
            }
881 926c2d23 balrog
882 b8fb60da Jes Sorensen
            if (n > bs_offset + bs_sectors - sector_num) {
883 926c2d23 balrog
                n = bs_offset + bs_sectors - sector_num;
884 b8fb60da Jes Sorensen
            }
885 926c2d23 balrog
886 f2feebbd Kevin Wolf
            if (has_zero_init) {
887 d032044f Akkarit Sangpetch
                /* If the output image is being created as a copy on write image,
888 d032044f Akkarit Sangpetch
                   assume that sectors which are unallocated in the input image
889 d032044f Akkarit Sangpetch
                   are present in both the output's and input's base images (no
890 d032044f Akkarit Sangpetch
                   need to copy them). */
891 d032044f Akkarit Sangpetch
                if (out_baseimg) {
892 d032044f Akkarit Sangpetch
                    if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
893 d032044f Akkarit Sangpetch
                                           n, &n1)) {
894 d032044f Akkarit Sangpetch
                        sector_num += n1;
895 d032044f Akkarit Sangpetch
                        continue;
896 d032044f Akkarit Sangpetch
                    }
897 d032044f Akkarit Sangpetch
                    /* The next 'n1' sectors are allocated in the input image. Copy
898 d032044f Akkarit Sangpetch
                       only those as they may be followed by unallocated sectors. */
899 d032044f Akkarit Sangpetch
                    n = n1;
900 93c65b47 aliguori
                }
901 93c65b47 aliguori
            } else {
902 93c65b47 aliguori
                n1 = n;
903 f58c7b35 ths
            }
904 f58c7b35 ths
905 c2abccec MORITA Kazutaka
            ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
906 c2abccec MORITA Kazutaka
            if (ret < 0) {
907 15654a6d Jes Sorensen
                error_report("error while reading");
908 c2abccec MORITA Kazutaka
                goto out;
909 c2abccec MORITA Kazutaka
            }
910 ea2384d3 bellard
            /* NOTE: at the same time we convert, we do not write zero
911 ea2384d3 bellard
               sectors to have a chance to compress the image. Ideally, we
912 ea2384d3 bellard
               should add a specific call to have the info to go faster */
913 ea2384d3 bellard
            buf1 = buf;
914 ea2384d3 bellard
            while (n > 0) {
915 f58c7b35 ths
                /* If the output image is being created as a copy on write image,
916 f58c7b35 ths
                   copy all sectors even the ones containing only NUL bytes,
917 93c65b47 aliguori
                   because they may differ from the sectors in the base image.
918 93c65b47 aliguori

919 93c65b47 aliguori
                   If the output is to a host device, we also write out
920 93c65b47 aliguori
                   sectors that are entirely 0, since whatever data was
921 93c65b47 aliguori
                   already there is garbage, not 0s. */
922 f2feebbd Kevin Wolf
                if (!has_zero_init || out_baseimg ||
923 93c65b47 aliguori
                    is_allocated_sectors(buf1, n, &n1)) {
924 c2abccec MORITA Kazutaka
                    ret = bdrv_write(out_bs, sector_num, buf1, n1);
925 c2abccec MORITA Kazutaka
                    if (ret < 0) {
926 15654a6d Jes Sorensen
                        error_report("error while writing");
927 c2abccec MORITA Kazutaka
                        goto out;
928 c2abccec MORITA Kazutaka
                    }
929 ea2384d3 bellard
                }
930 ea2384d3 bellard
                sector_num += n1;
931 ea2384d3 bellard
                n -= n1;
932 ea2384d3 bellard
                buf1 += n1 * 512;
933 ea2384d3 bellard
            }
934 6b837bc4 Jes Sorensen
            qemu_progress_print(local_progress, 100);
935 ea2384d3 bellard
        }
936 ea2384d3 bellard
    }
937 c2abccec MORITA Kazutaka
out:
938 6b837bc4 Jes Sorensen
    qemu_progress_end();
939 c2abccec MORITA Kazutaka
    free_option_parameters(create_options);
940 c2abccec MORITA Kazutaka
    free_option_parameters(param);
941 d6771bfa TeLeMan
    qemu_free(buf);
942 c2abccec MORITA Kazutaka
    if (out_bs) {
943 c2abccec MORITA Kazutaka
        bdrv_delete(out_bs);
944 c2abccec MORITA Kazutaka
    }
945 31ca34b8 Jes Sorensen
    if (bs) {
946 31ca34b8 Jes Sorensen
        for (bs_i = 0; bs_i < bs_n; bs_i++) {
947 31ca34b8 Jes Sorensen
            if (bs[bs_i]) {
948 31ca34b8 Jes Sorensen
                bdrv_delete(bs[bs_i]);
949 31ca34b8 Jes Sorensen
            }
950 c2abccec MORITA Kazutaka
        }
951 31ca34b8 Jes Sorensen
        qemu_free(bs);
952 c2abccec MORITA Kazutaka
    }
953 c2abccec MORITA Kazutaka
    if (ret) {
954 c2abccec MORITA Kazutaka
        return 1;
955 c2abccec MORITA Kazutaka
    }
956 ea2384d3 bellard
    return 0;
957 ea2384d3 bellard
}
958 ea2384d3 bellard
959 57d1a2b6 bellard
#ifdef _WIN32
960 57d1a2b6 bellard
static int64_t get_allocated_file_size(const char *filename)
961 57d1a2b6 bellard
{
962 e8445331 bellard
    typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
963 e8445331 bellard
    get_compressed_t get_compressed;
964 57d1a2b6 bellard
    struct _stati64 st;
965 e8445331 bellard
966 e8445331 bellard
    /* WinNT support GetCompressedFileSize to determine allocate size */
967 e8445331 bellard
    get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
968 e8445331 bellard
    if (get_compressed) {
969 e8445331 bellard
            DWORD high, low;
970 e8445331 bellard
            low = get_compressed(filename, &high);
971 e8445331 bellard
            if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
972 e8445331 bellard
            return (((int64_t) high) << 32) + low;
973 e8445331 bellard
    }
974 e8445331 bellard
975 5fafdf24 ths
    if (_stati64(filename, &st) < 0)
976 57d1a2b6 bellard
        return -1;
977 57d1a2b6 bellard
    return st.st_size;
978 57d1a2b6 bellard
}
979 57d1a2b6 bellard
#else
980 57d1a2b6 bellard
static int64_t get_allocated_file_size(const char *filename)
981 57d1a2b6 bellard
{
982 57d1a2b6 bellard
    struct stat st;
983 5fafdf24 ths
    if (stat(filename, &st) < 0)
984 57d1a2b6 bellard
        return -1;
985 57d1a2b6 bellard
    return (int64_t)st.st_blocks * 512;
986 57d1a2b6 bellard
}
987 57d1a2b6 bellard
#endif
988 57d1a2b6 bellard
989 faea38e7 bellard
static void dump_snapshots(BlockDriverState *bs)
990 faea38e7 bellard
{
991 faea38e7 bellard
    QEMUSnapshotInfo *sn_tab, *sn;
992 faea38e7 bellard
    int nb_sns, i;
993 faea38e7 bellard
    char buf[256];
994 faea38e7 bellard
995 faea38e7 bellard
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
996 faea38e7 bellard
    if (nb_sns <= 0)
997 faea38e7 bellard
        return;
998 faea38e7 bellard
    printf("Snapshot list:\n");
999 faea38e7 bellard
    printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
1000 faea38e7 bellard
    for(i = 0; i < nb_sns; i++) {
1001 faea38e7 bellard
        sn = &sn_tab[i];
1002 faea38e7 bellard
        printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
1003 faea38e7 bellard
    }
1004 faea38e7 bellard
    qemu_free(sn_tab);
1005 faea38e7 bellard
}
1006 faea38e7 bellard
1007 ea2384d3 bellard
static int img_info(int argc, char **argv)
1008 ea2384d3 bellard
{
1009 ea2384d3 bellard
    int c;
1010 ea2384d3 bellard
    const char *filename, *fmt;
1011 ea2384d3 bellard
    BlockDriverState *bs;
1012 ea2384d3 bellard
    char fmt_name[128], size_buf[128], dsize_buf[128];
1013 96b8f136 ths
    uint64_t total_sectors;
1014 96b8f136 ths
    int64_t allocated_size;
1015 93b6b2a3 bellard
    char backing_filename[1024];
1016 93b6b2a3 bellard
    char backing_filename2[1024];
1017 faea38e7 bellard
    BlockDriverInfo bdi;
1018 ea2384d3 bellard
1019 ea2384d3 bellard
    fmt = NULL;
1020 ea2384d3 bellard
    for(;;) {
1021 ea2384d3 bellard
        c = getopt(argc, argv, "f:h");
1022 b8fb60da Jes Sorensen
        if (c == -1) {
1023 ea2384d3 bellard
            break;
1024 b8fb60da Jes Sorensen
        }
1025 ea2384d3 bellard
        switch(c) {
1026 ef87394c Jes Sorensen
        case '?':
1027 ea2384d3 bellard
        case 'h':
1028 ea2384d3 bellard
            help();
1029 ea2384d3 bellard
            break;
1030 ea2384d3 bellard
        case 'f':
1031 ea2384d3 bellard
            fmt = optarg;
1032 ea2384d3 bellard
            break;
1033 ea2384d3 bellard
        }
1034 ea2384d3 bellard
    }
1035 b8fb60da Jes Sorensen
    if (optind >= argc) {
1036 ea2384d3 bellard
        help();
1037 b8fb60da Jes Sorensen
    }
1038 ea2384d3 bellard
    filename = argv[optind++];
1039 ea2384d3 bellard
1040 adfe078e Stefan Hajnoczi
    bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING);
1041 c2abccec MORITA Kazutaka
    if (!bs) {
1042 c2abccec MORITA Kazutaka
        return 1;
1043 c2abccec MORITA Kazutaka
    }
1044 ea2384d3 bellard
    bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
1045 ea2384d3 bellard
    bdrv_get_geometry(bs, &total_sectors);
1046 ea2384d3 bellard
    get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
1047 57d1a2b6 bellard
    allocated_size = get_allocated_file_size(filename);
1048 b8fb60da Jes Sorensen
    if (allocated_size < 0) {
1049 a10ea30b blueswir1
        snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
1050 b8fb60da Jes Sorensen
    } else {
1051 5fafdf24 ths
        get_human_readable_size(dsize_buf, sizeof(dsize_buf),
1052 de167e41 bellard
                                allocated_size);
1053 b8fb60da Jes Sorensen
    }
1054 ea2384d3 bellard
    printf("image: %s\n"
1055 ea2384d3 bellard
           "file format: %s\n"
1056 ec3757de bellard
           "virtual size: %s (%" PRId64 " bytes)\n"
1057 ea2384d3 bellard
           "disk size: %s\n",
1058 5fafdf24 ths
           filename, fmt_name, size_buf,
1059 ec3757de bellard
           (total_sectors * 512),
1060 ea2384d3 bellard
           dsize_buf);
1061 b8fb60da Jes Sorensen
    if (bdrv_is_encrypted(bs)) {
1062 ea2384d3 bellard
        printf("encrypted: yes\n");
1063 b8fb60da Jes Sorensen
    }
1064 faea38e7 bellard
    if (bdrv_get_info(bs, &bdi) >= 0) {
1065 b8fb60da Jes Sorensen
        if (bdi.cluster_size != 0) {
1066 faea38e7 bellard
            printf("cluster_size: %d\n", bdi.cluster_size);
1067 b8fb60da Jes Sorensen
        }
1068 faea38e7 bellard
    }
1069 93b6b2a3 bellard
    bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
1070 faea38e7 bellard
    if (backing_filename[0] != '\0') {
1071 93b6b2a3 bellard
        path_combine(backing_filename2, sizeof(backing_filename2),
1072 93b6b2a3 bellard
                     filename, backing_filename);
1073 5fafdf24 ths
        printf("backing file: %s (actual path: %s)\n",
1074 93b6b2a3 bellard
               backing_filename,
1075 93b6b2a3 bellard
               backing_filename2);
1076 faea38e7 bellard
    }
1077 faea38e7 bellard
    dump_snapshots(bs);
1078 ea2384d3 bellard
    bdrv_delete(bs);
1079 ea2384d3 bellard
    return 0;
1080 ea2384d3 bellard
}
1081 ea2384d3 bellard
1082 f7b4a940 aliguori
#define SNAPSHOT_LIST   1
1083 f7b4a940 aliguori
#define SNAPSHOT_CREATE 2
1084 f7b4a940 aliguori
#define SNAPSHOT_APPLY  3
1085 f7b4a940 aliguori
#define SNAPSHOT_DELETE 4
1086 f7b4a940 aliguori
1087 153859be Stuart Brady
static int img_snapshot(int argc, char **argv)
1088 f7b4a940 aliguori
{
1089 f7b4a940 aliguori
    BlockDriverState *bs;
1090 f7b4a940 aliguori
    QEMUSnapshotInfo sn;
1091 f7b4a940 aliguori
    char *filename, *snapshot_name = NULL;
1092 c2abccec MORITA Kazutaka
    int c, ret = 0, bdrv_oflags;
1093 f7b4a940 aliguori
    int action = 0;
1094 f7b4a940 aliguori
    qemu_timeval tv;
1095 f7b4a940 aliguori
1096 710da702 Kevin Wolf
    bdrv_oflags = BDRV_O_FLAGS | BDRV_O_RDWR;
1097 f7b4a940 aliguori
    /* Parse commandline parameters */
1098 f7b4a940 aliguori
    for(;;) {
1099 f7b4a940 aliguori
        c = getopt(argc, argv, "la:c:d:h");
1100 b8fb60da Jes Sorensen
        if (c == -1) {
1101 f7b4a940 aliguori
            break;
1102 b8fb60da Jes Sorensen
        }
1103 f7b4a940 aliguori
        switch(c) {
1104 ef87394c Jes Sorensen
        case '?':
1105 f7b4a940 aliguori
        case 'h':
1106 f7b4a940 aliguori
            help();
1107 153859be Stuart Brady
            return 0;
1108 f7b4a940 aliguori
        case 'l':
1109 f7b4a940 aliguori
            if (action) {
1110 f7b4a940 aliguori
                help();
1111 153859be Stuart Brady
                return 0;
1112 f7b4a940 aliguori
            }
1113 f7b4a940 aliguori
            action = SNAPSHOT_LIST;
1114 f5edb014 Naphtali Sprei
            bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
1115 f7b4a940 aliguori
            break;
1116 f7b4a940 aliguori
        case 'a':
1117 f7b4a940 aliguori
            if (action) {
1118 f7b4a940 aliguori
                help();
1119 153859be Stuart Brady
                return 0;
1120 f7b4a940 aliguori
            }
1121 f7b4a940 aliguori
            action = SNAPSHOT_APPLY;
1122 f7b4a940 aliguori
            snapshot_name = optarg;
1123 f7b4a940 aliguori
            break;
1124 f7b4a940 aliguori
        case 'c':
1125 f7b4a940 aliguori
            if (action) {
1126 f7b4a940 aliguori
                help();
1127 153859be Stuart Brady
                return 0;
1128 f7b4a940 aliguori
            }
1129 f7b4a940 aliguori
            action = SNAPSHOT_CREATE;
1130 f7b4a940 aliguori
            snapshot_name = optarg;
1131 f7b4a940 aliguori
            break;
1132 f7b4a940 aliguori
        case 'd':
1133 f7b4a940 aliguori
            if (action) {
1134 f7b4a940 aliguori
                help();
1135 153859be Stuart Brady
                return 0;
1136 f7b4a940 aliguori
            }
1137 f7b4a940 aliguori
            action = SNAPSHOT_DELETE;
1138 f7b4a940 aliguori
            snapshot_name = optarg;
1139 f7b4a940 aliguori
            break;
1140 f7b4a940 aliguori
        }
1141 f7b4a940 aliguori
    }
1142 f7b4a940 aliguori
1143 b8fb60da Jes Sorensen
    if (optind >= argc) {
1144 f7b4a940 aliguori
        help();
1145 b8fb60da Jes Sorensen
    }
1146 f7b4a940 aliguori
    filename = argv[optind++];
1147 f7b4a940 aliguori
1148 f7b4a940 aliguori
    /* Open the image */
1149 f163d073 Stefan Hajnoczi
    bs = bdrv_new_open(filename, NULL, bdrv_oflags);
1150 c2abccec MORITA Kazutaka
    if (!bs) {
1151 c2abccec MORITA Kazutaka
        return 1;
1152 c2abccec MORITA Kazutaka
    }
1153 f7b4a940 aliguori
1154 f7b4a940 aliguori
    /* Perform the requested action */
1155 f7b4a940 aliguori
    switch(action) {
1156 f7b4a940 aliguori
    case SNAPSHOT_LIST:
1157 f7b4a940 aliguori
        dump_snapshots(bs);
1158 f7b4a940 aliguori
        break;
1159 f7b4a940 aliguori
1160 f7b4a940 aliguori
    case SNAPSHOT_CREATE:
1161 f7b4a940 aliguori
        memset(&sn, 0, sizeof(sn));
1162 f7b4a940 aliguori
        pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
1163 f7b4a940 aliguori
1164 f7b4a940 aliguori
        qemu_gettimeofday(&tv);
1165 f7b4a940 aliguori
        sn.date_sec = tv.tv_sec;
1166 f7b4a940 aliguori
        sn.date_nsec = tv.tv_usec * 1000;
1167 f7b4a940 aliguori
1168 f7b4a940 aliguori
        ret = bdrv_snapshot_create(bs, &sn);
1169 b8fb60da Jes Sorensen
        if (ret) {
1170 15654a6d Jes Sorensen
            error_report("Could not create snapshot '%s': %d (%s)",
1171 f7b4a940 aliguori
                snapshot_name, ret, strerror(-ret));
1172 b8fb60da Jes Sorensen
        }
1173 f7b4a940 aliguori
        break;
1174 f7b4a940 aliguori
1175 f7b4a940 aliguori
    case SNAPSHOT_APPLY:
1176 f7b4a940 aliguori
        ret = bdrv_snapshot_goto(bs, snapshot_name);
1177 b8fb60da Jes Sorensen
        if (ret) {
1178 15654a6d Jes Sorensen
            error_report("Could not apply snapshot '%s': %d (%s)",
1179 f7b4a940 aliguori
                snapshot_name, ret, strerror(-ret));
1180 b8fb60da Jes Sorensen
        }
1181 f7b4a940 aliguori
        break;
1182 f7b4a940 aliguori
1183 f7b4a940 aliguori
    case SNAPSHOT_DELETE:
1184 f7b4a940 aliguori
        ret = bdrv_snapshot_delete(bs, snapshot_name);
1185 b8fb60da Jes Sorensen
        if (ret) {
1186 15654a6d Jes Sorensen
            error_report("Could not delete snapshot '%s': %d (%s)",
1187 f7b4a940 aliguori
                snapshot_name, ret, strerror(-ret));
1188 b8fb60da Jes Sorensen
        }
1189 f7b4a940 aliguori
        break;
1190 f7b4a940 aliguori
    }
1191 f7b4a940 aliguori
1192 f7b4a940 aliguori
    /* Cleanup */
1193 f7b4a940 aliguori
    bdrv_delete(bs);
1194 c2abccec MORITA Kazutaka
    if (ret) {
1195 c2abccec MORITA Kazutaka
        return 1;
1196 c2abccec MORITA Kazutaka
    }
1197 153859be Stuart Brady
    return 0;
1198 f7b4a940 aliguori
}
1199 f7b4a940 aliguori
1200 3e85c6fd Kevin Wolf
static int img_rebase(int argc, char **argv)
1201 3e85c6fd Kevin Wolf
{
1202 c2abccec MORITA Kazutaka
    BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
1203 f163d073 Stefan Hajnoczi
    BlockDriver *old_backing_drv, *new_backing_drv;
1204 3e85c6fd Kevin Wolf
    char *filename;
1205 e53dbee0 Kevin Wolf
    const char *fmt, *out_basefmt, *out_baseimg;
1206 3e85c6fd Kevin Wolf
    int c, flags, ret;
1207 3e85c6fd Kevin Wolf
    int unsafe = 0;
1208 6b837bc4 Jes Sorensen
    int progress = 0;
1209 3e85c6fd Kevin Wolf
1210 3e85c6fd Kevin Wolf
    /* Parse commandline parameters */
1211 e53dbee0 Kevin Wolf
    fmt = NULL;
1212 3e85c6fd Kevin Wolf
    out_baseimg = NULL;
1213 3e85c6fd Kevin Wolf
    out_basefmt = NULL;
1214 3e85c6fd Kevin Wolf
1215 3e85c6fd Kevin Wolf
    for(;;) {
1216 6b837bc4 Jes Sorensen
        c = getopt(argc, argv, "uhf:F:b:p");
1217 b8fb60da Jes Sorensen
        if (c == -1) {
1218 3e85c6fd Kevin Wolf
            break;
1219 b8fb60da Jes Sorensen
        }
1220 3e85c6fd Kevin Wolf
        switch(c) {
1221 ef87394c Jes Sorensen
        case '?':
1222 3e85c6fd Kevin Wolf
        case 'h':
1223 3e85c6fd Kevin Wolf
            help();
1224 3e85c6fd Kevin Wolf
            return 0;
1225 e53dbee0 Kevin Wolf
        case 'f':
1226 e53dbee0 Kevin Wolf
            fmt = optarg;
1227 e53dbee0 Kevin Wolf
            break;
1228 3e85c6fd Kevin Wolf
        case 'F':
1229 3e85c6fd Kevin Wolf
            out_basefmt = optarg;
1230 3e85c6fd Kevin Wolf
            break;
1231 3e85c6fd Kevin Wolf
        case 'b':
1232 3e85c6fd Kevin Wolf
            out_baseimg = optarg;
1233 3e85c6fd Kevin Wolf
            break;
1234 3e85c6fd Kevin Wolf
        case 'u':
1235 3e85c6fd Kevin Wolf
            unsafe = 1;
1236 3e85c6fd Kevin Wolf
            break;
1237 6b837bc4 Jes Sorensen
        case 'p':
1238 6b837bc4 Jes Sorensen
            progress = 1;
1239 6b837bc4 Jes Sorensen
            break;
1240 3e85c6fd Kevin Wolf
        }
1241 3e85c6fd Kevin Wolf
    }
1242 3e85c6fd Kevin Wolf
1243 b8fb60da Jes Sorensen
    if ((optind >= argc) || !out_baseimg) {
1244 3e85c6fd Kevin Wolf
        help();
1245 b8fb60da Jes Sorensen
    }
1246 3e85c6fd Kevin Wolf
    filename = argv[optind++];
1247 3e85c6fd Kevin Wolf
1248 6b837bc4 Jes Sorensen
    qemu_progress_init(progress, 2.0);
1249 6b837bc4 Jes Sorensen
    qemu_progress_print(0, 100);
1250 6b837bc4 Jes Sorensen
1251 3e85c6fd Kevin Wolf
    /*
1252 3e85c6fd Kevin Wolf
     * Open the images.
1253 3e85c6fd Kevin Wolf
     *
1254 3e85c6fd Kevin Wolf
     * Ignore the old backing file for unsafe rebase in case we want to correct
1255 3e85c6fd Kevin Wolf
     * the reference to a renamed or moved backing file.
1256 3e85c6fd Kevin Wolf
     */
1257 adfe078e Stefan Hajnoczi
    flags = BDRV_O_FLAGS | BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
1258 f163d073 Stefan Hajnoczi
    bs = bdrv_new_open(filename, fmt, flags);
1259 c2abccec MORITA Kazutaka
    if (!bs) {
1260 c2abccec MORITA Kazutaka
        return 1;
1261 c2abccec MORITA Kazutaka
    }
1262 3e85c6fd Kevin Wolf
1263 3e85c6fd Kevin Wolf
    /* Find the right drivers for the backing files */
1264 3e85c6fd Kevin Wolf
    old_backing_drv = NULL;
1265 3e85c6fd Kevin Wolf
    new_backing_drv = NULL;
1266 3e85c6fd Kevin Wolf
1267 3e85c6fd Kevin Wolf
    if (!unsafe && bs->backing_format[0] != '\0') {
1268 3e85c6fd Kevin Wolf
        old_backing_drv = bdrv_find_format(bs->backing_format);
1269 3e85c6fd Kevin Wolf
        if (old_backing_drv == NULL) {
1270 15654a6d Jes Sorensen
            error_report("Invalid format name: '%s'", bs->backing_format);
1271 c2abccec MORITA Kazutaka
            ret = -1;
1272 c2abccec MORITA Kazutaka
            goto out;
1273 3e85c6fd Kevin Wolf
        }
1274 3e85c6fd Kevin Wolf
    }
1275 3e85c6fd Kevin Wolf
1276 3e85c6fd Kevin Wolf
    if (out_basefmt != NULL) {
1277 3e85c6fd Kevin Wolf
        new_backing_drv = bdrv_find_format(out_basefmt);
1278 3e85c6fd Kevin Wolf
        if (new_backing_drv == NULL) {
1279 15654a6d Jes Sorensen
            error_report("Invalid format name: '%s'", out_basefmt);
1280 c2abccec MORITA Kazutaka
            ret = -1;
1281 c2abccec MORITA Kazutaka
            goto out;
1282 3e85c6fd Kevin Wolf
        }
1283 3e85c6fd Kevin Wolf
    }
1284 3e85c6fd Kevin Wolf
1285 3e85c6fd Kevin Wolf
    /* For safe rebasing we need to compare old and new backing file */
1286 3e85c6fd Kevin Wolf
    if (unsafe) {
1287 3e85c6fd Kevin Wolf
        /* Make the compiler happy */
1288 3e85c6fd Kevin Wolf
        bs_old_backing = NULL;
1289 3e85c6fd Kevin Wolf
        bs_new_backing = NULL;
1290 3e85c6fd Kevin Wolf
    } else {
1291 3e85c6fd Kevin Wolf
        char backing_name[1024];
1292 3e85c6fd Kevin Wolf
1293 3e85c6fd Kevin Wolf
        bs_old_backing = bdrv_new("old_backing");
1294 3e85c6fd Kevin Wolf
        bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
1295 c2abccec MORITA Kazutaka
        ret = bdrv_open(bs_old_backing, backing_name, BDRV_O_FLAGS,
1296 c2abccec MORITA Kazutaka
                        old_backing_drv);
1297 c2abccec MORITA Kazutaka
        if (ret) {
1298 15654a6d Jes Sorensen
            error_report("Could not open old backing file '%s'", backing_name);
1299 c2abccec MORITA Kazutaka
            goto out;
1300 3e85c6fd Kevin Wolf
        }
1301 3e85c6fd Kevin Wolf
1302 3e85c6fd Kevin Wolf
        bs_new_backing = bdrv_new("new_backing");
1303 cdbae851 Kevin Wolf
        ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS,
1304 c2abccec MORITA Kazutaka
                        new_backing_drv);
1305 c2abccec MORITA Kazutaka
        if (ret) {
1306 15654a6d Jes Sorensen
            error_report("Could not open new backing file '%s'", out_baseimg);
1307 c2abccec MORITA Kazutaka
            goto out;
1308 3e85c6fd Kevin Wolf
        }
1309 3e85c6fd Kevin Wolf
    }
1310 3e85c6fd Kevin Wolf
1311 3e85c6fd Kevin Wolf
    /*
1312 3e85c6fd Kevin Wolf
     * Check each unallocated cluster in the COW file. If it is unallocated,
1313 3e85c6fd Kevin Wolf
     * accesses go to the backing file. We must therefore compare this cluster
1314 3e85c6fd Kevin Wolf
     * in the old and new backing file, and if they differ we need to copy it
1315 3e85c6fd Kevin Wolf
     * from the old backing file into the COW file.
1316 3e85c6fd Kevin Wolf
     *
1317 3e85c6fd Kevin Wolf
     * If qemu-img crashes during this step, no harm is done. The content of
1318 3e85c6fd Kevin Wolf
     * the image is the same as the original one at any time.
1319 3e85c6fd Kevin Wolf
     */
1320 3e85c6fd Kevin Wolf
    if (!unsafe) {
1321 3e85c6fd Kevin Wolf
        uint64_t num_sectors;
1322 3e85c6fd Kevin Wolf
        uint64_t sector;
1323 cc60e327 Kevin Wolf
        int n;
1324 d6771bfa TeLeMan
        uint8_t * buf_old;
1325 d6771bfa TeLeMan
        uint8_t * buf_new;
1326 6b837bc4 Jes Sorensen
        float local_progress;
1327 d6771bfa TeLeMan
1328 d6771bfa TeLeMan
        buf_old = qemu_malloc(IO_BUF_SIZE);
1329 d6771bfa TeLeMan
        buf_new = qemu_malloc(IO_BUF_SIZE);
1330 3e85c6fd Kevin Wolf
1331 3e85c6fd Kevin Wolf
        bdrv_get_geometry(bs, &num_sectors);
1332 3e85c6fd Kevin Wolf
1333 6b837bc4 Jes Sorensen
        local_progress = (float)100 /
1334 6b837bc4 Jes Sorensen
            (num_sectors / MIN(num_sectors, (IO_BUF_SIZE / 512)));
1335 3e85c6fd Kevin Wolf
        for (sector = 0; sector < num_sectors; sector += n) {
1336 3e85c6fd Kevin Wolf
1337 3e85c6fd Kevin Wolf
            /* How many sectors can we handle with the next read? */
1338 3e85c6fd Kevin Wolf
            if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
1339 3e85c6fd Kevin Wolf
                n = (IO_BUF_SIZE / 512);
1340 3e85c6fd Kevin Wolf
            } else {
1341 3e85c6fd Kevin Wolf
                n = num_sectors - sector;
1342 3e85c6fd Kevin Wolf
            }
1343 3e85c6fd Kevin Wolf
1344 3e85c6fd Kevin Wolf
            /* If the cluster is allocated, we don't need to take action */
1345 cc60e327 Kevin Wolf
            ret = bdrv_is_allocated(bs, sector, n, &n);
1346 cc60e327 Kevin Wolf
            if (ret) {
1347 3e85c6fd Kevin Wolf
                continue;
1348 3e85c6fd Kevin Wolf
            }
1349 3e85c6fd Kevin Wolf
1350 3e85c6fd Kevin Wolf
            /* Read old and new backing file */
1351 c2abccec MORITA Kazutaka
            ret = bdrv_read(bs_old_backing, sector, buf_old, n);
1352 c2abccec MORITA Kazutaka
            if (ret < 0) {
1353 15654a6d Jes Sorensen
                error_report("error while reading from old backing file");
1354 c2abccec MORITA Kazutaka
                goto out;
1355 3e85c6fd Kevin Wolf
            }
1356 c2abccec MORITA Kazutaka
            ret = bdrv_read(bs_new_backing, sector, buf_new, n);
1357 c2abccec MORITA Kazutaka
            if (ret < 0) {
1358 15654a6d Jes Sorensen
                error_report("error while reading from new backing file");
1359 c2abccec MORITA Kazutaka
                goto out;
1360 3e85c6fd Kevin Wolf
            }
1361 3e85c6fd Kevin Wolf
1362 3e85c6fd Kevin Wolf
            /* If they differ, we need to write to the COW file */
1363 3e85c6fd Kevin Wolf
            uint64_t written = 0;
1364 3e85c6fd Kevin Wolf
1365 3e85c6fd Kevin Wolf
            while (written < n) {
1366 3e85c6fd Kevin Wolf
                int pnum;
1367 3e85c6fd Kevin Wolf
1368 3e85c6fd Kevin Wolf
                if (compare_sectors(buf_old + written * 512,
1369 60b1bd4f Kevin Wolf
                    buf_new + written * 512, n - written, &pnum))
1370 3e85c6fd Kevin Wolf
                {
1371 3e85c6fd Kevin Wolf
                    ret = bdrv_write(bs, sector + written,
1372 3e85c6fd Kevin Wolf
                        buf_old + written * 512, pnum);
1373 3e85c6fd Kevin Wolf
                    if (ret < 0) {
1374 15654a6d Jes Sorensen
                        error_report("Error while writing to COW image: %s",
1375 3e85c6fd Kevin Wolf
                            strerror(-ret));
1376 c2abccec MORITA Kazutaka
                        goto out;
1377 3e85c6fd Kevin Wolf
                    }
1378 3e85c6fd Kevin Wolf
                }
1379 3e85c6fd Kevin Wolf
1380 3e85c6fd Kevin Wolf
                written += pnum;
1381 3e85c6fd Kevin Wolf
            }
1382 6b837bc4 Jes Sorensen
            qemu_progress_print(local_progress, 100);
1383 3e85c6fd Kevin Wolf
        }
1384 d6771bfa TeLeMan
1385 d6771bfa TeLeMan
        qemu_free(buf_old);
1386 d6771bfa TeLeMan
        qemu_free(buf_new);
1387 3e85c6fd Kevin Wolf
    }
1388 3e85c6fd Kevin Wolf
1389 3e85c6fd Kevin Wolf
    /*
1390 3e85c6fd Kevin Wolf
     * Change the backing file. All clusters that are different from the old
1391 3e85c6fd Kevin Wolf
     * backing file are overwritten in the COW file now, so the visible content
1392 3e85c6fd Kevin Wolf
     * doesn't change when we switch the backing file.
1393 3e85c6fd Kevin Wolf
     */
1394 3e85c6fd Kevin Wolf
    ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
1395 3e85c6fd Kevin Wolf
    if (ret == -ENOSPC) {
1396 15654a6d Jes Sorensen
        error_report("Could not change the backing file to '%s': No "
1397 15654a6d Jes Sorensen
                     "space left in the file header", out_baseimg);
1398 3e85c6fd Kevin Wolf
    } else if (ret < 0) {
1399 15654a6d Jes Sorensen
        error_report("Could not change the backing file to '%s': %s",
1400 3e85c6fd Kevin Wolf
            out_baseimg, strerror(-ret));
1401 3e85c6fd Kevin Wolf
    }
1402 3e85c6fd Kevin Wolf
1403 6b837bc4 Jes Sorensen
    qemu_progress_print(100, 0);
1404 3e85c6fd Kevin Wolf
    /*
1405 3e85c6fd Kevin Wolf
     * TODO At this point it is possible to check if any clusters that are
1406 3e85c6fd Kevin Wolf
     * allocated in the COW file are the same in the backing file. If so, they
1407 3e85c6fd Kevin Wolf
     * could be dropped from the COW file. Don't do this before switching the
1408 3e85c6fd Kevin Wolf
     * backing file, in case of a crash this would lead to corruption.
1409 3e85c6fd Kevin Wolf
     */
1410 c2abccec MORITA Kazutaka
out:
1411 6b837bc4 Jes Sorensen
    qemu_progress_end();
1412 3e85c6fd Kevin Wolf
    /* Cleanup */
1413 3e85c6fd Kevin Wolf
    if (!unsafe) {
1414 3e85c6fd Kevin Wolf
        bdrv_delete(bs_old_backing);
1415 3e85c6fd Kevin Wolf
        bdrv_delete(bs_new_backing);
1416 3e85c6fd Kevin Wolf
    }
1417 3e85c6fd Kevin Wolf
1418 3e85c6fd Kevin Wolf
    bdrv_delete(bs);
1419 c2abccec MORITA Kazutaka
    if (ret) {
1420 c2abccec MORITA Kazutaka
        return 1;
1421 c2abccec MORITA Kazutaka
    }
1422 3e85c6fd Kevin Wolf
    return 0;
1423 3e85c6fd Kevin Wolf
}
1424 3e85c6fd Kevin Wolf
1425 ae6b0ed6 Stefan Hajnoczi
static int img_resize(int argc, char **argv)
1426 ae6b0ed6 Stefan Hajnoczi
{
1427 ae6b0ed6 Stefan Hajnoczi
    int c, ret, relative;
1428 ae6b0ed6 Stefan Hajnoczi
    const char *filename, *fmt, *size;
1429 ae6b0ed6 Stefan Hajnoczi
    int64_t n, total_size;
1430 2a81998a Jes Sorensen
    BlockDriverState *bs = NULL;
1431 ae6b0ed6 Stefan Hajnoczi
    QEMUOptionParameter *param;
1432 ae6b0ed6 Stefan Hajnoczi
    QEMUOptionParameter resize_options[] = {
1433 ae6b0ed6 Stefan Hajnoczi
        {
1434 ae6b0ed6 Stefan Hajnoczi
            .name = BLOCK_OPT_SIZE,
1435 ae6b0ed6 Stefan Hajnoczi
            .type = OPT_SIZE,
1436 ae6b0ed6 Stefan Hajnoczi
            .help = "Virtual disk size"
1437 ae6b0ed6 Stefan Hajnoczi
        },
1438 ae6b0ed6 Stefan Hajnoczi
        { NULL }
1439 ae6b0ed6 Stefan Hajnoczi
    };
1440 ae6b0ed6 Stefan Hajnoczi
1441 ae6b0ed6 Stefan Hajnoczi
    fmt = NULL;
1442 ae6b0ed6 Stefan Hajnoczi
    for(;;) {
1443 ae6b0ed6 Stefan Hajnoczi
        c = getopt(argc, argv, "f:h");
1444 ae6b0ed6 Stefan Hajnoczi
        if (c == -1) {
1445 ae6b0ed6 Stefan Hajnoczi
            break;
1446 ae6b0ed6 Stefan Hajnoczi
        }
1447 ae6b0ed6 Stefan Hajnoczi
        switch(c) {
1448 ef87394c Jes Sorensen
        case '?':
1449 ae6b0ed6 Stefan Hajnoczi
        case 'h':
1450 ae6b0ed6 Stefan Hajnoczi
            help();
1451 ae6b0ed6 Stefan Hajnoczi
            break;
1452 ae6b0ed6 Stefan Hajnoczi
        case 'f':
1453 ae6b0ed6 Stefan Hajnoczi
            fmt = optarg;
1454 ae6b0ed6 Stefan Hajnoczi
            break;
1455 ae6b0ed6 Stefan Hajnoczi
        }
1456 ae6b0ed6 Stefan Hajnoczi
    }
1457 ae6b0ed6 Stefan Hajnoczi
    if (optind + 1 >= argc) {
1458 ae6b0ed6 Stefan Hajnoczi
        help();
1459 ae6b0ed6 Stefan Hajnoczi
    }
1460 ae6b0ed6 Stefan Hajnoczi
    filename = argv[optind++];
1461 ae6b0ed6 Stefan Hajnoczi
    size = argv[optind++];
1462 ae6b0ed6 Stefan Hajnoczi
1463 ae6b0ed6 Stefan Hajnoczi
    /* Choose grow, shrink, or absolute resize mode */
1464 ae6b0ed6 Stefan Hajnoczi
    switch (size[0]) {
1465 ae6b0ed6 Stefan Hajnoczi
    case '+':
1466 ae6b0ed6 Stefan Hajnoczi
        relative = 1;
1467 ae6b0ed6 Stefan Hajnoczi
        size++;
1468 ae6b0ed6 Stefan Hajnoczi
        break;
1469 ae6b0ed6 Stefan Hajnoczi
    case '-':
1470 ae6b0ed6 Stefan Hajnoczi
        relative = -1;
1471 ae6b0ed6 Stefan Hajnoczi
        size++;
1472 ae6b0ed6 Stefan Hajnoczi
        break;
1473 ae6b0ed6 Stefan Hajnoczi
    default:
1474 ae6b0ed6 Stefan Hajnoczi
        relative = 0;
1475 ae6b0ed6 Stefan Hajnoczi
        break;
1476 ae6b0ed6 Stefan Hajnoczi
    }
1477 ae6b0ed6 Stefan Hajnoczi
1478 ae6b0ed6 Stefan Hajnoczi
    /* Parse size */
1479 ae6b0ed6 Stefan Hajnoczi
    param = parse_option_parameters("", resize_options, NULL);
1480 ae6b0ed6 Stefan Hajnoczi
    if (set_option_parameter(param, BLOCK_OPT_SIZE, size)) {
1481 ae6b0ed6 Stefan Hajnoczi
        /* Error message already printed when size parsing fails */
1482 2a81998a Jes Sorensen
        ret = -1;
1483 2a81998a Jes Sorensen
        goto out;
1484 ae6b0ed6 Stefan Hajnoczi
    }
1485 ae6b0ed6 Stefan Hajnoczi
    n = get_option_parameter(param, BLOCK_OPT_SIZE)->value.n;
1486 ae6b0ed6 Stefan Hajnoczi
    free_option_parameters(param);
1487 ae6b0ed6 Stefan Hajnoczi
1488 ae6b0ed6 Stefan Hajnoczi
    bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
1489 c2abccec MORITA Kazutaka
    if (!bs) {
1490 2a81998a Jes Sorensen
        ret = -1;
1491 2a81998a Jes Sorensen
        goto out;
1492 c2abccec MORITA Kazutaka
    }
1493 ae6b0ed6 Stefan Hajnoczi
1494 ae6b0ed6 Stefan Hajnoczi
    if (relative) {
1495 ae6b0ed6 Stefan Hajnoczi
        total_size = bdrv_getlength(bs) + n * relative;
1496 ae6b0ed6 Stefan Hajnoczi
    } else {
1497 ae6b0ed6 Stefan Hajnoczi
        total_size = n;
1498 ae6b0ed6 Stefan Hajnoczi
    }
1499 ae6b0ed6 Stefan Hajnoczi
    if (total_size <= 0) {
1500 15654a6d Jes Sorensen
        error_report("New image size must be positive");
1501 c2abccec MORITA Kazutaka
        ret = -1;
1502 c2abccec MORITA Kazutaka
        goto out;
1503 ae6b0ed6 Stefan Hajnoczi
    }
1504 ae6b0ed6 Stefan Hajnoczi
1505 ae6b0ed6 Stefan Hajnoczi
    ret = bdrv_truncate(bs, total_size);
1506 ae6b0ed6 Stefan Hajnoczi
    switch (ret) {
1507 ae6b0ed6 Stefan Hajnoczi
    case 0:
1508 ae6b0ed6 Stefan Hajnoczi
        printf("Image resized.\n");
1509 ae6b0ed6 Stefan Hajnoczi
        break;
1510 ae6b0ed6 Stefan Hajnoczi
    case -ENOTSUP:
1511 15654a6d Jes Sorensen
        error_report("This image format does not support resize");
1512 ae6b0ed6 Stefan Hajnoczi
        break;
1513 ae6b0ed6 Stefan Hajnoczi
    case -EACCES:
1514 15654a6d Jes Sorensen
        error_report("Image is read-only");
1515 ae6b0ed6 Stefan Hajnoczi
        break;
1516 ae6b0ed6 Stefan Hajnoczi
    default:
1517 15654a6d Jes Sorensen
        error_report("Error resizing image (%d)", -ret);
1518 ae6b0ed6 Stefan Hajnoczi
        break;
1519 ae6b0ed6 Stefan Hajnoczi
    }
1520 c2abccec MORITA Kazutaka
out:
1521 2a81998a Jes Sorensen
    if (bs) {
1522 2a81998a Jes Sorensen
        bdrv_delete(bs);
1523 2a81998a Jes Sorensen
    }
1524 c2abccec MORITA Kazutaka
    if (ret) {
1525 c2abccec MORITA Kazutaka
        return 1;
1526 c2abccec MORITA Kazutaka
    }
1527 ae6b0ed6 Stefan Hajnoczi
    return 0;
1528 ae6b0ed6 Stefan Hajnoczi
}
1529 ae6b0ed6 Stefan Hajnoczi
1530 c227f099 Anthony Liguori
static const img_cmd_t img_cmds[] = {
1531 153859be Stuart Brady
#define DEF(option, callback, arg_string)        \
1532 153859be Stuart Brady
    { option, callback },
1533 153859be Stuart Brady
#include "qemu-img-cmds.h"
1534 153859be Stuart Brady
#undef DEF
1535 153859be Stuart Brady
#undef GEN_DOCS
1536 153859be Stuart Brady
    { NULL, NULL, },
1537 153859be Stuart Brady
};
1538 153859be Stuart Brady
1539 ea2384d3 bellard
int main(int argc, char **argv)
1540 ea2384d3 bellard
{
1541 c227f099 Anthony Liguori
    const img_cmd_t *cmd;
1542 153859be Stuart Brady
    const char *cmdname;
1543 ea2384d3 bellard
1544 53f76e58 Kevin Wolf
    error_set_progname(argv[0]);
1545 53f76e58 Kevin Wolf
1546 ea2384d3 bellard
    bdrv_init();
1547 ea2384d3 bellard
    if (argc < 2)
1548 ea2384d3 bellard
        help();
1549 153859be Stuart Brady
    cmdname = argv[1];
1550 8f9b157e aurel32
    argc--; argv++;
1551 153859be Stuart Brady
1552 153859be Stuart Brady
    /* find the command */
1553 153859be Stuart Brady
    for(cmd = img_cmds; cmd->name != NULL; cmd++) {
1554 153859be Stuart Brady
        if (!strcmp(cmdname, cmd->name)) {
1555 153859be Stuart Brady
            return cmd->handler(argc, argv);
1556 153859be Stuart Brady
        }
1557 ea2384d3 bellard
    }
1558 153859be Stuart Brady
1559 153859be Stuart Brady
    /* not found */
1560 153859be Stuart Brady
    help();
1561 ea2384d3 bellard
    return 0;
1562 ea2384d3 bellard
}