Statistics
| Branch: | Revision:

root / qemu-img.c @ a22971f9

History | View | Annotate | Download (71.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 7b1b5d19 Paolo Bonzini
#include "qapi/qmp/qjson.h"
27 faf07963 pbrook
#include "qemu-common.h"
28 1de7afc9 Paolo Bonzini
#include "qemu/option.h"
29 1de7afc9 Paolo Bonzini
#include "qemu/error-report.h"
30 1de7afc9 Paolo Bonzini
#include "qemu/osdep.h"
31 9c17d615 Paolo Bonzini
#include "sysemu/sysemu.h"
32 737e150e Paolo Bonzini
#include "block/block_int.h"
33 c054b3fd Benoît Canet
#include <getopt.h>
34 9230eaf6 aliguori
#include <stdio.h>
35 f382d43a Miroslav Rezanina
#include <stdarg.h>
36 ea2384d3 bellard
37 e8445331 bellard
#ifdef _WIN32
38 e8445331 bellard
#include <windows.h>
39 e8445331 bellard
#endif
40 e8445331 bellard
41 c227f099 Anthony Liguori
typedef struct img_cmd_t {
42 153859be Stuart Brady
    const char *name;
43 153859be Stuart Brady
    int (*handler)(int argc, char **argv);
44 c227f099 Anthony Liguori
} img_cmd_t;
45 153859be Stuart Brady
46 8599ea4c Federico Simoncelli
enum {
47 8599ea4c Federico Simoncelli
    OPTION_OUTPUT = 256,
48 8599ea4c Federico Simoncelli
    OPTION_BACKING_CHAIN = 257,
49 8599ea4c Federico Simoncelli
};
50 8599ea4c Federico Simoncelli
51 8599ea4c Federico Simoncelli
typedef enum OutputFormat {
52 8599ea4c Federico Simoncelli
    OFORMAT_JSON,
53 8599ea4c Federico Simoncelli
    OFORMAT_HUMAN,
54 8599ea4c Federico Simoncelli
} OutputFormat;
55 8599ea4c Federico Simoncelli
56 137519ce aurel32
/* Default to cache=writeback as data integrity is not important for qemu-tcg. */
57 adfe078e Stefan Hajnoczi
#define BDRV_O_FLAGS BDRV_O_CACHE_WB
58 661a0f71 Federico Simoncelli
#define BDRV_DEFAULT_CACHE "writeback"
59 137519ce aurel32
60 ea2384d3 bellard
static void format_print(void *opaque, const char *name)
61 ea2384d3 bellard
{
62 ea2384d3 bellard
    printf(" %s", name);
63 ea2384d3 bellard
}
64 ea2384d3 bellard
65 d2c639d6 blueswir1
/* Please keep in synch with qemu-img.texi */
66 3f379ab1 pbrook
static void help(void)
67 ea2384d3 bellard
{
68 e00291c0 Paolo Bonzini
    const char *help_msg =
69 e00291c0 Paolo Bonzini
           "qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fabrice Bellard\n"
70 3f020d70 malc
           "usage: qemu-img command [command options]\n"
71 3f020d70 malc
           "QEMU disk image utility\n"
72 3f020d70 malc
           "\n"
73 3f020d70 malc
           "Command syntax:\n"
74 153859be Stuart Brady
#define DEF(option, callback, arg_string)        \
75 153859be Stuart Brady
           "  " arg_string "\n"
76 153859be Stuart Brady
#include "qemu-img-cmds.h"
77 153859be Stuart Brady
#undef DEF
78 153859be Stuart Brady
#undef GEN_DOCS
79 3f020d70 malc
           "\n"
80 3f020d70 malc
           "Command parameters:\n"
81 3f020d70 malc
           "  'filename' is a disk image filename\n"
82 3f020d70 malc
           "  'fmt' is the disk image format. It is guessed automatically in most cases\n"
83 661a0f71 Federico Simoncelli
           "  'cache' is the cache mode used to write the output disk image, the valid\n"
84 80ccf93b Liu Yuan
           "    options are: 'none', 'writeback' (default, except for convert), 'writethrough',\n"
85 80ccf93b Liu Yuan
           "    'directsync' and 'unsafe' (default for convert)\n"
86 3f020d70 malc
           "  'size' is the disk image size in bytes. Optional suffixes\n"
87 3f020d70 malc
           "    'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M)\n"
88 3f020d70 malc
           "    and T (terabyte, 1024G) are supported. 'b' is ignored.\n"
89 3f020d70 malc
           "  'output_filename' is the destination disk image filename\n"
90 3f020d70 malc
           "  'output_fmt' is the destination format\n"
91 3f020d70 malc
           "  'options' is a comma separated list of format specific options in a\n"
92 3f020d70 malc
           "    name=value format. Use -o ? for an overview of the options supported by the\n"
93 3f020d70 malc
           "    used format\n"
94 3f020d70 malc
           "  '-c' indicates that target image must be compressed (qcow format only)\n"
95 3f020d70 malc
           "  '-u' enables unsafe rebasing. It is assumed that old and new backing file\n"
96 3f020d70 malc
           "       match exactly. The image doesn't need a working backing file before\n"
97 3f020d70 malc
           "       rebasing in this case (useful for renaming the backing file)\n"
98 3f020d70 malc
           "  '-h' with or without a command shows this help and lists the supported formats\n"
99 6b837bc4 Jes Sorensen
           "  '-p' show progress of command (only certain commands)\n"
100 f382d43a Miroslav Rezanina
           "  '-q' use Quiet mode - do not print any output (except errors)\n"
101 a22f123c Kevin Wolf
           "  '-S' indicates the consecutive number of bytes that must contain only zeros\n"
102 a22f123c Kevin Wolf
           "       for qemu-img to create a sparse image during conversion\n"
103 c054b3fd Benoît Canet
           "  '--output' takes the format in which the output must be done (human or json)\n"
104 3f020d70 malc
           "\n"
105 4534ff54 Kevin Wolf
           "Parameters to check subcommand:\n"
106 4534ff54 Kevin Wolf
           "  '-r' tries to repair any inconsistencies that are found during the check.\n"
107 4534ff54 Kevin Wolf
           "       '-r leaks' repairs only cluster leaks, whereas '-r all' fixes all\n"
108 4534ff54 Kevin Wolf
           "       kinds of errors, with a higher risk of choosing the wrong fix or\n"
109 0546b8c2 Stefan Weil
           "       hiding corruption that has already occurred.\n"
110 4534ff54 Kevin Wolf
           "\n"
111 3f020d70 malc
           "Parameters to snapshot subcommand:\n"
112 3f020d70 malc
           "  'snapshot' is the name of the snapshot to create, apply or delete\n"
113 3f020d70 malc
           "  '-a' applies a snapshot (revert disk to saved state)\n"
114 3f020d70 malc
           "  '-c' creates a snapshot\n"
115 3f020d70 malc
           "  '-d' deletes a snapshot\n"
116 d14ed18c Miroslav Rezanina
           "  '-l' lists all snapshots in the given image\n"
117 d14ed18c Miroslav Rezanina
           "\n"
118 d14ed18c Miroslav Rezanina
           "Parameters to compare subcommand:\n"
119 d14ed18c Miroslav Rezanina
           "  '-f' first image format\n"
120 d14ed18c Miroslav Rezanina
           "  '-F' second image format\n"
121 d14ed18c Miroslav Rezanina
           "  '-s' run in Strict mode - fail on different image size or sector allocation\n";
122 e00291c0 Paolo Bonzini
123 e00291c0 Paolo Bonzini
    printf("%s\nSupported formats:", help_msg);
124 ea2384d3 bellard
    bdrv_iterate_format(format_print, NULL);
125 ea2384d3 bellard
    printf("\n");
126 ea2384d3 bellard
    exit(1);
127 ea2384d3 bellard
}
128 ea2384d3 bellard
129 f382d43a Miroslav Rezanina
static int qprintf(bool quiet, const char *fmt, ...)
130 f382d43a Miroslav Rezanina
{
131 f382d43a Miroslav Rezanina
    int ret = 0;
132 f382d43a Miroslav Rezanina
    if (!quiet) {
133 f382d43a Miroslav Rezanina
        va_list args;
134 f382d43a Miroslav Rezanina
        va_start(args, fmt);
135 f382d43a Miroslav Rezanina
        ret = vprintf(fmt, args);
136 f382d43a Miroslav Rezanina
        va_end(args);
137 f382d43a Miroslav Rezanina
    }
138 f382d43a Miroslav Rezanina
    return ret;
139 f382d43a Miroslav Rezanina
}
140 f382d43a Miroslav Rezanina
141 ea2384d3 bellard
#if defined(WIN32)
142 ea2384d3 bellard
/* XXX: put correct support for win32 */
143 ea2384d3 bellard
static int read_password(char *buf, int buf_size)
144 ea2384d3 bellard
{
145 ea2384d3 bellard
    int c, i;
146 ea2384d3 bellard
    printf("Password: ");
147 ea2384d3 bellard
    fflush(stdout);
148 ea2384d3 bellard
    i = 0;
149 ea2384d3 bellard
    for(;;) {
150 ea2384d3 bellard
        c = getchar();
151 ea2384d3 bellard
        if (c == '\n')
152 ea2384d3 bellard
            break;
153 ea2384d3 bellard
        if (i < (buf_size - 1))
154 ea2384d3 bellard
            buf[i++] = c;
155 ea2384d3 bellard
    }
156 ea2384d3 bellard
    buf[i] = '\0';
157 ea2384d3 bellard
    return 0;
158 ea2384d3 bellard
}
159 ea2384d3 bellard
160 ea2384d3 bellard
#else
161 ea2384d3 bellard
162 ea2384d3 bellard
#include <termios.h>
163 ea2384d3 bellard
164 ea2384d3 bellard
static struct termios oldtty;
165 ea2384d3 bellard
166 ea2384d3 bellard
static void term_exit(void)
167 ea2384d3 bellard
{
168 ea2384d3 bellard
    tcsetattr (0, TCSANOW, &oldtty);
169 ea2384d3 bellard
}
170 ea2384d3 bellard
171 ea2384d3 bellard
static void term_init(void)
172 ea2384d3 bellard
{
173 ea2384d3 bellard
    struct termios tty;
174 ea2384d3 bellard
175 ea2384d3 bellard
    tcgetattr (0, &tty);
176 ea2384d3 bellard
    oldtty = tty;
177 ea2384d3 bellard
178 ea2384d3 bellard
    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
179 ea2384d3 bellard
                          |INLCR|IGNCR|ICRNL|IXON);
180 ea2384d3 bellard
    tty.c_oflag |= OPOST;
181 ea2384d3 bellard
    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
182 ea2384d3 bellard
    tty.c_cflag &= ~(CSIZE|PARENB);
183 ea2384d3 bellard
    tty.c_cflag |= CS8;
184 ea2384d3 bellard
    tty.c_cc[VMIN] = 1;
185 ea2384d3 bellard
    tty.c_cc[VTIME] = 0;
186 3b46e624 ths
187 ea2384d3 bellard
    tcsetattr (0, TCSANOW, &tty);
188 ea2384d3 bellard
189 ea2384d3 bellard
    atexit(term_exit);
190 ea2384d3 bellard
}
191 ea2384d3 bellard
192 3f379ab1 pbrook
static int read_password(char *buf, int buf_size)
193 ea2384d3 bellard
{
194 ea2384d3 bellard
    uint8_t ch;
195 ea2384d3 bellard
    int i, ret;
196 ea2384d3 bellard
197 ea2384d3 bellard
    printf("password: ");
198 ea2384d3 bellard
    fflush(stdout);
199 ea2384d3 bellard
    term_init();
200 ea2384d3 bellard
    i = 0;
201 ea2384d3 bellard
    for(;;) {
202 ea2384d3 bellard
        ret = read(0, &ch, 1);
203 ea2384d3 bellard
        if (ret == -1) {
204 ea2384d3 bellard
            if (errno == EAGAIN || errno == EINTR) {
205 ea2384d3 bellard
                continue;
206 ea2384d3 bellard
            } else {
207 ea2384d3 bellard
                ret = -1;
208 ea2384d3 bellard
                break;
209 ea2384d3 bellard
            }
210 ea2384d3 bellard
        } else if (ret == 0) {
211 ea2384d3 bellard
            ret = -1;
212 ea2384d3 bellard
            break;
213 ea2384d3 bellard
        } else {
214 ea2384d3 bellard
            if (ch == '\r') {
215 ea2384d3 bellard
                ret = 0;
216 ea2384d3 bellard
                break;
217 ea2384d3 bellard
            }
218 ea2384d3 bellard
            if (i < (buf_size - 1))
219 ea2384d3 bellard
                buf[i++] = ch;
220 ea2384d3 bellard
        }
221 ea2384d3 bellard
    }
222 ea2384d3 bellard
    term_exit();
223 ea2384d3 bellard
    buf[i] = '\0';
224 ea2384d3 bellard
    printf("\n");
225 ea2384d3 bellard
    return ret;
226 ea2384d3 bellard
}
227 ea2384d3 bellard
#endif
228 ea2384d3 bellard
229 4ac8aacd Jes Sorensen
static int print_block_option_help(const char *filename, const char *fmt)
230 4ac8aacd Jes Sorensen
{
231 4ac8aacd Jes Sorensen
    BlockDriver *drv, *proto_drv;
232 4ac8aacd Jes Sorensen
    QEMUOptionParameter *create_options = NULL;
233 4ac8aacd Jes Sorensen
234 4ac8aacd Jes Sorensen
    /* Find driver and parse its options */
235 4ac8aacd Jes Sorensen
    drv = bdrv_find_format(fmt);
236 4ac8aacd Jes Sorensen
    if (!drv) {
237 15654a6d Jes Sorensen
        error_report("Unknown file format '%s'", fmt);
238 4ac8aacd Jes Sorensen
        return 1;
239 4ac8aacd Jes Sorensen
    }
240 4ac8aacd Jes Sorensen
241 4ac8aacd Jes Sorensen
    proto_drv = bdrv_find_protocol(filename);
242 4ac8aacd Jes Sorensen
    if (!proto_drv) {
243 15654a6d Jes Sorensen
        error_report("Unknown protocol '%s'", filename);
244 4ac8aacd Jes Sorensen
        return 1;
245 4ac8aacd Jes Sorensen
    }
246 4ac8aacd Jes Sorensen
247 4ac8aacd Jes Sorensen
    create_options = append_option_parameters(create_options,
248 4ac8aacd Jes Sorensen
                                              drv->create_options);
249 4ac8aacd Jes Sorensen
    create_options = append_option_parameters(create_options,
250 4ac8aacd Jes Sorensen
                                              proto_drv->create_options);
251 4ac8aacd Jes Sorensen
    print_option_help(create_options);
252 4ac8aacd Jes Sorensen
    free_option_parameters(create_options);
253 4ac8aacd Jes Sorensen
    return 0;
254 4ac8aacd Jes Sorensen
}
255 4ac8aacd Jes Sorensen
256 75c23805 bellard
static BlockDriverState *bdrv_new_open(const char *filename,
257 9bc378c1 Sheng Yang
                                       const char *fmt,
258 f0536bb8 Daniel P. Berrange
                                       int flags,
259 f382d43a Miroslav Rezanina
                                       bool require_io,
260 f382d43a Miroslav Rezanina
                                       bool quiet)
261 75c23805 bellard
{
262 75c23805 bellard
    BlockDriverState *bs;
263 75c23805 bellard
    BlockDriver *drv;
264 75c23805 bellard
    char password[256];
265 b9eaf9ec Kevin Wolf
    int ret;
266 75c23805 bellard
267 b9eaf9ec Kevin Wolf
    bs = bdrv_new("image");
268 ad717139 Kevin Wolf
269 75c23805 bellard
    if (fmt) {
270 75c23805 bellard
        drv = bdrv_find_format(fmt);
271 c2abccec MORITA Kazutaka
        if (!drv) {
272 15654a6d Jes Sorensen
            error_report("Unknown file format '%s'", fmt);
273 c2abccec MORITA Kazutaka
            goto fail;
274 c2abccec MORITA Kazutaka
        }
275 75c23805 bellard
    } else {
276 75c23805 bellard
        drv = NULL;
277 75c23805 bellard
    }
278 b9eaf9ec Kevin Wolf
279 de9c0cec Kevin Wolf
    ret = bdrv_open(bs, filename, NULL, flags, drv);
280 b9eaf9ec Kevin Wolf
    if (ret < 0) {
281 b9eaf9ec Kevin Wolf
        error_report("Could not open '%s': %s", filename, strerror(-ret));
282 c2abccec MORITA Kazutaka
        goto fail;
283 75c23805 bellard
    }
284 b9eaf9ec Kevin Wolf
285 f0536bb8 Daniel P. Berrange
    if (bdrv_is_encrypted(bs) && require_io) {
286 f382d43a Miroslav Rezanina
        qprintf(quiet, "Disk image '%s' is encrypted.\n", filename);
287 c2abccec MORITA Kazutaka
        if (read_password(password, sizeof(password)) < 0) {
288 15654a6d Jes Sorensen
            error_report("No password given");
289 c2abccec MORITA Kazutaka
            goto fail;
290 c2abccec MORITA Kazutaka
        }
291 c2abccec MORITA Kazutaka
        if (bdrv_set_key(bs, password) < 0) {
292 15654a6d Jes Sorensen
            error_report("invalid password");
293 c2abccec MORITA Kazutaka
            goto fail;
294 c2abccec MORITA Kazutaka
        }
295 75c23805 bellard
    }
296 75c23805 bellard
    return bs;
297 c2abccec MORITA Kazutaka
fail:
298 c2abccec MORITA Kazutaka
    if (bs) {
299 c2abccec MORITA Kazutaka
        bdrv_delete(bs);
300 c2abccec MORITA Kazutaka
    }
301 c2abccec MORITA Kazutaka
    return NULL;
302 75c23805 bellard
}
303 75c23805 bellard
304 c2abccec MORITA Kazutaka
static int add_old_style_options(const char *fmt, QEMUOptionParameter *list,
305 eec77d9e Jes Sorensen
                                 const char *base_filename,
306 eec77d9e Jes Sorensen
                                 const char *base_fmt)
307 efa84d43 Kevin Wolf
{
308 efa84d43 Kevin Wolf
    if (base_filename) {
309 efa84d43 Kevin Wolf
        if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) {
310 15654a6d Jes Sorensen
            error_report("Backing file not supported for file format '%s'",
311 15654a6d Jes Sorensen
                         fmt);
312 c2abccec MORITA Kazutaka
            return -1;
313 efa84d43 Kevin Wolf
        }
314 efa84d43 Kevin Wolf
    }
315 efa84d43 Kevin Wolf
    if (base_fmt) {
316 efa84d43 Kevin Wolf
        if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {
317 15654a6d Jes Sorensen
            error_report("Backing file format not supported for file "
318 15654a6d Jes Sorensen
                         "format '%s'", fmt);
319 c2abccec MORITA Kazutaka
            return -1;
320 efa84d43 Kevin Wolf
        }
321 efa84d43 Kevin Wolf
    }
322 c2abccec MORITA Kazutaka
    return 0;
