Statistics
| Branch: | Revision:

root / qemu-img.c @ 0834c9ea

History | View | Annotate | Download (52.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 c054b3fd Benoît Canet
#include "qapi-visit.h"
25 c054b3fd Benoît Canet
#include "qapi/qmp-output-visitor.h"
26 c054b3fd Benoît Canet
#include "qjson.h"
27 faf07963 pbrook
#include "qemu-common.h"
28 9ea2ea71 Kevin Wolf
#include "qemu-option.h"
29 53f76e58 Kevin Wolf
#include "qemu-error.h"
30 f7b4a940 aliguori
#include "osdep.h"
31 dc786bc9 Jes Sorensen
#include "sysemu.h"
32 ec36ba14 ths
#include "block_int.h"
33 c054b3fd Benoît Canet
#include <getopt.h>
34 9230eaf6 aliguori
#include <stdio.h>
35 ea2384d3 bellard
36 e8445331 bellard
#ifdef _WIN32
37 e8445331 bellard
#include <windows.h>
38 e8445331 bellard
#endif
39 e8445331 bellard
40 c227f099 Anthony Liguori
typedef struct img_cmd_t {
41 153859be Stuart Brady
    const char *name;
42 153859be Stuart Brady
    int (*handler)(int argc, char **argv);
43 c227f099 Anthony Liguori
} img_cmd_t;
44 153859be Stuart Brady
45 137519ce aurel32
/* Default to cache=writeback as data integrity is not important for qemu-tcg. */
46 adfe078e Stefan Hajnoczi
#define BDRV_O_FLAGS BDRV_O_CACHE_WB
47 661a0f71 Federico Simoncelli
#define BDRV_DEFAULT_CACHE "writeback"
48 137519ce aurel32
49 ea2384d3 bellard
static void format_print(void *opaque, const char *name)
50 ea2384d3 bellard
{
51 ea2384d3 bellard
    printf(" %s", name);
52 ea2384d3 bellard
}
53 ea2384d3 bellard
54 d2c639d6 blueswir1
/* Please keep in synch with qemu-img.texi */
55 3f379ab1 pbrook
static void help(void)
56 ea2384d3 bellard
{
57 e00291c0 Paolo Bonzini
    const char *help_msg =
58 e00291c0 Paolo Bonzini
           "qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fabrice Bellard\n"
59 3f020d70 malc
           "usage: qemu-img command [command options]\n"
60 3f020d70 malc
           "QEMU disk image utility\n"
61 3f020d70 malc
           "\n"
62 3f020d70 malc
           "Command syntax:\n"
63 153859be Stuart Brady
#define DEF(option, callback, arg_string)        \
64 153859be Stuart Brady
           "  " arg_string "\n"
65 153859be Stuart Brady
#include "qemu-img-cmds.h"
66 153859be Stuart Brady
#undef DEF
67 153859be Stuart Brady
#undef GEN_DOCS
68 3f020d70 malc
           "\n"
69 3f020d70 malc
           "Command parameters:\n"
70 3f020d70 malc
           "  'filename' is a disk image filename\n"
71 3f020d70 malc
           "  'fmt' is the disk image format. It is guessed automatically in most cases\n"
72 661a0f71 Federico Simoncelli
           "  'cache' is the cache mode used to write the output disk image, the valid\n"
73 80ccf93b Liu Yuan
           "    options are: 'none', 'writeback' (default, except for convert), 'writethrough',\n"
74 80ccf93b Liu Yuan
           "    'directsync' and 'unsafe' (default for convert)\n"
75 3f020d70 malc
           "  'size' is the disk image size in bytes. Optional suffixes\n"
76 3f020d70 malc
           "    'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M)\n"
77 3f020d70 malc
           "    and T (terabyte, 1024G) are supported. 'b' is ignored.\n"
78 3f020d70 malc
           "  'output_filename' is the destination disk image filename\n"
79 3f020d70 malc
           "  'output_fmt' is the destination format\n"
80 3f020d70 malc
           "  'options' is a comma separated list of format specific options in a\n"
81 3f020d70 malc
           "    name=value format. Use -o ? for an overview of the options supported by the\n"
82 3f020d70 malc
           "    used format\n"
83 3f020d70 malc
           "  '-c' indicates that target image must be compressed (qcow format only)\n"
84 3f020d70 malc
           "  '-u' enables unsafe rebasing. It is assumed that old and new backing file\n"
85 3f020d70 malc
           "       match exactly. The image doesn't need a working backing file before\n"
86 3f020d70 malc
           "       rebasing in this case (useful for renaming the backing file)\n"
87 3f020d70 malc
           "  '-h' with or without a command shows this help and lists the supported formats\n"
88 6b837bc4 Jes Sorensen
           "  '-p' show progress of command (only certain commands)\n"
89 a22f123c Kevin Wolf
           "  '-S' indicates the consecutive number of bytes that must contain only zeros\n"
90 a22f123c Kevin Wolf
           "       for qemu-img to create a sparse image during conversion\n"
91 c054b3fd Benoît Canet
           "  '--output' takes the format in which the output must be done (human or json)\n"
92 3f020d70 malc
           "\n"
93 4534ff54 Kevin Wolf
           "Parameters to check subcommand:\n"
94 4534ff54 Kevin Wolf
           "  '-r' tries to repair any inconsistencies that are found during the check.\n"
95 4534ff54 Kevin Wolf
           "       '-r leaks' repairs only cluster leaks, whereas '-r all' fixes all\n"
96 4534ff54 Kevin Wolf
           "       kinds of errors, with a higher risk of choosing the wrong fix or\n"
97 0546b8c2 Stefan Weil
           "       hiding corruption that has already occurred.\n"
98 4534ff54 Kevin Wolf
           "\n"
99 3f020d70 malc
           "Parameters to snapshot subcommand:\n"
100 3f020d70 malc
           "  'snapshot' is the name of the snapshot to create, apply or delete\n"
101 3f020d70 malc
           "  '-a' applies a snapshot (revert disk to saved state)\n"
102 3f020d70 malc
           "  '-c' creates a snapshot\n"
103 3f020d70 malc
           "  '-d' deletes a snapshot\n"
104 e00291c0 Paolo Bonzini
           "  '-l' lists all snapshots in the given image\n";
105 e00291c0 Paolo Bonzini
106 e00291c0 Paolo Bonzini
    printf("%s\nSupported formats:", help_msg);
107 ea2384d3 bellard
    bdrv_iterate_format(format_print, NULL);
108 ea2384d3 bellard
    printf("\n");
109 ea2384d3 bellard
    exit(1);
110 ea2384d3 bellard
}
111 ea2384d3 bellard
112 ea2384d3 bellard
#if defined(WIN32)
113 ea2384d3 bellard
/* XXX: put correct support for win32 */
114 ea2384d3 bellard
static int read_password(char *buf, int buf_size)
115 ea2384d3 bellard
{
116 ea2384d3 bellard
    int c, i;
117 ea2384d3 bellard
    printf("Password: ");
118 ea2384d3 bellard
    fflush(stdout);
119 ea2384d3 bellard
    i = 0;
120 ea2384d3 bellard
    for(;;) {
121 ea2384d3 bellard
        c = getchar();
122 ea2384d3 bellard
        if (c == '\n')
123 ea2384d3 bellard
            break;
124 ea2384d3 bellard
        if (i < (buf_size - 1))
125 ea2384d3 bellard
            buf[i++] = c;
126 ea2384d3 bellard
    }
127 ea2384d3 bellard
    buf[i] = '\0';
128 ea2384d3 bellard
    return 0;
129 ea2384d3 bellard
}
130 ea2384d3 bellard
131 ea2384d3 bellard
#else
132 ea2384d3 bellard
133 ea2384d3 bellard
#include <termios.h>
134 ea2384d3 bellard
135 ea2384d3 bellard
static struct termios oldtty;
136 ea2384d3 bellard
137 ea2384d3 bellard
static void term_exit(void)
138 ea2384d3 bellard
{
139 ea2384d3 bellard
    tcsetattr (0, TCSANOW, &oldtty);
140 ea2384d3 bellard
}
141 ea2384d3 bellard
142 ea2384d3 bellard
static void term_init(void)
143 ea2384d3 bellard
{
144 ea2384d3 bellard
    struct termios tty;
145 ea2384d3 bellard
146 ea2384d3 bellard
    tcgetattr (0, &tty);
147 ea2384d3 bellard
    oldtty = tty;
148 ea2384d3 bellard
149 ea2384d3 bellard
    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
150 ea2384d3 bellard
                          |INLCR|IGNCR|ICRNL|IXON);
151 ea2384d3 bellard
    tty.c_oflag |= OPOST;
152 ea2384d3 bellard
    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
153 ea2384d3 bellard
    tty.c_cflag &= ~(CSIZE|PARENB);
154 ea2384d3 bellard
    tty.c_cflag |= CS8;
155 ea2384d3 bellard
    tty.c_cc[VMIN] = 1;
156 ea2384d3 bellard
    tty.c_cc[VTIME] = 0;
157 3b46e624 ths
158 ea2384d3 bellard
    tcsetattr (0, TCSANOW, &tty);
159 ea2384d3 bellard
160 ea2384d3 bellard
    atexit(term_exit);
161 ea2384d3 bellard
}
162 ea2384d3 bellard
163 3f379ab1 pbrook
static int read_password(char *buf, int buf_size)
164 ea2384d3 bellard
{
165 ea2384d3 bellard
    uint8_t ch;
166 ea2384d3 bellard
    int i, ret;
167 ea2384d3 bellard
168 ea2384d3 bellard
    printf("password: ");
169 ea2384d3 bellard
    fflush(stdout);
170 ea2384d3 bellard
    term_init();
171 ea2384d3 bellard
    i = 0;
172 ea2384d3 bellard
    for(;;) {
173 ea2384d3 bellard
        ret = read(0, &ch, 1);
174 ea2384d3 bellard
        if (ret == -1) {
175 ea2384d3 bellard
            if (errno == EAGAIN || errno == EINTR) {
176 ea2384d3 bellard
                continue;
177 ea2384d3 bellard
            } else {
178 ea2384d3 bellard
                ret = -1;
179 ea2384d3 bellard
                break;
180 ea2384d3 bellard
            }
181 ea2384d3 bellard
        } else if (ret == 0) {
182 ea2384d3 bellard
            ret = -1;
183 ea2384d3 bellard
            break;
184 ea2384d3 bellard
        } else {
185 ea2384d3 bellard
            if (ch == '\r') {
186 ea2384d3 bellard
                ret = 0;
187 ea2384d3 bellard
                break;
188 ea2384d3 bellard
            }
189 ea2384d3 bellard
            if (i < (buf_size - 1))
190 ea2384d3 bellard
                buf[i++] = ch;
191 ea2384d3 bellard
        }
192 ea2384d3 bellard
    }
193 ea2384d3 bellard
    term_exit();
194 ea2384d3 bellard
    buf[i] = '\0';
195 ea2384d3 bellard
    printf("\n");
196 ea2384d3 bellard
    return ret;
197 ea2384d3 bellard
}
198 ea2384d3 bellard
#endif
199 ea2384d3 bellard
200 4ac8aacd Jes Sorensen
static int print_block_option_help(const char *filename, const char *fmt)
201 4ac8aacd Jes Sorensen
{
202 4ac8aacd Jes Sorensen
    BlockDriver *drv, *proto_drv;
203 4ac8aacd Jes Sorensen
    QEMUOptionParameter *create_options = NULL;
204 4ac8aacd Jes Sorensen
205 4ac8aacd Jes Sorensen
    /* Find driver and parse its options */
206 4ac8aacd Jes Sorensen
    drv = bdrv_find_format(fmt);
207 4ac8aacd Jes Sorensen
    if (!drv) {
208 15654a6d Jes Sorensen
        error_report("Unknown file format '%s'", fmt);
209 4ac8aacd Jes Sorensen
        return 1;
210 4ac8aacd Jes Sorensen
    }
211 4ac8aacd Jes Sorensen
212 4ac8aacd Jes Sorensen
    proto_drv = bdrv_find_protocol(filename);
213 4ac8aacd Jes Sorensen
    if (!proto_drv) {
214 15654a6d Jes Sorensen
        error_report("Unknown protocol '%s'", filename);
215 4ac8aacd Jes Sorensen
        return 1;
216 4ac8aacd Jes Sorensen
    }
217 4ac8aacd Jes Sorensen
218 4ac8aacd Jes Sorensen
    create_options = append_option_parameters(create_options,
219 4ac8aacd Jes Sorensen
                                              drv->create_options);
220 4ac8aacd Jes Sorensen
    create_options = append_option_parameters(create_options,
221 4ac8aacd Jes Sorensen
                                              proto_drv->create_options);
222 4ac8aacd Jes Sorensen
    print_option_help(create_options);
223 4ac8aacd Jes Sorensen
    free_option_parameters(create_options);
224 4ac8aacd Jes Sorensen
    return 0;
225 4ac8aacd Jes Sorensen
}
226 4ac8aacd Jes Sorensen
227 75c23805 bellard
static BlockDriverState *bdrv_new_open(const char *filename,
228 9bc378c1 Sheng Yang
                                       const char *fmt,
229 f0536bb8 Daniel P. Berrange
                                       int flags,
230 f0536bb8 Daniel P. Berrange
                                       bool require_io)
231 75c23805 bellard
{
232 75c23805 bellard
    BlockDriverState *bs;
233 75c23805 bellard
    BlockDriver *drv;
234 75c23805 bellard
    char password[256];
235 b9eaf9ec Kevin Wolf
    int ret;
236 75c23805 bellard
237 b9eaf9ec Kevin Wolf
    bs = bdrv_new("image");
238 ad717139 Kevin Wolf
239 75c23805 bellard
    if (fmt) {
240 75c23805 bellard
        drv = bdrv_find_format(fmt);
241 c2abccec MORITA Kazutaka
        if (!drv) {
242 15654a6d Jes Sorensen
            error_report("Unknown file format '%s'", fmt);
243 c2abccec MORITA Kazutaka
            goto fail;
244 c2abccec MORITA Kazutaka
        }
245 75c23805 bellard
    } else {
246 75c23805 bellard
        drv = NULL;
247 75c23805 bellard
    }
248 b9eaf9ec Kevin Wolf
249 b9eaf9ec Kevin Wolf
    ret = bdrv_open(bs, filename, flags, drv);
250 b9eaf9ec Kevin Wolf
    if (ret < 0) {
251 b9eaf9ec Kevin Wolf
        error_report("Could not open '%s': %s", filename, strerror(-ret));
252 c2abccec MORITA Kazutaka
        goto fail;
253 75c23805 bellard
    }
254 b9eaf9ec Kevin Wolf
255 f0536bb8 Daniel P. Berrange
    if (bdrv_is_encrypted(bs) && require_io) {
256 75c23805 bellard
        printf("Disk image '%s' is encrypted.\n", filename);
257 c2abccec MORITA Kazutaka
        if (read_password(password, sizeof(password)) < 0) {
258 15654a6d Jes Sorensen
            error_report("No password given");
259 c2abccec MORITA Kazutaka
            goto fail;
260 c2abccec MORITA Kazutaka
        }
261 c2abccec MORITA Kazutaka
        if (bdrv_set_key(bs, password) < 0) {
262 15654a6d Jes Sorensen
            error_report("invalid password");
263 c2abccec MORITA Kazutaka
            goto fail;
264 c2abccec MORITA Kazutaka
        }
265 75c23805 bellard
    }
266 75c23805 bellard
    return bs;
267 c2abccec MORITA Kazutaka
fail:
268 c2abccec MORITA Kazutaka
    if (bs) {
269 c2abccec MORITA Kazutaka
        bdrv_delete(bs);
270 c2abccec MORITA Kazutaka
    }
271 c2abccec MORITA Kazutaka
    return NULL;
272 75c23805 bellard
}
273 75c23805 bellard
274 c2abccec MORITA Kazutaka
static int add_old_style_options(const char *fmt, QEMUOptionParameter *list,
275 eec77d9e Jes Sorensen
                                 const char *base_filename,
276 eec77d9e Jes Sorensen
                                 const char *base_fmt)