323 efa84d43 Kevin Wolf
}
324 efa84d43 Kevin Wolf
325 ea2384d3 bellard
static int img_create(int argc, char **argv)
326 ea2384d3 bellard
{
327 a9300911 Luiz Capitulino
    int c;
328 1da7cfbd Jes Sorensen
    uint64_t img_size = -1;
329 ea2384d3 bellard
    const char *fmt = "raw";
330 9230eaf6 aliguori
    const char *base_fmt = NULL;
331 ea2384d3 bellard
    const char *filename;
332 ea2384d3 bellard
    const char *base_filename = NULL;
333 9ea2ea71 Kevin Wolf
    char *options = NULL;
334 9b37525a Luiz Capitulino
    Error *local_err = NULL;
335 f382d43a Miroslav Rezanina
    bool quiet = false;
336 3b46e624 ths
337 ea2384d3 bellard
    for(;;) {
338 f382d43a Miroslav Rezanina
        c = getopt(argc, argv, "F:b:f:he6o:q");
339 b8fb60da Jes Sorensen
        if (c == -1) {
340 ea2384d3 bellard
            break;
341 b8fb60da Jes Sorensen
        }
342 ea2384d3 bellard
        switch(c) {
343 ef87394c Jes Sorensen
        case '?':
344 ea2384d3 bellard
        case 'h':
345 ea2384d3 bellard
            help();
346 ea2384d3 bellard
            break;
347 9230eaf6 aliguori
        case 'F':
348 9230eaf6 aliguori
            base_fmt = optarg;
349 9230eaf6 aliguori
            break;
350 ea2384d3 bellard
        case 'b':
351 ea2384d3 bellard
            base_filename = optarg;
352 ea2384d3 bellard
            break;
353 ea2384d3 bellard
        case 'f':
354 ea2384d3 bellard
            fmt = optarg;
355 ea2384d3 bellard
            break;
356 ea2384d3 bellard
        case 'e':
357 9d42e15d Markus Armbruster
            error_report("option -e is deprecated, please use \'-o "
358 eec77d9e Jes Sorensen
                  "encryption\' instead!");
359 eec77d9e Jes Sorensen
            return 1;
360 d8871c5a ths
        case '6':
361 9d42e15d Markus Armbruster
            error_report("option -6 is deprecated, please use \'-o "
362 eec77d9e Jes Sorensen
                  "compat6\' instead!");
363 eec77d9e Jes Sorensen
            return 1;
364 9ea2ea71 Kevin Wolf
        case 'o':
365 9ea2ea71 Kevin Wolf
            options = optarg;
366 9ea2ea71 Kevin Wolf
            break;
367 f382d43a Miroslav Rezanina
        case 'q':
368 f382d43a Miroslav Rezanina
            quiet = true;
369 f382d43a Miroslav Rezanina
            break;
370 ea2384d3 bellard
        }
371 ea2384d3 bellard
    }
372 9230eaf6 aliguori
373 b50cbabc MORITA Kazutaka
    /* Get the filename */
374 b8fb60da Jes Sorensen
    if (optind >= argc) {
375 b50cbabc MORITA Kazutaka
        help();
376 b8fb60da Jes Sorensen
    }
377 b50cbabc MORITA Kazutaka
    filename = argv[optind++];
378 b50cbabc MORITA Kazutaka
379 1da7cfbd Jes Sorensen
    /* Get image size, if specified */
380 1da7cfbd Jes Sorensen
    if (optind < argc) {
381 70b4f4bb Jes Sorensen
        int64_t sval;
382 e36b3695 Markus Armbruster
        char *end;
383 e36b3695 Markus Armbruster
        sval = strtosz_suffix(argv[optind++], &end, STRTOSZ_DEFSUFFIX_B);
384 e36b3695 Markus Armbruster
        if (sval < 0 || *end) {
385 79443397 liguang
            if (sval == -ERANGE) {
386 79443397 liguang
                error_report("Image size must be less than 8 EiB!");
387 79443397 liguang
            } else {
388 79443397 liguang
                error_report("Invalid image size specified! You may use k, M, "
389 79443397 liguang
                      "G or T suffixes for ");
390 79443397 liguang
                error_report("kilobytes, megabytes, gigabytes and terabytes.");
391 79443397 liguang
            }
392 a9300911 Luiz Capitulino
            return 1;
393 1da7cfbd Jes Sorensen
        }
394 1da7cfbd Jes Sorensen
        img_size = (uint64_t)sval;
395 1da7cfbd Jes Sorensen
    }
396 1da7cfbd Jes Sorensen
397 c8057f95 Peter Maydell
    if (options && is_help_option(options)) {
398 a9300911 Luiz Capitulino
        return print_block_option_help(filename, fmt);
399 4ac8aacd Jes Sorensen
    }
400 4ac8aacd Jes Sorensen
401 9b37525a Luiz Capitulino
    bdrv_img_create(filename, fmt, base_filename, base_fmt,
402 f382d43a Miroslav Rezanina
                    options, img_size, BDRV_O_FLAGS, &local_err, quiet);
403 9b37525a Luiz Capitulino
    if (error_is_set(&local_err)) {
404 9b37525a Luiz Capitulino
        error_report("%s", error_get_pretty(local_err));
405 9b37525a Luiz Capitulino
        error_free(local_err);
406 c2abccec MORITA Kazutaka
        return 1;
407 c2abccec MORITA Kazutaka
    }
408 a9300911 Luiz Capitulino
409 ea2384d3 bellard
    return 0;
410 ea2384d3 bellard
}
411 ea2384d3 bellard
412 f382d43a Miroslav Rezanina
static void dump_json_image_check(ImageCheck *check, bool quiet)
413 8599ea4c Federico Simoncelli
{
414 8599ea4c Federico Simoncelli
    Error *errp = NULL;
415 8599ea4c Federico Simoncelli
    QString *str;
416 8599ea4c Federico Simoncelli
    QmpOutputVisitor *ov = qmp_output_visitor_new();
417 8599ea4c Federico Simoncelli
    QObject *obj;
418 8599ea4c Federico Simoncelli
    visit_type_ImageCheck(qmp_output_get_visitor(ov),
419 8599ea4c Federico Simoncelli
                          &check, NULL, &errp);
420 8599ea4c Federico Simoncelli
    obj = qmp_output_get_qobject(ov);
421 8599ea4c Federico Simoncelli
    str = qobject_to_json_pretty(obj);
422 8599ea4c Federico Simoncelli
    assert(str != NULL);
423 f382d43a Miroslav Rezanina
    qprintf(quiet, "%s\n", qstring_get_str(str));
424 8599ea4c Federico Simoncelli
    qobject_decref(obj);
425 8599ea4c Federico Simoncelli
    qmp_output_visitor_cleanup(ov);
426 8599ea4c Federico Simoncelli
    QDECREF(str);
427 8599ea4c Federico Simoncelli
}
428 8599ea4c Federico Simoncelli
429 f382d43a Miroslav Rezanina
static void dump_human_image_check(ImageCheck *check, bool quiet)
430 8599ea4c Federico Simoncelli
{
431 8599ea4c Federico Simoncelli
    if (!(check->corruptions || check->leaks || check->check_errors)) {
432 f382d43a Miroslav Rezanina
        qprintf(quiet, "No errors were found on the image.\n");
433 8599ea4c Federico Simoncelli
    } else {
434 8599ea4c Federico Simoncelli
        if (check->corruptions) {
435 f382d43a Miroslav Rezanina
            qprintf(quiet, "\n%" PRId64 " errors were found on the image.\n"
436 f382d43a Miroslav Rezanina
                    "Data may be corrupted, or further writes to the image "
437 f382d43a Miroslav Rezanina
                    "may corrupt it.\n",
438 f382d43a Miroslav Rezanina
                    check->corruptions);
439 8599ea4c Federico Simoncelli
        }
440 8599ea4c Federico Simoncelli
441 8599ea4c Federico Simoncelli
        if (check->leaks) {
442 f382d43a Miroslav Rezanina
            qprintf(quiet,
443 f382d43a Miroslav Rezanina
                    "\n%" PRId64 " leaked clusters were found on the image.\n"
444 f382d43a Miroslav Rezanina
                    "This means waste of disk space, but no harm to data.\n",
445 f382d43a Miroslav Rezanina
                    check->leaks);
446 8599ea4c Federico Simoncelli
        }
447 8599ea4c Federico Simoncelli
448 8599ea4c Federico Simoncelli
        if (check->check_errors) {
449 f382d43a Miroslav Rezanina
            qprintf(quiet,
450 f382d43a Miroslav Rezanina
                    "\n%" PRId64
451 f382d43a Miroslav Rezanina
                    " internal errors have occurred during the check.\n",
452 f382d43a Miroslav Rezanina
                    check->check_errors);
453 8599ea4c Federico Simoncelli
        }
454 8599ea4c Federico Simoncelli
    }
455 8599ea4c Federico Simoncelli
456 8599ea4c Federico Simoncelli
    if (check->total_clusters != 0 && check->allocated_clusters != 0) {
457 f382d43a Miroslav Rezanina
        qprintf(quiet, "%" PRId64 "/%" PRId64 " = %0.2f%% allocated, "
458 f382d43a Miroslav Rezanina
                "%0.2f%% fragmented, %0.2f%% compressed clusters\n",
459 f382d43a Miroslav Rezanina
                check->allocated_clusters, check->total_clusters,
460 f382d43a Miroslav Rezanina
                check->allocated_clusters * 100.0 / check->total_clusters,
461 f382d43a Miroslav Rezanina
                check->fragmented_clusters * 100.0 / check->allocated_clusters,
462 f382d43a Miroslav Rezanina
                check->compressed_clusters * 100.0 /
463 f382d43a Miroslav Rezanina
                check->allocated_clusters);
464 8599ea4c Federico Simoncelli
    }
465 8599ea4c Federico Simoncelli
466 8599ea4c Federico Simoncelli
    if (check->image_end_offset) {
467 f382d43a Miroslav Rezanina
        qprintf(quiet,
468 f382d43a Miroslav Rezanina
                "Image end offset: %" PRId64 "\n", check->image_end_offset);
469 8599ea4c Federico Simoncelli
    }
470 8599ea4c Federico Simoncelli
}
471 8599ea4c Federico Simoncelli
472 8599ea4c Federico Simoncelli
static int collect_image_check(BlockDriverState *bs,
473 8599ea4c Federico Simoncelli
                   ImageCheck *check,
474 8599ea4c Federico Simoncelli
                   const char *filename,
475 8599ea4c Federico Simoncelli
                   const char *fmt,
476 8599ea4c Federico Simoncelli
                   int fix)
477 8599ea4c Federico Simoncelli
{
478 8599ea4c Federico Simoncelli
    int ret;
479 8599ea4c Federico Simoncelli
    BdrvCheckResult result;
480 8599ea4c Federico Simoncelli
481 8599ea4c Federico Simoncelli
    ret = bdrv_check(bs, &result, fix);
482 8599ea4c Federico Simoncelli
    if (ret < 0) {
483 8599ea4c Federico Simoncelli
        return ret;
484 8599ea4c Federico Simoncelli
    }
485 8599ea4c Federico Simoncelli
486 8599ea4c Federico Simoncelli
    check->filename                 = g_strdup(filename);
487 8599ea4c Federico Simoncelli
    check->format                   = g_strdup(bdrv_get_format_name(bs));
488 8599ea4c Federico Simoncelli
    check->check_errors             = result.check_errors;
489 8599ea4c Federico Simoncelli
    check->corruptions              = result.corruptions;
490 8599ea4c Federico Simoncelli
    check->has_corruptions          = result.corruptions != 0;
491 8599ea4c Federico Simoncelli
    check->leaks                    = result.leaks;
492 8599ea4c Federico Simoncelli
    check->has_leaks                = result.leaks != 0;
493 8599ea4c Federico Simoncelli
    check->corruptions_fixed        = result.corruptions_fixed;
494 8599ea4c Federico Simoncelli
    check->has_corruptions_fixed    = result.corruptions != 0;
495 8599ea4c Federico Simoncelli
    check->leaks_fixed              = result.leaks_fixed;
496 8599ea4c Federico Simoncelli
    check->has_leaks_fixed          = result.leaks != 0;
497 8599ea4c Federico Simoncelli
    check->image_end_offset         = result.image_end_offset;
498 8599ea4c Federico Simoncelli
    check->has_image_end_offset     = result.image_end_offset != 0;
499 8599ea4c Federico Simoncelli
    check->total_clusters           = result.bfi.total_clusters;
500 8599ea4c Federico Simoncelli
    check->has_total_clusters       = result.bfi.total_clusters != 0;
501 8599ea4c Federico Simoncelli
    check->allocated_clusters       = result.bfi.allocated_clusters;
502 8599ea4c Federico Simoncelli
    check->has_allocated_clusters   = result.bfi.allocated_clusters != 0;
503 8599ea4c Federico Simoncelli
    check->fragmented_clusters      = result.bfi.fragmented_clusters;
504 8599ea4c Federico Simoncelli
    check->has_fragmented_clusters  = result.bfi.fragmented_clusters != 0;
505 e6439d78 Stefan Hajnoczi
    check->compressed_clusters      = result.bfi.compressed_clusters;
506 e6439d78 Stefan Hajnoczi
    check->has_compressed_clusters  = result.bfi.compressed_clusters != 0;
507 8599ea4c Federico Simoncelli
508 8599ea4c Federico Simoncelli
    return 0;
509 8599ea4c Federico Simoncelli
}
510 8599ea4c Federico Simoncelli
511 e076f338 Kevin Wolf
/*
512 e076f338 Kevin Wolf
 * Checks an image for consistency. Exit codes:
513 e076f338 Kevin Wolf
 *
514 e076f338 Kevin Wolf
 * 0 - Check completed, image is good
515 e076f338 Kevin Wolf
 * 1 - Check not completed because of internal errors
516 e076f338 Kevin Wolf
 * 2 - Check completed, image is corrupted
517 e076f338 Kevin Wolf
 * 3 - Check completed, image has leaked clusters, but is good otherwise
518 e076f338 Kevin Wolf
 */
519 1585969c aliguori
static int img_check(int argc, char **argv)
520 1585969c aliguori
{
521 1585969c aliguori
    int c, ret;
522 8599ea4c Federico Simoncelli
    OutputFormat output_format = OFORMAT_HUMAN;
523 8599ea4c Federico Simoncelli
    const char *filename, *fmt, *output;
524 1585969c aliguori
    BlockDriverState *bs;
525 4534ff54 Kevin Wolf
    int fix = 0;
526 058f8f16 Stefan Hajnoczi
    int flags = BDRV_O_FLAGS | BDRV_O_CHECK;
527 8599ea4c Federico Simoncelli
    ImageCheck *check;
528 f382d43a Miroslav Rezanina
    bool quiet = false;
529 1585969c aliguori
530 1585969c aliguori
    fmt = NULL;
531 8599ea4c Federico Simoncelli
    output = NULL;
532 1585969c aliguori
    for(;;) {
533 8599ea4c Federico Simoncelli
        int option_index = 0;
534 8599ea4c Federico Simoncelli
        static const struct option long_options[] = {
535 8599ea4c Federico Simoncelli
            {"help", no_argument, 0, 'h'},
536 8599ea4c Federico Simoncelli
            {"format", required_argument, 0, 'f'},
537 8599ea4c Federico Simoncelli
            {"repair", no_argument, 0, 'r'},
538 8599ea4c Federico Simoncelli
            {"output", required_argument, 0, OPTION_OUTPUT},
539 8599ea4c Federico Simoncelli
            {0, 0, 0, 0}
540 8599ea4c Federico Simoncelli
        };
541 f382d43a Miroslav Rezanina
        c = getopt_long(argc, argv, "f:hr:q",
542 8599ea4c Federico Simoncelli
                        long_options, &option_index);
543 b8fb60da Jes Sorensen
        if (c == -1) {
544 1585969c aliguori
            break;
545 b8fb60da Jes Sorensen
        }
546 1585969c aliguori
        switch(c) {
547 ef87394c Jes Sorensen
        case '?':
548 1585969c aliguori
        case 'h':
549 1585969c aliguori
            help();
550 1585969c aliguori
            break;
551 1585969c aliguori
        case 'f':
552 1585969c aliguori
            fmt = optarg;
553 1585969c aliguori
            break;
554 4534ff54 Kevin Wolf
        case 'r':
555 4534ff54 Kevin Wolf
            flags |= BDRV_O_RDWR;
556 4534ff54 Kevin Wolf
557 4534ff54 Kevin Wolf
            if (!strcmp(optarg, "leaks")) {
558 4534ff54 Kevin Wolf
                fix = BDRV_FIX_LEAKS;
559 4534ff54 Kevin Wolf
            } else if (!strcmp(optarg, "all")) {
560 4534ff54 Kevin Wolf
                fix = BDRV_FIX_LEAKS | BDRV_FIX_ERRORS;
561 4534ff54 Kevin Wolf
            } else {
562 4534ff54 Kevin Wolf
                help();
563 4534ff54 Kevin Wolf
            }
564 4534ff54 Kevin Wolf
            break;
565 8599ea4c Federico Simoncelli
        case OPTION_OUTPUT:
566 8599ea4c Federico Simoncelli
            output = optarg;
567 8599ea4c Federico Simoncelli
            break;
568 f382d43a Miroslav Rezanina
        case 'q':
569 f382d43a Miroslav Rezanina
            quiet = true;
570 f382d43a Miroslav Rezanina
            break;
571 1585969c aliguori
        }
572 1585969c aliguori
    }
573 b8fb60da Jes Sorensen
    if (optind >= argc) {
574 1585969c aliguori
        help();
575 b8fb60da Jes Sorensen
    }
576 1585969c aliguori
    filename = argv[optind++];
577 1585969c aliguori
578 8599ea4c Federico Simoncelli
    if (output && !strcmp(output, "json")) {
579 8599ea4c Federico Simoncelli
        output_format = OFORMAT_JSON;
580 8599ea4c Federico Simoncelli
    } else if (output && !strcmp(output, "human")) {
581 8599ea4c Federico Simoncelli
        output_format = OFORMAT_HUMAN;
582 8599ea4c Federico Simoncelli
    } else if (output) {
583 8599ea4c Federico Simoncelli
        error_report("--output must be used with human or json as argument.");
584 8599ea4c Federico Simoncelli
        return 1;
585 8599ea4c Federico Simoncelli
    }
586 8599ea4c Federico Simoncelli
587 f382d43a Miroslav Rezanina
    bs = bdrv_new_open(filename, fmt, flags, true, quiet);
588 c2abccec MORITA Kazutaka
    if (!bs) {
589 c2abccec MORITA Kazutaka
        return 1;
590 c2abccec MORITA Kazutaka
    }
591 8599ea4c Federico Simoncelli
592 8599ea4c Federico Simoncelli
    check = g_new0(ImageCheck, 1);
593 8599ea4c Federico Simoncelli
    ret = collect_image_check(bs, check, filename, fmt, fix);
594 e076f338 Kevin Wolf
595 e076f338 Kevin Wolf
    if (ret == -ENOTSUP) {
596 8599ea4c Federico Simoncelli
        if (output_format == OFORMAT_HUMAN) {
597 8599ea4c Federico Simoncelli
            error_report("This image format does not support checks");
598 8599ea4c Federico Simoncelli
        }
599 8599ea4c Federico Simoncelli
        ret = 1;
600 8599ea4c Federico Simoncelli
        goto fail;
601 e076f338 Kevin Wolf
    }
602 e076f338 Kevin Wolf
603 8599ea4c Federico Simoncelli
    if (check->corruptions_fixed || check->leaks_fixed) {
604 8599ea4c Federico Simoncelli
        int corruptions_fixed, leaks_fixed;
605 ccf34716 Kevin Wolf
606 8599ea4c Federico Simoncelli
        leaks_fixed         = check->leaks_fixed;
607 8599ea4c Federico Simoncelli
        corruptions_fixed   = check->corruptions_fixed;
608 e076f338 Kevin Wolf
609 8599ea4c Federico Simoncelli
        if (output_format == OFORMAT_HUMAN) {
610 f382d43a Miroslav Rezanina
            qprintf(quiet,
611 f382d43a Miroslav Rezanina
                    "The following inconsistencies were found and repaired:\n\n"
612 f382d43a Miroslav Rezanina
                    "    %" PRId64 " leaked clusters\n"
613 f382d43a Miroslav Rezanina
                    "    %" PRId64 " corruptions\n\n"
614 f382d43a Miroslav Rezanina
                    "Double checking the fixed image now...\n",
615 f382d43a Miroslav Rezanina
                    check->leaks_fixed,
616 f382d43a Miroslav Rezanina
                    check->corruptions_fixed);
617 e076f338 Kevin Wolf
        }
618 e076f338 Kevin Wolf
619 8599ea4c Federico Simoncelli
        ret = collect_image_check(bs, check, filename, fmt, 0);
620 1585969c aliguori
621 8599ea4c Federico Simoncelli
        check->leaks_fixed          = leaks_fixed;
622 8599ea4c Federico Simoncelli
        check->corruptions_fixed    = corruptions_fixed;
623 f8111c24 Dong Xu Wang
    }
624 f8111c24 Dong Xu Wang
625 8599ea4c Federico Simoncelli
    switch (output_format) {
626 8599ea4c Federico Simoncelli
    case OFORMAT_HUMAN:
627 f382d43a Miroslav Rezanina
        dump_human_image_check(check, quiet);
628 8599ea4c Federico Simoncelli
        break;
629 8599ea4c Federico Simoncelli
    case OFORMAT_JSON:
630 f382d43a Miroslav Rezanina
        dump_json_image_check(check, quiet);
631 8599ea4c Federico Simoncelli
        break;
632 c6bb9ad1 Federico Simoncelli
    }
633 c6bb9ad1 Federico Simoncelli
634 8599ea4c Federico Simoncelli
    if (ret || check->check_errors) {
635 8599ea4c Federico Simoncelli
        ret = 1;
636 8599ea4c Federico Simoncelli
        goto fail;
637 c2abccec MORITA Kazutaka
    }
638 e076f338 Kevin Wolf
639 8599ea4c Federico Simoncelli
    if (check->corruptions) {
640 8599ea4c Federico Simoncelli
        ret = 2;
641 8599ea4c Federico Simoncelli
    } else if (check->leaks) {
642 8599ea4c Federico Simoncelli
        ret = 3;
643 e076f338 Kevin Wolf
    } else {
644 8599ea4c Federico Simoncelli
        ret = 0;
645 e076f338 Kevin Wolf
    }
646 8599ea4c Federico Simoncelli
647 8599ea4c Federico Simoncelli
fail:
648 8599ea4c Federico Simoncelli
    qapi_free_ImageCheck(check);
649 8599ea4c Federico Simoncelli
    bdrv_delete(bs);
650 8599ea4c Federico Simoncelli
651 8599ea4c Federico Simoncelli
    return ret;
652 1585969c aliguori
}
653 1585969c aliguori
654 ea2384d3 bellard
static int img_commit(int argc, char **argv)
655 ea2384d3 bellard
{
656 661a0f71 Federico Simoncelli
    int c, ret, flags;
657 661a0f71 Federico Simoncelli
    const char *filename, *fmt, *cache;
658 ea2384d3 bellard
    BlockDriverState *bs;
659 f382d43a Miroslav Rezanina
    bool quiet = false;
660 ea2384d3 bellard
661 ea2384d3 bellard
    fmt = NULL;
662 661a0f71 Federico Simoncelli
    cache = BDRV_DEFAULT_CACHE;
663 ea2384d3 bellard
    for(;;) {
664 f382d43a Miroslav Rezanina
        c = getopt(argc, argv, "f:ht:q");
665 b8fb60da Jes Sorensen
        if (c == -1) {
666 ea2384d3 bellard
            break;
667 b8fb60da Jes Sorensen
        }
668 ea2384d3 bellard
        switch(c) {
669 ef87394c Jes Sorensen
        case '?':
670 ea2384d3 bellard
        case 'h':
671 ea2384d3 bellard
            help();
672 ea2384d3 bellard
            break;
673 ea2384d3 bellard
        case 'f':
674 ea2384d3 bellard
            fmt = optarg;
675 ea2384d3 bellard
            break;
676 661a0f71 Federico Simoncelli
        case 't':
677 661a0f71 Federico Simoncelli
            cache = optarg;
678 661a0f71 Federico Simoncelli
            break;
679 f382d43a Miroslav Rezanina
        case 'q':
680 f382d43a Miroslav Rezanina
            quiet = true;
681 f382d43a Miroslav Rezanina
            break;
682 ea2384d3 bellard
        }
683 ea2384d3 bellard
    }
684 b8fb60da Jes Sorensen
    if (optind >= argc) {
685 ea2384d3 bellard
        help();
686 b8fb60da Jes Sorensen
    }
687 ea2384d3 bellard
    filename = argv[optind++];
688 ea2384d3 bellard
689 661a0f71 Federico Simoncelli
    flags = BDRV_O_RDWR;
690 c3993cdc Stefan Hajnoczi
    ret = bdrv_parse_cache_flags(cache, &flags);
691 661a0f71 Federico Simoncelli
    if (ret < 0) {
692 661a0f71 Federico Simoncelli
        error_report("Invalid cache option: %s", cache);
693 661a0f71 Federico Simoncelli
        return -1;
694 661a0f71 Federico Simoncelli
    }
695 661a0f71 Federico Simoncelli
696 f382d43a Miroslav Rezanina
    bs = bdrv_new_open(filename, fmt, flags, true, quiet);
697 c2abccec MORITA Kazutaka
    if (!bs) {
698 c2abccec MORITA Kazutaka
        return 1;
699 c2abccec MORITA Kazutaka
    }
700 ea2384d3 bellard
    ret = bdrv_commit(bs);
701 ea2384d3 bellard
    switch(ret) {
702 ea2384d3 bellard
    case 0:
703 f382d43a Miroslav Rezanina
        qprintf(quiet, "Image committed.\n");
704 ea2384d3 bellard
        break;
705 ea2384d3 bellard
    case -ENOENT:
706 15654a6d Jes Sorensen
        error_report("No disk inserted");
707 ea2384d3 bellard
        break;
708 ea2384d3 bellard
    case -EACCES:
709 15654a6d Jes Sorensen
        error_report("Image is read-only");
710 ea2384d3 bellard
        break;
711 ea2384d3 bellard
    case -ENOTSUP:
712 15654a6d Jes Sorensen
        error_report("Image is already committed");
713 ea2384d3 bellard
        break;
714 ea2384d3 bellard
    default:
715 15654a6d Jes Sorensen
        error_report("Error while committing image");
716 ea2384d3 bellard
        break;
717 ea2384d3 bellard
    }
718 ea2384d3 bellard
719 ea2384d3 bellard
    bdrv_delete(bs);
720 c2abccec MORITA Kazutaka
    if (ret) {
721 c2abccec MORITA Kazutaka
        return 1;
722 c2abccec MORITA Kazutaka
    }
723 ea2384d3 bellard
    return 0;
724 ea2384d3 bellard
}
725 ea2384d3 bellard
726 f6a00aa1 Dmitry Konishchev
/*
727 f58c7b35 ths
 * Returns true iff the first sector pointed to by 'buf' contains at least
728 f58c7b35 ths
 * a non-NUL byte.
729 f58c7b35 ths
 *
730 f58c7b35 ths
 * 'pnum' is set to the number of sectors (including and immediately following
731 f58c7b35 ths
 * the first one) that are known to be in the same allocated/unallocated state.
732 f58c7b35 ths
 */
733 ea2384d3 bellard
static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
734 ea2384d3 bellard
{
735 1a6d39fd Stefan Hajnoczi
    bool is_zero;
736 1a6d39fd Stefan Hajnoczi
    int i;
737 ea2384d3 bellard
738 ea2384d3 bellard
    if (n <= 0) {
739 ea2384d3 bellard
        *pnum = 0;
740 ea2384d3 bellard
        return 0;
741 ea2384d3 bellard
    }
742 1a6d39fd Stefan Hajnoczi
    is_zero = buffer_is_zero(buf, 512);
743 ea2384d3 bellard
    for(i = 1; i < n; i++) {
744 ea2384d3 bellard
        buf += 512;
745 1a6d39fd Stefan Hajnoczi
        if (is_zero != buffer_is_zero(buf, 512)) {
746 ea2384d3 bellard
            break;
747 1a6d39fd Stefan Hajnoczi
        }
748 ea2384d3 bellard
    }
749 ea2384d3 bellard
    *pnum = i;
750 1a6d39fd Stefan Hajnoczi
    return !is_zero;
751 ea2384d3 bellard
}
752 ea2384d3 bellard
753 3e85c6fd Kevin Wolf
/*
754 a22f123c Kevin Wolf
 * Like is_allocated_sectors, but if the buffer starts with a used sector,
755 a22f123c Kevin Wolf
 * up to 'min' consecutive sectors containing zeros are ignored. This avoids
756 a22f123c Kevin Wolf
 * breaking up write requests for only small sparse areas.
757 a22f123c Kevin Wolf
 */
758 a22f123c Kevin Wolf
static int is_allocated_sectors_min(const uint8_t *buf, int n, int *pnum,
759 a22f123c Kevin Wolf
    int min)
760 a22f123c Kevin Wolf
{
761 a22f123c Kevin Wolf
    int ret;
762 a22f123c Kevin Wolf
    int num_checked, num_used;
763 a22f123c Kevin Wolf
764 a22f123c Kevin Wolf
    if (n < min) {
765 a22f123c Kevin Wolf
        min = n;
766 a22f123c Kevin Wolf
    }
767 a22f123c Kevin Wolf
768 a22f123c Kevin Wolf
    ret = is_allocated_sectors(buf, n, pnum);
769 a22f123c Kevin Wolf
    if (!ret) {
770 a22f123c Kevin Wolf
        return ret;
771 a22f123c Kevin Wolf
    }
772 a22f123c Kevin Wolf
773 a22f123c Kevin Wolf
    num_used = *pnum;
774 a22f123c Kevin Wolf
    buf += BDRV_SECTOR_SIZE * *pnum;
775 a22f123c Kevin Wolf
    n -= *pnum;
776 a22f123c Kevin Wolf
    num_checked = num_used;
777 a22f123c Kevin Wolf
778 a22f123c Kevin Wolf
    while (n > 0) {
779 a22f123c Kevin Wolf
        ret = is_allocated_sectors(buf, n, pnum);
780 a22f123c Kevin Wolf
781 a22f123c Kevin Wolf
        buf += BDRV_SECTOR_SIZE * *pnum;
782 a22f123c Kevin Wolf
        n -= *pnum;
783 a22f123c Kevin Wolf
        num_checked += *pnum;
784 a22f123c Kevin Wolf
        if (ret) {
785 a22f123c Kevin Wolf
            num_used = num_checked;
786 a22f123c Kevin Wolf
        } else if (*pnum >= min) {
787 a22f123c Kevin Wolf
            break;
788 a22f123c Kevin Wolf
        }
789 a22f123c Kevin Wolf
    }
790 a22f123c Kevin Wolf
791 a22f123c Kevin Wolf
    *pnum = num_used;
792 a22f123c Kevin Wolf
    return 1;
793 a22f123c Kevin Wolf
}
794 a22f123c Kevin Wolf
795 a22f123c Kevin Wolf
/*
796 3e85c6fd Kevin Wolf
 * Compares two buffers sector by sector. Returns 0 if the first sector of both
797 3e85c6fd Kevin Wolf
 * buffers matches, non-zero otherwise.
798 3e85c6fd Kevin Wolf
 *
799 3e85c6fd Kevin Wolf
 * pnum is set to the number of sectors (including and immediately following
800 3e85c6fd Kevin Wolf
 * the first one) that are known to have the same comparison result
801 3e85c6fd Kevin Wolf
 */
802 3e85c6fd Kevin Wolf
static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
803 3e85c6fd Kevin Wolf
    int *pnum)
804 3e85c6fd Kevin Wolf
{
805 3e85c6fd Kevin Wolf
    int res, i;
806 3e85c6fd Kevin Wolf
807 3e85c6fd Kevin Wolf
    if (n <= 0) {
808 3e85c6fd Kevin Wolf
        *pnum = 0;
809 3e85c6fd Kevin Wolf
        return 0;
810 3e85c6fd Kevin Wolf
    }
811 3e85c6fd Kevin Wolf
812 3e85c6fd Kevin Wolf
    res = !!memcmp(buf1, buf2, 512);
813 3e85c6fd Kevin Wolf
    for(i = 1; i < n; i++) {
814 3e85c6fd Kevin Wolf
        buf1 += 512;
815 3e85c6fd Kevin Wolf
        buf2 += 512;
816 3e85c6fd Kevin Wolf
817 3e85c6fd Kevin Wolf
        if (!!memcmp(buf1, buf2, 512) != res) {
818 3e85c6fd Kevin Wolf
            break;
819 3e85c6fd Kevin Wolf
        }
820 3e85c6fd Kevin Wolf
    }
821 3e85c6fd Kevin Wolf
822 3e85c6fd Kevin Wolf
    *pnum = i;
823 3e85c6fd Kevin Wolf
    return res;
824 3e85c6fd Kevin Wolf
}
825 3e85c6fd Kevin Wolf
826 80ee15a6 Kevin Wolf
#define IO_BUF_SIZE (2 * 1024 * 1024)
827 ea2384d3 bellard
828 d14ed18c Miroslav Rezanina
static int64_t sectors_to_bytes(int64_t sectors)
829 d14ed18c Miroslav Rezanina
{
830 d14ed18c Miroslav Rezanina
    return sectors << BDRV_SECTOR_BITS;
831 d14ed18c Miroslav Rezanina
}
832 d14ed18c Miroslav Rezanina
833 d14ed18c Miroslav Rezanina
static int64_t sectors_to_process(int64_t total, int64_t from)
834 d14ed18c Miroslav Rezanina
{
835 d14ed18c Miroslav Rezanina
    return MIN(total - from, IO_BUF_SIZE >> BDRV_SECTOR_BITS);
836 d14ed18c Miroslav Rezanina
}
837 d14ed18c Miroslav Rezanina
838 d14ed18c Miroslav Rezanina
/*
839 d14ed18c Miroslav Rezanina
 * Check if passed sectors are empty (not allocated or contain only 0 bytes)
840 d14ed18c Miroslav Rezanina
 *
841 d14ed18c Miroslav Rezanina
 * Returns 0 in case sectors are filled with 0, 1 if sectors contain non-zero
842 d14ed18c Miroslav Rezanina
 * data and negative value on error.
843 d14ed18c Miroslav Rezanina
 *
844 d14ed18c Miroslav Rezanina
 * @param bs:  Driver used for accessing file
845 d14ed18c Miroslav Rezanina
 * @param sect_num: Number of first sector to check
846 d14ed18c Miroslav Rezanina
 * @param sect_count: Number of sectors to check
847 d14ed18c Miroslav Rezanina
 * @param filename: Name of disk file we are checking (logging purpose)
848 d14ed18c Miroslav Rezanina
 * @param buffer: Allocated buffer for storing read data
849 d14ed18c Miroslav Rezanina
 * @param quiet: Flag for quiet mode
850 d14ed18c Miroslav Rezanina
 */
851 d14ed18c Miroslav Rezanina
static int check_empty_sectors(BlockDriverState *bs, int64_t sect_num,
852 d14ed18c Miroslav Rezanina
                               int sect_count, const char *filename,
853 d14ed18c Miroslav Rezanina
                               uint8_t *buffer, bool quiet)
854 d14ed18c Miroslav Rezanina
{
855 d14ed18c Miroslav Rezanina
    int pnum, ret = 0;
856 d14ed18c Miroslav Rezanina
    ret = bdrv_read(bs, sect_num, buffer, sect_count);
857 d14ed18c Miroslav Rezanina
    if (ret < 0) {
858 d14ed18c Miroslav Rezanina
        error_report("Error while reading offset %" PRId64 " of %s: %s",
859 d14ed18c Miroslav Rezanina
                     sectors_to_bytes(sect_num), filename, strerror(-ret));
860 d14ed18c Miroslav Rezanina
        return ret;
861 d14ed18c Miroslav Rezanina
    }
862 d14ed18c Miroslav Rezanina
    ret = is_allocated_sectors(buffer, sect_count, &pnum);
863 d14ed18c Miroslav Rezanina
    if (ret || pnum != sect_count) {
864 d14ed18c Miroslav Rezanina
        qprintf(quiet, "Content mismatch at offset %" PRId64 "!\n",
865 d14ed18c Miroslav Rezanina
                sectors_to_bytes(ret ? sect_num : sect_num + pnum));
866 d14ed18c Miroslav Rezanina
        return 1;
867 d14ed18c Miroslav Rezanina
    }
868 d14ed18c Miroslav Rezanina
869 d14ed18c Miroslav Rezanina
    return 0;
870 d14ed18c Miroslav Rezanina
}
871 d14ed18c Miroslav Rezanina
872 d14ed18c Miroslav Rezanina
/*
873 d14ed18c Miroslav Rezanina
 * Compares two images. Exit codes:
874 d14ed18c Miroslav Rezanina
 *
875 d14ed18c Miroslav Rezanina
 * 0 - Images are identical
876 d14ed18c Miroslav Rezanina
 * 1 - Images differ
877 d14ed18c Miroslav Rezanina
 * >1 - Error occurred
878 d14ed18c Miroslav Rezanina
 */