277 efa84d43 Kevin Wolf
{
278 efa84d43 Kevin Wolf
    if (base_filename) {
279 efa84d43 Kevin Wolf
        if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) {
280 15654a6d Jes Sorensen
            error_report("Backing file not supported for file format '%s'",
281 15654a6d Jes Sorensen
                         fmt);
282 c2abccec MORITA Kazutaka
            return -1;
283 efa84d43 Kevin Wolf
        }
284 efa84d43 Kevin Wolf
    }
285 efa84d43 Kevin Wolf
    if (base_fmt) {
286 efa84d43 Kevin Wolf
        if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {
287 15654a6d Jes Sorensen
            error_report("Backing file format not supported for file "
288 15654a6d Jes Sorensen
                         "format '%s'", fmt);
289 c2abccec MORITA Kazutaka
            return -1;
290 efa84d43 Kevin Wolf
        }
291 efa84d43 Kevin Wolf
    }
292 c2abccec MORITA Kazutaka
    return 0;
293 efa84d43 Kevin Wolf
}
294 efa84d43 Kevin Wolf
295 ea2384d3 bellard
static int img_create(int argc, char **argv)
296 ea2384d3 bellard
{
297 eec77d9e Jes Sorensen
    int c, ret = 0;
298 1da7cfbd Jes Sorensen
    uint64_t img_size = -1;
299 ea2384d3 bellard
    const char *fmt = "raw";
300 9230eaf6 aliguori
    const char *base_fmt = NULL;
301 ea2384d3 bellard
    const char *filename;
302 ea2384d3 bellard
    const char *base_filename = NULL;
303 9ea2ea71 Kevin Wolf
    char *options = NULL;
304 3b46e624 ths
305 ea2384d3 bellard
    for(;;) {
306 9ea2ea71 Kevin Wolf
        c = getopt(argc, argv, "F:b:f:he6o:");
307 b8fb60da Jes Sorensen
        if (c == -1) {
308 ea2384d3 bellard
            break;
309 b8fb60da Jes Sorensen
        }
310 ea2384d3 bellard
        switch(c) {
311 ef87394c Jes Sorensen
        case '?':
312 ea2384d3 bellard
        case 'h':
313 ea2384d3 bellard
            help();
314 ea2384d3 bellard
            break;
315 9230eaf6 aliguori
        case 'F':
316 9230eaf6 aliguori
            base_fmt = optarg;
317 9230eaf6 aliguori
            break;
318 ea2384d3 bellard
        case 'b':
319 ea2384d3 bellard
            base_filename = optarg;
320 ea2384d3 bellard
            break;
321 ea2384d3 bellard
        case 'f':
322 ea2384d3 bellard
            fmt = optarg;
323 ea2384d3 bellard
            break;
324 ea2384d3 bellard
        case 'e':
325 9d42e15d Markus Armbruster
            error_report("option -e is deprecated, please use \'-o "
326 eec77d9e Jes Sorensen
                  "encryption\' instead!");
327 eec77d9e Jes Sorensen
            return 1;
328 d8871c5a ths
        case '6':
329 9d42e15d Markus Armbruster
            error_report("option -6 is deprecated, please use \'-o "
330 eec77d9e Jes Sorensen
                  "compat6\' instead!");
331 eec77d9e Jes Sorensen
            return 1;
332 9ea2ea71 Kevin Wolf
        case 'o':
333 9ea2ea71 Kevin Wolf
            options = optarg;
334 9ea2ea71 Kevin Wolf
            break;
335 ea2384d3 bellard
        }
336 ea2384d3 bellard
    }
337 9230eaf6 aliguori
338 b50cbabc MORITA Kazutaka
    /* Get the filename */
339 b8fb60da Jes Sorensen
    if (optind >= argc) {
340 b50cbabc MORITA Kazutaka
        help();
341 b8fb60da Jes Sorensen
    }
342 b50cbabc MORITA Kazutaka
    filename = argv[optind++];
343 b50cbabc MORITA Kazutaka
344 1da7cfbd Jes Sorensen
    /* Get image size, if specified */
345 1da7cfbd Jes Sorensen
    if (optind < argc) {
346 70b4f4bb Jes Sorensen
        int64_t sval;
347 e36b3695 Markus Armbruster
        char *end;
348 e36b3695 Markus Armbruster
        sval = strtosz_suffix(argv[optind++], &end, STRTOSZ_DEFSUFFIX_B);
349 e36b3695 Markus Armbruster
        if (sval < 0 || *end) {
350 15654a6d Jes Sorensen
            error_report("Invalid image size specified! You may use k, M, G or "
351 1da7cfbd Jes Sorensen
                  "T suffixes for ");
352 15654a6d Jes Sorensen
            error_report("kilobytes, megabytes, gigabytes and terabytes.");
353 1da7cfbd Jes Sorensen
            ret = -1;
354 1da7cfbd Jes Sorensen
            goto out;
355 1da7cfbd Jes Sorensen
        }
356 1da7cfbd Jes Sorensen
        img_size = (uint64_t)sval;
357 1da7cfbd Jes Sorensen
    }
358 1da7cfbd Jes Sorensen
359 c8057f95 Peter Maydell
    if (options && is_help_option(options)) {
360 4ac8aacd Jes Sorensen
        ret = print_block_option_help(filename, fmt);
361 4ac8aacd Jes Sorensen
        goto out;
362 4ac8aacd Jes Sorensen
    }
363 4ac8aacd Jes Sorensen
364 f88e1a42 Jes Sorensen
    ret = bdrv_img_create(filename, fmt, base_filename, base_fmt,
365 f88e1a42 Jes Sorensen
                          options, img_size, BDRV_O_FLAGS);
366 c2abccec MORITA Kazutaka
out:
367 c2abccec MORITA Kazutaka
    if (ret) {
368 c2abccec MORITA Kazutaka
        return 1;
369 c2abccec MORITA Kazutaka
    }
370 ea2384d3 bellard
    return 0;
371 ea2384d3 bellard
}
372 ea2384d3 bellard
373 e076f338 Kevin Wolf
/*
374 e076f338 Kevin Wolf
 * Checks an image for consistency. Exit codes:
375 e076f338 Kevin Wolf
 *
376 e076f338 Kevin Wolf
 * 0 - Check completed, image is good
377 e076f338 Kevin Wolf
 * 1 - Check not completed because of internal errors
378 e076f338 Kevin Wolf
 * 2 - Check completed, image is corrupted
379 e076f338 Kevin Wolf
 * 3 - Check completed, image has leaked clusters, but is good otherwise
380 e076f338 Kevin Wolf
 */
381 1585969c aliguori
static int img_check(int argc, char **argv)
382 1585969c aliguori
{
383 1585969c aliguori
    int c, ret;
384 1585969c aliguori
    const char *filename, *fmt;
385 1585969c aliguori
    BlockDriverState *bs;
386 e076f338 Kevin Wolf
    BdrvCheckResult result;
387 4534ff54 Kevin Wolf
    int fix = 0;
388 058f8f16 Stefan Hajnoczi
    int flags = BDRV_O_FLAGS | BDRV_O_CHECK;
389 1585969c aliguori
390 1585969c aliguori
    fmt = NULL;
391 1585969c aliguori
    for(;;) {
392 4534ff54 Kevin Wolf
        c = getopt(argc, argv, "f:hr:");
393 b8fb60da Jes Sorensen
        if (c == -1) {
394 1585969c aliguori
            break;
395 b8fb60da Jes Sorensen
        }
396 1585969c aliguori
        switch(c) {
397 ef87394c Jes Sorensen
        case '?':
398 1585969c aliguori
        case 'h':
399 1585969c aliguori
            help();
400 1585969c aliguori
            break;
401 1585969c aliguori
        case 'f':
402 1585969c aliguori
            fmt = optarg;
403 1585969c aliguori
            break;
404 4534ff54 Kevin Wolf
        case 'r':
405 4534ff54 Kevin Wolf
            flags |= BDRV_O_RDWR;
406 4534ff54 Kevin Wolf
407 4534ff54 Kevin Wolf
            if (!strcmp(optarg, "leaks")) {
408 4534ff54 Kevin Wolf
                fix = BDRV_FIX_LEAKS;
409 4534ff54 Kevin Wolf
            } else if (!strcmp(optarg, "all")) {
410 4534ff54 Kevin Wolf
                fix = BDRV_FIX_LEAKS | BDRV_FIX_ERRORS;
411 4534ff54 Kevin Wolf
            } else {
412 4534ff54 Kevin Wolf
                help();
413 4534ff54 Kevin Wolf
            }
414 4534ff54 Kevin Wolf
            break;
415 1585969c aliguori
        }
416 1585969c aliguori
    }
417 b8fb60da Jes Sorensen
    if (optind >= argc) {
418 1585969c aliguori
        help();
419 b8fb60da Jes Sorensen
    }
420 1585969c aliguori
    filename = argv[optind++];
421 1585969c aliguori
422 f0536bb8 Daniel P. Berrange
    bs = bdrv_new_open(filename, fmt, flags, true);
423 c2abccec MORITA Kazutaka
    if (!bs) {
424 c2abccec MORITA Kazutaka
        return 1;
425 c2abccec MORITA Kazutaka
    }
426 4534ff54 Kevin Wolf
    ret = bdrv_check(bs, &result, fix);
427 e076f338 Kevin Wolf
428 e076f338 Kevin Wolf
    if (ret == -ENOTSUP) {
429 15654a6d Jes Sorensen
        error_report("This image format does not support checks");
430 e076f338 Kevin Wolf
        bdrv_delete(bs);
431 e076f338 Kevin Wolf
        return 1;
432 e076f338 Kevin Wolf
    }
433 e076f338 Kevin Wolf
434 ccf34716 Kevin Wolf
    if (result.corruptions_fixed || result.leaks_fixed) {
435 ccf34716 Kevin Wolf
        printf("The following inconsistencies were found and repaired:\n\n"
436 ccf34716 Kevin Wolf
               "    %d leaked clusters\n"
437 ccf34716 Kevin Wolf
               "    %d corruptions\n\n"
438 ccf34716 Kevin Wolf
               "Double checking the fixed image now...\n",
439 ccf34716 Kevin Wolf
               result.leaks_fixed,
440 ccf34716 Kevin Wolf
               result.corruptions_fixed);
441 ccf34716 Kevin Wolf
        ret = bdrv_check(bs, &result, 0);
442 ccf34716 Kevin Wolf
    }
443 ccf34716 Kevin Wolf
444 e076f338 Kevin Wolf
    if (!(result.corruptions || result.leaks || result.check_errors)) {
445 e076f338 Kevin Wolf
        printf("No errors were found on the image.\n");
446 e076f338 Kevin Wolf
    } else {
447 e076f338 Kevin Wolf
        if (result.corruptions) {
448 e076f338 Kevin Wolf
            printf("\n%d errors were found on the image.\n"
449 e076f338 Kevin Wolf
                "Data may be corrupted, or further writes to the image "
450 e076f338 Kevin Wolf
                "may corrupt it.\n",
451 e076f338 Kevin Wolf
                result.corruptions);
452 e076f338 Kevin Wolf
        }
453 e076f338 Kevin Wolf
454 e076f338 Kevin Wolf
        if (result.leaks) {
455 e076f338 Kevin Wolf
            printf("\n%d leaked clusters were found on the image.\n"
456 e076f338 Kevin Wolf
                "This means waste of disk space, but no harm to data.\n",
457 e076f338 Kevin Wolf
                result.leaks);
458 e076f338 Kevin Wolf
        }
459 e076f338 Kevin Wolf
460 e076f338 Kevin Wolf
        if (result.check_errors) {
461 e076f338 Kevin Wolf
            printf("\n%d internal errors have occurred during the check.\n",
462 e076f338 Kevin Wolf
                result.check_errors);
463 1585969c aliguori
        }
464 1585969c aliguori
    }
465 1585969c aliguori
466 f8111c24 Dong Xu Wang
    if (result.bfi.total_clusters != 0 && result.bfi.allocated_clusters != 0) {
467 f8111c24 Dong Xu Wang
        printf("%" PRId64 "/%" PRId64 "= %0.2f%% allocated, %0.2f%% fragmented\n",
468 f8111c24 Dong Xu Wang
        result.bfi.allocated_clusters, result.bfi.total_clusters,
469 f8111c24 Dong Xu Wang
        result.bfi.allocated_clusters * 100.0 / result.bfi.total_clusters,
470 f8111c24 Dong Xu Wang
        result.bfi.fragmented_clusters * 100.0 / result.bfi.allocated_clusters);
471 f8111c24 Dong Xu Wang
    }
472 f8111c24 Dong Xu Wang
473 1585969c aliguori
    bdrv_delete(bs);
474 e076f338 Kevin Wolf
475 e076f338 Kevin Wolf
    if (ret < 0 || result.check_errors) {
476 e076f338 Kevin Wolf
        printf("\nAn error has occurred during the check: %s\n"
477 e076f338 Kevin Wolf
            "The check is not complete and may have missed error.\n",
478 e076f338 Kevin Wolf
            strerror(-ret));
479 c2abccec MORITA Kazutaka
        return 1;
480 c2abccec MORITA Kazutaka
    }
481 e076f338 Kevin Wolf
482 e076f338 Kevin Wolf
    if (result.corruptions) {
483 e076f338 Kevin Wolf
        return 2;
484 e076f338 Kevin Wolf
    } else if (result.leaks) {
485 e076f338 Kevin Wolf
        return 3;
486 e076f338 Kevin Wolf
    } else {
487 e076f338 Kevin Wolf
        return 0;
488 e076f338 Kevin Wolf
    }
489 1585969c aliguori
}
490 1585969c aliguori
491 ea2384d3 bellard
static int img_commit(int argc, char **argv)
492 ea2384d3 bellard
{
493 661a0f71 Federico Simoncelli
    int c, ret, flags;
494 661a0f71 Federico Simoncelli
    const char *filename, *fmt, *cache;
495 ea2384d3 bellard
    BlockDriverState *bs;
496 ea2384d3 bellard
497 ea2384d3 bellard
    fmt = NULL;
498 661a0f71 Federico Simoncelli
    cache = BDRV_DEFAULT_CACHE;
499 ea2384d3 bellard
    for(;;) {
500 661a0f71 Federico Simoncelli
        c = getopt(argc, argv, "f:ht:");
501 b8fb60da Jes Sorensen
        if (c == -1) {
502 ea2384d3 bellard
            break;
503 b8fb60da Jes Sorensen
        }
504 ea2384d3 bellard
        switch(c) {
505 ef87394c Jes Sorensen
        case '?':
506 ea2384d3 bellard
        case 'h':
507 ea2384d3 bellard
            help();
508 ea2384d3 bellard
            break;
509 ea2384d3 bellard
        case 'f':
510 ea2384d3 bellard
            fmt = optarg;
511 ea2384d3 bellard
            break;
512 661a0f71 Federico Simoncelli
        case 't':
513 661a0f71 Federico Simoncelli
            cache = optarg;
514 661a0f71 Federico Simoncelli
            break;
515 ea2384d3 bellard
        }
516 ea2384d3 bellard
    }
517 b8fb60da Jes Sorensen
    if (optind >= argc) {
518 ea2384d3 bellard
        help();
519 b8fb60da Jes Sorensen
    }
520 ea2384d3 bellard
    filename = argv[optind++];
521 ea2384d3 bellard
522 661a0f71 Federico Simoncelli
    flags = BDRV_O_RDWR;
523 c3993cdc Stefan Hajnoczi
    ret = bdrv_parse_cache_flags(cache, &flags);
524 661a0f71 Federico Simoncelli
    if (ret < 0) {
525 661a0f71 Federico Simoncelli
        error_report("Invalid cache option: %s", cache);
526 661a0f71 Federico Simoncelli
        return -1;
527 661a0f71 Federico Simoncelli
    }
528 661a0f71 Federico Simoncelli
529 f0536bb8 Daniel P. Berrange
    bs = bdrv_new_open(filename, fmt, flags, true);
530 c2abccec MORITA Kazutaka
    if (!bs) {
531 c2abccec MORITA Kazutaka
        return 1;
532 c2abccec MORITA Kazutaka
    }
533 ea2384d3 bellard
    ret = bdrv_commit(bs);
534 ea2384d3 bellard
    switch(ret) {
535 ea2384d3 bellard
    case 0:
536 ea2384d3 bellard
        printf("Image committed.\n");
537 ea2384d3 bellard
        break;
538 ea2384d3 bellard
    case -ENOENT:
539 15654a6d Jes Sorensen
        error_report("No disk inserted");
540 ea2384d3 bellard
        break;
541 ea2384d3 bellard
    case -EACCES:
542 15654a6d Jes Sorensen
        error_report("Image is read-only");
543 ea2384d3 bellard
        break;
544 ea2384d3 bellard
    case -ENOTSUP:
545 15654a6d Jes Sorensen
        error_report("Image is already committed");
546 ea2384d3 bellard
        break;
547 ea2384d3 bellard
    default:
548 15654a6d Jes Sorensen
        error_report("Error while committing image");
549 ea2384d3 bellard
        break;
550 ea2384d3 bellard
    }
551 ea2384d3 bellard
552 ea2384d3 bellard
    bdrv_delete(bs);
553 c2abccec MORITA Kazutaka
    if (ret) {
554 c2abccec MORITA Kazutaka
        return 1;
555 c2abccec MORITA Kazutaka
    }
556 ea2384d3 bellard
    return 0;
557 ea2384d3 bellard
}
558 ea2384d3 bellard
559 f6a00aa1 Dmitry Konishchev
/*
560 f58c7b35 ths
 * Returns true iff the first sector pointed to by 'buf' contains at least
561 f58c7b35 ths
 * a non-NUL byte.
562 f58c7b35 ths
 *
563 f58c7b35 ths
 * 'pnum' is set to the number of sectors (including and immediately following
564 f58c7b35 ths
 * the first one) that are known to be in the same allocated/unallocated state.
565 f58c7b35 ths
 */