879 d14ed18c Miroslav Rezanina
static int img_compare(int argc, char **argv)
880 d14ed18c Miroslav Rezanina
{
881 d14ed18c Miroslav Rezanina
    const char *fmt1 = NULL, *fmt2 = NULL, *filename1, *filename2;
882 d14ed18c Miroslav Rezanina
    BlockDriverState *bs1, *bs2;
883 d14ed18c Miroslav Rezanina
    int64_t total_sectors1, total_sectors2;
884 d14ed18c Miroslav Rezanina
    uint8_t *buf1 = NULL, *buf2 = NULL;
885 d14ed18c Miroslav Rezanina
    int pnum1, pnum2;
886 d14ed18c Miroslav Rezanina
    int allocated1, allocated2;
887 d14ed18c Miroslav Rezanina
    int ret = 0; /* return value - 0 Ident, 1 Different, >1 Error */
888 d14ed18c Miroslav Rezanina
    bool progress = false, quiet = false, strict = false;
889 d14ed18c Miroslav Rezanina
    int64_t total_sectors;
890 d14ed18c Miroslav Rezanina
    int64_t sector_num = 0;
891 d14ed18c Miroslav Rezanina
    int64_t nb_sectors;
892 d14ed18c Miroslav Rezanina
    int c, pnum;
893 d14ed18c Miroslav Rezanina
    uint64_t bs_sectors;
894 d14ed18c Miroslav Rezanina
    uint64_t progress_base;
895 d14ed18c Miroslav Rezanina
896 d14ed18c Miroslav Rezanina
    for (;;) {
897 d14ed18c Miroslav Rezanina
        c = getopt(argc, argv, "hpf:F:sq");
898 d14ed18c Miroslav Rezanina
        if (c == -1) {
899 d14ed18c Miroslav Rezanina
            break;
900 d14ed18c Miroslav Rezanina
        }
901 d14ed18c Miroslav Rezanina
        switch (c) {
902 d14ed18c Miroslav Rezanina
        case '?':
903 d14ed18c Miroslav Rezanina
        case 'h':
904 d14ed18c Miroslav Rezanina
            help();
905 d14ed18c Miroslav Rezanina
            break;
906 d14ed18c Miroslav Rezanina
        case 'f':
907 d14ed18c Miroslav Rezanina
            fmt1 = optarg;
908 d14ed18c Miroslav Rezanina
            break;
909 d14ed18c Miroslav Rezanina
        case 'F':
910 d14ed18c Miroslav Rezanina
            fmt2 = optarg;
911 d14ed18c Miroslav Rezanina
            break;
912 d14ed18c Miroslav Rezanina
        case 'p':
913 d14ed18c Miroslav Rezanina
            progress = true;
914 d14ed18c Miroslav Rezanina
            break;
915 d14ed18c Miroslav Rezanina
        case 'q':
916 d14ed18c Miroslav Rezanina
            quiet = true;
917 d14ed18c Miroslav Rezanina
            break;
918 d14ed18c Miroslav Rezanina
        case 's':
919 d14ed18c Miroslav Rezanina
            strict = true;
920 d14ed18c Miroslav Rezanina
            break;
921 d14ed18c Miroslav Rezanina
        }
922 d14ed18c Miroslav Rezanina
    }
923 d14ed18c Miroslav Rezanina
924 d14ed18c Miroslav Rezanina
    /* Progress is not shown in Quiet mode */
925 d14ed18c Miroslav Rezanina
    if (quiet) {
926 d14ed18c Miroslav Rezanina
        progress = false;
927 d14ed18c Miroslav Rezanina
    }
928 d14ed18c Miroslav Rezanina
929 d14ed18c Miroslav Rezanina
930 d14ed18c Miroslav Rezanina
    if (optind > argc - 2) {
931 d14ed18c Miroslav Rezanina
        help();
932 d14ed18c Miroslav Rezanina
    }
933 d14ed18c Miroslav Rezanina
    filename1 = argv[optind++];
934 d14ed18c Miroslav Rezanina
    filename2 = argv[optind++];
935 d14ed18c Miroslav Rezanina
936 d14ed18c Miroslav Rezanina
    /* Initialize before goto out */
937 d14ed18c Miroslav Rezanina
    qemu_progress_init(progress, 2.0);
938 d14ed18c Miroslav Rezanina
939 d14ed18c Miroslav Rezanina
    bs1 = bdrv_new_open(filename1, fmt1, BDRV_O_FLAGS, true, quiet);
940 d14ed18c Miroslav Rezanina
    if (!bs1) {
941 d14ed18c Miroslav Rezanina
        error_report("Can't open file %s", filename1);
942 d14ed18c Miroslav Rezanina
        ret = 2;
943 d14ed18c Miroslav Rezanina
        goto out3;
944 d14ed18c Miroslav Rezanina
    }
945 d14ed18c Miroslav Rezanina
946 d14ed18c Miroslav Rezanina
    bs2 = bdrv_new_open(filename2, fmt2, BDRV_O_FLAGS, true, quiet);
947 d14ed18c Miroslav Rezanina
    if (!bs2) {
948 d14ed18c Miroslav Rezanina
        error_report("Can't open file %s", filename2);
949 d14ed18c Miroslav Rezanina
        ret = 2;
950 d14ed18c Miroslav Rezanina
        goto out2;
951 d14ed18c Miroslav Rezanina
    }
952 d14ed18c Miroslav Rezanina
953 d14ed18c Miroslav Rezanina
    buf1 = qemu_blockalign(bs1, IO_BUF_SIZE);
954 d14ed18c Miroslav Rezanina
    buf2 = qemu_blockalign(bs2, IO_BUF_SIZE);
955 d14ed18c Miroslav Rezanina
    bdrv_get_geometry(bs1, &bs_sectors);
956 d14ed18c Miroslav Rezanina
    total_sectors1 = bs_sectors;
957 d14ed18c Miroslav Rezanina
    bdrv_get_geometry(bs2, &bs_sectors);
958 d14ed18c Miroslav Rezanina
    total_sectors2 = bs_sectors;
959 d14ed18c Miroslav Rezanina
    total_sectors = MIN(total_sectors1, total_sectors2);
960 d14ed18c Miroslav Rezanina
    progress_base = MAX(total_sectors1, total_sectors2);
961 d14ed18c Miroslav Rezanina
962 d14ed18c Miroslav Rezanina
    qemu_progress_print(0, 100);
963 d14ed18c Miroslav Rezanina
964 d14ed18c Miroslav Rezanina
    if (strict && total_sectors1 != total_sectors2) {
965 d14ed18c Miroslav Rezanina
        ret = 1;
966 d14ed18c Miroslav Rezanina
        qprintf(quiet, "Strict mode: Image size mismatch!\n");
967 d14ed18c Miroslav Rezanina
        goto out;
968 d14ed18c Miroslav Rezanina
    }
969 d14ed18c Miroslav Rezanina
970 d14ed18c Miroslav Rezanina
    for (;;) {
971 d14ed18c Miroslav Rezanina
        nb_sectors = sectors_to_process(total_sectors, sector_num);
972 d14ed18c Miroslav Rezanina
        if (nb_sectors <= 0) {
973 d14ed18c Miroslav Rezanina
            break;
974 d14ed18c Miroslav Rezanina
        }
975 d14ed18c Miroslav Rezanina
        allocated1 = bdrv_is_allocated_above(bs1, NULL, sector_num, nb_sectors,
976 d14ed18c Miroslav Rezanina
                                             &pnum1);
977 d14ed18c Miroslav Rezanina
        if (allocated1 < 0) {
978 d14ed18c Miroslav Rezanina
            ret = 3;
979 d14ed18c Miroslav Rezanina
            error_report("Sector allocation test failed for %s", filename1);
980 d14ed18c Miroslav Rezanina
            goto out;
981 d14ed18c Miroslav Rezanina
        }
982 d14ed18c Miroslav Rezanina
983 d14ed18c Miroslav Rezanina
        allocated2 = bdrv_is_allocated_above(bs2, NULL, sector_num, nb_sectors,
984 d14ed18c Miroslav Rezanina
                                             &pnum2);
985 d14ed18c Miroslav Rezanina
        if (allocated2 < 0) {
986 d14ed18c Miroslav Rezanina
            ret = 3;
987 d14ed18c Miroslav Rezanina
            error_report("Sector allocation test failed for %s", filename2);
988 d14ed18c Miroslav Rezanina
            goto out;
989 d14ed18c Miroslav Rezanina
        }
990 d14ed18c Miroslav Rezanina
        nb_sectors = MIN(pnum1, pnum2);
991 d14ed18c Miroslav Rezanina
992 d14ed18c Miroslav Rezanina
        if (allocated1 == allocated2) {
993 d14ed18c Miroslav Rezanina
            if (allocated1) {
994 d14ed18c Miroslav Rezanina
                ret = bdrv_read(bs1, sector_num, buf1, nb_sectors);
995 d14ed18c Miroslav Rezanina
                if (ret < 0) {
996 d14ed18c Miroslav Rezanina
                    error_report("Error while reading offset %" PRId64 " of %s:"
997 d14ed18c Miroslav Rezanina
                                 " %s", sectors_to_bytes(sector_num), filename1,
998 d14ed18c Miroslav Rezanina
                                 strerror(-ret));
999 d14ed18c Miroslav Rezanina
                    ret = 4;
1000 d14ed18c Miroslav Rezanina
                    goto out;
1001 d14ed18c Miroslav Rezanina
                }
1002 d14ed18c Miroslav Rezanina
                ret = bdrv_read(bs2, sector_num, buf2, nb_sectors);
1003 d14ed18c Miroslav Rezanina
                if (ret < 0) {
1004 d14ed18c Miroslav Rezanina
                    error_report("Error while reading offset %" PRId64
1005 d14ed18c Miroslav Rezanina
                                 " of %s: %s", sectors_to_bytes(sector_num),
1006 d14ed18c Miroslav Rezanina
                                 filename2, strerror(-ret));
1007 d14ed18c Miroslav Rezanina
                    ret = 4;
1008 d14ed18c Miroslav Rezanina
                    goto out;
1009 d14ed18c Miroslav Rezanina
                }
1010 d14ed18c Miroslav Rezanina
                ret = compare_sectors(buf1, buf2, nb_sectors, &pnum);
1011 d14ed18c Miroslav Rezanina
                if (ret || pnum != nb_sectors) {
1012 d14ed18c Miroslav Rezanina
                    ret = 1;
1013 d14ed18c Miroslav Rezanina
                    qprintf(quiet, "Content mismatch at offset %" PRId64 "!\n",
1014 d14ed18c Miroslav Rezanina
                            sectors_to_bytes(
1015 d14ed18c Miroslav Rezanina
                                ret ? sector_num : sector_num + pnum));
1016 d14ed18c Miroslav Rezanina
                    goto out;
1017 d14ed18c Miroslav Rezanina
                }
1018 d14ed18c Miroslav Rezanina
            }
1019 d14ed18c Miroslav Rezanina
        } else {
1020 d14ed18c Miroslav Rezanina
            if (strict) {
1021 d14ed18c Miroslav Rezanina
                ret = 1;
1022 d14ed18c Miroslav Rezanina
                qprintf(quiet, "Strict mode: Offset %" PRId64
1023 d14ed18c Miroslav Rezanina
                        " allocation mismatch!\n",
1024 d14ed18c Miroslav Rezanina
                        sectors_to_bytes(sector_num));
1025 d14ed18c Miroslav Rezanina
                goto out;
1026 d14ed18c Miroslav Rezanina
            }
1027 d14ed18c Miroslav Rezanina
1028 d14ed18c Miroslav Rezanina
            if (allocated1) {
1029 d14ed18c Miroslav Rezanina
                ret = check_empty_sectors(bs1, sector_num, nb_sectors,
1030 d14ed18c Miroslav Rezanina
                                          filename1, buf1, quiet);
1031 d14ed18c Miroslav Rezanina
            } else {
1032 d14ed18c Miroslav Rezanina
                ret = check_empty_sectors(bs2, sector_num, nb_sectors,
1033 d14ed18c Miroslav Rezanina
                                          filename2, buf1, quiet);
1034 d14ed18c Miroslav Rezanina
            }
1035 d14ed18c Miroslav Rezanina
            if (ret) {
1036 d14ed18c Miroslav Rezanina
                if (ret < 0) {
1037 d14ed18c Miroslav Rezanina
                    ret = 4;
1038 d14ed18c Miroslav Rezanina
                    error_report("Error while reading offset %" PRId64 ": %s",
1039 d14ed18c Miroslav Rezanina
                                 sectors_to_bytes(sector_num), strerror(-ret));
1040 d14ed18c Miroslav Rezanina
                }
1041 d14ed18c Miroslav Rezanina
                goto out;
1042 d14ed18c Miroslav Rezanina
            }
1043 d14ed18c Miroslav Rezanina
        }
1044 d14ed18c Miroslav Rezanina
        sector_num += nb_sectors;
1045 d14ed18c Miroslav Rezanina
        qemu_progress_print(((float) nb_sectors / progress_base)*100, 100);
1046 d14ed18c Miroslav Rezanina
    }
1047 d14ed18c Miroslav Rezanina
1048 d14ed18c Miroslav Rezanina
    if (total_sectors1 != total_sectors2) {
1049 d14ed18c Miroslav Rezanina
        BlockDriverState *bs_over;
1050 d14ed18c Miroslav Rezanina
        int64_t total_sectors_over;
1051 d14ed18c Miroslav Rezanina
        const char *filename_over;
1052 d14ed18c Miroslav Rezanina
1053 d14ed18c Miroslav Rezanina
        qprintf(quiet, "Warning: Image size mismatch!\n");
1054 d14ed18c Miroslav Rezanina
        if (total_sectors1 > total_sectors2) {
1055 d14ed18c Miroslav Rezanina
            total_sectors_over = total_sectors1;
1056 d14ed18c Miroslav Rezanina
            bs_over = bs1;
1057 d14ed18c Miroslav Rezanina
            filename_over = filename1;
1058 d14ed18c Miroslav Rezanina
        } else {
1059 d14ed18c Miroslav Rezanina
            total_sectors_over = total_sectors2;
1060 d14ed18c Miroslav Rezanina
            bs_over = bs2;
1061 d14ed18c Miroslav Rezanina
            filename_over = filename2;
1062 d14ed18c Miroslav Rezanina
        }
1063 d14ed18c Miroslav Rezanina
1064 d14ed18c Miroslav Rezanina
        for (;;) {
1065 d14ed18c Miroslav Rezanina
            nb_sectors = sectors_to_process(total_sectors_over, sector_num);
1066 d14ed18c Miroslav Rezanina
            if (nb_sectors <= 0) {
1067 d14ed18c Miroslav Rezanina
                break;
1068 d14ed18c Miroslav Rezanina
            }
1069 d14ed18c Miroslav Rezanina
            ret = bdrv_is_allocated_above(bs_over, NULL, sector_num,
1070 d14ed18c Miroslav Rezanina
                                          nb_sectors, &pnum);
1071 d14ed18c Miroslav Rezanina
            if (ret < 0) {
1072 d14ed18c Miroslav Rezanina
                ret = 3;
1073 d14ed18c Miroslav Rezanina
                error_report("Sector allocation test failed for %s",
1074 d14ed18c Miroslav Rezanina
                             filename_over);
1075 d14ed18c Miroslav Rezanina
                goto out;
1076 d14ed18c Miroslav Rezanina
1077 d14ed18c Miroslav Rezanina
            }
1078 d14ed18c Miroslav Rezanina
            nb_sectors = pnum;
1079 d14ed18c Miroslav Rezanina
            if (ret) {
1080 d14ed18c Miroslav Rezanina
                ret = check_empty_sectors(bs_over, sector_num, nb_sectors,
1081 d14ed18c Miroslav Rezanina
                                          filename_over, buf1, quiet);
1082 d14ed18c Miroslav Rezanina
                if (ret) {
1083 d14ed18c Miroslav Rezanina
                    if (ret < 0) {
1084 d14ed18c Miroslav Rezanina
                        ret = 4;
1085 d14ed18c Miroslav Rezanina
                        error_report("Error while reading offset %" PRId64
1086 d14ed18c Miroslav Rezanina
                                     " of %s: %s", sectors_to_bytes(sector_num),
1087 d14ed18c Miroslav Rezanina
                                     filename_over, strerror(-ret));
1088 d14ed18c Miroslav Rezanina
                    }
1089 d14ed18c Miroslav Rezanina
                    goto out;
1090 d14ed18c Miroslav Rezanina
                }
1091 d14ed18c Miroslav Rezanina
            }
1092 d14ed18c Miroslav Rezanina
            sector_num += nb_sectors;
1093 d14ed18c Miroslav Rezanina
            qemu_progress_print(((float) nb_sectors / progress_base)*100, 100);
1094 d14ed18c Miroslav Rezanina
        }
1095 d14ed18c Miroslav Rezanina
    }
1096 d14ed18c Miroslav Rezanina
1097 d14ed18c Miroslav Rezanina
    qprintf(quiet, "Images are identical.\n");
1098 d14ed18c Miroslav Rezanina
    ret = 0;
1099 d14ed18c Miroslav Rezanina
1100 d14ed18c Miroslav Rezanina
out:
1101 d14ed18c Miroslav Rezanina
    bdrv_delete(bs2);
1102 d14ed18c Miroslav Rezanina
    qemu_vfree(buf1);
1103 d14ed18c Miroslav Rezanina
    qemu_vfree(buf2);
1104 d14ed18c Miroslav Rezanina
out2:
1105 d14ed18c Miroslav Rezanina
    bdrv_delete(bs1);
1106 d14ed18c Miroslav Rezanina
out3:
1107 d14ed18c Miroslav Rezanina
    qemu_progress_end();
1108 d14ed18c Miroslav Rezanina
    return ret;
1109 d14ed18c Miroslav Rezanina
}
1110 d14ed18c Miroslav Rezanina
1111 ea2384d3 bellard
static int img_convert(int argc, char **argv)
1112 ea2384d3 bellard
{
1113 eec77d9e Jes Sorensen
    int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;
1114 661a0f71 Federico Simoncelli
    int progress = 0, flags;
1115 661a0f71 Federico Simoncelli
    const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename;
1116 b50cbabc MORITA Kazutaka
    BlockDriver *drv, *proto_drv;
1117 c2abccec MORITA Kazutaka
    BlockDriverState **bs = NULL, *out_bs = NULL;
1118 96b8f136 ths
    int64_t total_sectors, nb_sectors, sector_num, bs_offset;
1119 96b8f136 ths
    uint64_t bs_sectors;
1120 c2abccec MORITA Kazutaka
    uint8_t * buf = NULL;
1121 ea2384d3 bellard
    const uint8_t *buf1;
1122 faea38e7 bellard
    BlockDriverInfo bdi;
1123 b50cbabc MORITA Kazutaka
    QEMUOptionParameter *param = NULL, *create_options = NULL;
1124 a18953fb Kevin Wolf
    QEMUOptionParameter *out_baseimg_param;
1125 efa84d43 Kevin Wolf
    char *options = NULL;
1126 51ef6727 edison
    const char *snapshot_name = NULL;
1127 1f710495 Kevin Wolf
    float local_progress = 0;
1128 a22f123c Kevin Wolf
    int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */
1129 f382d43a Miroslav Rezanina
    bool quiet = false;
1130 ea2384d3 bellard
1131 ea2384d3 bellard
    fmt = NULL;
1132 ea2384d3 bellard
    out_fmt = "raw";
1133 661a0f71 Federico Simoncelli
    cache = "unsafe";
1134 f58c7b35 ths
    out_baseimg = NULL;
1135 eec77d9e Jes Sorensen
    compress = 0;
1136 ea2384d3 bellard
    for(;;) {
1137 f382d43a Miroslav Rezanina
        c = getopt(argc, argv, "f:O:B:s:hce6o:pS:t:q");
1138 b8fb60da Jes Sorensen
        if (c == -1) {
1139 ea2384d3 bellard
            break;
1140 b8fb60da Jes Sorensen
        }
1141 ea2384d3 bellard
        switch(c) {
1142 ef87394c Jes Sorensen
        case '?':
1143 ea2384d3 bellard
        case 'h':
1144 ea2384d3 bellard
            help();
1145 ea2384d3 bellard
            break;
1146 ea2384d3 bellard
        case 'f':
1147 ea2384d3 bellard
            fmt = optarg;
1148 ea2384d3 bellard
            break;
1149 ea2384d3 bellard
        case 'O':
1150 ea2384d3 bellard
            out_fmt = optarg;
1151 ea2384d3 bellard
            break;
1152 f58c7b35 ths
        case 'B':
1153 f58c7b35 ths
            out_baseimg = optarg;
1154 f58c7b35 ths
            break;
1155 ea2384d3 bellard
        case 'c':
1156 eec77d9e Jes Sorensen
            compress = 1;
1157 ea2384d3 bellard
            break;
1158 ea2384d3 bellard
        case 'e':
1159 9d42e15d Markus Armbruster
            error_report("option -e is deprecated, please use \'-o "
1160 eec77d9e Jes Sorensen
                  "encryption\' instead!");
1161 eec77d9e Jes Sorensen
            return 1;
1162 ec36ba14 ths
        case '6':
1163 9d42e15d Markus Armbruster
            error_report("option -6 is deprecated, please use \'-o "
1164 eec77d9e Jes Sorensen
                  "compat6\' instead!");
1165 eec77d9e Jes Sorensen
            return 1;
1166 efa84d43 Kevin Wolf
        case 'o':
1167 efa84d43 Kevin Wolf
            options = optarg;
1168 efa84d43 Kevin Wolf
            break;
1169 51ef6727 edison
        case 's':
1170 51ef6727 edison
            snapshot_name = optarg;
1171 51ef6727 edison
            break;
1172 a22f123c Kevin Wolf
        case 'S':
1173 a22f123c Kevin Wolf
        {
1174 a22f123c Kevin Wolf
            int64_t sval;
1175 e36b3695 Markus Armbruster
            char *end;
1176 e36b3695 Markus Armbruster
            sval = strtosz_suffix(optarg, &end, STRTOSZ_DEFSUFFIX_B);
1177 e36b3695 Markus Armbruster
            if (sval < 0 || *end) {
1178 a22f123c Kevin Wolf
                error_report("Invalid minimum zero buffer size for sparse output specified");
1179 a22f123c Kevin Wolf
                return 1;
1180 a22f123c Kevin Wolf
            }
1181 a22f123c Kevin Wolf
1182 a22f123c Kevin Wolf
            min_sparse = sval / BDRV_SECTOR_SIZE;
1183 a22f123c Kevin Wolf
            break;
1184 a22f123c Kevin Wolf
        }
1185 6b837bc4 Jes Sorensen
        case 'p':
1186 6b837bc4 Jes Sorensen
            progress = 1;
1187 6b837bc4 Jes Sorensen
            break;
1188 661a0f71 Federico Simoncelli
        case 't':
1189 661a0f71 Federico Simoncelli
            cache = optarg;
1190 661a0f71 Federico Simoncelli
            break;
1191 f382d43a Miroslav Rezanina
        case 'q':
1192 f382d43a Miroslav Rezanina
            quiet = true;
1193 f382d43a Miroslav Rezanina
            break;
1194 ea2384d3 bellard
        }
1195 ea2384d3 bellard
    }
1196 3b46e624 ths
1197 f382d43a Miroslav Rezanina
    if (quiet) {
1198 f382d43a Miroslav Rezanina
        progress = 0;
1199 f382d43a Miroslav Rezanina
    }
1200 f382d43a Miroslav Rezanina
1201 926c2d23 balrog
    bs_n = argc - optind - 1;
1202 b8fb60da Jes Sorensen
    if (bs_n < 1) {
1203 b8fb60da Jes Sorensen
        help();
1204 b8fb60da Jes Sorensen
    }
1205 926c2d23 balrog
1206 926c2d23 balrog
    out_filename = argv[argc - 1];
1207 f58c7b35 ths
1208 fa170c14 Charles Arnold
    /* Initialize before goto out */
1209 fa170c14 Charles Arnold
    qemu_progress_init(progress, 2.0);
1210 fa170c14 Charles Arnold
1211 c8057f95 Peter Maydell
    if (options && is_help_option(options)) {
1212 4ac8aacd Jes Sorensen
        ret = print_block_option_help(out_filename, out_fmt);
1213 4ac8aacd Jes Sorensen
        goto out;
1214 4ac8aacd Jes Sorensen
    }
1215 4ac8aacd Jes Sorensen
1216 c2abccec MORITA Kazutaka
    if (bs_n > 1 && out_baseimg) {
1217 15654a6d Jes Sorensen
        error_report("-B makes no sense when concatenating multiple input "
1218 15654a6d Jes Sorensen
                     "images");
1219 31ca34b8 Jes Sorensen
        ret = -1;
1220 31ca34b8 Jes Sorensen
        goto out;
1221 c2abccec MORITA Kazutaka
    }
1222 f8111c24 Dong Xu Wang
1223 6b837bc4 Jes Sorensen
    qemu_progress_print(0, 100);
1224 6b837bc4 Jes Sorensen
1225 7267c094 Anthony Liguori
    bs = g_malloc0(bs_n * sizeof(BlockDriverState *));
1226 926c2d23 balrog
1227 926c2d23 balrog
    total_sectors = 0;
1228 926c2d23 balrog
    for (bs_i = 0; bs_i < bs_n; bs_i++) {
1229 f382d43a Miroslav Rezanina
        bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS, true,
1230 f382d43a Miroslav Rezanina
                                 quiet);
1231 c2abccec MORITA Kazutaka
        if (!bs[bs_i]) {
1232 15654a6d Jes Sorensen
            error_report("Could not open '%s'", argv[optind + bs_i]);
1233 c2abccec MORITA Kazutaka
            ret = -1;
1234 c2abccec MORITA Kazutaka
            goto out;
1235 c2abccec MORITA Kazutaka
        }
1236 926c2d23 balrog
        bdrv_get_geometry(bs[bs_i], &bs_sectors);
1237 926c2d23 balrog
        total_sectors += bs_sectors;
1238 926c2d23 balrog
    }
1239 ea2384d3 bellard
1240 51ef6727 edison
    if (snapshot_name != NULL) {
1241 51ef6727 edison
        if (bs_n > 1) {
1242 6daf194d Markus Armbruster
            error_report("No support for concatenating multiple snapshot");
1243 51ef6727 edison
            ret = -1;
1244 51ef6727 edison
            goto out;
1245 51ef6727 edison
        }
1246 51ef6727 edison
        if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
1247 6daf194d Markus Armbruster
            error_report("Failed to load snapshot");
1248 51ef6727 edison
            ret = -1;
1249 51ef6727 edison
            goto out;
1250 51ef6727 edison
        }
1251 51ef6727 edison
    }
1252 51ef6727 edison
1253 efa84d43 Kevin Wolf
    /* Find driver and parse its options */
1254 ea2384d3 bellard
    drv = bdrv_find_format(out_fmt);
1255 c2abccec MORITA Kazutaka
    if (!drv) {
1256 15654a6d Jes Sorensen
        error_report("Unknown file format '%s'", out_fmt);
1257 c2abccec MORITA Kazutaka
        ret = -1;
1258 c2abccec MORITA Kazutaka
        goto out;
1259 c2abccec MORITA Kazutaka
    }
1260 efa84d43 Kevin Wolf
1261 b50cbabc MORITA Kazutaka
    proto_drv = bdrv_find_protocol(out_filename);
1262 c2abccec MORITA Kazutaka
    if (!proto_drv) {
1263 15654a6d Jes Sorensen
        error_report("Unknown protocol '%s'", out_filename);
1264 c2abccec MORITA Kazutaka
        ret = -1;
1265 c2abccec MORITA Kazutaka
        goto out;
1266 c2abccec MORITA Kazutaka
    }
1267 b50cbabc MORITA Kazutaka
1268 b50cbabc MORITA Kazutaka
    create_options = append_option_parameters(create_options,
1269 b50cbabc MORITA Kazutaka
                                              drv->create_options);
1270 b50cbabc MORITA Kazutaka
    create_options = append_option_parameters(create_options,
1271 b50cbabc MORITA Kazutaka
                                              proto_drv->create_options);
1272 db08adf5 Kevin Wolf
1273 efa84d43 Kevin Wolf
    if (options) {
1274 b50cbabc MORITA Kazutaka
        param = parse_option_parameters(options, create_options, param);
1275 efa84d43 Kevin Wolf
        if (param == NULL) {
1276 15654a6d Jes Sorensen
            error_report("Invalid options for file format '%s'.", out_fmt);
1277 c2abccec MORITA Kazutaka
            ret = -1;
1278 c2abccec MORITA Kazutaka
            goto out;
1279 efa84d43 Kevin Wolf
        }
1280 efa84d43 Kevin Wolf
    } else {
1281 b50cbabc MORITA Kazutaka
        param = parse_option_parameters("", create_options, param);
1282 efa84d43 Kevin Wolf
    }
1283 efa84d43 Kevin Wolf
1284 efa84d43 Kevin Wolf
    set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
1285 eec77d9e Jes Sorensen
    ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);
1286 c2abccec MORITA Kazutaka
    if (ret < 0) {
1287 c2abccec MORITA Kazutaka
        goto out;
1288 c2abccec MORITA Kazutaka
    }
1289 efa84d43 Kevin Wolf
1290 a18953fb Kevin Wolf
    /* Get backing file name if -o backing_file was used */
1291 a18953fb Kevin Wolf
    out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
1292 a18953fb Kevin Wolf
    if (out_baseimg_param) {
1293 a18953fb Kevin Wolf
        out_baseimg = out_baseimg_param->value.s;
1294 a18953fb Kevin Wolf
    }
1295 a18953fb Kevin Wolf
1296 efa84d43 Kevin Wolf
    /* Check if compression is supported */
1297 eec77d9e Jes Sorensen
    if (compress) {
1298 efa84d43 Kevin Wolf
        QEMUOptionParameter *encryption =
1299 efa84d43 Kevin Wolf
            get_option_parameter(param, BLOCK_OPT_ENCRYPT);
1300 41521fa4 Kevin Wolf
        QEMUOptionParameter *preallocation =
1301 41521fa4 Kevin Wolf
            get_option_parameter(param, BLOCK_OPT_PREALLOC);
1302 efa84d43 Kevin Wolf
1303 efa84d43 Kevin Wolf
        if (!drv->bdrv_write_compressed) {
1304 15654a6d Jes Sorensen
            error_report("Compression not supported for this file format");
1305 c2abccec MORITA Kazutaka
            ret = -1;
1306 c2abccec MORITA Kazutaka
            goto out;
1307 efa84d43 Kevin Wolf
        }
1308 efa84d43 Kevin Wolf
1309 efa84d43 Kevin Wolf
        if (encryption && encryption->value.n) {
1310 15654a6d Jes Sorensen
            error_report("Compression and encryption not supported at "
1311 15654a6d Jes Sorensen
                         "the same time");
1312 c2abccec MORITA Kazutaka
            ret = -1;
1313 c2abccec MORITA Kazutaka
            goto out;
1314 efa84d43 Kevin Wolf
        }
1315 41521fa4 Kevin Wolf
1316 41521fa4 Kevin Wolf
        if (preallocation && preallocation->value.s
1317 41521fa4 Kevin Wolf
            && strcmp(preallocation->value.s, "off"))
1318 41521fa4 Kevin Wolf
        {
1319 41521fa4 Kevin Wolf
            error_report("Compression and preallocation not supported at "
1320 41521fa4 Kevin Wolf
                         "the same time");
1321 41521fa4 Kevin Wolf
            ret = -1;
1322 41521fa4 Kevin Wolf
            goto out;
1323 41521fa4 Kevin Wolf
        }
1324 efa84d43 Kevin Wolf
    }
1325 efa84d43 Kevin Wolf
1326 efa84d43 Kevin Wolf
    /* Create the new image */
1327 efa84d43 Kevin Wolf
    ret = bdrv_create(drv, out_filename, param);
1328 ea2384d3 bellard
    if (ret < 0) {
1329 ea2384d3 bellard
        if (ret == -ENOTSUP) {
1330 15654a6d Jes Sorensen
            error_report("Formatting not supported for file format '%s'",
1331 15654a6d Jes Sorensen
                         out_fmt);
1332 6e9ea0c0 aurel32
        } else if (ret == -EFBIG) {
1333 15654a6d Jes Sorensen
            error_report("The image size is too large for file format '%s'",
1334 15654a6d Jes Sorensen
                         out_fmt);
1335 ea2384d3 bellard
        } else {
1336 15654a6d Jes Sorensen
            error_report("%s: error while converting %s: %s",
1337 15654a6d Jes Sorensen
                         out_filename, out_fmt, strerror(-ret));
1338 ea2384d3 bellard
        }
1339 c2abccec MORITA Kazutaka
        goto out;
1340 ea2384d3 bellard
    }
1341 3b46e624 ths
1342 661a0f71 Federico Simoncelli
    flags = BDRV_O_RDWR;
1343 c3993cdc Stefan Hajnoczi
    ret = bdrv_parse_cache_flags(cache, &flags);
1344 661a0f71 Federico Simoncelli
    if (ret < 0) {
1345 661a0f71 Federico Simoncelli
        error_report("Invalid cache option: %s", cache);
1346 661a0f71 Federico Simoncelli
        return -1;
1347 661a0f71 Federico Simoncelli
    }
1348 661a0f71 Federico Simoncelli
1349 f382d43a Miroslav Rezanina
    out_bs = bdrv_new_open(out_filename, out_fmt, flags, true, quiet);
1350 c2abccec MORITA Kazutaka
    if (!out_bs) {
1351 c2abccec MORITA Kazutaka
        ret = -1;
1352 c2abccec MORITA Kazutaka
        goto out;
1353 c2abccec MORITA Kazutaka
    }
1354 ea2384d3 bellard
1355 926c2d23 balrog
    bs_i = 0;
1356 926c2d23 balrog
    bs_offset = 0;
1357 926c2d23 balrog
    bdrv_get_geometry(bs[0], &bs_sectors);
1358 bb1c0597 Kevin Wolf
    buf = qemu_blockalign(out_bs, IO_BUF_SIZE);
1359 926c2d23 balrog
1360 eec77d9e Jes Sorensen
    if (compress) {
1361 c2abccec MORITA Kazutaka
        ret = bdrv_get_info(out_bs, &bdi);
1362 c2abccec MORITA Kazutaka
        if (ret < 0) {
1363 15654a6d Jes Sorensen
            error_report("could not get block driver info");
1364 c2abccec MORITA Kazutaka
            goto out;
1365 c2abccec MORITA Kazutaka
        }
1366 faea38e7 bellard
        cluster_size = bdi.cluster_size;
1367 c2abccec MORITA Kazutaka
        if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
1368 15654a6d Jes Sorensen
            error_report("invalid cluster size");
1369 c2abccec MORITA Kazutaka
            ret = -1;
1370 c2abccec MORITA Kazutaka
            goto out;
1371 c2abccec MORITA Kazutaka
        }
1372 ea2384d3 bellard
        cluster_sectors = cluster_size >> 9;
1373 ea2384d3 bellard
        sector_num = 0;
1374 6b837bc4 Jes Sorensen
1375 6b837bc4 Jes Sorensen
        nb_sectors = total_sectors;
1376 1f710495 Kevin Wolf
        if (nb_sectors != 0) {
1377 1f710495 Kevin Wolf
            local_progress = (float)100 /
1378 1f710495 Kevin Wolf
                (nb_sectors / MIN(nb_sectors, cluster_sectors));
1379 1f710495 Kevin Wolf
        }
1380 6b837bc4 Jes Sorensen
1381 ea2384d3 bellard
        for(;;) {
1382 926c2d23 balrog
            int64_t bs_num;
1383 926c2d23 balrog
            int remainder;
1384 926c2d23 balrog
            uint8_t *buf2;
1385 926c2d23 balrog
1386 ea2384d3 bellard
            nb_sectors = total_sectors - sector_num;
1387 ea2384d3 bellard
            if (nb_sectors <= 0)
1388 ea2384d3 bellard
                break;
1389 ea2384d3 bellard
            if (nb_sectors >= cluster_sectors)
1390 ea2384d3 bellard
                n = cluster_sectors;
1391 ea2384d3 bellard
            else
1392 ea2384d3 bellard
                n = nb_sectors;
1393 926c2d23 balrog
1394 926c2d23 balrog
            bs_num = sector_num - bs_offset;
1395 926c2d23 balrog
            assert (bs_num >= 0);
1396 926c2d23 balrog
            remainder = n;
1397 926c2d23 balrog
            buf2 = buf;
1398 926c2d23 balrog
            while (remainder > 0) {
1399 926c2d23 balrog
                int nlow;
1400 926c2d23 balrog
                while (bs_num == bs_sectors) {
1401 926c2d23 balrog
                    bs_i++;
1402 926c2d23 balrog
                    assert (bs_i < bs_n);
1403 926c2d23 balrog
                    bs_offset += bs_sectors;
1404 926c2d23 balrog
                    bdrv_get_geometry(bs[bs_i], &bs_sectors);
1405 926c2d23 balrog
                    bs_num = 0;
1406 0bfcd599 Blue Swirl
                    /* printf("changing part: sector_num=%" PRId64 ", "
1407 0bfcd599 Blue Swirl
                       "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64
1408 0bfcd599 Blue Swirl
                       "\n", sector_num, bs_i, bs_offset, bs_sectors); */
1409 926c2d23 balrog
                }
1410 926c2d23 balrog
                assert (bs_num < bs_sectors);
1411 926c2d23 balrog
1412 926c2d23 balrog
                nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
1413 926c2d23 balrog
1414 c2abccec MORITA Kazutaka
                ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
1415 c2abccec MORITA Kazutaka
                if (ret < 0) {
1416 3fba9d81 Stefan Hajnoczi
                    error_report("error while reading sector %" PRId64 ": %s",
1417 3fba9d81 Stefan Hajnoczi
                                 bs_num, strerror(-ret));
1418 c2abccec MORITA Kazutaka
                    goto out;
1419 c2abccec MORITA Kazutaka
                }
1420 926c2d23 balrog
1421 926c2d23 balrog
                buf2 += nlow * 512;
1422 926c2d23 balrog
                bs_num += nlow;
1423 926c2d23 balrog
1424 926c2d23 balrog
                remainder -= nlow;
1425 926c2d23 balrog
            }
1426 926c2d23 balrog
            assert (remainder == 0);
1427 926c2d23 balrog
1428 b8fb60da Jes Sorensen
            if (n < cluster_sectors) {
1429 ea2384d3 bellard
                memset(buf + n * 512, 0, cluster_size - n * 512);
1430 b8fb60da Jes Sorensen
            }
1431 1a6d39fd Stefan Hajnoczi
            if (!buffer_is_zero(buf, cluster_size)) {
1432 c2abccec MORITA Kazutaka
                ret = bdrv_write_compressed(out_bs, sector_num, buf,
1433 c2abccec MORITA Kazutaka
                                            cluster_sectors);
1434 c2abccec MORITA Kazutaka
                if (ret != 0) {
1435 3fba9d81 Stefan Hajnoczi
                    error_report("error while compressing sector %" PRId64
1436 3fba9d81 Stefan Hajnoczi
                                 ": %s", sector_num, strerror(-ret));
1437 c2abccec MORITA Kazutaka
                    goto out;
1438 c2abccec MORITA Kazutaka
                }
1439 ea2384d3 bellard
            }
1440 ea2384d3 bellard
            sector_num += n;
1441 6b837bc4 Jes Sorensen
            qemu_progress_print(local_progress, 100);
1442 ea2384d3 bellard
        }
1443 faea38e7 bellard
        /* signal EOF to align */
1444 faea38e7 bellard
        bdrv_write_compressed(out_bs, 0, NULL, 0);
1445 ea2384d3 bellard
    } else {
1446 f2feebbd Kevin Wolf
        int has_zero_init = bdrv_has_zero_init(out_bs);
1447 f2feebbd Kevin Wolf
1448 f58c7b35 ths
        sector_num = 0; // total number of sectors converted so far
1449 6b837bc4 Jes Sorensen
        nb_sectors = total_sectors - sector_num;
1450 1f710495 Kevin Wolf
        if (nb_sectors != 0) {
1451 1f710495 Kevin Wolf
            local_progress = (float)100 /
1452 1f710495 Kevin Wolf
                (nb_sectors / MIN(nb_sectors, IO_BUF_SIZE / 512));
1453 1f710495 Kevin Wolf
        }
1454 6b837bc4 Jes Sorensen
1455 ea2384d3 bellard
        for(;;) {
1456 ea2384d3 bellard
            nb_sectors = total_sectors - sector_num;
1457 b8fb60da Jes Sorensen
            if (nb_sectors <= 0) {
1458 ea2384d3 bellard
                break;
1459 b8fb60da Jes Sorensen
            }
1460 b8fb60da Jes Sorensen
            if (nb_sectors >= (IO_BUF_SIZE / 512)) {
1461 ea2384d3 bellard
                n = (IO_BUF_SIZE / 512);
1462 b8fb60da Jes Sorensen
            } else {
1463 ea2384d3 bellard
                n = nb_sectors;
1464 b8fb60da Jes Sorensen
            }
1465 926c2d23 balrog
1466 926c2d23 balrog
            while (sector_num - bs_offset >= bs_sectors) {
1467 926c2d23 balrog
                bs_i ++;
1468 926c2d23 balrog
                assert (bs_i < bs_n);
1469 926c2d23 balrog
                bs_offset += bs_sectors;
1470 926c2d23 balrog
                bdrv_get_geometry(bs[bs_i], &bs_sectors);
1471 0bfcd599 Blue Swirl
                /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "
1472 0bfcd599 Blue Swirl
                  "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",
1473 926c2d23 balrog
                   sector_num, bs_i, bs_offset, bs_sectors); */
1474 926c2d23 balrog
            }
1475 926c2d23 balrog
1476 b8fb60da Jes Sorensen
            if (n > bs_offset + bs_sectors - sector_num) {
1477 926c2d23 balrog
                n = bs_offset + bs_sectors - sector_num;
1478 b8fb60da Jes Sorensen
            }
1479 926c2d23 balrog
1480 f2feebbd Kevin Wolf
            if (has_zero_init) {
1481 d032044f Akkarit Sangpetch
                /* If the output image is being created as a copy on write image,
1482 d032044f Akkarit Sangpetch
                   assume that sectors which are unallocated in the input image
1483 d032044f Akkarit Sangpetch
                   are present in both the output's and input's base images (no
1484 d032044f Akkarit Sangpetch
                   need to copy them). */
1485 d032044f Akkarit Sangpetch
                if (out_baseimg) {
1486 d032044f Akkarit Sangpetch
                    if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
1487 d032044f Akkarit Sangpetch
                                           n, &n1)) {
1488 d032044f Akkarit Sangpetch
                        sector_num += n1;
1489 d032044f Akkarit Sangpetch
                        continue;
1490 d032044f Akkarit Sangpetch
                    }
1491 d032044f Akkarit Sangpetch
                    /* The next 'n1' sectors are allocated in the input image. Copy
1492 d032044f Akkarit Sangpetch
                       only those as they may be followed by unallocated sectors. */
1493 d032044f Akkarit Sangpetch
                    n = n1;
1494 93c65b47 aliguori
                }
1495 93c65b47 aliguori
            } else {
1496 93c65b47 aliguori
                n1 = n;
1497 f58c7b35 ths
            }
1498 f58c7b35 ths
1499 c2abccec MORITA Kazutaka
            ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
1500 c2abccec MORITA Kazutaka
            if (ret < 0) {
1501 3fba9d81 Stefan Hajnoczi
                error_report("error while reading sector %" PRId64 ": %s",
1502 3fba9d81 Stefan Hajnoczi
                             sector_num - bs_offset, strerror(-ret));
1503 c2abccec MORITA Kazutaka
                goto out;
1504 c2abccec MORITA Kazutaka
            }
1505 ea2384d3 bellard
            /* NOTE: at the same time we convert, we do not write zero
1506 ea2384d3 bellard
               sectors to have a chance to compress the image. Ideally, we
1507 ea2384d3 bellard
               should add a specific call to have the info to go faster */
1508 ea2384d3 bellard
            buf1 = buf;
1509 ea2384d3 bellard
            while (n > 0) {
1510 f58c7b35 ths
                /* If the output image is being created as a copy on write image,
1511 f58c7b35 ths
                   copy all sectors even the ones containing only NUL bytes,
1512 93c65b47 aliguori
                   because they may differ from the sectors in the base image.
1513 93c65b47 aliguori

1514 93c65b47 aliguori
                   If the output is to a host device, we also write out
1515 93c65b47 aliguori
                   sectors that are entirely 0, since whatever data was
1516 93c65b47 aliguori
                   already there is garbage, not 0s. */
1517 f2feebbd Kevin Wolf
                if (!has_zero_init || out_baseimg ||
1518 a22f123c Kevin Wolf
                    is_allocated_sectors_min(buf1, n, &n1, min_sparse)) {
1519 c2abccec MORITA Kazutaka
                    ret = bdrv_write(out_bs, sector_num, buf1, n1);
1520 c2abccec MORITA Kazutaka
                    if (ret < 0) {
1521 3fba9d81 Stefan Hajnoczi
                        error_report("error while writing sector %" PRId64
1522 3fba9d81 Stefan Hajnoczi
                                     ": %s", sector_num, strerror(-ret));
1523 c2abccec MORITA Kazutaka
                        goto out;
1524 c2abccec MORITA Kazutaka
                    }
1525 ea2384d3 bellard
                }
1526 ea2384d3 bellard
                sector_num += n1;
1527 ea2384d3 bellard
                n -= n1;
1528 ea2384d3 bellard
                buf1 += n1 * 512;
1529 ea2384d3 bellard
            }
1530 6b837bc4 Jes Sorensen
            qemu_progress_print(local_progress, 100);
1531 ea2384d3 bellard
        }
1532 ea2384d3 bellard
    }
1533 c2abccec MORITA Kazutaka
out:
1534 6b837bc4 Jes Sorensen
    qemu_progress_end();
1535 c2abccec MORITA Kazutaka
    free_option_parameters(create_options);
1536 c2abccec MORITA Kazutaka
    free_option_parameters(param);
1537 bb1c0597 Kevin Wolf
    qemu_vfree(buf);
1538 c2abccec MORITA Kazutaka
    if (out_bs) {
1539 c2abccec MORITA Kazutaka
        bdrv_delete(out_bs);
1540 c2abccec MORITA Kazutaka
    }
1541 31ca34b8 Jes Sorensen
    if (bs) {
1542 31ca34b8 Jes Sorensen
        for (bs_i = 0; bs_i < bs_n; bs_i++) {
1543 31ca34b8 Jes Sorensen
            if (bs[bs_i]) {
1544 31ca34b8 Jes Sorensen
                bdrv_delete(bs[bs_i]);
1545 31ca34b8 Jes Sorensen
            }
1546 c2abccec MORITA Kazutaka
        }
1547 7267c094 Anthony Liguori
        g_free(bs);
1548 c2abccec MORITA Kazutaka
    }
1549 c2abccec MORITA Kazutaka
    if (ret) {
1550 c2abccec MORITA Kazutaka
        return 1;
1551 c2abccec MORITA Kazutaka
    }
1552 ea2384d3 bellard
    return 0;