566 ea2384d3 bellard
static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
567 ea2384d3 bellard
{
568 1a6d39fd Stefan Hajnoczi
    bool is_zero;
569 1a6d39fd Stefan Hajnoczi
    int i;
570 ea2384d3 bellard
571 ea2384d3 bellard
    if (n <= 0) {
572 ea2384d3 bellard
        *pnum = 0;
573 ea2384d3 bellard
        return 0;
574 ea2384d3 bellard
    }
575 1a6d39fd Stefan Hajnoczi
    is_zero = buffer_is_zero(buf, 512);
576 ea2384d3 bellard
    for(i = 1; i < n; i++) {
577 ea2384d3 bellard
        buf += 512;
578 1a6d39fd Stefan Hajnoczi
        if (is_zero != buffer_is_zero(buf, 512)) {
579 ea2384d3 bellard
            break;
580 1a6d39fd Stefan Hajnoczi
        }
581 ea2384d3 bellard
    }
582 ea2384d3 bellard
    *pnum = i;
583 1a6d39fd Stefan Hajnoczi
    return !is_zero;
584 ea2384d3 bellard
}
585 ea2384d3 bellard
586 3e85c6fd Kevin Wolf
/*
587 a22f123c Kevin Wolf
 * Like is_allocated_sectors, but if the buffer starts with a used sector,
588 a22f123c Kevin Wolf
 * up to 'min' consecutive sectors containing zeros are ignored. This avoids
589 a22f123c Kevin Wolf
 * breaking up write requests for only small sparse areas.
590 a22f123c Kevin Wolf
 */
591 a22f123c Kevin Wolf
static int is_allocated_sectors_min(const uint8_t *buf, int n, int *pnum,
592 a22f123c Kevin Wolf
    int min)
593 a22f123c Kevin Wolf
{
594 a22f123c Kevin Wolf
    int ret;
595 a22f123c Kevin Wolf
    int num_checked, num_used;
596 a22f123c Kevin Wolf
597 a22f123c Kevin Wolf
    if (n < min) {
598 a22f123c Kevin Wolf
        min = n;
599 a22f123c Kevin Wolf
    }
600 a22f123c Kevin Wolf
601 a22f123c Kevin Wolf
    ret = is_allocated_sectors(buf, n, pnum);
602 a22f123c Kevin Wolf
    if (!ret) {
603 a22f123c Kevin Wolf
        return ret;
604 a22f123c Kevin Wolf
    }
605 a22f123c Kevin Wolf
606 a22f123c Kevin Wolf
    num_used = *pnum;
607 a22f123c Kevin Wolf
    buf += BDRV_SECTOR_SIZE * *pnum;
608 a22f123c Kevin Wolf
    n -= *pnum;
609 a22f123c Kevin Wolf
    num_checked = num_used;
610 a22f123c Kevin Wolf
611 a22f123c Kevin Wolf
    while (n > 0) {
612 a22f123c Kevin Wolf
        ret = is_allocated_sectors(buf, n, pnum);
613 a22f123c Kevin Wolf
614 a22f123c Kevin Wolf
        buf += BDRV_SECTOR_SIZE * *pnum;
615 a22f123c Kevin Wolf
        n -= *pnum;
616 a22f123c Kevin Wolf
        num_checked += *pnum;
617 a22f123c Kevin Wolf
        if (ret) {
618 a22f123c Kevin Wolf
            num_used = num_checked;
619 a22f123c Kevin Wolf
        } else if (*pnum >= min) {
620 a22f123c Kevin Wolf
            break;
621 a22f123c Kevin Wolf
        }
622 a22f123c Kevin Wolf
    }
623 a22f123c Kevin Wolf
624 a22f123c Kevin Wolf
    *pnum = num_used;
625 a22f123c Kevin Wolf
    return 1;
626 a22f123c Kevin Wolf
}
627 a22f123c Kevin Wolf
628 a22f123c Kevin Wolf
/*
629 3e85c6fd Kevin Wolf
 * Compares two buffers sector by sector. Returns 0 if the first sector of both
630 3e85c6fd Kevin Wolf
 * buffers matches, non-zero otherwise.
631 3e85c6fd Kevin Wolf
 *
632 3e85c6fd Kevin Wolf
 * pnum is set to the number of sectors (including and immediately following
633 3e85c6fd Kevin Wolf
 * the first one) that are known to have the same comparison result
634 3e85c6fd Kevin Wolf
 */
635 3e85c6fd Kevin Wolf
static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
636 3e85c6fd Kevin Wolf
    int *pnum)
637 3e85c6fd Kevin Wolf
{
638 3e85c6fd Kevin Wolf
    int res, i;
639 3e85c6fd Kevin Wolf
640 3e85c6fd Kevin Wolf
    if (n <= 0) {
641 3e85c6fd Kevin Wolf
        *pnum = 0;
642 3e85c6fd Kevin Wolf
        return 0;
643 3e85c6fd Kevin Wolf
    }
644 3e85c6fd Kevin Wolf
645 3e85c6fd Kevin Wolf
    res = !!memcmp(buf1, buf2, 512);
646 3e85c6fd Kevin Wolf
    for(i = 1; i < n; i++) {
647 3e85c6fd Kevin Wolf
        buf1 += 512;
648 3e85c6fd Kevin Wolf
        buf2 += 512;
649 3e85c6fd Kevin Wolf
650 3e85c6fd Kevin Wolf
        if (!!memcmp(buf1, buf2, 512) != res) {
651 3e85c6fd Kevin Wolf
            break;
652 3e85c6fd Kevin Wolf
        }
653 3e85c6fd Kevin Wolf
    }
654 3e85c6fd Kevin Wolf
655 3e85c6fd Kevin Wolf
    *pnum = i;
656 3e85c6fd Kevin Wolf
    return res;
657 3e85c6fd Kevin Wolf
}
658 3e85c6fd Kevin Wolf
659 80ee15a6 Kevin Wolf
#define IO_BUF_SIZE (2 * 1024 * 1024)
660 ea2384d3 bellard
661 ea2384d3 bellard
static int img_convert(int argc, char **argv)
662 ea2384d3 bellard
{
663 eec77d9e Jes Sorensen
    int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;
664 661a0f71 Federico Simoncelli
    int progress = 0, flags;
665 661a0f71 Federico Simoncelli
    const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename;
666 b50cbabc MORITA Kazutaka
    BlockDriver *drv, *proto_drv;
667 c2abccec MORITA Kazutaka
    BlockDriverState **bs = NULL, *out_bs = NULL;
668 96b8f136 ths
    int64_t total_sectors, nb_sectors, sector_num, bs_offset;
669 96b8f136 ths
    uint64_t bs_sectors;
670 c2abccec MORITA Kazutaka
    uint8_t * buf = NULL;
671 ea2384d3 bellard
    const uint8_t *buf1;
672 faea38e7 bellard
    BlockDriverInfo bdi;
673 b50cbabc MORITA Kazutaka
    QEMUOptionParameter *param = NULL, *create_options = NULL;
674 a18953fb Kevin Wolf
    QEMUOptionParameter *out_baseimg_param;
675 efa84d43 Kevin Wolf
    char *options = NULL;
676 51ef6727 edison
    const char *snapshot_name = NULL;
677 6b837bc4 Jes Sorensen
    float local_progress;
678 a22f123c Kevin Wolf
    int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */
679 ea2384d3 bellard
680 ea2384d3 bellard
    fmt = NULL;
681 ea2384d3 bellard
    out_fmt = "raw";
682 661a0f71 Federico Simoncelli
    cache = "unsafe";
683 f58c7b35 ths
    out_baseimg = NULL;
684 eec77d9e Jes Sorensen
    compress = 0;
685 ea2384d3 bellard
    for(;;) {
686 a22f123c Kevin Wolf
        c = getopt(argc, argv, "f:O:B:s:hce6o:pS:t:");
687 b8fb60da Jes Sorensen
        if (c == -1) {
688 ea2384d3 bellard
            break;
689 b8fb60da Jes Sorensen
        }
690 ea2384d3 bellard
        switch(c) {
691 ef87394c Jes Sorensen
        case '?':
692 ea2384d3 bellard
        case 'h':
693 ea2384d3 bellard
            help();
694 ea2384d3 bellard
            break;
695 ea2384d3 bellard
        case 'f':
696 ea2384d3 bellard
            fmt = optarg;
697 ea2384d3 bellard
            break;
698 ea2384d3 bellard
        case 'O':
699 ea2384d3 bellard
            out_fmt = optarg;
700 ea2384d3 bellard
            break;
701 f58c7b35 ths
        case 'B':
702 f58c7b35 ths
            out_baseimg = optarg;
703 f58c7b35 ths
            break;
704 ea2384d3 bellard
        case 'c':
705 eec77d9e Jes Sorensen
            compress = 1;
706 ea2384d3 bellard
            break;
707 ea2384d3 bellard
        case 'e':
708 9d42e15d Markus Armbruster
            error_report("option -e is deprecated, please use \'-o "
709 eec77d9e Jes Sorensen
                  "encryption\' instead!");
710 eec77d9e Jes Sorensen
            return 1;
711 ec36ba14 ths
        case '6':
712 9d42e15d Markus Armbruster
            error_report("option -6 is deprecated, please use \'-o "
713 eec77d9e Jes Sorensen
                  "compat6\' instead!");
714 eec77d9e Jes Sorensen
            return 1;
715 efa84d43 Kevin Wolf
        case 'o':
716 efa84d43 Kevin Wolf
            options = optarg;
717 efa84d43 Kevin Wolf
            break;
718 51ef6727 edison
        case 's':
719 51ef6727 edison
            snapshot_name = optarg;
720 51ef6727 edison
            break;
721 a22f123c Kevin Wolf
        case 'S':
722 a22f123c Kevin Wolf
        {
723 a22f123c Kevin Wolf
            int64_t sval;
724 e36b3695 Markus Armbruster
            char *end;
725 e36b3695 Markus Armbruster
            sval = strtosz_suffix(optarg, &end, STRTOSZ_DEFSUFFIX_B);
726 e36b3695 Markus Armbruster
            if (sval < 0 || *end) {
727 a22f123c Kevin Wolf
                error_report("Invalid minimum zero buffer size for sparse output specified");
728 a22f123c Kevin Wolf
                return 1;
729 a22f123c Kevin Wolf
            }
730 a22f123c Kevin Wolf
731 a22f123c Kevin Wolf
            min_sparse = sval / BDRV_SECTOR_SIZE;
732 a22f123c Kevin Wolf
            break;
733 a22f123c Kevin Wolf
        }
734 6b837bc4 Jes Sorensen
        case 'p':
735 6b837bc4 Jes Sorensen
            progress = 1;
736 6b837bc4 Jes Sorensen
            break;
737 661a0f71 Federico Simoncelli
        case 't':
738 661a0f71 Federico Simoncelli
            cache = optarg;
739 661a0f71 Federico Simoncelli
            break;
740 ea2384d3 bellard
        }
741 ea2384d3 bellard
    }
742 3b46e624 ths
743 926c2d23 balrog
    bs_n = argc - optind - 1;
744 b8fb60da Jes Sorensen
    if (bs_n < 1) {
745 b8fb60da Jes Sorensen
        help();
746 b8fb60da Jes Sorensen
    }
747 926c2d23 balrog
748 926c2d23 balrog
    out_filename = argv[argc - 1];
749 f58c7b35 ths
750 fa170c14 Charles Arnold
    /* Initialize before goto out */
751 fa170c14 Charles Arnold
    qemu_progress_init(progress, 2.0);
752 fa170c14 Charles Arnold
753 c8057f95 Peter Maydell
    if (options && is_help_option(options)) {
754 4ac8aacd Jes Sorensen
        ret = print_block_option_help(out_filename, out_fmt);
755 4ac8aacd Jes Sorensen
        goto out;
756 4ac8aacd Jes Sorensen
    }
757 4ac8aacd Jes Sorensen
758 c2abccec MORITA Kazutaka
    if (bs_n > 1 && out_baseimg) {
759 15654a6d Jes Sorensen
        error_report("-B makes no sense when concatenating multiple input "
760 15654a6d Jes Sorensen
                     "images");
761 31ca34b8 Jes Sorensen
        ret = -1;
762 31ca34b8 Jes Sorensen
        goto out;
763 c2abccec MORITA Kazutaka
    }
764 f8111c24 Dong Xu Wang
765 6b837bc4 Jes Sorensen
    qemu_progress_print(0, 100);
766 6b837bc4 Jes Sorensen
767 7267c094 Anthony Liguori
    bs = g_malloc0(bs_n * sizeof(BlockDriverState *));
768 926c2d23 balrog
769 926c2d23 balrog
    total_sectors = 0;
770 926c2d23 balrog
    for (bs_i = 0; bs_i < bs_n; bs_i++) {
771 f0536bb8 Daniel P. Berrange
        bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS, true);
772 c2abccec MORITA Kazutaka
        if (!bs[bs_i]) {
773 15654a6d Jes Sorensen
            error_report("Could not open '%s'", argv[optind + bs_i]);
774 c2abccec MORITA Kazutaka
            ret = -1;
775 c2abccec MORITA Kazutaka
            goto out;
776 c2abccec MORITA Kazutaka
        }
777 926c2d23 balrog
        bdrv_get_geometry(bs[bs_i], &bs_sectors);
778 926c2d23 balrog
        total_sectors += bs_sectors;
779 926c2d23 balrog
    }