1553 ea2384d3 bellard
}
1554 ea2384d3 bellard
1555 57d1a2b6 bellard
1556 faea38e7 bellard
static void dump_snapshots(BlockDriverState *bs)
1557 faea38e7 bellard
{
1558 faea38e7 bellard
    QEMUSnapshotInfo *sn_tab, *sn;
1559 faea38e7 bellard
    int nb_sns, i;
1560 faea38e7 bellard
    char buf[256];
1561 faea38e7 bellard
1562 faea38e7 bellard
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1563 faea38e7 bellard
    if (nb_sns <= 0)
1564 faea38e7 bellard
        return;
1565 faea38e7 bellard
    printf("Snapshot list:\n");
1566 faea38e7 bellard
    printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
1567 faea38e7 bellard
    for(i = 0; i < nb_sns; i++) {
1568 faea38e7 bellard
        sn = &sn_tab[i];
1569 faea38e7 bellard
        printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
1570 faea38e7 bellard
    }
1571 7267c094 Anthony Liguori
    g_free(sn_tab);
1572 faea38e7 bellard
}
1573 faea38e7 bellard
1574 9699bf0d Stefan Hajnoczi
static void dump_json_image_info_list(ImageInfoList *list)
1575 9699bf0d Stefan Hajnoczi
{
1576 9699bf0d Stefan Hajnoczi
    Error *errp = NULL;
1577 9699bf0d Stefan Hajnoczi
    QString *str;
1578 9699bf0d Stefan Hajnoczi
    QmpOutputVisitor *ov = qmp_output_visitor_new();
1579 9699bf0d Stefan Hajnoczi
    QObject *obj;
1580 9699bf0d Stefan Hajnoczi
    visit_type_ImageInfoList(qmp_output_get_visitor(ov),
1581 9699bf0d Stefan Hajnoczi
                             &list, NULL, &errp);
1582 9699bf0d Stefan Hajnoczi
    obj = qmp_output_get_qobject(ov);
1583 9699bf0d Stefan Hajnoczi
    str = qobject_to_json_pretty(obj);
1584 9699bf0d Stefan Hajnoczi
    assert(str != NULL);
1585 9699bf0d Stefan Hajnoczi
    printf("%s\n", qstring_get_str(str));
1586 9699bf0d Stefan Hajnoczi
    qobject_decref(obj);
1587 9699bf0d Stefan Hajnoczi
    qmp_output_visitor_cleanup(ov);
1588 9699bf0d Stefan Hajnoczi
    QDECREF(str);
1589 9699bf0d Stefan Hajnoczi
}
1590 9699bf0d Stefan Hajnoczi
1591 c054b3fd Benoît Canet
static void collect_snapshots(BlockDriverState *bs , ImageInfo *info)
1592 c054b3fd Benoît Canet
{
1593 c054b3fd Benoît Canet
    int i, sn_count;
1594 c054b3fd Benoît Canet
    QEMUSnapshotInfo *sn_tab = NULL;
1595 c054b3fd Benoît Canet
    SnapshotInfoList *info_list, *cur_item = NULL;
1596 c054b3fd Benoît Canet
    sn_count = bdrv_snapshot_list(bs, &sn_tab);
1597 c054b3fd Benoît Canet
1598 c054b3fd Benoît Canet
    for (i = 0; i < sn_count; i++) {
1599 c054b3fd Benoît Canet
        info->has_snapshots = true;
1600 c054b3fd Benoît Canet
        info_list = g_new0(SnapshotInfoList, 1);
1601 c054b3fd Benoît Canet
1602 c054b3fd Benoît Canet
        info_list->value                = g_new0(SnapshotInfo, 1);
1603 c054b3fd Benoît Canet
        info_list->value->id            = g_strdup(sn_tab[i].id_str);
1604 c054b3fd Benoît Canet
        info_list->value->name          = g_strdup(sn_tab[i].name);
1605 c054b3fd Benoît Canet
        info_list->value->vm_state_size = sn_tab[i].vm_state_size;
1606 c054b3fd Benoît Canet
        info_list->value->date_sec      = sn_tab[i].date_sec;
1607 c054b3fd Benoît Canet
        info_list->value->date_nsec     = sn_tab[i].date_nsec;
1608 c054b3fd Benoît Canet
        info_list->value->vm_clock_sec  = sn_tab[i].vm_clock_nsec / 1000000000;
1609 c054b3fd Benoît Canet
        info_list->value->vm_clock_nsec = sn_tab[i].vm_clock_nsec % 1000000000;
1610 c054b3fd Benoît Canet
1611 c054b3fd Benoît Canet
        /* XXX: waiting for the qapi to support qemu-queue.h types */
1612 c054b3fd Benoît Canet
        if (!cur_item) {
1613 c054b3fd Benoît Canet
            info->snapshots = cur_item = info_list;
1614 c054b3fd Benoît Canet
        } else {
1615 c054b3fd Benoît Canet
            cur_item->next = info_list;
1616 c054b3fd Benoît Canet
            cur_item = info_list;
1617 c054b3fd Benoît Canet
        }
1618 c054b3fd Benoît Canet
1619 c054b3fd Benoît Canet
    }
1620 c054b3fd Benoît Canet
1621 c054b3fd Benoît Canet
    g_free(sn_tab);
1622 c054b3fd Benoît Canet
}
1623 c054b3fd Benoît Canet
1624 c054b3fd Benoît Canet
static void dump_json_image_info(ImageInfo *info)
1625 c054b3fd Benoît Canet
{
1626 c054b3fd Benoît Canet
    Error *errp = NULL;
1627 c054b3fd Benoît Canet
    QString *str;
1628 c054b3fd Benoît Canet
    QmpOutputVisitor *ov = qmp_output_visitor_new();
1629 c054b3fd Benoît Canet
    QObject *obj;
1630 c054b3fd Benoît Canet
    visit_type_ImageInfo(qmp_output_get_visitor(ov),
1631 c054b3fd Benoît Canet
                         &info, NULL, &errp);
1632 c054b3fd Benoît Canet
    obj = qmp_output_get_qobject(ov);
1633 c054b3fd Benoît Canet
    str = qobject_to_json_pretty(obj);
1634 c054b3fd Benoît Canet
    assert(str != NULL);
1635 c054b3fd Benoît Canet
    printf("%s\n", qstring_get_str(str));
1636 c054b3fd Benoît Canet
    qobject_decref(obj);
1637 c054b3fd Benoît Canet
    qmp_output_visitor_cleanup(ov);
1638 c054b3fd Benoît Canet
    QDECREF(str);
1639 c054b3fd Benoît Canet
}
1640 c054b3fd Benoît Canet
1641 c054b3fd Benoît Canet
static void collect_image_info(BlockDriverState *bs,
1642 c054b3fd Benoît Canet
                   ImageInfo *info,
1643 c054b3fd Benoît Canet
                   const char *filename,
1644 c054b3fd Benoît Canet
                   const char *fmt)
1645 ea2384d3 bellard
{
1646 96b8f136 ths
    uint64_t total_sectors;
1647 93b6b2a3 bellard
    char backing_filename[1024];
1648 93b6b2a3 bellard
    char backing_filename2[1024];
1649 faea38e7 bellard
    BlockDriverInfo bdi;
1650 ea2384d3 bellard
1651 c054b3fd Benoît Canet
    bdrv_get_geometry(bs, &total_sectors);
1652 c054b3fd Benoît Canet
1653 c054b3fd Benoît Canet
    info->filename        = g_strdup(filename);
1654 c054b3fd Benoît Canet
    info->format          = g_strdup(bdrv_get_format_name(bs));
1655 c054b3fd Benoît Canet
    info->virtual_size    = total_sectors * 512;
1656 c054b3fd Benoît Canet
    info->actual_size     = bdrv_get_allocated_file_size(bs);
1657 c054b3fd Benoît Canet
    info->has_actual_size = info->actual_size >= 0;
1658 c054b3fd Benoît Canet
    if (bdrv_is_encrypted(bs)) {
1659 c054b3fd Benoît Canet
        info->encrypted = true;
1660 c054b3fd Benoît Canet
        info->has_encrypted = true;
1661 c054b3fd Benoît Canet
    }
1662 c054b3fd Benoît Canet
    if (bdrv_get_info(bs, &bdi) >= 0) {
1663 c054b3fd Benoît Canet
        if (bdi.cluster_size != 0) {
1664 c054b3fd Benoît Canet
            info->cluster_size = bdi.cluster_size;
1665 c054b3fd Benoît Canet
            info->has_cluster_size = true;
1666 c054b3fd Benoît Canet
        }
1667 c054b3fd Benoît Canet
        info->dirty_flag = bdi.is_dirty;
1668 c054b3fd Benoît Canet
        info->has_dirty_flag = true;
1669 c054b3fd Benoît Canet
    }
1670 c054b3fd Benoît Canet
    bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
1671 c054b3fd Benoît Canet
    if (backing_filename[0] != '\0') {
1672 c054b3fd Benoît Canet
        info->backing_filename = g_strdup(backing_filename);
1673 c054b3fd Benoît Canet
        info->has_backing_filename = true;
1674 c054b3fd Benoît Canet
        bdrv_get_full_backing_filename(bs, backing_filename2,
1675 c054b3fd Benoît Canet
                                       sizeof(backing_filename2));
1676 c054b3fd Benoît Canet
1677 c054b3fd Benoît Canet
        if (strcmp(backing_filename, backing_filename2) != 0) {
1678 c054b3fd Benoît Canet
            info->full_backing_filename =
1679 c054b3fd Benoît Canet
                        g_strdup(backing_filename2);
1680 c054b3fd Benoît Canet
            info->has_full_backing_filename = true;
1681 c054b3fd Benoît Canet
        }
1682 c054b3fd Benoît Canet
1683 c054b3fd Benoît Canet
        if (bs->backing_format[0]) {
1684 c054b3fd Benoît Canet
            info->backing_filename_format = g_strdup(bs->backing_format);
1685 c054b3fd Benoît Canet
            info->has_backing_filename_format = true;
1686 c054b3fd Benoît Canet
        }
1687 c054b3fd Benoît Canet
    }
1688 c054b3fd Benoît Canet
}
1689 c054b3fd Benoît Canet
1690 c054b3fd Benoît Canet
static void dump_human_image_info(ImageInfo *info)
1691 c054b3fd Benoît Canet
{
1692 c054b3fd Benoît Canet
    char size_buf[128], dsize_buf[128];
1693 c054b3fd Benoît Canet
    if (!info->has_actual_size) {
1694 c054b3fd Benoît Canet
        snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
1695 c054b3fd Benoît Canet
    } else {
1696 c054b3fd Benoît Canet
        get_human_readable_size(dsize_buf, sizeof(dsize_buf),
1697 c054b3fd Benoît Canet
                                info->actual_size);
1698 c054b3fd Benoît Canet
    }
1699 c054b3fd Benoît Canet
    get_human_readable_size(size_buf, sizeof(size_buf), info->virtual_size);
1700 c054b3fd Benoît Canet
    printf("image: %s\n"
1701 c054b3fd Benoît Canet
           "file format: %s\n"
1702 c054b3fd Benoît Canet
           "virtual size: %s (%" PRId64 " bytes)\n"
1703 c054b3fd Benoît Canet
           "disk size: %s\n",
1704 c054b3fd Benoît Canet
           info->filename, info->format, size_buf,
1705 c054b3fd Benoît Canet
           info->virtual_size,
1706 c054b3fd Benoît Canet
           dsize_buf);
1707 c054b3fd Benoît Canet
1708 c054b3fd Benoît Canet
    if (info->has_encrypted && info->encrypted) {
1709 c054b3fd Benoît Canet
        printf("encrypted: yes\n");
1710 c054b3fd Benoît Canet
    }
1711 c054b3fd Benoît Canet
1712 c054b3fd Benoît Canet
    if (info->has_cluster_size) {
1713 c054b3fd Benoît Canet
        printf("cluster_size: %" PRId64 "\n", info->cluster_size);
1714 c054b3fd Benoît Canet
    }
1715 c054b3fd Benoît Canet
1716 c054b3fd Benoît Canet
    if (info->has_dirty_flag && info->dirty_flag) {
1717 c054b3fd Benoît Canet
        printf("cleanly shut down: no\n");
1718 c054b3fd Benoît Canet
    }
1719 c054b3fd Benoît Canet
1720 c054b3fd Benoît Canet
    if (info->has_backing_filename) {
1721 c054b3fd Benoît Canet
        printf("backing file: %s", info->backing_filename);
1722 c054b3fd Benoît Canet
        if (info->has_full_backing_filename) {
1723 c054b3fd Benoît Canet
            printf(" (actual path: %s)", info->full_backing_filename);
1724 c054b3fd Benoît Canet
        }
1725 c054b3fd Benoît Canet
        putchar('\n');
1726 c054b3fd Benoît Canet
        if (info->has_backing_filename_format) {
1727 c054b3fd Benoît Canet
            printf("backing file format: %s\n", info->backing_filename_format);
1728 c054b3fd Benoît Canet
        }
1729 c054b3fd Benoît Canet
    }
1730 9699bf0d Stefan Hajnoczi
1731 9699bf0d Stefan Hajnoczi
    if (info->has_snapshots) {
1732 9699bf0d Stefan Hajnoczi
        SnapshotInfoList *elem;
1733 9699bf0d Stefan Hajnoczi
        char buf[256];
1734 9699bf0d Stefan Hajnoczi
1735 9699bf0d Stefan Hajnoczi
        printf("Snapshot list:\n");
1736 9699bf0d Stefan Hajnoczi
        printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
1737 9699bf0d Stefan Hajnoczi
1738 9699bf0d Stefan Hajnoczi
        /* Ideally bdrv_snapshot_dump() would operate on SnapshotInfoList but
1739 9699bf0d Stefan Hajnoczi
         * we convert to the block layer's native QEMUSnapshotInfo for now.
1740 9699bf0d Stefan Hajnoczi
         */
1741 9699bf0d Stefan Hajnoczi
        for (elem = info->snapshots; elem; elem = elem->next) {
1742 9699bf0d Stefan Hajnoczi
            QEMUSnapshotInfo sn = {
1743 9699bf0d Stefan Hajnoczi
                .vm_state_size = elem->value->vm_state_size,
1744 9699bf0d Stefan Hajnoczi
                .date_sec = elem->value->date_sec,
1745 9699bf0d Stefan Hajnoczi
                .date_nsec = elem->value->date_nsec,
1746 9699bf0d Stefan Hajnoczi
                .vm_clock_nsec = elem->value->vm_clock_sec * 1000000000ULL +
1747 9699bf0d Stefan Hajnoczi
                                 elem->value->vm_clock_nsec,
1748 9699bf0d Stefan Hajnoczi
            };
1749 9699bf0d Stefan Hajnoczi
1750 9699bf0d Stefan Hajnoczi
            pstrcpy(sn.id_str, sizeof(sn.id_str), elem->value->id);
1751 9699bf0d Stefan Hajnoczi
            pstrcpy(sn.name, sizeof(sn.name), elem->value->name);
1752 9699bf0d Stefan Hajnoczi
            printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), &sn));
1753 9699bf0d Stefan Hajnoczi
        }
1754 9699bf0d Stefan Hajnoczi
    }
1755 c054b3fd Benoît Canet
}
1756 c054b3fd Benoît Canet
1757 9699bf0d Stefan Hajnoczi
static void dump_human_image_info_list(ImageInfoList *list)
1758 9699bf0d Stefan Hajnoczi
{
1759 9699bf0d Stefan Hajnoczi
    ImageInfoList *elem;
1760 9699bf0d Stefan Hajnoczi
    bool delim = false;
1761 9699bf0d Stefan Hajnoczi
1762 9699bf0d Stefan Hajnoczi
    for (elem = list; elem; elem = elem->next) {
1763 9699bf0d Stefan Hajnoczi
        if (delim) {
1764 9699bf0d Stefan Hajnoczi
            printf("\n");
1765 9699bf0d Stefan Hajnoczi
        }
1766 9699bf0d Stefan Hajnoczi
        delim = true;
1767 9699bf0d Stefan Hajnoczi
1768 9699bf0d Stefan Hajnoczi
        dump_human_image_info(elem->value);
1769 9699bf0d Stefan Hajnoczi
    }
1770 9699bf0d Stefan Hajnoczi
}
1771 9699bf0d Stefan Hajnoczi
1772 9699bf0d Stefan Hajnoczi
static gboolean str_equal_func(gconstpointer a, gconstpointer b)
1773 9699bf0d Stefan Hajnoczi
{
1774 9699bf0d Stefan Hajnoczi
    return strcmp(a, b) == 0;
1775 9699bf0d Stefan Hajnoczi
}
1776 9699bf0d Stefan Hajnoczi
1777 9699bf0d Stefan Hajnoczi
/**
1778 9699bf0d Stefan Hajnoczi
 * Open an image file chain and return an ImageInfoList
1779 9699bf0d Stefan Hajnoczi
 *
1780 9699bf0d Stefan Hajnoczi
 * @filename: topmost image filename
1781 9699bf0d Stefan Hajnoczi
 * @fmt: topmost image format (may be NULL to autodetect)
1782 9699bf0d Stefan Hajnoczi
 * @chain: true  - enumerate entire backing file chain
1783 9699bf0d Stefan Hajnoczi
 *         false - only topmost image file
1784 9699bf0d Stefan Hajnoczi
 *
1785 9699bf0d Stefan Hajnoczi
 * Returns a list of ImageInfo objects or NULL if there was an error opening an
1786 9699bf0d Stefan Hajnoczi
 * image file.  If there was an error a message will have been printed to
1787 9699bf0d Stefan Hajnoczi
 * stderr.
1788 9699bf0d Stefan Hajnoczi
 */
1789 9699bf0d Stefan Hajnoczi
static ImageInfoList *collect_image_info_list(const char *filename,
1790 9699bf0d Stefan Hajnoczi
                                              const char *fmt,
1791 9699bf0d Stefan Hajnoczi
                                              bool chain)
1792 9699bf0d Stefan Hajnoczi
{
1793 9699bf0d Stefan Hajnoczi
    ImageInfoList *head = NULL;
1794 9699bf0d Stefan Hajnoczi
    ImageInfoList **last = &head;
1795 9699bf0d Stefan Hajnoczi
    GHashTable *filenames;
1796 9699bf0d Stefan Hajnoczi
1797 9699bf0d Stefan Hajnoczi
    filenames = g_hash_table_new_full(g_str_hash, str_equal_func, NULL, NULL);
1798 9699bf0d Stefan Hajnoczi
1799 9699bf0d Stefan Hajnoczi
    while (filename) {
1800 9699bf0d Stefan Hajnoczi
        BlockDriverState *bs;
1801 9699bf0d Stefan Hajnoczi
        ImageInfo *info;
1802 9699bf0d Stefan Hajnoczi
        ImageInfoList *elem;
1803 9699bf0d Stefan Hajnoczi
1804 9699bf0d Stefan Hajnoczi
        if (g_hash_table_lookup_extended(filenames, filename, NULL, NULL)) {
1805 9699bf0d Stefan Hajnoczi
            error_report("Backing file '%s' creates an infinite loop.",
1806 9699bf0d Stefan Hajnoczi
                         filename);
1807 9699bf0d Stefan Hajnoczi
            goto err;
1808 9699bf0d Stefan Hajnoczi
        }
1809 9699bf0d Stefan Hajnoczi
        g_hash_table_insert(filenames, (gpointer)filename, NULL);
1810 9699bf0d Stefan Hajnoczi
1811 9699bf0d Stefan Hajnoczi
        bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING,
1812 f382d43a Miroslav Rezanina
                           false, false);
1813 9699bf0d Stefan Hajnoczi
        if (!bs) {
1814 9699bf0d Stefan Hajnoczi
            goto err;
1815 9699bf0d Stefan Hajnoczi
        }
1816 9699bf0d Stefan Hajnoczi
1817 9699bf0d Stefan Hajnoczi
        info = g_new0(ImageInfo, 1);
1818 9699bf0d Stefan Hajnoczi
        collect_image_info(bs, info, filename, fmt);
1819 9699bf0d Stefan Hajnoczi
        collect_snapshots(bs, info);
1820 9699bf0d Stefan Hajnoczi
1821 9699bf0d Stefan Hajnoczi
        elem = g_new0(ImageInfoList, 1);
1822 9699bf0d Stefan Hajnoczi
        elem->value = info;
1823 9699bf0d Stefan Hajnoczi
        *last = elem;
1824 9699bf0d Stefan Hajnoczi
        last = &elem->next;
1825 9699bf0d Stefan Hajnoczi
1826 9699bf0d Stefan Hajnoczi
        bdrv_delete(bs);
1827 9699bf0d Stefan Hajnoczi
1828 9699bf0d Stefan Hajnoczi
        filename = fmt = NULL;
1829 9699bf0d Stefan Hajnoczi
        if (chain) {
1830 9699bf0d Stefan Hajnoczi
            if (info->has_full_backing_filename) {
1831 9699bf0d Stefan Hajnoczi
                filename = info->full_backing_filename;
1832 9699bf0d Stefan Hajnoczi
            } else if (info->has_backing_filename) {
1833 9699bf0d Stefan Hajnoczi
                filename = info->backing_filename;
1834 9699bf0d Stefan Hajnoczi
            }
1835 9699bf0d Stefan Hajnoczi
            if (info->has_backing_filename_format) {
1836 9699bf0d Stefan Hajnoczi
                fmt = info->backing_filename_format;
1837 9699bf0d Stefan Hajnoczi
            }
1838 9699bf0d Stefan Hajnoczi
        }
1839 9699bf0d Stefan Hajnoczi
    }
1840 9699bf0d Stefan Hajnoczi
    g_hash_table_destroy(filenames);
1841 9699bf0d Stefan Hajnoczi
    return head;
1842 9699bf0d Stefan Hajnoczi
1843 9699bf0d Stefan Hajnoczi
err:
1844 9699bf0d Stefan Hajnoczi
    qapi_free_ImageInfoList(head);
1845 9699bf0d Stefan Hajnoczi
    g_hash_table_destroy(filenames);
1846 9699bf0d Stefan Hajnoczi
    return NULL;