780 ea2384d3 bellard
781 51ef6727 edison
    if (snapshot_name != NULL) {
782 51ef6727 edison
        if (bs_n > 1) {
783 6daf194d Markus Armbruster
            error_report("No support for concatenating multiple snapshot");
784 51ef6727 edison
            ret = -1;
785 51ef6727 edison
            goto out;
786 51ef6727 edison
        }
787 51ef6727 edison
        if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
788 6daf194d Markus Armbruster
            error_report("Failed to load snapshot");
789 51ef6727 edison
            ret = -1;
790 51ef6727 edison
            goto out;
791 51ef6727 edison
        }
792 51ef6727 edison
    }
793 51ef6727 edison
794 efa84d43 Kevin Wolf
    /* Find driver and parse its options */
795 ea2384d3 bellard
    drv = bdrv_find_format(out_fmt);
796 c2abccec MORITA Kazutaka
    if (!drv) {
797 15654a6d Jes Sorensen
        error_report("Unknown file format '%s'", out_fmt);
798 c2abccec MORITA Kazutaka
        ret = -1;
799 c2abccec MORITA Kazutaka
        goto out;
800 c2abccec MORITA Kazutaka
    }
801 efa84d43 Kevin Wolf
802 b50cbabc MORITA Kazutaka
    proto_drv = bdrv_find_protocol(out_filename);
803 c2abccec MORITA Kazutaka
    if (!proto_drv) {
804 15654a6d Jes Sorensen
        error_report("Unknown protocol '%s'", out_filename);
805 c2abccec MORITA Kazutaka
        ret = -1;
806 c2abccec MORITA Kazutaka
        goto out;
807 c2abccec MORITA Kazutaka
    }
808 b50cbabc MORITA Kazutaka
809 b50cbabc MORITA Kazutaka
    create_options = append_option_parameters(create_options,
810 b50cbabc MORITA Kazutaka
                                              drv->create_options);
811 b50cbabc MORITA Kazutaka
    create_options = append_option_parameters(create_options,
812 b50cbabc MORITA Kazutaka
                                              proto_drv->create_options);
813 db08adf5 Kevin Wolf
814 efa84d43 Kevin Wolf
    if (options) {
815 b50cbabc MORITA Kazutaka
        param = parse_option_parameters(options, create_options, param);
816 efa84d43 Kevin Wolf
        if (param == NULL) {
817 15654a6d Jes Sorensen
            error_report("Invalid options for file format '%s'.", out_fmt);
818 c2abccec MORITA Kazutaka
            ret = -1;
819 c2abccec MORITA Kazutaka
            goto out;
820 efa84d43 Kevin Wolf
        }
821 efa84d43 Kevin Wolf
    } else {
822 b50cbabc MORITA Kazutaka
        param = parse_option_parameters("", create_options, param);
823 efa84d43 Kevin Wolf
    }
824 efa84d43 Kevin Wolf
825 efa84d43 Kevin Wolf
    set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
826 eec77d9e Jes Sorensen
    ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);
827 c2abccec MORITA Kazutaka
    if (ret < 0) {
828 c2abccec MORITA Kazutaka
        goto out;
829 c2abccec MORITA Kazutaka
    }
830 efa84d43 Kevin Wolf
831 a18953fb Kevin Wolf
    /* Get backing file name if -o backing_file was used */
832 a18953fb Kevin Wolf
    out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
833 a18953fb Kevin Wolf
    if (out_baseimg_param) {
834 a18953fb Kevin Wolf
        out_baseimg = out_baseimg_param->value.s;
835 a18953fb Kevin Wolf
    }
836 a18953fb Kevin Wolf
837 efa84d43 Kevin Wolf
    /* Check if compression is supported */
838 eec77d9e Jes Sorensen
    if (compress) {
839 efa84d43 Kevin Wolf
        QEMUOptionParameter *encryption =
840 efa84d43 Kevin Wolf
            get_option_parameter(param, BLOCK_OPT_ENCRYPT);
841 41521fa4 Kevin Wolf
        QEMUOptionParameter *preallocation =
842 41521fa4 Kevin Wolf
            get_option_parameter(param, BLOCK_OPT_PREALLOC);
843 efa84d43 Kevin Wolf
844 efa84d43 Kevin Wolf
        if (!drv->bdrv_write_compressed) {
845 15654a6d Jes Sorensen
            error_report("Compression not supported for this file format");
846 c2abccec MORITA Kazutaka
            ret = -1;
847 c2abccec MORITA Kazutaka
            goto out;
848 efa84d43 Kevin Wolf
        }
849 efa84d43 Kevin Wolf
850 efa84d43 Kevin Wolf
        if (encryption && encryption->value.n) {
851 15654a6d Jes Sorensen
            error_report("Compression and encryption not supported at "
852 15654a6d Jes Sorensen
                         "the same time");
853 c2abccec MORITA Kazutaka
            ret = -1;
854 c2abccec MORITA Kazutaka
            goto out;
855 efa84d43 Kevin Wolf
        }
856 41521fa4 Kevin Wolf
857 41521fa4 Kevin Wolf
        if (preallocation && preallocation->value.s
858 41521fa4 Kevin Wolf
            && strcmp(preallocation->value.s, "off"))
859 41521fa4 Kevin Wolf
        {
860 41521fa4 Kevin Wolf
            error_report("Compression and preallocation not supported at "
861 41521fa4 Kevin Wolf
                         "the same time");
862 41521fa4 Kevin Wolf
            ret = -1;
863 41521fa4 Kevin Wolf
            goto out;
864 41521fa4 Kevin Wolf
        }
865 efa84d43 Kevin Wolf
    }
866 efa84d43 Kevin Wolf
867 efa84d43 Kevin Wolf
    /* Create the new image */
868 efa84d43 Kevin Wolf
    ret = bdrv_create(drv, out_filename, param);
869 ea2384d3 bellard
    if (ret < 0) {
870 ea2384d3 bellard
        if (ret == -ENOTSUP) {
871 15654a6d Jes Sorensen
            error_report("Formatting not supported for file format '%s'",
872 15654a6d Jes Sorensen
                         out_fmt);
873 6e9ea0c0 aurel32
        } else if (ret == -EFBIG) {
874 15654a6d Jes Sorensen
            error_report("The image size is too large for file format '%s'",
875 15654a6d Jes Sorensen
                         out_fmt);
876 ea2384d3 bellard
        } else {
877 15654a6d Jes Sorensen
            error_report("%s: error while converting %s: %s",
878 15654a6d Jes Sorensen
                         out_filename, out_fmt, strerror(-ret));
879 ea2384d3 bellard
        }
880 c2abccec MORITA Kazutaka
        goto out;
881 ea2384d3 bellard
    }
882 3b46e624 ths
883 661a0f71 Federico Simoncelli
    flags = BDRV_O_RDWR;
884 c3993cdc Stefan Hajnoczi
    ret = bdrv_parse_cache_flags(cache, &flags);
885 661a0f71 Federico Simoncelli
    if (ret < 0) {
886 661a0f71 Federico Simoncelli
        error_report("Invalid cache option: %s", cache);
887 661a0f71 Federico Simoncelli
        return -1;
888 661a0f71 Federico Simoncelli
    }
889 661a0f71 Federico Simoncelli
890 f0536bb8 Daniel P. Berrange
    out_bs = bdrv_new_open(out_filename, out_fmt, flags, true);
891 c2abccec MORITA Kazutaka
    if (!out_bs) {
892 c2abccec MORITA Kazutaka
        ret = -1;
893 c2abccec MORITA Kazutaka
        goto out;
894 c2abccec MORITA Kazutaka
    }
895 ea2384d3 bellard
896 926c2d23 balrog
    bs_i = 0;
897 926c2d23 balrog
    bs_offset = 0;
898 926c2d23 balrog
    bdrv_get_geometry(bs[0], &bs_sectors);
899 bb1c0597 Kevin Wolf
    buf = qemu_blockalign(out_bs, IO_BUF_SIZE);
900 926c2d23 balrog
901 eec77d9e Jes Sorensen
    if (compress) {
902 c2abccec MORITA Kazutaka
        ret = bdrv_get_info(out_bs, &bdi);
903 c2abccec MORITA Kazutaka
        if (ret < 0) {
904 15654a6d Jes Sorensen
            error_report("could not get block driver info");
905 c2abccec MORITA Kazutaka
            goto out;
906 c2abccec MORITA Kazutaka
        }
907 faea38e7 bellard
        cluster_size = bdi.cluster_size;
908 c2abccec MORITA Kazutaka
        if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
909 15654a6d Jes Sorensen
            error_report("invalid cluster size");
910 c2abccec MORITA Kazutaka
            ret = -1;
911 c2abccec MORITA Kazutaka
            goto out;
912 c2abccec MORITA Kazutaka
        }
913 ea2384d3 bellard
        cluster_sectors = cluster_size >> 9;
914 ea2384d3 bellard
        sector_num = 0;
915 6b837bc4 Jes Sorensen
916 6b837bc4 Jes Sorensen
        nb_sectors = total_sectors;
917 6b837bc4 Jes Sorensen
        local_progress = (float)100 /
918 4ee96418 Jes Sorensen
            (nb_sectors / MIN(nb_sectors, cluster_sectors));
919 6b837bc4 Jes Sorensen
920 ea2384d3 bellard
        for(;;) {
921 926c2d23 balrog
            int64_t bs_num;
922 926c2d23 balrog
            int remainder;
923 926c2d23 balrog
            uint8_t *buf2;
924 926c2d23 balrog
925 ea2384d3 bellard
            nb_sectors = total_sectors - sector_num;
926 ea2384d3 bellard
            if (nb_sectors <= 0)
927 ea2384d3 bellard
                break;
928 ea2384d3 bellard
            if (nb_sectors >= cluster_sectors)
929 ea2384d3 bellard
                n = cluster_sectors;
930 ea2384d3 bellard
            else
931 ea2384d3 bellard
                n = nb_sectors;
932 926c2d23 balrog
933 926c2d23 balrog
            bs_num = sector_num - bs_offset;
934 926c2d23 balrog
            assert (bs_num >= 0);
935 926c2d23 balrog
            remainder = n;
936 926c2d23 balrog
            buf2 = buf;
937 926c2d23 balrog
            while (remainder > 0) {
938 926c2d23 balrog
                int nlow;
939 926c2d23 balrog
                while (bs_num == bs_sectors) {
940 926c2d23 balrog
                    bs_i++;
941 926c2d23 balrog
                    assert (bs_i < bs_n);
942 926c2d23 balrog
                    bs_offset += bs_sectors;
943 926c2d23 balrog
                    bdrv_get_geometry(bs[bs_i], &bs_sectors);
944 926c2d23 balrog
                    bs_num = 0;
945 0bfcd599 Blue Swirl
                    /* printf("changing part: sector_num=%" PRId64 ", "
946 0bfcd599 Blue Swirl
                       "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64
947 0bfcd599 Blue Swirl
                       "\n", sector_num, bs_i, bs_offset, bs_sectors); */
948 926c2d23 balrog
                }
949 926c2d23 balrog
                assert (bs_num < bs_sectors);
950 926c2d23 balrog
951 926c2d23 balrog
                nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
952 926c2d23 balrog
953 c2abccec MORITA Kazutaka
                ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
954 c2abccec MORITA Kazutaka
                if (ret < 0) {
955 3fba9d81 Stefan Hajnoczi
                    error_report("error while reading sector %" PRId64 ": %s",
956 3fba9d81 Stefan Hajnoczi
                                 bs_num, strerror(-ret));
957 c2abccec MORITA Kazutaka
                    goto out;
958 c2abccec MORITA Kazutaka
                }
959 926c2d23 balrog
960 926c2d23 balrog
                buf2 += nlow * 512;
961 926c2d23 balrog
                bs_num += nlow;
962 926c2d23 balrog
963 926c2d23 balrog
                remainder -= nlow;
964 926c2d23 balrog
            }
965 926c2d23 balrog
            assert (remainder == 0);
966 926c2d23 balrog
967 b8fb60da Jes Sorensen
            if (n < cluster_sectors) {
968 ea2384d3 bellard
                memset(buf + n * 512, 0, cluster_size - n * 512);
969 b8fb60da Jes Sorensen
            }
970 1a6d39fd Stefan Hajnoczi
            if (!buffer_is_zero(buf, cluster_size)) {
971 c2abccec MORITA Kazutaka
                ret = bdrv_write_compressed(out_bs, sector_num, buf,
972 c2abccec MORITA Kazutaka
                                            cluster_sectors);
973 c2abccec MORITA Kazutaka
                if (ret != 0) {
974 3fba9d81 Stefan Hajnoczi
                    error_report("error while compressing sector %" PRId64
975 3fba9d81 Stefan Hajnoczi
                                 ": %s", sector_num, strerror(-ret));
976 c2abccec MORITA Kazutaka
                    goto out;
977 c2abccec MORITA Kazutaka
                }
978 ea2384d3 bellard
            }
979 ea2384d3 bellard
            sector_num += n;
980 6b837bc4 Jes Sorensen
            qemu_progress_print(local_progress, 100);
981 ea2384d3 bellard
        }
982 faea38e7 bellard
        /* signal EOF to align */
983 faea38e7 bellard
        bdrv_write_compressed(out_bs, 0, NULL, 0);