1847 9699bf0d Stefan Hajnoczi
}
1848 9699bf0d Stefan Hajnoczi
1849 c054b3fd Benoît Canet
static int img_info(int argc, char **argv)
1850 c054b3fd Benoît Canet
{
1851 c054b3fd Benoît Canet
    int c;
1852 c054b3fd Benoît Canet
    OutputFormat output_format = OFORMAT_HUMAN;
1853 9699bf0d Stefan Hajnoczi
    bool chain = false;
1854 c054b3fd Benoît Canet
    const char *filename, *fmt, *output;
1855 9699bf0d Stefan Hajnoczi
    ImageInfoList *list;
1856 c054b3fd Benoît Canet
1857 ea2384d3 bellard
    fmt = NULL;
1858 c054b3fd Benoît Canet
    output = NULL;
1859 ea2384d3 bellard
    for(;;) {
1860 c054b3fd Benoît Canet
        int option_index = 0;
1861 c054b3fd Benoît Canet
        static const struct option long_options[] = {
1862 c054b3fd Benoît Canet
            {"help", no_argument, 0, 'h'},
1863 c054b3fd Benoît Canet
            {"format", required_argument, 0, 'f'},
1864 c054b3fd Benoît Canet
            {"output", required_argument, 0, OPTION_OUTPUT},
1865 9699bf0d Stefan Hajnoczi
            {"backing-chain", no_argument, 0, OPTION_BACKING_CHAIN},
1866 c054b3fd Benoît Canet
            {0, 0, 0, 0}
1867 c054b3fd Benoît Canet
        };
1868 c054b3fd Benoît Canet
        c = getopt_long(argc, argv, "f:h",
1869 c054b3fd Benoît Canet
                        long_options, &option_index);
1870 b8fb60da Jes Sorensen
        if (c == -1) {
1871 ea2384d3 bellard
            break;
1872 b8fb60da Jes Sorensen
        }
1873 ea2384d3 bellard
        switch(c) {
1874 ef87394c Jes Sorensen
        case '?':
1875 ea2384d3 bellard
        case 'h':
1876 ea2384d3 bellard
            help();
1877 ea2384d3 bellard
            break;
1878 ea2384d3 bellard
        case 'f':
1879 ea2384d3 bellard
            fmt = optarg;
1880 ea2384d3 bellard
            break;
1881 c054b3fd Benoît Canet
        case OPTION_OUTPUT:
1882 c054b3fd Benoît Canet
            output = optarg;
1883 c054b3fd Benoît Canet
            break;
1884 9699bf0d Stefan Hajnoczi
        case OPTION_BACKING_CHAIN:
1885 9699bf0d Stefan Hajnoczi
            chain = true;
1886 9699bf0d Stefan Hajnoczi
            break;
1887 ea2384d3 bellard
        }
1888 ea2384d3 bellard
    }
1889 b8fb60da Jes Sorensen
    if (optind >= argc) {
1890 ea2384d3 bellard
        help();
1891 b8fb60da Jes Sorensen
    }
1892 ea2384d3 bellard
    filename = argv[optind++];
1893 ea2384d3 bellard
1894 c054b3fd Benoît Canet
    if (output && !strcmp(output, "json")) {
1895 c054b3fd Benoît Canet
        output_format = OFORMAT_JSON;
1896 c054b3fd Benoît Canet
    } else if (output && !strcmp(output, "human")) {
1897 c054b3fd Benoît Canet
        output_format = OFORMAT_HUMAN;
1898 c054b3fd Benoît Canet
    } else if (output) {
1899 c054b3fd Benoît Canet
        error_report("--output must be used with human or json as argument.");
1900 c2abccec MORITA Kazutaka
        return 1;
1901 c2abccec MORITA Kazutaka
    }
1902 c054b3fd Benoît Canet
1903 9699bf0d Stefan Hajnoczi
    list = collect_image_info_list(filename, fmt, chain);
1904 9699bf0d Stefan Hajnoczi
    if (!list) {
1905 c2abccec MORITA Kazutaka
        return 1;
1906 faea38e7 bellard
    }
1907 c054b3fd Benoît Canet
1908 c054b3fd Benoît Canet
    switch (output_format) {
1909 c054b3fd Benoît Canet
    case OFORMAT_HUMAN:
1910 9699bf0d Stefan Hajnoczi
        dump_human_image_info_list(list);
1911 c054b3fd Benoît Canet
        break;
1912 c054b3fd Benoît Canet
    case OFORMAT_JSON:
1913 9699bf0d Stefan Hajnoczi
        if (chain) {
1914 9699bf0d Stefan Hajnoczi
            dump_json_image_info_list(list);
1915 9699bf0d Stefan Hajnoczi
        } else {
1916 9699bf0d Stefan Hajnoczi
            dump_json_image_info(list->value);
1917 9699bf0d Stefan Hajnoczi
        }
1918 c054b3fd Benoît Canet
        break;
1919 faea38e7 bellard
    }
1920 c054b3fd Benoît Canet
1921 9699bf0d Stefan Hajnoczi
    qapi_free_ImageInfoList(list);
1922 ea2384d3 bellard
    return 0;
1923 ea2384d3 bellard
}
1924 ea2384d3 bellard
1925 f7b4a940 aliguori
#define SNAPSHOT_LIST   1
1926 f7b4a940 aliguori
#define SNAPSHOT_CREATE 2
1927 f7b4a940 aliguori
#define SNAPSHOT_APPLY  3
1928 f7b4a940 aliguori
#define SNAPSHOT_DELETE 4
1929 f7b4a940 aliguori
1930 153859be Stuart Brady
static int img_snapshot(int argc, char **argv)
1931 f7b4a940 aliguori
{
1932 f7b4a940 aliguori
    BlockDriverState *bs;
1933 f7b4a940 aliguori
    QEMUSnapshotInfo sn;
1934 f7b4a940 aliguori
    char *filename, *snapshot_name = NULL;
1935 c2abccec MORITA Kazutaka
    int c, ret = 0, bdrv_oflags;
1936 f7b4a940 aliguori
    int action = 0;
1937 f7b4a940 aliguori
    qemu_timeval tv;
1938 f382d43a Miroslav Rezanina
    bool quiet = false;
1939 f7b4a940 aliguori
1940 710da702 Kevin Wolf
    bdrv_oflags = BDRV_O_FLAGS | BDRV_O_RDWR;
1941 f7b4a940 aliguori
    /* Parse commandline parameters */
1942 f7b4a940 aliguori
    for(;;) {
1943 f382d43a Miroslav Rezanina
        c = getopt(argc, argv, "la:c:d:hq");
1944 b8fb60da Jes Sorensen
        if (c == -1) {
1945 f7b4a940 aliguori
            break;
1946 b8fb60da Jes Sorensen
        }
1947 f7b4a940 aliguori
        switch(c) {
1948 ef87394c Jes Sorensen
        case '?':
1949 f7b4a940 aliguori
        case 'h':
1950 f7b4a940 aliguori
            help();
1951 153859be Stuart Brady
            return 0;
1952 f7b4a940 aliguori
        case 'l':
1953 f7b4a940 aliguori
            if (action) {
1954 f7b4a940 aliguori
                help();
1955 153859be Stuart Brady
                return 0;
1956 f7b4a940 aliguori
            }
1957 f7b4a940 aliguori
            action = SNAPSHOT_LIST;
1958 f5edb014 Naphtali Sprei
            bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
1959 f7b4a940 aliguori
            break;
1960 f7b4a940 aliguori
        case 'a':
1961 f7b4a940 aliguori
            if (action) {
1962 f7b4a940 aliguori
                help();
1963 153859be Stuart Brady
                return 0;
1964 f7b4a940 aliguori
            }
1965 f7b4a940 aliguori
            action = SNAPSHOT_APPLY;
1966 f7b4a940 aliguori
            snapshot_name = optarg;
1967 f7b4a940 aliguori
            break;
1968 f7b4a940 aliguori
        case 'c':
1969 f7b4a940 aliguori
            if (action) {
1970 f7b4a940 aliguori
                help();
1971 153859be Stuart Brady
                return 0;
1972 f7b4a940 aliguori
            }
1973 f7b4a940 aliguori
            action = SNAPSHOT_CREATE;
1974 f7b4a940 aliguori
            snapshot_name = optarg;
1975 f7b4a940 aliguori
            break;
1976 f7b4a940 aliguori
        case 'd':
1977 f7b4a940 aliguori
            if (action) {
1978 f7b4a940 aliguori
                help();
1979 153859be Stuart Brady
                return 0;
1980 f7b4a940 aliguori
            }
1981 f7b4a940 aliguori
            action = SNAPSHOT_DELETE;
1982 f7b4a940 aliguori
            snapshot_name = optarg;
1983 f7b4a940 aliguori
            break;
1984 f382d43a Miroslav Rezanina
        case 'q':
1985 f382d43a Miroslav Rezanina
            quiet = true;
1986 f382d43a Miroslav Rezanina
            break;
1987 f7b4a940 aliguori
        }
1988 f7b4a940 aliguori
    }
1989 f7b4a940 aliguori
1990 b8fb60da Jes Sorensen
    if (optind >= argc) {
1991 f7b4a940 aliguori
        help();
1992 b8fb60da Jes Sorensen
    }
1993 f7b4a940 aliguori
    filename = argv[optind++];
1994 f7b4a940 aliguori
1995 f7b4a940 aliguori
    /* Open the image */
1996 f382d43a Miroslav Rezanina
    bs = bdrv_new_open(filename, NULL, bdrv_oflags, true, quiet);
1997 c2abccec MORITA Kazutaka
    if (!bs) {
1998 c2abccec MORITA Kazutaka
        return 1;
1999 c2abccec MORITA Kazutaka
    }
2000 f7b4a940 aliguori
2001 f7b4a940 aliguori
    /* Perform the requested action */
2002 f7b4a940 aliguori
    switch(action) {
2003 f7b4a940 aliguori
    case SNAPSHOT_LIST:
2004 f7b4a940 aliguori
        dump_snapshots(bs);
2005 f7b4a940 aliguori
        break;
2006 f7b4a940 aliguori
2007 f7b4a940 aliguori
    case SNAPSHOT_CREATE:
2008 f7b4a940 aliguori
        memset(&sn, 0, sizeof(sn));
2009 f7b4a940 aliguori
        pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
2010 f7b4a940 aliguori
2011 f7b4a940 aliguori
        qemu_gettimeofday(&tv);
2012 f7b4a940 aliguori
        sn.date_sec = tv.tv_sec;
2013 f7b4a940 aliguori
        sn.date_nsec = tv.tv_usec * 1000;
2014 f7b4a940 aliguori
2015 f7b4a940 aliguori
        ret = bdrv_snapshot_create(bs, &sn);
2016 b8fb60da Jes Sorensen
        if (ret) {
2017 15654a6d Jes Sorensen
            error_report("Could not create snapshot '%s': %d (%s)",
2018 f7b4a940 aliguori
                snapshot_name, ret, strerror(-ret));
2019 b8fb60da Jes Sorensen
        }
2020 f7b4a940 aliguori
        break;
2021 f7b4a940 aliguori
2022 f7b4a940 aliguori
    case SNAPSHOT_APPLY:
2023 f7b4a940 aliguori
        ret = bdrv_snapshot_goto(bs, snapshot_name);
2024 b8fb60da Jes Sorensen
        if (ret) {
2025 15654a6d Jes Sorensen
            error_report("Could not apply snapshot '%s': %d (%s)",
2026 f7b4a940 aliguori
                snapshot_name, ret, strerror(-ret));
2027 b8fb60da Jes Sorensen
        }
2028 f7b4a940 aliguori
        break;
2029 f7b4a940 aliguori
2030 f7b4a940 aliguori
    case SNAPSHOT_DELETE:
2031 f7b4a940 aliguori
        ret = bdrv_snapshot_delete(bs, snapshot_name);
2032 b8fb60da Jes Sorensen
        if (ret) {
2033 15654a6d Jes Sorensen
            error_report("Could not delete snapshot '%s': %d (%s)",
2034 f7b4a940 aliguori
                snapshot_name, ret, strerror(-ret));
2035 b8fb60da Jes Sorensen
        }
2036 f7b4a940 aliguori
        break;
2037 f7b4a940 aliguori
    }
2038 f7b4a940 aliguori
2039 f7b4a940 aliguori
    /* Cleanup */
2040 f7b4a940 aliguori
    bdrv_delete(bs);
2041 c2abccec MORITA Kazutaka
    if (ret) {
2042 c2abccec MORITA Kazutaka
        return 1;
2043 c2abccec MORITA Kazutaka
    }
2044 153859be Stuart Brady
    return 0;
2045 f7b4a940 aliguori
}
2046 f7b4a940 aliguori
2047 3e85c6fd Kevin Wolf
static int img_rebase(int argc, char **argv)
2048 3e85c6fd Kevin Wolf
{
2049 c2abccec MORITA Kazutaka
    BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
2050 f163d073 Stefan Hajnoczi
    BlockDriver *old_backing_drv, *new_backing_drv;
2051 3e85c6fd Kevin Wolf
    char *filename;
2052 661a0f71 Federico Simoncelli
    const char *fmt, *cache, *out_basefmt, *out_baseimg;
2053 3e85c6fd Kevin Wolf
    int c, flags, ret;
2054 3e85c6fd Kevin Wolf
    int unsafe = 0;
2055 6b837bc4 Jes Sorensen
    int progress = 0;
2056 f382d43a Miroslav Rezanina
    bool quiet = false;
2057 3e85c6fd Kevin Wolf
2058 3e85c6fd Kevin Wolf
    /* Parse commandline parameters */
2059 e53dbee0 Kevin Wolf
    fmt = NULL;
2060 661a0f71 Federico Simoncelli
    cache = BDRV_DEFAULT_CACHE;
2061 3e85c6fd Kevin Wolf
    out_baseimg = NULL;
2062 3e85c6fd Kevin Wolf
    out_basefmt = NULL;
2063 3e85c6fd Kevin Wolf
    for(;;) {
2064 f382d43a Miroslav Rezanina
        c = getopt(argc, argv, "uhf:F:b:pt:q");
2065 b8fb60da Jes Sorensen
        if (c == -1) {
2066 3e85c6fd Kevin Wolf
            break;
2067 b8fb60da Jes Sorensen
        }
2068 3e85c6fd Kevin Wolf
        switch(c) {
2069 ef87394c Jes Sorensen
        case '?':
2070 3e85c6fd Kevin Wolf
        case 'h':
2071 3e85c6fd Kevin Wolf
            help();
2072 3e85c6fd Kevin Wolf
            return 0;
2073 e53dbee0 Kevin Wolf
        case 'f':
2074 e53dbee0 Kevin Wolf
            fmt = optarg;
2075 e53dbee0 Kevin Wolf
            break;
2076 3e85c6fd Kevin Wolf
        case 'F':
2077 3e85c6fd Kevin Wolf
            out_basefmt = optarg;
2078 3e85c6fd Kevin Wolf
            break;
2079 3e85c6fd Kevin Wolf
        case 'b':
2080 3e85c6fd Kevin Wolf
            out_baseimg = optarg;
2081 3e85c6fd Kevin Wolf
            break;
2082 3e85c6fd Kevin Wolf
        case 'u':
2083 3e85c6fd Kevin Wolf
            unsafe = 1;
2084 3e85c6fd Kevin Wolf
            break;
2085 6b837bc4 Jes Sorensen
        case 'p':
2086 6b837bc4 Jes Sorensen
            progress = 1;
2087 6b837bc4 Jes Sorensen
            break;
2088 661a0f71 Federico Simoncelli
        case 't':
2089 661a0f71 Federico Simoncelli
            cache = optarg;
2090 661a0f71 Federico Simoncelli
            break;
2091 f382d43a Miroslav Rezanina
        case 'q':
2092 f382d43a Miroslav Rezanina
            quiet = true;
2093 f382d43a Miroslav Rezanina
            break;
2094 3e85c6fd Kevin Wolf
        }
2095 3e85c6fd Kevin Wolf
    }
2096 3e85c6fd Kevin Wolf
2097 f382d43a Miroslav Rezanina
    if (quiet) {
2098 f382d43a Miroslav Rezanina
        progress = 0;
2099 f382d43a Miroslav Rezanina
    }
2100 f382d43a Miroslav Rezanina
2101 9a9d9dba Anthony Liguori
    if ((optind >= argc) || (!unsafe && !out_baseimg)) {
2102 3e85c6fd Kevin Wolf
        help();
2103 b8fb60da Jes Sorensen
    }
2104 3e85c6fd Kevin Wolf
    filename = argv[optind++];
2105 3e85c6fd Kevin Wolf
2106 6b837bc4 Jes Sorensen
    qemu_progress_init(progress, 2.0);
2107 6b837bc4 Jes Sorensen
    qemu_progress_print(0, 100);
2108 6b837bc4 Jes Sorensen
2109 661a0f71 Federico Simoncelli
    flags = BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
2110 c3993cdc Stefan Hajnoczi
    ret = bdrv_parse_cache_flags(cache, &flags);
2111 661a0f71 Federico Simoncelli
    if (ret < 0) {
2112 661a0f71 Federico Simoncelli
        error_report("Invalid cache option: %s", cache);
2113 661a0f71 Federico Simoncelli
        return -1;
2114 661a0f71 Federico Simoncelli
    }
2115 661a0f71 Federico Simoncelli
2116 3e85c6fd Kevin Wolf
    /*
2117 3e85c6fd Kevin Wolf
     * Open the images.
2118 3e85c6fd Kevin Wolf
     *
2119 3e85c6fd Kevin Wolf
     * Ignore the old backing file for unsafe rebase in case we want to correct
2120 3e85c6fd Kevin Wolf
     * the reference to a renamed or moved backing file.
2121 3e85c6fd Kevin Wolf
     */
2122 f382d43a Miroslav Rezanina
    bs = bdrv_new_open(filename, fmt, flags, true, quiet);
2123 c2abccec MORITA Kazutaka
    if (!bs) {
2124 c2abccec MORITA Kazutaka
        return 1;
2125 c2abccec MORITA Kazutaka
    }
2126 3e85c6fd Kevin Wolf
2127 3e85c6fd Kevin Wolf
    /* Find the right drivers for the backing files */
2128 3e85c6fd Kevin Wolf
    old_backing_drv = NULL;
2129 3e85c6fd Kevin Wolf
    new_backing_drv = NULL;
2130 3e85c6fd Kevin Wolf
2131 3e85c6fd Kevin Wolf
    if (!unsafe && bs->backing_format[0] != '\0') {
2132 3e85c6fd Kevin Wolf
        old_backing_drv = bdrv_find_format(bs->backing_format);
2133 3e85c6fd Kevin Wolf
        if (old_backing_drv == NULL) {
2134 15654a6d Jes Sorensen
            error_report("Invalid format name: '%s'", bs->backing_format);
2135 c2abccec MORITA Kazutaka
            ret = -1;
2136 c2abccec MORITA Kazutaka
            goto out;
2137 3e85c6fd Kevin Wolf
        }
2138 3e85c6fd Kevin Wolf
    }
2139 3e85c6fd Kevin Wolf
2140 3e85c6fd Kevin Wolf
    if (out_basefmt != NULL) {
2141 3e85c6fd Kevin Wolf
        new_backing_drv = bdrv_find_format(out_basefmt);
2142 3e85c6fd Kevin Wolf
        if (new_backing_drv == NULL) {
2143 15654a6d Jes Sorensen
            error_report("Invalid format name: '%s'", out_basefmt);
2144 c2abccec MORITA Kazutaka
            ret = -1;
2145 c2abccec MORITA Kazutaka
            goto out;
2146 3e85c6fd Kevin Wolf
        }
2147 3e85c6fd Kevin Wolf
    }
2148 3e85c6fd Kevin Wolf
2149 3e85c6fd Kevin Wolf
    /* For safe rebasing we need to compare old and new backing file */
2150 3e85c6fd Kevin Wolf
    if (unsafe) {
2151 3e85c6fd Kevin Wolf
        /* Make the compiler happy */
2152 3e85c6fd Kevin Wolf
        bs_old_backing = NULL;
2153 3e85c6fd Kevin Wolf
        bs_new_backing = NULL;
2154 3e85c6fd Kevin Wolf
    } else {
2155 3e85c6fd Kevin Wolf
        char backing_name[1024];
2156 3e85c6fd Kevin Wolf
2157 3e85c6fd Kevin Wolf
        bs_old_backing = bdrv_new("old_backing");
2158 3e85c6fd Kevin Wolf
        bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
2159 de9c0cec Kevin Wolf
        ret = bdrv_open(bs_old_backing, backing_name, NULL, BDRV_O_FLAGS,
2160 c2abccec MORITA Kazutaka
                        old_backing_drv);
2161 c2abccec MORITA Kazutaka
        if (ret) {
2162 15654a6d Jes Sorensen
            error_report("Could not open old backing file '%s'", backing_name);
2163 c2abccec MORITA Kazutaka
            goto out;
2164 3e85c6fd Kevin Wolf
        }
2165 a616673d Alex Bligh
        if (out_baseimg[0]) {
2166 a616673d Alex Bligh
            bs_new_backing = bdrv_new("new_backing");
2167 de9c0cec Kevin Wolf
            ret = bdrv_open(bs_new_backing, out_baseimg, NULL, BDRV_O_FLAGS,
2168 c2abccec MORITA Kazutaka
                        new_backing_drv);
2169 a616673d Alex Bligh
            if (ret) {
2170 a616673d Alex Bligh
                error_report("Could not open new backing file '%s'",
2171 a616673d Alex Bligh
                             out_baseimg);
2172 a616673d Alex Bligh
                goto out;
2173 a616673d Alex Bligh
            }
2174 3e85c6fd Kevin Wolf
        }
2175 3e85c6fd Kevin Wolf
    }
2176 3e85c6fd Kevin Wolf
2177 3e85c6fd Kevin Wolf
    /*
2178 3e85c6fd Kevin Wolf
     * Check each unallocated cluster in the COW file. If it is unallocated,
2179 3e85c6fd Kevin Wolf
     * accesses go to the backing file. We must therefore compare this cluster
2180 3e85c6fd Kevin Wolf
     * in the old and new backing file, and if they differ we need to copy it
2181 3e85c6fd Kevin Wolf
     * from the old backing file into the COW file.
2182 3e85c6fd Kevin Wolf
     *
2183 3e85c6fd Kevin Wolf
     * If qemu-img crashes during this step, no harm is done. The content of
2184 3e85c6fd Kevin Wolf
     * the image is the same as the original one at any time.
2185 3e85c6fd Kevin Wolf
     */
2186 3e85c6fd Kevin Wolf
    if (!unsafe) {
2187 3e85c6fd Kevin Wolf
        uint64_t num_sectors;
2188 87a1b3e3 Kevin Wolf
        uint64_t old_backing_num_sectors;
2189 a616673d Alex Bligh
        uint64_t new_backing_num_sectors = 0;
2190 3e85c6fd Kevin Wolf
        uint64_t sector;
2191 cc60e327 Kevin Wolf
        int n;
2192 d6771bfa TeLeMan
        uint8_t * buf_old;
2193 d6771bfa TeLeMan
        uint8_t * buf_new;
2194 1f710495 Kevin Wolf
        float local_progress = 0;
2195 d6771bfa TeLeMan
2196 bb1c0597 Kevin Wolf
        buf_old = qemu_blockalign(bs, IO_BUF_SIZE);
2197 bb1c0597 Kevin Wolf
        buf_new = qemu_blockalign(bs, IO_BUF_SIZE);
2198 3e85c6fd Kevin Wolf
2199 3e85c6fd Kevin Wolf
        bdrv_get_geometry(bs, &num_sectors);
2200 87a1b3e3 Kevin Wolf
        bdrv_get_geometry(bs_old_backing, &old_backing_num_sectors);
2201 a616673d Alex Bligh
        if (bs_new_backing) {
2202 a616673d Alex Bligh
            bdrv_get_geometry(bs_new_backing, &new_backing_num_sectors);
2203 a616673d Alex Bligh
        }
2204 3e85c6fd Kevin Wolf
2205 1f710495 Kevin Wolf
        if (num_sectors != 0) {
2206 1f710495 Kevin Wolf
            local_progress = (float)100 /
2207 1f710495 Kevin Wolf
                (num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512));
2208 1f710495 Kevin Wolf
        }
2209 1f710495 Kevin Wolf
2210 3e85c6fd Kevin Wolf
        for (sector = 0; sector < num_sectors; sector += n) {
2211 3e85c6fd Kevin Wolf
2212 3e85c6fd Kevin Wolf
            /* How many sectors can we handle with the next read? */
2213 3e85c6fd Kevin Wolf
            if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
2214 3e85c6fd Kevin Wolf
                n = (IO_BUF_SIZE / 512);
2215 3e85c6fd Kevin Wolf
            } else {
2216 3e85c6fd Kevin Wolf
                n = num_sectors - sector;
2217 3e85c6fd Kevin Wolf
            }
2218 3e85c6fd Kevin Wolf
2219 3e85c6fd Kevin Wolf
            /* If the cluster is allocated, we don't need to take action */
2220 cc60e327 Kevin Wolf
            ret = bdrv_is_allocated(bs, sector, n, &n);
2221 cc60e327 Kevin Wolf
            if (ret) {
2222 3e85c6fd Kevin Wolf
                continue;
2223 3e85c6fd Kevin Wolf
            }
2224 3e85c6fd Kevin Wolf
2225 87a1b3e3 Kevin Wolf
            /*
2226 87a1b3e3 Kevin Wolf
             * Read old and new backing file and take into consideration that
2227 87a1b3e3 Kevin Wolf
             * backing files may be smaller than the COW image.
2228 87a1b3e3 Kevin Wolf
             */
2229 87a1b3e3 Kevin Wolf
            if (sector >= old_backing_num_sectors) {
2230 87a1b3e3 Kevin Wolf
                memset(buf_old, 0, n * BDRV_SECTOR_SIZE);
2231 87a1b3e3 Kevin Wolf
            } else {
2232 87a1b3e3 Kevin Wolf
                if (sector + n > old_backing_num_sectors) {
2233 87a1b3e3 Kevin Wolf
                    n = old_backing_num_sectors - sector;
2234 87a1b3e3 Kevin Wolf
                }
2235 87a1b3e3 Kevin Wolf
2236 87a1b3e3 Kevin Wolf
                ret = bdrv_read(bs_old_backing, sector, buf_old, n);
2237 87a1b3e3 Kevin Wolf
                if (ret < 0) {
2238 87a1b3e3 Kevin Wolf
                    error_report("error while reading from old backing file");
2239 87a1b3e3 Kevin Wolf
                    goto out;
2240 87a1b3e3 Kevin Wolf
                }
2241 3e85c6fd Kevin Wolf
            }
2242 87a1b3e3 Kevin Wolf
2243 a616673d Alex Bligh
            if (sector >= new_backing_num_sectors || !bs_new_backing) {
2244 87a1b3e3 Kevin Wolf
                memset(buf_new, 0, n * BDRV_SECTOR_SIZE);
2245 87a1b3e3 Kevin Wolf
            } else {
2246 87a1b3e3 Kevin Wolf
                if (sector + n > new_backing_num_sectors) {
2247 87a1b3e3 Kevin Wolf
                    n = new_backing_num_sectors - sector;
2248 87a1b3e3 Kevin Wolf
                }
2249 87a1b3e3 Kevin Wolf
2250 87a1b3e3 Kevin Wolf
                ret = bdrv_read(bs_new_backing, sector, buf_new, n);
2251 87a1b3e3 Kevin Wolf
                if (ret < 0) {
2252 87a1b3e3 Kevin Wolf
                    error_report("error while reading from new backing file");
2253 87a1b3e3 Kevin Wolf
                    goto out;
2254 87a1b3e3 Kevin Wolf
                }
2255 3e85c6fd Kevin Wolf
            }
2256 3e85c6fd Kevin Wolf
2257 3e85c6fd Kevin Wolf
            /* If they differ, we need to write to the COW file */
2258 3e85c6fd Kevin Wolf
            uint64_t written = 0;
2259 3e85c6fd Kevin Wolf
2260 3e85c6fd Kevin Wolf
            while (written < n) {
2261 3e85c6fd Kevin Wolf
                int pnum;
2262 3e85c6fd Kevin Wolf
2263 3e85c6fd Kevin Wolf
                if (compare_sectors(buf_old + written * 512,
2264 60b1bd4f Kevin Wolf
                    buf_new + written * 512, n - written, &pnum))
2265 3e85c6fd Kevin Wolf
                {
2266 3e85c6fd Kevin Wolf
                    ret = bdrv_write(bs, sector + written,
2267 3e85c6fd Kevin Wolf
                        buf_old + written * 512, pnum);
2268 3e85c6fd Kevin Wolf
                    if (ret < 0) {
2269 15654a6d Jes Sorensen
                        error_report("Error while writing to COW image: %s",
2270 3e85c6fd Kevin Wolf
                            strerror(-ret));
2271 c2abccec MORITA Kazutaka
                        goto out;
2272 3e85c6fd Kevin Wolf
                    }
2273 3e85c6fd Kevin Wolf
                }
2274 3e85c6fd Kevin Wolf
2275 3e85c6fd Kevin Wolf
                written += pnum;
2276 3e85c6fd Kevin Wolf
            }
2277 6b837bc4 Jes Sorensen
            qemu_progress_print(local_progress, 100);
2278 3e85c6fd Kevin Wolf
        }