984 ea2384d3 bellard
    } else {
985 f2feebbd Kevin Wolf
        int has_zero_init = bdrv_has_zero_init(out_bs);
986 f2feebbd Kevin Wolf
987 f58c7b35 ths
        sector_num = 0; // total number of sectors converted so far
988 6b837bc4 Jes Sorensen
        nb_sectors = total_sectors - sector_num;
989 6b837bc4 Jes Sorensen
        local_progress = (float)100 /
990 4ee96418 Jes Sorensen
            (nb_sectors / MIN(nb_sectors, IO_BUF_SIZE / 512));
991 6b837bc4 Jes Sorensen
992 ea2384d3 bellard
        for(;;) {
993 ea2384d3 bellard
            nb_sectors = total_sectors - sector_num;
994 b8fb60da Jes Sorensen
            if (nb_sectors <= 0) {
995 ea2384d3 bellard
                break;
996 b8fb60da Jes Sorensen
            }
997 b8fb60da Jes Sorensen
            if (nb_sectors >= (IO_BUF_SIZE / 512)) {
998 ea2384d3 bellard
                n = (IO_BUF_SIZE / 512);
999 b8fb60da Jes Sorensen
            } else {
1000 ea2384d3 bellard
                n = nb_sectors;
1001 b8fb60da Jes Sorensen
            }
1002 926c2d23 balrog
1003 926c2d23 balrog
            while (sector_num - bs_offset >= bs_sectors) {
1004 926c2d23 balrog
                bs_i ++;
1005 926c2d23 balrog
                assert (bs_i < bs_n);
1006 926c2d23 balrog
                bs_offset += bs_sectors;
1007 926c2d23 balrog
                bdrv_get_geometry(bs[bs_i], &bs_sectors);
1008 0bfcd599 Blue Swirl
                /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "
1009 0bfcd599 Blue Swirl
                  "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",
1010 926c2d23 balrog
                   sector_num, bs_i, bs_offset, bs_sectors); */
1011 926c2d23 balrog
            }
1012 926c2d23 balrog
1013 b8fb60da Jes Sorensen
            if (n > bs_offset + bs_sectors - sector_num) {
1014 926c2d23 balrog
                n = bs_offset + bs_sectors - sector_num;
1015 b8fb60da Jes Sorensen
            }
1016 926c2d23 balrog
1017 f2feebbd Kevin Wolf
            if (has_zero_init) {
1018 d032044f Akkarit Sangpetch
                /* If the output image is being created as a copy on write image,
1019 d032044f Akkarit Sangpetch
                   assume that sectors which are unallocated in the input image
1020 d032044f Akkarit Sangpetch
                   are present in both the output's and input's base images (no
1021 d032044f Akkarit Sangpetch
                   need to copy them). */
1022 d032044f Akkarit Sangpetch
                if (out_baseimg) {
1023 d032044f Akkarit Sangpetch
                    if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
1024 d032044f Akkarit Sangpetch
                                           n, &n1)) {
1025 d032044f Akkarit Sangpetch
                        sector_num += n1;
1026 d032044f Akkarit Sangpetch
                        continue;
1027 d032044f Akkarit Sangpetch
                    }
1028 d032044f Akkarit Sangpetch
                    /* The next 'n1' sectors are allocated in the input image. Copy
1029 d032044f Akkarit Sangpetch
                       only those as they may be followed by unallocated sectors. */
1030 d032044f Akkarit Sangpetch
                    n = n1;
1031 93c65b47 aliguori
                }
1032 93c65b47 aliguori
            } else {
1033 93c65b47 aliguori
                n1 = n;
1034 f58c7b35 ths
            }
1035 f58c7b35 ths
1036 c2abccec MORITA Kazutaka
            ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
1037 c2abccec MORITA Kazutaka
            if (ret < 0) {
1038 3fba9d81 Stefan Hajnoczi
                error_report("error while reading sector %" PRId64 ": %s",
1039 3fba9d81 Stefan Hajnoczi
                             sector_num - bs_offset, strerror(-ret));
1040 c2abccec MORITA Kazutaka
                goto out;
1041 c2abccec MORITA Kazutaka
            }
1042 ea2384d3 bellard
            /* NOTE: at the same time we convert, we do not write zero
1043 ea2384d3 bellard
               sectors to have a chance to compress the image. Ideally, we
1044 ea2384d3 bellard
               should add a specific call to have the info to go faster */
1045 ea2384d3 bellard
            buf1 = buf;
1046 ea2384d3 bellard
            while (n > 0) {
1047 f58c7b35 ths
                /* If the output image is being created as a copy on write image,
1048 f58c7b35 ths
                   copy all sectors even the ones containing only NUL bytes,
1049 93c65b47 aliguori
                   because they may differ from the sectors in the base image.
1050 93c65b47 aliguori

1051 93c65b47 aliguori
                   If the output is to a host device, we also write out
1052 93c65b47 aliguori
                   sectors that are entirely 0, since whatever data was
1053 93c65b47 aliguori
                   already there is garbage, not 0s. */
1054 f2feebbd Kevin Wolf
                if (!has_zero_init || out_baseimg ||
1055 a22f123c Kevin Wolf
                    is_allocated_sectors_min(buf1, n, &n1, min_sparse)) {
1056 c2abccec MORITA Kazutaka
                    ret = bdrv_write(out_bs, sector_num, buf1, n1);
1057 c2abccec MORITA Kazutaka
                    if (ret < 0) {
1058 3fba9d81 Stefan Hajnoczi
                        error_report("error while writing sector %" PRId64
1059 3fba9d81 Stefan Hajnoczi
                                     ": %s", sector_num, strerror(-ret));
1060 c2abccec MORITA Kazutaka
                        goto out;
1061 c2abccec MORITA Kazutaka
                    }
1062 ea2384d3 bellard
                }
1063 ea2384d3 bellard
                sector_num += n1;
1064 ea2384d3 bellard
                n -= n1;
1065 ea2384d3 bellard
                buf1 += n1 * 512;
1066 ea2384d3 bellard
            }
1067 6b837bc4 Jes Sorensen
            qemu_progress_print(local_progress, 100);
1068 ea2384d3 bellard
        }
1069 ea2384d3 bellard
    }
1070 c2abccec MORITA Kazutaka
out:
1071 6b837bc4 Jes Sorensen
    qemu_progress_end();
1072 c2abccec MORITA Kazutaka
    free_option_parameters(create_options);
1073 c2abccec MORITA Kazutaka
    free_option_parameters(param);
1074 bb1c0597 Kevin Wolf
    qemu_vfree(buf);
1075 c2abccec MORITA Kazutaka
    if (out_bs) {
1076 c2abccec MORITA Kazutaka
        bdrv_delete(out_bs);
1077 c2abccec MORITA Kazutaka
    }
1078 31ca34b8 Jes Sorensen
    if (bs) {
1079 31ca34b8 Jes Sorensen
        for (bs_i = 0; bs_i < bs_n; bs_i++) {
1080 31ca34b8 Jes Sorensen
            if (bs[bs_i]) {
1081 31ca34b8 Jes Sorensen
                bdrv_delete(bs[bs_i]);
1082 31ca34b8 Jes Sorensen
            }
1083 c2abccec MORITA Kazutaka
        }
1084 7267c094 Anthony Liguori
        g_free(bs);
1085 c2abccec MORITA Kazutaka
    }
1086 c2abccec MORITA Kazutaka
    if (ret) {
1087 c2abccec MORITA Kazutaka
        return 1;
1088 c2abccec MORITA Kazutaka
    }
1089 ea2384d3 bellard
    return 0;
1090 ea2384d3 bellard
}
1091 ea2384d3 bellard
1092 57d1a2b6 bellard
1093 faea38e7 bellard
static void dump_snapshots(BlockDriverState *bs)
1094 faea38e7 bellard
{
1095 faea38e7 bellard
    QEMUSnapshotInfo *sn_tab, *sn;
1096 faea38e7 bellard
    int nb_sns, i;
1097 faea38e7 bellard
    char buf[256];
1098 faea38e7 bellard
1099 faea38e7 bellard
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1100 faea38e7 bellard
    if (nb_sns <= 0)
1101 faea38e7 bellard
        return;
1102 faea38e7 bellard
    printf("Snapshot list:\n");
1103 faea38e7 bellard
    printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
1104 faea38e7 bellard
    for(i = 0; i < nb_sns; i++) {
1105 faea38e7 bellard
        sn = &sn_tab[i];
1106 faea38e7 bellard
        printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
1107 faea38e7 bellard
    }
1108 7267c094 Anthony Liguori
    g_free(sn_tab);
1109 faea38e7 bellard
}
1110 faea38e7 bellard
1111 c054b3fd Benoît Canet
static void collect_snapshots(BlockDriverState *bs , ImageInfo *info)
1112 c054b3fd Benoît Canet
{
1113 c054b3fd Benoît Canet
    int i, sn_count;
1114 c054b3fd Benoît Canet
    QEMUSnapshotInfo *sn_tab = NULL;
1115 c054b3fd Benoît Canet
    SnapshotInfoList *info_list, *cur_item = NULL;
1116 c054b3fd Benoît Canet
    sn_count = bdrv_snapshot_list(bs, &sn_tab);
1117 c054b3fd Benoît Canet
1118 c054b3fd Benoît Canet
    for (i = 0; i < sn_count; i++) {
1119 c054b3fd Benoît Canet
        info->has_snapshots = true;
1120 c054b3fd Benoît Canet
        info_list = g_new0(SnapshotInfoList, 1);
1121 c054b3fd Benoît Canet
1122 c054b3fd Benoît Canet
        info_list->value                = g_new0(SnapshotInfo, 1);
1123 c054b3fd Benoît Canet
        info_list->value->id            = g_strdup(sn_tab[i].id_str);
1124 c054b3fd Benoît Canet
        info_list->value->name          = g_strdup(sn_tab[i].name);
1125 c054b3fd Benoît Canet
        info_list->value->vm_state_size = sn_tab[i].vm_state_size;
1126 c054b3fd Benoît Canet
        info_list->value->date_sec      = sn_tab[i].date_sec;
1127 c054b3fd Benoît Canet
        info_list->value->date_nsec     = sn_tab[i].date_nsec;
1128 c054b3fd Benoît Canet
        info_list->value->vm_clock_sec  = sn_tab[i].vm_clock_nsec / 1000000000;
1129 c054b3fd Benoît Canet
        info_list->value->vm_clock_nsec = sn_tab[i].vm_clock_nsec % 1000000000;
1130 c054b3fd Benoît Canet
1131 c054b3fd Benoît Canet
        /* XXX: waiting for the qapi to support qemu-queue.h types */
1132 c054b3fd Benoît Canet
        if (!cur_item) {
1133 c054b3fd Benoît Canet
            info->snapshots = cur_item = info_list;
1134 c054b3fd Benoît Canet
        } else {
1135 c054b3fd Benoît Canet
            cur_item->next = info_list;
1136 c054b3fd Benoît Canet
            cur_item = info_list;
1137 c054b3fd Benoît Canet
        }
1138 c054b3fd Benoît Canet
1139 c054b3fd Benoît Canet
    }
1140 c054b3fd Benoît Canet
1141 c054b3fd Benoît Canet
    g_free(sn_tab);
1142 c054b3fd Benoît Canet
}
1143 c054b3fd Benoît Canet
1144 c054b3fd Benoît Canet
static void dump_json_image_info(ImageInfo *info)
1145 c054b3fd Benoît Canet
{
1146 c054b3fd Benoît Canet
    Error *errp = NULL;
1147 c054b3fd Benoît Canet
    QString *str;
1148 c054b3fd Benoît Canet
    QmpOutputVisitor *ov = qmp_output_visitor_new();
1149 c054b3fd Benoît Canet
    QObject *obj;
1150 c054b3fd Benoît Canet
    visit_type_ImageInfo(qmp_output_get_visitor(ov),
1151 c054b3fd Benoît Canet
                         &info, NULL, &errp);
1152 c054b3fd Benoît Canet
    obj = qmp_output_get_qobject(ov);
1153 c054b3fd Benoît Canet
    str = qobject_to_json_pretty(obj);
1154 c054b3fd Benoît Canet
    assert(str != NULL);
1155 c054b3fd Benoît Canet
    printf("%s\n", qstring_get_str(str));
1156 c054b3fd Benoît Canet
    qobject_decref(obj);
1157 c054b3fd Benoît Canet
    qmp_output_visitor_cleanup(ov);
1158 c054b3fd Benoît Canet
    QDECREF(str);
1159 c054b3fd Benoît Canet
}
1160 c054b3fd Benoît Canet
1161 c054b3fd Benoît Canet
static void collect_image_info(BlockDriverState *bs,
1162 c054b3fd Benoît Canet
                   ImageInfo *info,
1163 c054b3fd Benoît Canet
                   const char *filename,
1164 c054b3fd Benoît Canet
                   const char *fmt)