2279 d6771bfa TeLeMan
2280 bb1c0597 Kevin Wolf
        qemu_vfree(buf_old);
2281 bb1c0597 Kevin Wolf
        qemu_vfree(buf_new);
2282 3e85c6fd Kevin Wolf
    }
2283 3e85c6fd Kevin Wolf
2284 3e85c6fd Kevin Wolf
    /*
2285 3e85c6fd Kevin Wolf
     * Change the backing file. All clusters that are different from the old
2286 3e85c6fd Kevin Wolf
     * backing file are overwritten in the COW file now, so the visible content
2287 3e85c6fd Kevin Wolf
     * doesn't change when we switch the backing file.
2288 3e85c6fd Kevin Wolf
     */
2289 a616673d Alex Bligh
    if (out_baseimg && *out_baseimg) {
2290 a616673d Alex Bligh
        ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
2291 a616673d Alex Bligh
    } else {
2292 a616673d Alex Bligh
        ret = bdrv_change_backing_file(bs, NULL, NULL);
2293 a616673d Alex Bligh
    }
2294 a616673d Alex Bligh
2295 3e85c6fd Kevin Wolf
    if (ret == -ENOSPC) {
2296 15654a6d Jes Sorensen
        error_report("Could not change the backing file to '%s': No "
2297 15654a6d Jes Sorensen
                     "space left in the file header", out_baseimg);
2298 3e85c6fd Kevin Wolf
    } else if (ret < 0) {
2299 15654a6d Jes Sorensen
        error_report("Could not change the backing file to '%s': %s",
2300 3e85c6fd Kevin Wolf
            out_baseimg, strerror(-ret));
2301 3e85c6fd Kevin Wolf
    }
2302 3e85c6fd Kevin Wolf
2303 6b837bc4 Jes Sorensen
    qemu_progress_print(100, 0);
2304 3e85c6fd Kevin Wolf
    /*
2305 3e85c6fd Kevin Wolf
     * TODO At this point it is possible to check if any clusters that are
2306 3e85c6fd Kevin Wolf
     * allocated in the COW file are the same in the backing file. If so, they
2307 3e85c6fd Kevin Wolf
     * could be dropped from the COW file. Don't do this before switching the
2308 3e85c6fd Kevin Wolf
     * backing file, in case of a crash this would lead to corruption.
2309 3e85c6fd Kevin Wolf
     */
2310 c2abccec MORITA Kazutaka
out:
2311 6b837bc4 Jes Sorensen
    qemu_progress_end();
2312 3e85c6fd Kevin Wolf
    /* Cleanup */
2313 3e85c6fd Kevin Wolf
    if (!unsafe) {
2314 eb863add Kevin Wolf
        if (bs_old_backing != NULL) {
2315 eb863add Kevin Wolf
            bdrv_delete(bs_old_backing);
2316 eb863add Kevin Wolf
        }
2317 eb863add Kevin Wolf
        if (bs_new_backing != NULL) {
2318 eb863add Kevin Wolf
            bdrv_delete(bs_new_backing);
2319 eb863add Kevin Wolf
        }
2320 3e85c6fd Kevin Wolf
    }
2321 3e85c6fd Kevin Wolf
2322 3e85c6fd Kevin Wolf
    bdrv_delete(bs);
2323 c2abccec MORITA Kazutaka
    if (ret) {
2324 c2abccec MORITA Kazutaka
        return 1;
2325 c2abccec MORITA Kazutaka
    }
2326 3e85c6fd Kevin Wolf
    return 0;
2327 3e85c6fd Kevin Wolf
}
2328 3e85c6fd Kevin Wolf
2329 ae6b0ed6 Stefan Hajnoczi
static int img_resize(int argc, char **argv)
2330 ae6b0ed6 Stefan Hajnoczi
{
2331 ae6b0ed6 Stefan Hajnoczi
    int c, ret, relative;
2332 ae6b0ed6 Stefan Hajnoczi
    const char *filename, *fmt, *size;
2333 ae6b0ed6 Stefan Hajnoczi
    int64_t n, total_size;
2334 f382d43a Miroslav Rezanina
    bool quiet = false;
2335 2a81998a Jes Sorensen
    BlockDriverState *bs = NULL;
2336 20caf0f7 Dong Xu Wang
    QemuOpts *param;
2337 20caf0f7 Dong Xu Wang
    static QemuOptsList resize_options = {
2338 20caf0f7 Dong Xu Wang
        .name = "resize_options",
2339 20caf0f7 Dong Xu Wang
        .head = QTAILQ_HEAD_INITIALIZER(resize_options.head),
2340 20caf0f7 Dong Xu Wang
        .desc = {
2341 20caf0f7 Dong Xu Wang
            {
2342 20caf0f7 Dong Xu Wang
                .name = BLOCK_OPT_SIZE,
2343 20caf0f7 Dong Xu Wang
                .type = QEMU_OPT_SIZE,
2344 20caf0f7 Dong Xu Wang
                .help = "Virtual disk size"
2345 20caf0f7 Dong Xu Wang
            }, {
2346 20caf0f7 Dong Xu Wang
                /* end of list */
2347 20caf0f7 Dong Xu Wang
            }
2348 ae6b0ed6 Stefan Hajnoczi
        },
2349 ae6b0ed6 Stefan Hajnoczi
    };
2350 ae6b0ed6 Stefan Hajnoczi
2351 e80fec7f Kevin Wolf
    /* Remove size from argv manually so that negative numbers are not treated
2352 e80fec7f Kevin Wolf
     * as options by getopt. */
2353 e80fec7f Kevin Wolf
    if (argc < 3) {
2354 e80fec7f Kevin Wolf
        help();
2355 e80fec7f Kevin Wolf
        return 1;
2356 e80fec7f Kevin Wolf
    }
2357 e80fec7f Kevin Wolf
2358 e80fec7f Kevin Wolf
    size = argv[--argc];
2359 e80fec7f Kevin Wolf
2360 e80fec7f Kevin Wolf
    /* Parse getopt arguments */
2361 ae6b0ed6 Stefan Hajnoczi
    fmt = NULL;
2362 ae6b0ed6 Stefan Hajnoczi
    for(;;) {
2363 f382d43a Miroslav Rezanina
        c = getopt(argc, argv, "f:hq");
2364 ae6b0ed6 Stefan Hajnoczi
        if (c == -1) {
2365 ae6b0ed6 Stefan Hajnoczi
            break;
2366 ae6b0ed6 Stefan Hajnoczi
        }
2367 ae6b0ed6 Stefan Hajnoczi
        switch(c) {
2368 ef87394c Jes Sorensen
        case '?':
2369 ae6b0ed6 Stefan Hajnoczi
        case 'h':
2370 ae6b0ed6 Stefan Hajnoczi
            help();
2371 ae6b0ed6 Stefan Hajnoczi
            break;
2372 ae6b0ed6 Stefan Hajnoczi
        case 'f':
2373 ae6b0ed6 Stefan Hajnoczi
            fmt = optarg;
2374 ae6b0ed6 Stefan Hajnoczi
            break;
2375 f382d43a Miroslav Rezanina
        case 'q':
2376 f382d43a Miroslav Rezanina
            quiet = true;
2377 f382d43a Miroslav Rezanina
            break;
2378 ae6b0ed6 Stefan Hajnoczi
        }
2379 ae6b0ed6 Stefan Hajnoczi
    }
2380 e80fec7f Kevin Wolf
    if (optind >= argc) {
2381 ae6b0ed6 Stefan Hajnoczi
        help();
2382 ae6b0ed6 Stefan Hajnoczi
    }
2383 ae6b0ed6 Stefan Hajnoczi
    filename = argv[optind++];
2384 ae6b0ed6 Stefan Hajnoczi
2385 ae6b0ed6 Stefan Hajnoczi
    /* Choose grow, shrink, or absolute resize mode */
2386 ae6b0ed6 Stefan Hajnoczi
    switch (size[0]) {
2387 ae6b0ed6 Stefan Hajnoczi
    case '+':
2388 ae6b0ed6 Stefan Hajnoczi
        relative = 1;
2389 ae6b0ed6 Stefan Hajnoczi
        size++;
2390 ae6b0ed6 Stefan Hajnoczi
        break;
2391 ae6b0ed6 Stefan Hajnoczi
    case '-':
2392 ae6b0ed6 Stefan Hajnoczi
        relative = -1;
2393 ae6b0ed6 Stefan Hajnoczi
        size++;
2394 ae6b0ed6 Stefan Hajnoczi
        break;
2395 ae6b0ed6 Stefan Hajnoczi
    default:
2396 ae6b0ed6 Stefan Hajnoczi
        relative = 0;
2397 ae6b0ed6 Stefan Hajnoczi
        break;
2398 ae6b0ed6 Stefan Hajnoczi
    }
2399 ae6b0ed6 Stefan Hajnoczi
2400 ae6b0ed6 Stefan Hajnoczi
    /* Parse size */
2401 e478b448 Dong Xu Wang
    param = qemu_opts_create_nofail(&resize_options);
2402 20caf0f7 Dong Xu Wang
    if (qemu_opt_set(param, BLOCK_OPT_SIZE, size)) {
2403 ae6b0ed6 Stefan Hajnoczi
        /* Error message already printed when size parsing fails */
2404 2a81998a Jes Sorensen
        ret = -1;
2405 20caf0f7 Dong Xu Wang
        qemu_opts_del(param);
2406 2a81998a Jes Sorensen
        goto out;
2407 ae6b0ed6 Stefan Hajnoczi
    }
2408 20caf0f7 Dong Xu Wang
    n = qemu_opt_get_size(param, BLOCK_OPT_SIZE, 0);
2409 20caf0f7 Dong Xu Wang
    qemu_opts_del(param);
2410 ae6b0ed6 Stefan Hajnoczi
2411 f382d43a Miroslav Rezanina
    bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR, true, quiet);
2412 c2abccec MORITA Kazutaka
    if (!bs) {
2413 2a81998a Jes Sorensen
        ret = -1;
2414 2a81998a Jes Sorensen
        goto out;
2415 c2abccec MORITA Kazutaka
    }
2416 ae6b0ed6 Stefan Hajnoczi
2417 ae6b0ed6 Stefan Hajnoczi
    if (relative) {
2418 ae6b0ed6 Stefan Hajnoczi
        total_size = bdrv_getlength(bs) + n * relative;
2419 ae6b0ed6 Stefan Hajnoczi
    } else {
2420 ae6b0ed6 Stefan Hajnoczi
        total_size = n;
2421 ae6b0ed6 Stefan Hajnoczi
    }
2422 ae6b0ed6 Stefan Hajnoczi
    if (total_size <= 0) {
2423 15654a6d Jes Sorensen
        error_report("New image size must be positive");
2424 c2abccec MORITA Kazutaka
        ret = -1;
2425 c2abccec MORITA Kazutaka
        goto out;
2426 ae6b0ed6 Stefan Hajnoczi
    }
2427 ae6b0ed6 Stefan Hajnoczi
2428 ae6b0ed6 Stefan Hajnoczi
    ret = bdrv_truncate(bs, total_size);
2429 ae6b0ed6 Stefan Hajnoczi
    switch (ret) {
2430 ae6b0ed6 Stefan Hajnoczi
    case 0:
2431 f382d43a Miroslav Rezanina
        qprintf(quiet, "Image resized.\n");
2432 ae6b0ed6 Stefan Hajnoczi
        break;
2433 ae6b0ed6 Stefan Hajnoczi
    case -ENOTSUP:
2434 259b2173 Kevin Wolf
        error_report("This image does not support resize");
2435 ae6b0ed6 Stefan Hajnoczi
        break;
2436 ae6b0ed6 Stefan Hajnoczi
    case -EACCES:
2437 15654a6d Jes Sorensen
        error_report("Image is read-only");
2438 ae6b0ed6 Stefan Hajnoczi
        break;
2439 ae6b0ed6 Stefan Hajnoczi
    default:
2440 15654a6d Jes Sorensen
        error_report("Error resizing image (%d)", -ret);
2441 ae6b0ed6 Stefan Hajnoczi
        break;
2442 ae6b0ed6 Stefan Hajnoczi
    }
2443 c2abccec MORITA Kazutaka
out:
2444 2a81998a Jes Sorensen
    if (bs) {
2445 2a81998a Jes Sorensen
        bdrv_delete(bs);
2446 2a81998a Jes Sorensen
    }
2447 c2abccec MORITA Kazutaka
    if (ret) {
2448 c2abccec MORITA Kazutaka
        return 1;
2449 c2abccec MORITA Kazutaka
    }
2450 ae6b0ed6 Stefan Hajnoczi
    return 0;
2451 ae6b0ed6 Stefan Hajnoczi
}
2452 ae6b0ed6 Stefan Hajnoczi
2453 c227f099 Anthony Liguori
static const img_cmd_t img_cmds[] = {
2454 153859be Stuart Brady
#define DEF(option, callback, arg_string)        \
2455 153859be Stuart Brady
    { option, callback },
2456 153859be Stuart Brady
#include "qemu-img-cmds.h"
2457 153859be Stuart Brady
#undef DEF
2458 153859be Stuart Brady
#undef GEN_DOCS
2459 153859be Stuart Brady
    { NULL, NULL, },
2460 153859be Stuart Brady
};
2461 153859be Stuart Brady
2462 ea2384d3 bellard
int main(int argc, char **argv)
2463 ea2384d3 bellard
{
2464 c227f099 Anthony Liguori
    const img_cmd_t *cmd;
2465 153859be Stuart Brady
    const char *cmdname;
2466 ea2384d3 bellard
2467 53f76e58 Kevin Wolf
    error_set_progname(argv[0]);
2468 53f76e58 Kevin Wolf
2469 2592c59a Paolo Bonzini
    qemu_init_main_loop();
2470 ea2384d3 bellard
    bdrv_init();
2471 ea2384d3 bellard
    if (argc < 2)
2472 ea2384d3 bellard
        help();
2473 153859be Stuart Brady
    cmdname = argv[1];
2474 8f9b157e aurel32
    argc--; argv++;
2475 153859be Stuart Brady
2476 153859be Stuart Brady
    /* find the command */
2477 153859be Stuart Brady
    for(cmd = img_cmds; cmd->name != NULL; cmd++) {
2478 153859be Stuart Brady
        if (!strcmp(cmdname, cmd->name)) {
2479 153859be Stuart Brady
            return cmd->handler(argc, argv);
2480 153859be Stuart Brady
        }
2481 ea2384d3 bellard
    }
2482 153859be Stuart Brady
2483 153859be Stuart Brady
    /* not found */
2484 153859be Stuart Brady
    help();
2485 ea2384d3 bellard
    return 0;
2486 ea2384d3 bellard
}