1165 ea2384d3 bellard
{
1166 96b8f136 ths
    uint64_t total_sectors;
1167 93b6b2a3 bellard
    char backing_filename[1024];
1168 93b6b2a3 bellard
    char backing_filename2[1024];
1169 faea38e7 bellard
    BlockDriverInfo bdi;
1170 ea2384d3 bellard
1171 c054b3fd Benoît Canet
    bdrv_get_geometry(bs, &total_sectors);
1172 c054b3fd Benoît Canet
1173 c054b3fd Benoît Canet
    info->filename        = g_strdup(filename);
1174 c054b3fd Benoît Canet
    info->format          = g_strdup(bdrv_get_format_name(bs));
1175 c054b3fd Benoît Canet
    info->virtual_size    = total_sectors * 512;
1176 c054b3fd Benoît Canet
    info->actual_size     = bdrv_get_allocated_file_size(bs);
1177 c054b3fd Benoît Canet
    info->has_actual_size = info->actual_size >= 0;
1178 c054b3fd Benoît Canet
    if (bdrv_is_encrypted(bs)) {
1179 c054b3fd Benoît Canet
        info->encrypted = true;
1180 c054b3fd Benoît Canet
        info->has_encrypted = true;
1181 c054b3fd Benoît Canet
    }
1182 c054b3fd Benoît Canet
    if (bdrv_get_info(bs, &bdi) >= 0) {
1183 c054b3fd Benoît Canet
        if (bdi.cluster_size != 0) {
1184 c054b3fd Benoît Canet
            info->cluster_size = bdi.cluster_size;
1185 c054b3fd Benoît Canet
            info->has_cluster_size = true;
1186 c054b3fd Benoît Canet
        }
1187 c054b3fd Benoît Canet
        info->dirty_flag = bdi.is_dirty;
1188 c054b3fd Benoît Canet
        info->has_dirty_flag = true;
1189 c054b3fd Benoît Canet
    }
1190 c054b3fd Benoît Canet
    bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
1191 c054b3fd Benoît Canet
    if (backing_filename[0] != '\0') {
1192 c054b3fd Benoît Canet
        info->backing_filename = g_strdup(backing_filename);
1193 c054b3fd Benoît Canet
        info->has_backing_filename = true;
1194 c054b3fd Benoît Canet
        bdrv_get_full_backing_filename(bs, backing_filename2,
1195 c054b3fd Benoît Canet
                                       sizeof(backing_filename2));
1196 c054b3fd Benoît Canet
1197 c054b3fd Benoît Canet
        if (strcmp(backing_filename, backing_filename2) != 0) {
1198 c054b3fd Benoît Canet
            info->full_backing_filename =
1199 c054b3fd Benoît Canet
                        g_strdup(backing_filename2);
1200 c054b3fd Benoît Canet
            info->has_full_backing_filename = true;
1201 c054b3fd Benoît Canet
        }
1202 c054b3fd Benoît Canet
1203 c054b3fd Benoît Canet
        if (bs->backing_format[0]) {
1204 c054b3fd Benoît Canet
            info->backing_filename_format = g_strdup(bs->backing_format);
1205 c054b3fd Benoît Canet
            info->has_backing_filename_format = true;
1206 c054b3fd Benoît Canet
        }
1207 c054b3fd Benoît Canet
    }
1208 c054b3fd Benoît Canet
}
1209 c054b3fd Benoît Canet
1210 c054b3fd Benoît Canet
static void dump_human_image_info(ImageInfo *info)
1211 c054b3fd Benoît Canet
{
1212 c054b3fd Benoît Canet
    char size_buf[128], dsize_buf[128];
1213 c054b3fd Benoît Canet
    if (!info->has_actual_size) {
1214 c054b3fd Benoît Canet
        snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
1215 c054b3fd Benoît Canet
    } else {
1216 c054b3fd Benoît Canet
        get_human_readable_size(dsize_buf, sizeof(dsize_buf),
1217 c054b3fd Benoît Canet
                                info->actual_size);
1218 c054b3fd Benoît Canet
    }
1219 c054b3fd Benoît Canet
    get_human_readable_size(size_buf, sizeof(size_buf), info->virtual_size);
1220 c054b3fd Benoît Canet
    printf("image: %s\n"
1221 c054b3fd Benoît Canet
           "file format: %s\n"
1222 c054b3fd Benoît Canet
           "virtual size: %s (%" PRId64 " bytes)\n"
1223 c054b3fd Benoît Canet
           "disk size: %s\n",
1224 c054b3fd Benoît Canet
           info->filename, info->format, size_buf,
1225 c054b3fd Benoît Canet
           info->virtual_size,
1226 c054b3fd Benoît Canet
           dsize_buf);
1227 c054b3fd Benoît Canet
1228 c054b3fd Benoît Canet
    if (info->has_encrypted && info->encrypted) {
1229 c054b3fd Benoît Canet
        printf("encrypted: yes\n");
1230 c054b3fd Benoît Canet
    }
1231 c054b3fd Benoît Canet
1232 c054b3fd Benoît Canet
    if (info->has_cluster_size) {
1233 c054b3fd Benoît Canet
        printf("cluster_size: %" PRId64 "\n", info->cluster_size);
1234 c054b3fd Benoît Canet
    }
1235 c054b3fd Benoît Canet
1236 c054b3fd Benoît Canet
    if (info->has_dirty_flag && info->dirty_flag) {
1237 c054b3fd Benoît Canet
        printf("cleanly shut down: no\n");
1238 c054b3fd Benoît Canet
    }
1239 c054b3fd Benoît Canet
1240 c054b3fd Benoît Canet
    if (info->has_backing_filename) {
1241 c054b3fd Benoît Canet
        printf("backing file: %s", info->backing_filename);
1242 c054b3fd Benoît Canet
        if (info->has_full_backing_filename) {
1243 c054b3fd Benoît Canet
            printf(" (actual path: %s)", info->full_backing_filename);
1244 c054b3fd Benoît Canet
        }
1245 c054b3fd Benoît Canet
        putchar('\n');
1246 c054b3fd Benoît Canet
        if (info->has_backing_filename_format) {
1247 c054b3fd Benoît Canet
            printf("backing file format: %s\n", info->backing_filename_format);
1248 c054b3fd Benoît Canet
        }
1249 c054b3fd Benoît Canet
    }
1250 c054b3fd Benoît Canet
}
1251 c054b3fd Benoît Canet
1252 c054b3fd Benoît Canet
enum {OPTION_OUTPUT = 256};
1253 c054b3fd Benoît Canet
1254 c054b3fd Benoît Canet
typedef enum OutputFormat {
1255 c054b3fd Benoît Canet
    OFORMAT_JSON,
1256 c054b3fd Benoît Canet
    OFORMAT_HUMAN,
1257 c054b3fd Benoît Canet
} OutputFormat;
1258 c054b3fd Benoît Canet
1259 c054b3fd Benoît Canet
static int img_info(int argc, char **argv)
1260 c054b3fd Benoît Canet
{
1261 c054b3fd Benoît Canet
    int c;
1262 c054b3fd Benoît Canet
    OutputFormat output_format = OFORMAT_HUMAN;
1263 c054b3fd Benoît Canet
    const char *filename, *fmt, *output;
1264 c054b3fd Benoît Canet
    BlockDriverState *bs;
1265 c054b3fd Benoît Canet
    ImageInfo *info;
1266 c054b3fd Benoît Canet
1267 ea2384d3 bellard
    fmt = NULL;
1268 c054b3fd Benoît Canet
    output = NULL;
1269 ea2384d3 bellard
    for(;;) {
1270 c054b3fd Benoît Canet
        int option_index = 0;
1271 c054b3fd Benoît Canet
        static const struct option long_options[] = {
1272 c054b3fd Benoît Canet
            {"help", no_argument, 0, 'h'},
1273 c054b3fd Benoît Canet
            {"format", required_argument, 0, 'f'},
1274 c054b3fd Benoît Canet
            {"output", required_argument, 0, OPTION_OUTPUT},
1275 c054b3fd Benoît Canet
            {0, 0, 0, 0}
1276 c054b3fd Benoît Canet
        };
1277 c054b3fd Benoît Canet
        c = getopt_long(argc, argv, "f:h",
1278 c054b3fd Benoît Canet
                        long_options, &option_index);
1279 b8fb60da Jes Sorensen
        if (c == -1) {
1280 ea2384d3 bellard
            break;
1281 b8fb60da Jes Sorensen
        }
1282 ea2384d3 bellard
        switch(c) {
1283 ef87394c Jes Sorensen
        case '?':
1284 ea2384d3 bellard
        case 'h':
1285 ea2384d3 bellard
            help();
1286 ea2384d3 bellard
            break;
1287 ea2384d3 bellard
        case 'f':
1288 ea2384d3 bellard
            fmt = optarg;
1289 ea2384d3 bellard
            break;
1290 c054b3fd Benoît Canet
        case OPTION_OUTPUT:
1291 c054b3fd Benoît Canet
            output = optarg;
1292 c054b3fd Benoît Canet
            break;
1293 ea2384d3 bellard
        }
1294 ea2384d3 bellard
    }
1295 b8fb60da Jes Sorensen
    if (optind >= argc) {
1296 ea2384d3 bellard
        help();
1297 b8fb60da Jes Sorensen
    }
1298 ea2384d3 bellard
    filename = argv[optind++];
1299 ea2384d3 bellard
1300 c054b3fd Benoît Canet
    if (output && !strcmp(output, "json")) {
1301 c054b3fd Benoît Canet
        output_format = OFORMAT_JSON;
1302 c054b3fd Benoît Canet
    } else if (output && !strcmp(output, "human")) {
1303 c054b3fd Benoît Canet
        output_format = OFORMAT_HUMAN;
1304 c054b3fd Benoît Canet
    } else if (output) {
1305 c054b3fd Benoît Canet
        error_report("--output must be used with human or json as argument.");
1306 c2abccec MORITA Kazutaka
        return 1;
1307 c2abccec MORITA Kazutaka
    }
1308 c054b3fd Benoît Canet
1309 f0536bb8 Daniel P. Berrange
    bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING, false);
1310 c2abccec MORITA Kazutaka
    if (!bs) {
1311 c2abccec MORITA Kazutaka
        return 1;
1312 faea38e7 bellard
    }
1313 c054b3fd Benoît Canet
1314 c054b3fd Benoît Canet
    info = g_new0(ImageInfo, 1);
1315 c054b3fd Benoît Canet
    collect_image_info(bs, info, filename, fmt);
1316 c054b3fd Benoît Canet
1317 c054b3fd Benoît Canet
    switch (output_format) {
1318 c054b3fd Benoît Canet
    case OFORMAT_HUMAN:
1319 c054b3fd Benoît Canet
        dump_human_image_info(info);
1320 c054b3fd Benoît Canet
        dump_snapshots(bs);
1321 c054b3fd Benoît Canet
        break;
1322 c054b3fd Benoît Canet
    case OFORMAT_JSON:
1323 c054b3fd Benoît Canet
        collect_snapshots(bs, info);
1324 c054b3fd Benoît Canet
        dump_json_image_info(info);
1325 c054b3fd Benoît Canet
        break;
1326 faea38e7 bellard
    }
1327 c054b3fd Benoît Canet
1328 c054b3fd Benoît Canet
    qapi_free_ImageInfo(info);
1329 ea2384d3 bellard
    bdrv_delete(bs);
1330 ea2384d3 bellard
    return 0;
1331 ea2384d3 bellard
}
1332 ea2384d3 bellard
1333 f7b4a940 aliguori
#define SNAPSHOT_LIST   1
1334 f7b4a940 aliguori
#define SNAPSHOT_CREATE 2
1335 f7b4a940 aliguori
#define SNAPSHOT_APPLY  3
1336 f7b4a940 aliguori
#define SNAPSHOT_DELETE 4
1337 f7b4a940 aliguori
1338 153859be Stuart Brady
static int img_snapshot(int argc, char **argv)
1339 f7b4a940 aliguori
{
1340 f7b4a940 aliguori
    BlockDriverState *bs;
1341 f7b4a940 aliguori
    QEMUSnapshotInfo sn;
1342 f7b4a940 aliguori
    char *filename, *snapshot_name = NULL;
1343 c2abccec MORITA Kazutaka
    int c, ret = 0, bdrv_oflags;
1344 f7b4a940 aliguori
    int action = 0;
1345 f7b4a940 aliguori
    qemu_timeval tv;
1346 f7b4a940 aliguori
1347 710da702 Kevin Wolf
    bdrv_oflags = BDRV_O_FLAGS | BDRV_O_RDWR;
1348 f7b4a940 aliguori
    /* Parse commandline parameters */
1349 f7b4a940 aliguori
    for(;;) {
1350 f7b4a940 aliguori
        c = getopt(argc, argv, "la:c:d:h");
1351 b8fb60da Jes Sorensen
        if (c == -1) {
1352 f7b4a940 aliguori
            break;
1353 b8fb60da Jes Sorensen
        }
1354 f7b4a940 aliguori
        switch(c) {
1355 ef87394c Jes Sorensen
        case '?':
1356 f7b4a940 aliguori
        case 'h':
1357 f7b4a940 aliguori
            help();
1358 153859be Stuart Brady
            return 0;
1359 f7b4a940 aliguori
        case 'l':
1360 f7b4a940 aliguori
            if (action) {
1361 f7b4a940 aliguori
                help();
1362 153859be Stuart Brady
                return 0;
1363 f7b4a940 aliguori
            }
1364 f7b4a940 aliguori
            action = SNAPSHOT_LIST;
1365 f5edb014 Naphtali Sprei
            bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
1366 f7b4a940 aliguori
            break;
1367 f7b4a940 aliguori
        case 'a':
1368 f7b4a940 aliguori
            if (action) {
1369 f7b4a940 aliguori
                help();
1370 153859be Stuart Brady
                return 0;
1371 f7b4a940 aliguori
            }
1372 f7b4a940 aliguori
            action = SNAPSHOT_APPLY;
1373 f7b4a940 aliguori
            snapshot_name = optarg;
1374 f7b4a940 aliguori
            break;
1375 f7b4a940 aliguori
        case 'c':
1376 f7b4a940 aliguori
            if (action) {
1377 f7b4a940 aliguori
                help();
1378 153859be Stuart Brady
                return 0;
1379 f7b4a940 aliguori
            }
1380 f7b4a940 aliguori
            action = SNAPSHOT_CREATE;
1381 f7b4a940 aliguori
            snapshot_name = optarg;
1382 f7b4a940 aliguori
            break;
1383 f7b4a940 aliguori
        case 'd':
1384 f7b4a940 aliguori
            if (action) {
1385 f7b4a940 aliguori
                help();
1386 153859be Stuart Brady
                return 0;
1387 f7b4a940 aliguori
            }
1388 f7b4a940 aliguori
            action = SNAPSHOT_DELETE;
1389 f7b4a940 aliguori
            snapshot_name = optarg;
1390 f7b4a940 aliguori
            break;
1391 f7b4a940 aliguori
        }
1392 f7b4a940 aliguori
    }
1393 f7b4a940 aliguori
1394 b8fb60da Jes Sorensen
    if (optind >= argc) {
1395 f7b4a940 aliguori
        help();
1396 b8fb60da Jes Sorensen
    }
1397 f7b4a940 aliguori
    filename = argv[optind++];
1398 f7b4a940 aliguori
1399 f7b4a940 aliguori
    /* Open the image */
1400 f0536bb8 Daniel P. Berrange
    bs = bdrv_new_open(filename, NULL, bdrv_oflags, true);
1401 c2abccec MORITA Kazutaka
    if (!bs) {
1402 c2abccec MORITA Kazutaka
        return 1;
1403 c2abccec MORITA Kazutaka
    }
1404 f7b4a940 aliguori
1405 f7b4a940 aliguori
    /* Perform the requested action */
1406 f7b4a940 aliguori
    switch(action) {
1407 f7b4a940 aliguori
    case SNAPSHOT_LIST:
1408 f7b4a940 aliguori
        dump_snapshots(bs);
1409 f7b4a940 aliguori
        break;
1410 f7b4a940 aliguori
1411 f7b4a940 aliguori
    case SNAPSHOT_CREATE:
1412 f7b4a940 aliguori
        memset(&sn, 0, sizeof(sn));
1413 f7b4a940 aliguori
        pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
1414 f7b4a940 aliguori
1415 f7b4a940 aliguori
        qemu_gettimeofday(&tv);
1416 f7b4a940 aliguori
        sn.date_sec = tv.tv_sec;
1417 f7b4a940 aliguori
        sn.date_nsec = tv.tv_usec * 1000;
1418 f7b4a940 aliguori
1419 f7b4a940 aliguori
        ret = bdrv_snapshot_create(bs, &sn);
1420 b8fb60da Jes Sorensen
        if (ret) {
1421 15654a6d Jes Sorensen
            error_report("Could not create snapshot '%s': %d (%s)",
1422 f7b4a940 aliguori
                snapshot_name, ret, strerror(-ret));
1423 b8fb60da Jes Sorensen
        }
1424 f7b4a940 aliguori
        break;
1425 f7b4a940 aliguori
1426 f7b4a940 aliguori
    case SNAPSHOT_APPLY:
1427 f7b4a940 aliguori
        ret = bdrv_snapshot_goto(bs, snapshot_name);
1428 b8fb60da Jes Sorensen
        if (ret) {
1429 15654a6d Jes Sorensen
            error_report("Could not apply snapshot '%s': %d (%s)",
1430 f7b4a940 aliguori
                snapshot_name, ret, strerror(-ret));
1431 b8fb60da Jes Sorensen
        }
1432 f7b4a940 aliguori
        break;
1433 f7b4a940 aliguori
1434 f7b4a940 aliguori
    case SNAPSHOT_DELETE:
1435 f7b4a940 aliguori
        ret = bdrv_snapshot_delete(bs, snapshot_name);
1436 b8fb60da Jes Sorensen
        if (ret) {
1437 15654a6d Jes Sorensen
            error_report("Could not delete snapshot '%s': %d (%s)",
1438 f7b4a940 aliguori
                snapshot_name, ret, strerror(-ret));
1439 b8fb60da Jes Sorensen
        }
1440 f7b4a940 aliguori
        break;
1441 f7b4a940 aliguori
    }
1442 f7b4a940 aliguori
1443 f7b4a940 aliguori
    /* Cleanup */
1444 f7b4a940 aliguori
    bdrv_delete(bs);
1445 c2abccec MORITA Kazutaka
    if (ret) {
1446 c2abccec MORITA Kazutaka
        return 1;
1447 c2abccec MORITA Kazutaka
    }
1448 153859be Stuart Brady
    return 0;
1449 f7b4a940 aliguori
}
1450 f7b4a940 aliguori
1451 3e85c6fd Kevin Wolf
static int img_rebase(int argc, char **argv)
1452 3e85c6fd Kevin Wolf
{
1453 c2abccec MORITA Kazutaka
    BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
1454 f163d073 Stefan Hajnoczi
    BlockDriver *old_backing_drv, *new_backing_drv;
1455 3e85c6fd Kevin Wolf
    char *filename;
1456 661a0f71 Federico Simoncelli
    const char *fmt, *cache, *out_basefmt, *out_baseimg;
1457 3e85c6fd Kevin Wolf
    int c, flags, ret;
1458 3e85c6fd Kevin Wolf
    int unsafe = 0;
1459 6b837bc4 Jes Sorensen
    int progress = 0;
1460 3e85c6fd Kevin Wolf
1461 3e85c6fd Kevin Wolf
    /* Parse commandline parameters */
1462 e53dbee0 Kevin Wolf
    fmt = NULL;
1463 661a0f71 Federico Simoncelli
    cache = BDRV_DEFAULT_CACHE;
1464 3e85c6fd Kevin Wolf
    out_baseimg = NULL;
1465 3e85c6fd Kevin Wolf
    out_basefmt = NULL;
1466 3e85c6fd Kevin Wolf
    for(;;) {
1467 661a0f71 Federico Simoncelli
        c = getopt(argc, argv, "uhf:F:b:pt:");
1468 b8fb60da Jes Sorensen
        if (c == -1) {
1469 3e85c6fd Kevin Wolf
            break;
1470 b8fb60da Jes Sorensen
        }
1471 3e85c6fd Kevin Wolf
        switch(c) {
1472 ef87394c Jes Sorensen
        case '?':
1473 3e85c6fd Kevin Wolf
        case 'h':
1474 3e85c6fd Kevin Wolf
            help();
1475 3e85c6fd Kevin Wolf
            return 0;
1476 e53dbee0 Kevin Wolf
        case 'f':
1477 e53dbee0 Kevin Wolf
            fmt = optarg;
1478 e53dbee0 Kevin Wolf
            break;
1479 3e85c6fd Kevin Wolf
        case 'F':
1480 3e85c6fd Kevin Wolf
            out_basefmt = optarg;
1481 3e85c6fd Kevin Wolf
            break;
1482 3e85c6fd Kevin Wolf
        case 'b':
1483 3e85c6fd Kevin Wolf
            out_baseimg = optarg;
1484 3e85c6fd Kevin Wolf
            break;
1485 3e85c6fd Kevin Wolf
        case 'u':
1486 3e85c6fd Kevin Wolf
            unsafe = 1;
1487 3e85c6fd Kevin Wolf
            break;
1488 6b837bc4 Jes Sorensen
        case 'p':
1489 6b837bc4 Jes Sorensen
            progress = 1;
1490 6b837bc4 Jes Sorensen
            break;
1491 661a0f71 Federico Simoncelli
        case 't':
1492 661a0f71 Federico Simoncelli
            cache = optarg;
1493 661a0f71 Federico Simoncelli
            break;
1494 3e85c6fd Kevin Wolf
        }
1495 3e85c6fd Kevin Wolf
    }
1496 3e85c6fd Kevin Wolf
1497 9a9d9dba Anthony Liguori
    if ((optind >= argc) || (!unsafe && !out_baseimg)) {
1498 3e85c6fd Kevin Wolf
        help();
1499 b8fb60da Jes Sorensen
    }
1500 3e85c6fd Kevin Wolf
    filename = argv[optind++];
1501 3e85c6fd Kevin Wolf
1502 6b837bc4 Jes Sorensen
    qemu_progress_init(progress, 2.0);
1503 6b837bc4 Jes Sorensen
    qemu_progress_print(0, 100);
1504 6b837bc4 Jes Sorensen
1505 661a0f71 Federico Simoncelli
    flags = BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
1506 c3993cdc Stefan Hajnoczi
    ret = bdrv_parse_cache_flags(cache, &flags);
1507 661a0f71 Federico Simoncelli
    if (ret < 0) {
1508 661a0f71 Federico Simoncelli
        error_report("Invalid cache option: %s", cache);
1509 661a0f71 Federico Simoncelli
        return -1;
1510 661a0f71 Federico Simoncelli
    }
1511 661a0f71 Federico Simoncelli
1512 3e85c6fd Kevin Wolf
    /*
1513 3e85c6fd Kevin Wolf
     * Open the images.
1514 3e85c6fd Kevin Wolf
     *
1515 3e85c6fd Kevin Wolf
     * Ignore the old backing file for unsafe rebase in case we want to correct
1516 3e85c6fd Kevin Wolf
     * the reference to a renamed or moved backing file.
1517 3e85c6fd Kevin Wolf
     */
1518 f0536bb8 Daniel P. Berrange
    bs = bdrv_new_open(filename, fmt, flags, true);
1519 c2abccec MORITA Kazutaka
    if (!bs) {
1520 c2abccec MORITA Kazutaka
        return 1;
1521 c2abccec MORITA Kazutaka
    }
1522 3e85c6fd Kevin Wolf
1523 3e85c6fd Kevin Wolf
    /* Find the right drivers for the backing files */
1524 3e85c6fd Kevin Wolf
    old_backing_drv = NULL;
1525 3e85c6fd Kevin Wolf
    new_backing_drv = NULL;
1526 3e85c6fd Kevin Wolf
1527 3e85c6fd Kevin Wolf
    if (!unsafe && bs->backing_format[0] != '\0') {
1528 3e85c6fd Kevin Wolf
        old_backing_drv = bdrv_find_format(bs->backing_format);
1529 3e85c6fd Kevin Wolf
        if (old_backing_drv == NULL) {
1530 15654a6d Jes Sorensen
            error_report("Invalid format name: '%s'", bs->backing_format);
1531 c2abccec MORITA Kazutaka
            ret = -1;
1532 c2abccec MORITA Kazutaka
            goto out;
1533 3e85c6fd Kevin Wolf
        }
1534 3e85c6fd Kevin Wolf
    }
1535 3e85c6fd Kevin Wolf
1536 3e85c6fd Kevin Wolf
    if (out_basefmt != NULL) {
1537 3e85c6fd Kevin Wolf
        new_backing_drv = bdrv_find_format(out_basefmt);
1538 3e85c6fd Kevin Wolf
        if (new_backing_drv == NULL) {
1539 15654a6d Jes Sorensen
            error_report("Invalid format name: '%s'", out_basefmt);
1540 c2abccec MORITA Kazutaka
            ret = -1;
1541 c2abccec MORITA Kazutaka
            goto out;
1542 3e85c6fd Kevin Wolf
        }
1543 3e85c6fd Kevin Wolf
    }
1544 3e85c6fd Kevin Wolf
1545 3e85c6fd Kevin Wolf
    /* For safe rebasing we need to compare old and new backing file */
1546 3e85c6fd Kevin Wolf
    if (unsafe) {
1547 3e85c6fd Kevin Wolf
        /* Make the compiler happy */
1548 3e85c6fd Kevin Wolf
        bs_old_backing = NULL;
1549 3e85c6fd Kevin Wolf
        bs_new_backing = NULL;
1550 3e85c6fd Kevin Wolf
    } else {
1551 3e85c6fd Kevin Wolf
        char backing_name[1024];
1552 3e85c6fd Kevin Wolf
1553 3e85c6fd Kevin Wolf
        bs_old_backing = bdrv_new("old_backing");
1554 3e85c6fd Kevin Wolf
        bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
1555 c2abccec MORITA Kazutaka
        ret = bdrv_open(bs_old_backing, backing_name, BDRV_O_FLAGS,
1556 c2abccec MORITA Kazutaka
                        old_backing_drv);
1557 c2abccec MORITA Kazutaka
        if (ret) {
1558 15654a6d Jes Sorensen
            error_report("Could not open old backing file '%s'", backing_name);
1559 c2abccec MORITA Kazutaka
            goto out;
1560 3e85c6fd Kevin Wolf
        }
1561 3e85c6fd Kevin Wolf
1562 3e85c6fd Kevin Wolf
        bs_new_backing = bdrv_new("new_backing");
1563 cdbae851 Kevin Wolf
        ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS,
1564 c2abccec MORITA Kazutaka
                        new_backing_drv);
1565 c2abccec MORITA Kazutaka
        if (ret) {
1566 15654a6d Jes Sorensen
            error_report("Could not open new backing file '%s'", out_baseimg);
1567 c2abccec MORITA Kazutaka
            goto out;
1568 3e85c6fd Kevin Wolf
        }
1569 3e85c6fd Kevin Wolf
    }
1570 3e85c6fd Kevin Wolf
1571 3e85c6fd Kevin Wolf
    /*
1572 3e85c6fd Kevin Wolf
     * Check each unallocated cluster in the COW file. If it is unallocated,
1573 3e85c6fd Kevin Wolf
     * accesses go to the backing file. We must therefore compare this cluster
1574 3e85c6fd Kevin Wolf
     * in the old and new backing file, and if they differ we need to copy it
1575 3e85c6fd Kevin Wolf
     * from the old backing file into the COW file.
1576 3e85c6fd Kevin Wolf
     *
1577 3e85c6fd Kevin Wolf
     * If qemu-img crashes during this step, no harm is done. The content of
1578 3e85c6fd Kevin Wolf
     * the image is the same as the original one at any time.
1579 3e85c6fd Kevin Wolf
     */
1580 3e85c6fd Kevin Wolf
    if (!unsafe) {
1581 3e85c6fd Kevin Wolf
        uint64_t num_sectors;
1582 87a1b3e3 Kevin Wolf
        uint64_t old_backing_num_sectors;
1583 87a1b3e3 Kevin Wolf
        uint64_t new_backing_num_sectors;
1584 3e85c6fd Kevin Wolf
        uint64_t sector;
1585 cc60e327 Kevin Wolf
        int n;
1586 d6771bfa TeLeMan
        uint8_t * buf_old;
1587 d6771bfa TeLeMan
        uint8_t * buf_new;
1588 6b837bc4 Jes Sorensen
        float local_progress;
1589 d6771bfa TeLeMan
1590 bb1c0597 Kevin Wolf
        buf_old = qemu_blockalign(bs, IO_BUF_SIZE);
1591 bb1c0597 Kevin Wolf
        buf_new = qemu_blockalign(bs, IO_BUF_SIZE);
1592 3e85c6fd Kevin Wolf
1593 3e85c6fd Kevin Wolf
        bdrv_get_geometry(bs, &num_sectors);
1594 87a1b3e3 Kevin Wolf
        bdrv_get_geometry(bs_old_backing, &old_backing_num_sectors);
1595 87a1b3e3 Kevin Wolf
        bdrv_get_geometry(bs_new_backing, &new_backing_num_sectors);
1596 3e85c6fd Kevin Wolf
1597 6b837bc4 Jes Sorensen
        local_progress = (float)100 /
1598 4ee96418 Jes Sorensen
            (num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512));
1599 3e85c6fd Kevin Wolf
        for (sector = 0; sector < num_sectors; sector += n) {
1600 3e85c6fd Kevin Wolf
1601 3e85c6fd Kevin Wolf
            /* How many sectors can we handle with the next read? */
1602 3e85c6fd Kevin Wolf
            if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
1603 3e85c6fd Kevin Wolf
                n = (IO_BUF_SIZE / 512);
1604 3e85c6fd Kevin Wolf
            } else {
1605 3e85c6fd Kevin Wolf
                n = num_sectors - sector;
1606 3e85c6fd Kevin Wolf
            }
1607 3e85c6fd Kevin Wolf
1608 3e85c6fd Kevin Wolf
            /* If the cluster is allocated, we don't need to take action */
1609 cc60e327 Kevin Wolf
            ret = bdrv_is_allocated(bs, sector, n, &n);
1610 cc60e327 Kevin Wolf
            if (ret) {
1611 3e85c6fd Kevin Wolf
                continue;
1612 3e85c6fd Kevin Wolf
            }
1613 3e85c6fd Kevin Wolf
1614 87a1b3e3 Kevin Wolf
            /*
1615 87a1b3e3 Kevin Wolf
             * Read old and new backing file and take into consideration that
1616 87a1b3e3 Kevin Wolf
             * backing files may be smaller than the COW image.
1617 87a1b3e3 Kevin Wolf
             */
1618 87a1b3e3 Kevin Wolf
            if (sector >= old_backing_num_sectors) {
1619 87a1b3e3 Kevin Wolf
                memset(buf_old, 0, n * BDRV_SECTOR_SIZE);
1620 87a1b3e3 Kevin Wolf
            } else {
1621 87a1b3e3 Kevin Wolf
                if (sector + n > old_backing_num_sectors) {
1622 87a1b3e3 Kevin Wolf
                    n = old_backing_num_sectors - sector;
1623 87a1b3e3 Kevin Wolf
                }
1624 87a1b3e3 Kevin Wolf
1625 87a1b3e3 Kevin Wolf
                ret = bdrv_read(bs_old_backing, sector, buf_old, n);
1626 87a1b3e3 Kevin Wolf
                if (ret < 0) {
1627 87a1b3e3 Kevin Wolf
                    error_report("error while reading from old backing file");
1628 87a1b3e3 Kevin Wolf
                    goto out;
1629 87a1b3e3 Kevin Wolf
                }
1630 3e85c6fd Kevin Wolf
            }
1631 87a1b3e3 Kevin Wolf
1632 87a1b3e3 Kevin Wolf
            if (sector >= new_backing_num_sectors) {
1633 87a1b3e3 Kevin Wolf
                memset(buf_new, 0, n * BDRV_SECTOR_SIZE);
1634 87a1b3e3 Kevin Wolf
            } else {
1635 87a1b3e3 Kevin Wolf
                if (sector + n > new_backing_num_sectors) {
1636 87a1b3e3 Kevin Wolf
                    n = new_backing_num_sectors - sector;
1637 87a1b3e3 Kevin Wolf
                }
1638 87a1b3e3 Kevin Wolf
1639 87a1b3e3 Kevin Wolf
                ret = bdrv_read(bs_new_backing, sector, buf_new, n);
1640 87a1b3e3 Kevin Wolf
                if (ret < 0) {
1641 87a1b3e3 Kevin Wolf
                    error_report("error while reading from new backing file");
1642 87a1b3e3 Kevin Wolf
                    goto out;
1643 87a1b3e3 Kevin Wolf
                }
1644 3e85c6fd Kevin Wolf
            }
1645 3e85c6fd Kevin Wolf
1646 3e85c6fd Kevin Wolf
            /* If they differ, we need to write to the COW file */
1647 3e85c6fd Kevin Wolf
            uint64_t written = 0;
1648 3e85c6fd Kevin Wolf
1649 3e85c6fd Kevin Wolf
            while (written < n) {
1650 3e85c6fd Kevin Wolf
                int pnum;
1651 3e85c6fd Kevin Wolf
1652 3e85c6fd Kevin Wolf
                if (compare_sectors(buf_old + written * 512,
1653 60b1bd4f Kevin Wolf
                    buf_new + written * 512, n - written, &pnum))
1654 3e85c6fd Kevin Wolf
                {
1655 3e85c6fd Kevin Wolf
                    ret = bdrv_write(bs, sector + written,
1656 3e85c6fd Kevin Wolf
                        buf_old + written * 512, pnum);
1657 3e85c6fd Kevin Wolf
                    if (ret < 0) {
1658 15654a6d Jes Sorensen
                        error_report("Error while writing to COW image: %s",
1659 3e85c6fd Kevin Wolf
                            strerror(-ret));
1660 c2abccec MORITA Kazutaka
                        goto out;
1661 3e85c6fd Kevin Wolf
                    }
1662 3e85c6fd Kevin Wolf
                }
1663 3e85c6fd Kevin Wolf
1664 3e85c6fd Kevin Wolf
                written += pnum;
1665 3e85c6fd Kevin Wolf
            }
1666 6b837bc4 Jes Sorensen
            qemu_progress_print(local_progress, 100);
1667 3e85c6fd Kevin Wolf
        }
1668 d6771bfa TeLeMan
1669 bb1c0597 Kevin Wolf
        qemu_vfree(buf_old);
1670 bb1c0597 Kevin Wolf
        qemu_vfree(buf_new);
1671 3e85c6fd Kevin Wolf
    }
1672 3e85c6fd Kevin Wolf
1673 3e85c6fd Kevin Wolf
    /*
1674 3e85c6fd Kevin Wolf
     * Change the backing file. All clusters that are different from the old
1675 3e85c6fd Kevin Wolf
     * backing file are overwritten in the COW file now, so the visible content
1676 3e85c6fd Kevin Wolf
     * doesn't change when we switch the backing file.
1677 3e85c6fd Kevin Wolf
     */
1678 3e85c6fd Kevin Wolf
    ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
1679 3e85c6fd Kevin Wolf
    if (ret == -ENOSPC) {
1680 15654a6d Jes Sorensen
        error_report("Could not change the backing file to '%s': No "
1681 15654a6d Jes Sorensen
                     "space left in the file header", out_baseimg);
1682 3e85c6fd Kevin Wolf
    } else if (ret < 0) {
1683 15654a6d Jes Sorensen
        error_report("Could not change the backing file to '%s': %s",
1684 3e85c6fd Kevin Wolf
            out_baseimg, strerror(-ret));
1685 3e85c6fd Kevin Wolf
    }
1686 3e85c6fd Kevin Wolf
1687 6b837bc4 Jes Sorensen
    qemu_progress_print(100, 0);
1688 3e85c6fd Kevin Wolf
    /*
1689 3e85c6fd Kevin Wolf
     * TODO At this point it is possible to check if any clusters that are
1690 3e85c6fd Kevin Wolf
     * allocated in the COW file are the same in the backing file. If so, they
1691 3e85c6fd Kevin Wolf
     * could be dropped from the COW file. Don't do this before switching the
1692 3e85c6fd Kevin Wolf
     * backing file, in case of a crash this would lead to corruption.
1693 3e85c6fd Kevin Wolf
     */
1694 c2abccec MORITA Kazutaka
out:
1695 6b837bc4 Jes Sorensen
    qemu_progress_end();
1696 3e85c6fd Kevin Wolf
    /* Cleanup */
1697 3e85c6fd Kevin Wolf
    if (!unsafe) {
1698 eb863add Kevin Wolf
        if (bs_old_backing != NULL) {
1699 eb863add Kevin Wolf
            bdrv_delete(bs_old_backing);
1700 eb863add Kevin Wolf
        }
1701 eb863add Kevin Wolf
        if (bs_new_backing != NULL) {
1702 eb863add Kevin Wolf
            bdrv_delete(bs_new_backing);
1703 eb863add Kevin Wolf
        }
1704 3e85c6fd Kevin Wolf
    }
1705 3e85c6fd Kevin Wolf
1706 3e85c6fd Kevin Wolf
    bdrv_delete(bs);
1707 c2abccec MORITA Kazutaka
    if (ret) {
1708 c2abccec MORITA Kazutaka
        return 1;
1709 c2abccec MORITA Kazutaka
    }
1710 3e85c6fd Kevin Wolf
    return 0;
1711 3e85c6fd Kevin Wolf
}
1712 3e85c6fd Kevin Wolf
1713 ae6b0ed6 Stefan Hajnoczi
static int img_resize(int argc, char **argv)
1714 ae6b0ed6 Stefan Hajnoczi
{
1715 ae6b0ed6 Stefan Hajnoczi
    int c, ret, relative;
1716 ae6b0ed6 Stefan Hajnoczi
    const char *filename, *fmt, *size;
1717 ae6b0ed6 Stefan Hajnoczi
    int64_t n, total_size;
1718 2a81998a Jes Sorensen
    BlockDriverState *bs = NULL;
1719 20caf0f7 Dong Xu Wang
    QemuOpts *param;
1720 20caf0f7 Dong Xu Wang
    static QemuOptsList resize_options = {
1721 20caf0f7 Dong Xu Wang
        .name = "resize_options",
1722 20caf0f7 Dong Xu Wang
        .head = QTAILQ_HEAD_INITIALIZER(resize_options.head),
1723 20caf0f7 Dong Xu Wang
        .desc = {
1724 20caf0f7 Dong Xu Wang
            {
1725 20caf0f7 Dong Xu Wang
                .name = BLOCK_OPT_SIZE,
1726 20caf0f7 Dong Xu Wang
                .type = QEMU_OPT_SIZE,
1727 20caf0f7 Dong Xu Wang
                .help = "Virtual disk size"
1728 20caf0f7 Dong Xu Wang
            }, {
1729 20caf0f7 Dong Xu Wang
                /* end of list */
1730 20caf0f7 Dong Xu Wang
            }
1731 ae6b0ed6 Stefan Hajnoczi
        },
1732 ae6b0ed6 Stefan Hajnoczi
    };
1733 ae6b0ed6 Stefan Hajnoczi
1734 e80fec7f Kevin Wolf
    /* Remove size from argv manually so that negative numbers are not treated
1735 e80fec7f Kevin Wolf
     * as options by getopt. */
1736 e80fec7f Kevin Wolf
    if (argc < 3) {
1737 e80fec7f Kevin Wolf
        help();
1738 e80fec7f Kevin Wolf
        return 1;
1739 e80fec7f Kevin Wolf
    }
1740 e80fec7f Kevin Wolf
1741 e80fec7f Kevin Wolf
    size = argv[--argc];
1742 e80fec7f Kevin Wolf
1743 e80fec7f Kevin Wolf
    /* Parse getopt arguments */
1744 ae6b0ed6 Stefan Hajnoczi
    fmt = NULL;
1745 ae6b0ed6 Stefan Hajnoczi
    for(;;) {
1746 ae6b0ed6 Stefan Hajnoczi
        c = getopt(argc, argv, "f:h");
1747 ae6b0ed6 Stefan Hajnoczi
        if (c == -1) {
1748 ae6b0ed6 Stefan Hajnoczi
            break;
1749 ae6b0ed6 Stefan Hajnoczi
        }
1750 ae6b0ed6 Stefan Hajnoczi
        switch(c) {
1751 ef87394c Jes Sorensen
        case '?':
1752 ae6b0ed6 Stefan Hajnoczi
        case 'h':
1753 ae6b0ed6 Stefan Hajnoczi
            help();
1754 ae6b0ed6 Stefan Hajnoczi
            break;
1755 ae6b0ed6 Stefan Hajnoczi
        case 'f':
1756 ae6b0ed6 Stefan Hajnoczi
            fmt = optarg;
1757 ae6b0ed6 Stefan Hajnoczi
            break;
1758 ae6b0ed6 Stefan Hajnoczi
        }
1759 ae6b0ed6 Stefan Hajnoczi
    }
1760 e80fec7f Kevin Wolf
    if (optind >= argc) {
1761 ae6b0ed6 Stefan Hajnoczi
        help();
1762 ae6b0ed6 Stefan Hajnoczi
    }
1763 ae6b0ed6 Stefan Hajnoczi
    filename = argv[optind++];
1764 ae6b0ed6 Stefan Hajnoczi
1765 ae6b0ed6 Stefan Hajnoczi
    /* Choose grow, shrink, or absolute resize mode */
1766 ae6b0ed6 Stefan Hajnoczi
    switch (size[0]) {
1767 ae6b0ed6 Stefan Hajnoczi
    case '+':
1768 ae6b0ed6 Stefan Hajnoczi
        relative = 1;
1769 ae6b0ed6 Stefan Hajnoczi
        size++;
1770 ae6b0ed6 Stefan Hajnoczi
        break;
1771 ae6b0ed6 Stefan Hajnoczi
    case '-':
1772 ae6b0ed6 Stefan Hajnoczi
        relative = -1;
1773 ae6b0ed6 Stefan Hajnoczi
        size++;
1774 ae6b0ed6 Stefan Hajnoczi
        break;
1775 ae6b0ed6 Stefan Hajnoczi
    default:
1776 ae6b0ed6 Stefan Hajnoczi
        relative = 0;
1777 ae6b0ed6 Stefan Hajnoczi
        break;
1778 ae6b0ed6 Stefan Hajnoczi
    }
1779 ae6b0ed6 Stefan Hajnoczi
1780 ae6b0ed6 Stefan Hajnoczi
    /* Parse size */
1781 20caf0f7 Dong Xu Wang
    param = qemu_opts_create(&resize_options, NULL, 0, NULL);
1782 20caf0f7 Dong Xu Wang
    if (qemu_opt_set(param, BLOCK_OPT_SIZE, size)) {
1783 ae6b0ed6 Stefan Hajnoczi
        /* Error message already printed when size parsing fails */
1784 2a81998a Jes Sorensen
        ret = -1;
1785 20caf0f7 Dong Xu Wang
        qemu_opts_del(param);
1786 2a81998a Jes Sorensen
        goto out;
1787 ae6b0ed6 Stefan Hajnoczi
    }
1788 20caf0f7 Dong Xu Wang
    n = qemu_opt_get_size(param, BLOCK_OPT_SIZE, 0);
1789 20caf0f7 Dong Xu Wang
    qemu_opts_del(param);
1790 ae6b0ed6 Stefan Hajnoczi
1791 f0536bb8 Daniel P. Berrange
    bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR, true);
1792 c2abccec MORITA Kazutaka
    if (!bs) {
1793 2a81998a Jes Sorensen
        ret = -1;
1794 2a81998a Jes Sorensen
        goto out;
1795 c2abccec MORITA Kazutaka
    }
1796 ae6b0ed6 Stefan Hajnoczi
1797 ae6b0ed6 Stefan Hajnoczi
    if (relative) {
1798 ae6b0ed6 Stefan Hajnoczi
        total_size = bdrv_getlength(bs) + n * relative;
1799 ae6b0ed6 Stefan Hajnoczi
    } else {
1800 ae6b0ed6 Stefan Hajnoczi
        total_size = n;
1801 ae6b0ed6 Stefan Hajnoczi
    }
1802 ae6b0ed6 Stefan Hajnoczi
    if (total_size <= 0) {
1803 15654a6d Jes Sorensen
        error_report("New image size must be positive");
1804 c2abccec MORITA Kazutaka
        ret = -1;
1805 c2abccec MORITA Kazutaka
        goto out;
1806 ae6b0ed6 Stefan Hajnoczi
    }
1807 ae6b0ed6 Stefan Hajnoczi
1808 ae6b0ed6 Stefan Hajnoczi
    ret = bdrv_truncate(bs, total_size);
1809 ae6b0ed6 Stefan Hajnoczi
    switch (ret) {
1810 ae6b0ed6 Stefan Hajnoczi
    case 0:
1811 ae6b0ed6 Stefan Hajnoczi
        printf("Image resized.\n");
1812 ae6b0ed6 Stefan Hajnoczi
        break;
1813 ae6b0ed6 Stefan Hajnoczi
    case -ENOTSUP:
1814 259b2173 Kevin Wolf
        error_report("This image does not support resize");
1815 ae6b0ed6 Stefan Hajnoczi
        break;
1816 ae6b0ed6 Stefan Hajnoczi
    case -EACCES:
1817 15654a6d Jes Sorensen
        error_report("Image is read-only");
1818 ae6b0ed6 Stefan Hajnoczi
        break;
1819 ae6b0ed6 Stefan Hajnoczi
    default:
1820 15654a6d Jes Sorensen
        error_report("Error resizing image (%d)", -ret);
1821 ae6b0ed6 Stefan Hajnoczi
        break;
1822 ae6b0ed6 Stefan Hajnoczi
    }
1823 c2abccec MORITA Kazutaka
out:
1824 2a81998a Jes Sorensen
    if (bs) {
1825 2a81998a Jes Sorensen
        bdrv_delete(bs);
1826 2a81998a Jes Sorensen
    }
1827 c2abccec MORITA Kazutaka
    if (ret) {
1828 c2abccec MORITA Kazutaka
        return 1;
1829 c2abccec MORITA Kazutaka
    }
1830 ae6b0ed6 Stefan Hajnoczi
    return 0;
1831 ae6b0ed6 Stefan Hajnoczi
}
1832 ae6b0ed6 Stefan Hajnoczi
1833 c227f099 Anthony Liguori
static const img_cmd_t img_cmds[] = {
1834 153859be Stuart Brady
#define DEF(option, callback, arg_string)        \
1835 153859be Stuart Brady
    { option, callback },
1836 153859be Stuart Brady
#include "qemu-img-cmds.h"
1837 153859be Stuart Brady
#undef DEF
1838 153859be Stuart Brady
#undef GEN_DOCS
1839 153859be Stuart Brady
    { NULL, NULL, },
1840 153859be Stuart Brady
};
1841 153859be Stuart Brady
1842 ea2384d3 bellard
int main(int argc, char **argv)
1843 ea2384d3 bellard
{
1844 c227f099 Anthony Liguori
    const img_cmd_t *cmd;
1845 153859be Stuart Brady
    const char *cmdname;
1846 ea2384d3 bellard
1847 53f76e58 Kevin Wolf
    error_set_progname(argv[0]);
1848 53f76e58 Kevin Wolf
1849 ea2384d3 bellard
    bdrv_init();
1850 ea2384d3 bellard
    if (argc < 2)
1851 ea2384d3 bellard
        help();
1852 153859be Stuart Brady
    cmdname = argv[1];
1853 8f9b157e aurel32
    argc--; argv++;
1854 153859be Stuart Brady
1855 67d384e8 Zhi Yong Wu
    qemu_init_main_loop();
1856 67d384e8 Zhi Yong Wu
1857 153859be Stuart Brady
    /* find the command */
1858 153859be Stuart Brady
    for(cmd = img_cmds; cmd->name != NULL; cmd++) {
1859 153859be Stuart Brady
        if (!strcmp(cmdname, cmd->name)) {
1860 153859be Stuart Brady
            return cmd->handler(argc, argv);
1861 153859be Stuart Brady
        }
1862 ea2384d3 bellard
    }
1863 153859be Stuart Brady
1864 153859be Stuart Brady
    /* not found */
1865 153859be Stuart Brady
    help();
1866 ea2384d3 bellard
    return 0;
1867 ea2384d3 bellard
}