Statistics
| Branch: | Revision:

root / qemu-img.c @ cc84d90f

History | View | Annotate | Download (74.9 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 f364ec65 Wenchao Xia
#include "block/qapi.h"
34 c054b3fd Benoît Canet
#include <getopt.h>
35 9230eaf6 aliguori
#include <stdio.h>
36 f382d43a Miroslav Rezanina
#include <stdarg.h>
37 ea2384d3 bellard
38 e8445331 bellard
#ifdef _WIN32
39 e8445331 bellard
#include <windows.h>
40 e8445331 bellard
#endif
41 e8445331 bellard
42 c227f099 Anthony Liguori
typedef struct img_cmd_t {
43 153859be Stuart Brady
    const char *name;
44 153859be Stuart Brady
    int (*handler)(int argc, char **argv);
45 c227f099 Anthony Liguori
} img_cmd_t;
46 153859be Stuart Brady
47 8599ea4c Federico Simoncelli
enum {
48 8599ea4c Federico Simoncelli
    OPTION_OUTPUT = 256,
49 8599ea4c Federico Simoncelli
    OPTION_BACKING_CHAIN = 257,
50 8599ea4c Federico Simoncelli
};
51 8599ea4c Federico Simoncelli
52 8599ea4c Federico Simoncelli
typedef enum OutputFormat {
53 8599ea4c Federico Simoncelli
    OFORMAT_JSON,
54 8599ea4c Federico Simoncelli
    OFORMAT_HUMAN,
55 8599ea4c Federico Simoncelli
} OutputFormat;
56 8599ea4c Federico Simoncelli
57 137519ce aurel32
/* Default to cache=writeback as data integrity is not important for qemu-tcg. */
58 adfe078e Stefan Hajnoczi
#define BDRV_O_FLAGS BDRV_O_CACHE_WB
59 661a0f71 Federico Simoncelli
#define BDRV_DEFAULT_CACHE "writeback"
60 137519ce aurel32
61 ea2384d3 bellard
static void format_print(void *opaque, const char *name)
62 ea2384d3 bellard
{
63 ea2384d3 bellard
    printf(" %s", name);
64 ea2384d3 bellard
}
65 ea2384d3 bellard
66 d2c639d6 blueswir1
/* Please keep in synch with qemu-img.texi */
67 3f379ab1 pbrook
static void help(void)
68 ea2384d3 bellard
{
69 e00291c0 Paolo Bonzini
    const char *help_msg =
70 e00291c0 Paolo Bonzini
           "qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fabrice Bellard\n"
71 3f020d70 malc
           "usage: qemu-img command [command options]\n"
72 3f020d70 malc
           "QEMU disk image utility\n"
73 3f020d70 malc
           "\n"
74 3f020d70 malc
           "Command syntax:\n"
75 153859be Stuart Brady
#define DEF(option, callback, arg_string)        \
76 153859be Stuart Brady
           "  " arg_string "\n"
77 153859be Stuart Brady
#include "qemu-img-cmds.h"
78 153859be Stuart Brady
#undef DEF
79 153859be Stuart Brady
#undef GEN_DOCS
80 3f020d70 malc
           "\n"
81 3f020d70 malc
           "Command parameters:\n"
82 3f020d70 malc
           "  'filename' is a disk image filename\n"
83 3f020d70 malc
           "  'fmt' is the disk image format. It is guessed automatically in most cases\n"
84 661a0f71 Federico Simoncelli
           "  'cache' is the cache mode used to write the output disk image, the valid\n"
85 80ccf93b Liu Yuan
           "    options are: 'none', 'writeback' (default, except for convert), 'writethrough',\n"
86 80ccf93b Liu Yuan
           "    'directsync' and 'unsafe' (default for convert)\n"
87 3f020d70 malc
           "  'size' is the disk image size in bytes. Optional suffixes\n"
88 5e00984a Kevin Wolf
           "    'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M),\n"
89 5e00984a Kevin Wolf
           "    'T' (terabyte, 1024G), 'P' (petabyte, 1024T) and 'E' (exabyte, 1024P)  are\n"
90 5e00984a Kevin Wolf
           "    supported. 'b' is ignored.\n"
91 3f020d70 malc
           "  'output_filename' is the destination disk image filename\n"
92 3f020d70 malc
           "  'output_fmt' is the destination format\n"
93 3f020d70 malc
           "  'options' is a comma separated list of format specific options in a\n"
94 3f020d70 malc
           "    name=value format. Use -o ? for an overview of the options supported by the\n"
95 3f020d70 malc
           "    used format\n"
96 3f020d70 malc
           "  '-c' indicates that target image must be compressed (qcow format only)\n"
97 3f020d70 malc
           "  '-u' enables unsafe rebasing. It is assumed that old and new backing file\n"
98 3f020d70 malc
           "       match exactly. The image doesn't need a working backing file before\n"
99 3f020d70 malc
           "       rebasing in this case (useful for renaming the backing file)\n"
100 3f020d70 malc
           "  '-h' with or without a command shows this help and lists the supported formats\n"
101 6b837bc4 Jes Sorensen
           "  '-p' show progress of command (only certain commands)\n"
102 f382d43a Miroslav Rezanina
           "  '-q' use Quiet mode - do not print any output (except errors)\n"
103 a22f123c Kevin Wolf
           "  '-S' indicates the consecutive number of bytes that must contain only zeros\n"
104 a22f123c Kevin Wolf
           "       for qemu-img to create a sparse image during conversion\n"
105 c054b3fd Benoît Canet
           "  '--output' takes the format in which the output must be done (human or json)\n"
106 b2e10493 Alexandre Derumier
           "  '-n' skips the target volume creation (useful if the volume is created\n"
107 b2e10493 Alexandre Derumier
           "       prior to running qemu-img)\n"
108 3f020d70 malc
           "\n"
109 4534ff54 Kevin Wolf
           "Parameters to check subcommand:\n"
110 4534ff54 Kevin Wolf
           "  '-r' tries to repair any inconsistencies that are found during the check.\n"
111 4534ff54 Kevin Wolf
           "       '-r leaks' repairs only cluster leaks, whereas '-r all' fixes all\n"
112 4534ff54 Kevin Wolf
           "       kinds of errors, with a higher risk of choosing the wrong fix or\n"
113 0546b8c2 Stefan Weil
           "       hiding corruption that has already occurred.\n"
114 4534ff54 Kevin Wolf
           "\n"
115 3f020d70 malc
           "Parameters to snapshot subcommand:\n"
116 3f020d70 malc
           "  'snapshot' is the name of the snapshot to create, apply or delete\n"
117 3f020d70 malc
           "  '-a' applies a snapshot (revert disk to saved state)\n"
118 3f020d70 malc
           "  '-c' creates a snapshot\n"
119 3f020d70 malc
           "  '-d' deletes a snapshot\n"
120 d14ed18c Miroslav Rezanina
           "  '-l' lists all snapshots in the given image\n"
121 d14ed18c Miroslav Rezanina
           "\n"
122 d14ed18c Miroslav Rezanina
           "Parameters to compare subcommand:\n"
123 d14ed18c Miroslav Rezanina
           "  '-f' first image format\n"
124 d14ed18c Miroslav Rezanina
           "  '-F' second image format\n"
125 d14ed18c Miroslav Rezanina
           "  '-s' run in Strict mode - fail on different image size or sector allocation\n";
126 e00291c0 Paolo Bonzini
127 e00291c0 Paolo Bonzini
    printf("%s\nSupported formats:", help_msg);
128 ea2384d3 bellard
    bdrv_iterate_format(format_print, NULL);
129 ea2384d3 bellard
    printf("\n");
130 ea2384d3 bellard
    exit(1);
131 ea2384d3 bellard
}
132 ea2384d3 bellard
133 7c30f657 Stefan Weil
static int GCC_FMT_ATTR(2, 3) qprintf(bool quiet, const char *fmt, ...)
134 f382d43a Miroslav Rezanina
{
135 f382d43a Miroslav Rezanina
    int ret = 0;
136 f382d43a Miroslav Rezanina
    if (!quiet) {
137 f382d43a Miroslav Rezanina
        va_list args;
138 f382d43a Miroslav Rezanina
        va_start(args, fmt);
139 f382d43a Miroslav Rezanina
        ret = vprintf(fmt, args);
140 f382d43a Miroslav Rezanina
        va_end(args);
141 f382d43a Miroslav Rezanina
    }
142 f382d43a Miroslav Rezanina
    return ret;
143 f382d43a Miroslav Rezanina
}
144 f382d43a Miroslav Rezanina
145 ea2384d3 bellard
#if defined(WIN32)
146 ea2384d3 bellard
/* XXX: put correct support for win32 */
147 ea2384d3 bellard
static int read_password(char *buf, int buf_size)
148 ea2384d3 bellard
{
149 ea2384d3 bellard
    int c, i;
150 ea2384d3 bellard
    printf("Password: ");
151 ea2384d3 bellard
    fflush(stdout);
152 ea2384d3 bellard
    i = 0;
153 ea2384d3 bellard
    for(;;) {
154 ea2384d3 bellard
        c = getchar();
155 ea2384d3 bellard
        if (c == '\n')
156 ea2384d3 bellard
            break;
157 ea2384d3 bellard
        if (i < (buf_size - 1))
158 ea2384d3 bellard
            buf[i++] = c;
159 ea2384d3 bellard
    }
160 ea2384d3 bellard
    buf[i] = '\0';
161 ea2384d3 bellard
    return 0;
162 ea2384d3 bellard
}
163 ea2384d3 bellard
164 ea2384d3 bellard
#else
165 ea2384d3 bellard
166 ea2384d3 bellard
#include <termios.h>
167 ea2384d3 bellard
168 ea2384d3 bellard
static struct termios oldtty;
169 ea2384d3 bellard
170 ea2384d3 bellard
static void term_exit(void)
171 ea2384d3 bellard
{
172 ea2384d3 bellard
    tcsetattr (0, TCSANOW, &oldtty);
173 ea2384d3 bellard
}
174 ea2384d3 bellard
175 ea2384d3 bellard
static void term_init(void)
176 ea2384d3 bellard
{
177 ea2384d3 bellard
    struct termios tty;
178 ea2384d3 bellard
179 ea2384d3 bellard
    tcgetattr (0, &tty);
180 ea2384d3 bellard
    oldtty = tty;
181 ea2384d3 bellard
182 ea2384d3 bellard
    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
183 ea2384d3 bellard
                          |INLCR|IGNCR|ICRNL|IXON);
184 ea2384d3 bellard
    tty.c_oflag |= OPOST;
185 ea2384d3 bellard
    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
186 ea2384d3 bellard
    tty.c_cflag &= ~(CSIZE|PARENB);
187 ea2384d3 bellard
    tty.c_cflag |= CS8;
188 ea2384d3 bellard
    tty.c_cc[VMIN] = 1;
189 ea2384d3 bellard
    tty.c_cc[VTIME] = 0;
190 3b46e624 ths
191 ea2384d3 bellard
    tcsetattr (0, TCSANOW, &tty);
192 ea2384d3 bellard
193 ea2384d3 bellard
    atexit(term_exit);
194 ea2384d3 bellard
}
195 ea2384d3 bellard
196 3f379ab1 pbrook
static int read_password(char *buf, int buf_size)
197 ea2384d3 bellard
{
198 ea2384d3 bellard
    uint8_t ch;
199 ea2384d3 bellard
    int i, ret;
200 ea2384d3 bellard
201 ea2384d3 bellard
    printf("password: ");
202 ea2384d3 bellard
    fflush(stdout);
203 ea2384d3 bellard
    term_init();
204 ea2384d3 bellard
    i = 0;
205 ea2384d3 bellard
    for(;;) {
206 ea2384d3 bellard
        ret = read(0, &ch, 1);
207 ea2384d3 bellard
        if (ret == -1) {
208 ea2384d3 bellard
            if (errno == EAGAIN || errno == EINTR) {
209 ea2384d3 bellard
                continue;
210 ea2384d3 bellard
            } else {
211 ea2384d3 bellard
                ret = -1;
212 ea2384d3 bellard
                break;
213 ea2384d3 bellard
            }
214 ea2384d3 bellard
        } else if (ret == 0) {
215 ea2384d3 bellard
            ret = -1;
216 ea2384d3 bellard
            break;
217 ea2384d3 bellard
        } else {
218 ea2384d3 bellard
            if (ch == '\r') {
219 ea2384d3 bellard
                ret = 0;
220 ea2384d3 bellard
                break;
221 ea2384d3 bellard
            }
222 ea2384d3 bellard
            if (i < (buf_size - 1))
223 ea2384d3 bellard
                buf[i++] = ch;
224 ea2384d3 bellard
        }
225 ea2384d3 bellard
    }
226 ea2384d3 bellard
    term_exit();
227 ea2384d3 bellard
    buf[i] = '\0';
228 ea2384d3 bellard
    printf("\n");
229 ea2384d3 bellard
    return ret;
230 ea2384d3 bellard
}
231 ea2384d3 bellard
#endif
232 ea2384d3 bellard
233 4ac8aacd Jes Sorensen
static int print_block_option_help(const char *filename, const char *fmt)
234 4ac8aacd Jes Sorensen
{
235 4ac8aacd Jes Sorensen
    BlockDriver *drv, *proto_drv;
236 4ac8aacd Jes Sorensen
    QEMUOptionParameter *create_options = NULL;
237 4ac8aacd Jes Sorensen
238 4ac8aacd Jes Sorensen
    /* Find driver and parse its options */
239 4ac8aacd Jes Sorensen
    drv = bdrv_find_format(fmt);
240 4ac8aacd Jes Sorensen
    if (!drv) {
241 15654a6d Jes Sorensen
        error_report("Unknown file format '%s'", fmt);
242 4ac8aacd Jes Sorensen
        return 1;
243 4ac8aacd Jes Sorensen
    }
244 4ac8aacd Jes Sorensen
245 98289620 Kevin Wolf
    proto_drv = bdrv_find_protocol(filename, true);
246 4ac8aacd Jes Sorensen
    if (!proto_drv) {
247 15654a6d Jes Sorensen
        error_report("Unknown protocol '%s'", filename);
248 4ac8aacd Jes Sorensen
        return 1;
249 4ac8aacd Jes Sorensen
    }
250 4ac8aacd Jes Sorensen
251 4ac8aacd Jes Sorensen
    create_options = append_option_parameters(create_options,
252 4ac8aacd Jes Sorensen
                                              drv->create_options);
253 4ac8aacd Jes Sorensen
    create_options = append_option_parameters(create_options,
254 4ac8aacd Jes Sorensen
                                              proto_drv->create_options);
255 4ac8aacd Jes Sorensen
    print_option_help(create_options);
256 4ac8aacd Jes Sorensen
    free_option_parameters(create_options);
257 4ac8aacd Jes Sorensen
    return 0;
258 4ac8aacd Jes Sorensen
}
259 4ac8aacd Jes Sorensen
260 75c23805 bellard
static BlockDriverState *bdrv_new_open(const char *filename,
261 9bc378c1 Sheng Yang
                                       const char *fmt,
262 f0536bb8 Daniel P. Berrange
                                       int flags,
263 f382d43a Miroslav Rezanina
                                       bool require_io,
264 f382d43a Miroslav Rezanina
                                       bool quiet)
265 75c23805 bellard
{
266 75c23805 bellard
    BlockDriverState *bs;
267 75c23805 bellard
    BlockDriver *drv;
268 75c23805 bellard
    char password[256];
269 34b5d2c6 Max Reitz
    Error *local_err = NULL;
270 b9eaf9ec Kevin Wolf
    int ret;
271 75c23805 bellard
272 b9eaf9ec Kevin Wolf
    bs = bdrv_new("image");
273 ad717139 Kevin Wolf
274 75c23805 bellard
    if (fmt) {
275 75c23805 bellard
        drv = bdrv_find_format(fmt);
276 c2abccec MORITA Kazutaka
        if (!drv) {
277 15654a6d Jes Sorensen
            error_report("Unknown file format '%s'", fmt);
278 c2abccec MORITA Kazutaka
            goto fail;
279 c2abccec MORITA Kazutaka
        }
280 75c23805 bellard
    } else {
281 75c23805 bellard
        drv = NULL;
282 75c23805 bellard
    }
283 b9eaf9ec Kevin Wolf
284 34b5d2c6 Max Reitz
    ret = bdrv_open(bs, filename, NULL, flags, drv, &local_err);
285 b9eaf9ec Kevin Wolf
    if (ret < 0) {
286 34b5d2c6 Max Reitz
        error_report("Could not open '%s': %s", filename,
287 34b5d2c6 Max Reitz
                     error_get_pretty(local_err));
288 34b5d2c6 Max Reitz
        error_free(local_err);
289 c2abccec MORITA Kazutaka
        goto fail;
290 75c23805 bellard
    }
291 b9eaf9ec Kevin Wolf
292 f0536bb8 Daniel P. Berrange
    if (bdrv_is_encrypted(bs) && require_io) {
293 f382d43a Miroslav Rezanina
        qprintf(quiet, "Disk image '%s' is encrypted.\n", filename);
294 c2abccec MORITA Kazutaka
        if (read_password(password, sizeof(password)) < 0) {
295 15654a6d Jes Sorensen
            error_report("No password given");
296 c2abccec MORITA Kazutaka
            goto fail;
297 c2abccec MORITA Kazutaka
        }
298 c2abccec MORITA Kazutaka
        if (bdrv_set_key(bs, password) < 0) {
299 15654a6d Jes Sorensen
            error_report("invalid password");
300 c2abccec MORITA Kazutaka
            goto fail;
301 c2abccec MORITA Kazutaka
        }
302 75c23805 bellard
    }
303 75c23805 bellard
    return bs;
304 c2abccec MORITA Kazutaka
fail:
305 c2abccec MORITA Kazutaka
    if (bs) {
306 4f6fd349 Fam Zheng
        bdrv_unref(bs);
307 c2abccec MORITA Kazutaka
    }
308 c2abccec MORITA Kazutaka
    return NULL;
309 75c23805 bellard
}
310 75c23805 bellard
311 c2abccec MORITA Kazutaka
static int add_old_style_options(const char *fmt, QEMUOptionParameter *list,
312 eec77d9e Jes Sorensen
                                 const char *base_filename,
313 eec77d9e Jes Sorensen
                                 const char *base_fmt)
314 efa84d43 Kevin Wolf
{
315 efa84d43 Kevin Wolf
    if (base_filename) {
316 efa84d43 Kevin Wolf
        if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) {
317 15654a6d Jes Sorensen
            error_report("Backing file not supported for file format '%s'",
318 15654a6d Jes Sorensen
                         fmt);
319 c2abccec MORITA Kazutaka
            return -1;
320 efa84d43 Kevin Wolf
        }
321 efa84d43 Kevin Wolf
    }
322 efa84d43 Kevin Wolf
    if (base_fmt) {
323 efa84d43 Kevin Wolf
        if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {
324 15654a6d Jes Sorensen
            error_report("Backing file format not supported for file "
325 15654a6d Jes Sorensen
                         "format '%s'", fmt);
326 c2abccec MORITA Kazutaka
            return -1;
327 efa84d43 Kevin Wolf
        }
328 efa84d43 Kevin Wolf
    }
329 c2abccec MORITA Kazutaka
    return 0;
330 efa84d43 Kevin Wolf
}
331 efa84d43 Kevin Wolf
332 ea2384d3 bellard
static int img_create(int argc, char **argv)
333 ea2384d3 bellard
{
334 a9300911 Luiz Capitulino
    int c;
335 1da7cfbd Jes Sorensen
    uint64_t img_size = -1;
336 ea2384d3 bellard
    const char *fmt = "raw";
337 9230eaf6 aliguori
    const char *base_fmt = NULL;
338 ea2384d3 bellard
    const char *filename;
339 ea2384d3 bellard
    const char *base_filename = NULL;
340 9ea2ea71 Kevin Wolf
    char *options = NULL;
341 9b37525a Luiz Capitulino
    Error *local_err = NULL;
342 f382d43a Miroslav Rezanina
    bool quiet = false;
343 3b46e624 ths
344 ea2384d3 bellard
    for(;;) {
345 f382d43a Miroslav Rezanina
        c = getopt(argc, argv, "F:b:f:he6o:q");
346 b8fb60da Jes Sorensen
        if (c == -1) {
347 ea2384d3 bellard
            break;
348 b8fb60da Jes Sorensen
        }
349 ea2384d3 bellard
        switch(c) {
350 ef87394c Jes Sorensen
        case '?':
351 ea2384d3 bellard
        case 'h':
352 ea2384d3 bellard
            help();
353 ea2384d3 bellard
            break;
354 9230eaf6 aliguori
        case 'F':
355 9230eaf6 aliguori
            base_fmt = optarg;
356 9230eaf6 aliguori
            break;
357 ea2384d3 bellard
        case 'b':
358 ea2384d3 bellard
            base_filename = optarg;
359 ea2384d3 bellard
            break;
360 ea2384d3 bellard
        case 'f':
361 ea2384d3 bellard
            fmt = optarg;
362 ea2384d3 bellard
            break;
363 ea2384d3 bellard
        case 'e':
364 9d42e15d Markus Armbruster
            error_report("option -e is deprecated, please use \'-o "
365 eec77d9e Jes Sorensen
                  "encryption\' instead!");
366 eec77d9e Jes Sorensen
            return 1;
367 d8871c5a ths
        case '6':
368 9d42e15d Markus Armbruster
            error_report("option -6 is deprecated, please use \'-o "
369 eec77d9e Jes Sorensen
                  "compat6\' instead!");
370 eec77d9e Jes Sorensen
            return 1;
371 9ea2ea71 Kevin Wolf
        case 'o':
372 9ea2ea71 Kevin Wolf
            options = optarg;
373 9ea2ea71 Kevin Wolf
            break;
374 f382d43a Miroslav Rezanina
        case 'q':
375 f382d43a Miroslav Rezanina
            quiet = true;
376 f382d43a Miroslav Rezanina
            break;
377 ea2384d3 bellard
        }
378 ea2384d3 bellard
    }
379 9230eaf6 aliguori
380 b50cbabc MORITA Kazutaka
    /* Get the filename */
381 b8fb60da Jes Sorensen
    if (optind >= argc) {
382 b50cbabc MORITA Kazutaka
        help();
383 b8fb60da Jes Sorensen
    }
384 b50cbabc MORITA Kazutaka
    filename = argv[optind++];
385 b50cbabc MORITA Kazutaka
386 1da7cfbd Jes Sorensen
    /* Get image size, if specified */
387 1da7cfbd Jes Sorensen
    if (optind < argc) {
388 70b4f4bb Jes Sorensen
        int64_t sval;
389 e36b3695 Markus Armbruster
        char *end;
390 e36b3695 Markus Armbruster
        sval = strtosz_suffix(argv[optind++], &end, STRTOSZ_DEFSUFFIX_B);
391 e36b3695 Markus Armbruster
        if (sval < 0 || *end) {
392 79443397 liguang
            if (sval == -ERANGE) {
393 79443397 liguang
                error_report("Image size must be less than 8 EiB!");
394 79443397 liguang
            } else {
395 79443397 liguang
                error_report("Invalid image size specified! You may use k, M, "
396 5e00984a Kevin Wolf
                      "G, T, P or E suffixes for ");
397 5e00984a Kevin Wolf
                error_report("kilobytes, megabytes, gigabytes, terabytes, "
398 5e00984a Kevin Wolf
                             "petabytes and exabytes.");
399 79443397 liguang
            }
400 a9300911 Luiz Capitulino
            return 1;
401 1da7cfbd Jes Sorensen
        }
402 1da7cfbd Jes Sorensen
        img_size = (uint64_t)sval;
403 1da7cfbd Jes Sorensen
    }
404 fc11eb26 Kevin Wolf
    if (optind != argc) {
405 fc11eb26 Kevin Wolf
        help();
406 fc11eb26 Kevin Wolf
    }
407 1da7cfbd Jes Sorensen
408 c8057f95 Peter Maydell
    if (options && is_help_option(options)) {
409 a9300911 Luiz Capitulino
        return print_block_option_help(filename, fmt);
410 4ac8aacd Jes Sorensen
    }
411 4ac8aacd Jes Sorensen
412 9b37525a Luiz Capitulino
    bdrv_img_create(filename, fmt, base_filename, base_fmt,
413 f382d43a Miroslav Rezanina
                    options, img_size, BDRV_O_FLAGS, &local_err, quiet);
414 9b37525a Luiz Capitulino
    if (error_is_set(&local_err)) {
415 9b37525a Luiz Capitulino
        error_report("%s", error_get_pretty(local_err));
416 9b37525a Luiz Capitulino
        error_free(local_err);
417 c2abccec MORITA Kazutaka
        return 1;
418 c2abccec MORITA Kazutaka
    }
419 a9300911 Luiz Capitulino
420 ea2384d3 bellard
    return 0;
421 ea2384d3 bellard
}
422 ea2384d3 bellard
423 f382d43a Miroslav Rezanina
static void dump_json_image_check(ImageCheck *check, bool quiet)
424 8599ea4c Federico Simoncelli
{
425 8599ea4c Federico Simoncelli
    Error *errp = NULL;
426 8599ea4c Federico Simoncelli
    QString *str;
427 8599ea4c Federico Simoncelli
    QmpOutputVisitor *ov = qmp_output_visitor_new();
428 8599ea4c Federico Simoncelli
    QObject *obj;
429 8599ea4c Federico Simoncelli
    visit_type_ImageCheck(qmp_output_get_visitor(ov),
430 8599ea4c Federico Simoncelli
                          &check, NULL, &errp);
431 8599ea4c Federico Simoncelli
    obj = qmp_output_get_qobject(ov);
432 8599ea4c Federico Simoncelli
    str = qobject_to_json_pretty(obj);
433 8599ea4c Federico Simoncelli
    assert(str != NULL);
434 f382d43a Miroslav Rezanina
    qprintf(quiet, "%s\n", qstring_get_str(str));
435 8599ea4c Federico Simoncelli
    qobject_decref(obj);
436 8599ea4c Federico Simoncelli
    qmp_output_visitor_cleanup(ov);
437 8599ea4c Federico Simoncelli
    QDECREF(str);
438 8599ea4c Federico Simoncelli
}
439 8599ea4c Federico Simoncelli
440 f382d43a Miroslav Rezanina
static void dump_human_image_check(ImageCheck *check, bool quiet)
441 8599ea4c Federico Simoncelli
{
442 8599ea4c Federico Simoncelli
    if (!(check->corruptions || check->leaks || check->check_errors)) {
443 f382d43a Miroslav Rezanina
        qprintf(quiet, "No errors were found on the image.\n");
444 8599ea4c Federico Simoncelli
    } else {
445 8599ea4c Federico Simoncelli
        if (check->corruptions) {
446 f382d43a Miroslav Rezanina
            qprintf(quiet, "\n%" PRId64 " errors were found on the image.\n"
447 f382d43a Miroslav Rezanina
                    "Data may be corrupted, or further writes to the image "
448 f382d43a Miroslav Rezanina
                    "may corrupt it.\n",
449 f382d43a Miroslav Rezanina
                    check->corruptions);
450 8599ea4c Federico Simoncelli
        }
451 8599ea4c Federico Simoncelli
452 8599ea4c Federico Simoncelli
        if (check->leaks) {
453 f382d43a Miroslav Rezanina
            qprintf(quiet,
454 f382d43a Miroslav Rezanina
                    "\n%" PRId64 " leaked clusters were found on the image.\n"
455 f382d43a Miroslav Rezanina
                    "This means waste of disk space, but no harm to data.\n",
456 f382d43a Miroslav Rezanina
                    check->leaks);
457 8599ea4c Federico Simoncelli
        }
458 8599ea4c Federico Simoncelli
459 8599ea4c Federico Simoncelli
        if (check->check_errors) {
460 f382d43a Miroslav Rezanina
            qprintf(quiet,
461 f382d43a Miroslav Rezanina
                    "\n%" PRId64
462 f382d43a Miroslav Rezanina
                    " internal errors have occurred during the check.\n",
463 f382d43a Miroslav Rezanina
                    check->check_errors);
464 8599ea4c Federico Simoncelli
        }
465 8599ea4c Federico Simoncelli
    }
466 8599ea4c Federico Simoncelli
467 8599ea4c Federico Simoncelli
    if (check->total_clusters != 0 && check->allocated_clusters != 0) {
468 f382d43a Miroslav Rezanina
        qprintf(quiet, "%" PRId64 "/%" PRId64 " = %0.2f%% allocated, "
469 f382d43a Miroslav Rezanina
                "%0.2f%% fragmented, %0.2f%% compressed clusters\n",
470 f382d43a Miroslav Rezanina
                check->allocated_clusters, check->total_clusters,
471 f382d43a Miroslav Rezanina
                check->allocated_clusters * 100.0 / check->total_clusters,
472 f382d43a Miroslav Rezanina
                check->fragmented_clusters * 100.0 / check->allocated_clusters,
473 f382d43a Miroslav Rezanina
                check->compressed_clusters * 100.0 /
474 f382d43a Miroslav Rezanina
                check->allocated_clusters);
475 8599ea4c Federico Simoncelli
    }
476 8599ea4c Federico Simoncelli
477 8599ea4c Federico Simoncelli
    if (check->image_end_offset) {
478 f382d43a Miroslav Rezanina
        qprintf(quiet,
479 f382d43a Miroslav Rezanina
                "Image end offset: %" PRId64 "\n", check->image_end_offset);
480 8599ea4c Federico Simoncelli
    }
481 8599ea4c Federico Simoncelli
}
482 8599ea4c Federico Simoncelli
483 8599ea4c Federico Simoncelli
static int collect_image_check(BlockDriverState *bs,
484 8599ea4c Federico Simoncelli
                   ImageCheck *check,
485 8599ea4c Federico Simoncelli
                   const char *filename,
486 8599ea4c Federico Simoncelli
                   const char *fmt,
487 8599ea4c Federico Simoncelli
                   int fix)
488 8599ea4c Federico Simoncelli
{
489 8599ea4c Federico Simoncelli
    int ret;
490 8599ea4c Federico Simoncelli
    BdrvCheckResult result;
491 8599ea4c Federico Simoncelli
492 8599ea4c Federico Simoncelli
    ret = bdrv_check(bs, &result, fix);
493 8599ea4c Federico Simoncelli
    if (ret < 0) {
494 8599ea4c Federico Simoncelli
        return ret;
495 8599ea4c Federico Simoncelli
    }
496 8599ea4c Federico Simoncelli
497 8599ea4c Federico Simoncelli
    check->filename                 = g_strdup(filename);
498 8599ea4c Federico Simoncelli
    check->format                   = g_strdup(bdrv_get_format_name(bs));
499 8599ea4c Federico Simoncelli
    check->check_errors             = result.check_errors;
500 8599ea4c Federico Simoncelli
    check->corruptions              = result.corruptions;
501 8599ea4c Federico Simoncelli
    check->has_corruptions          = result.corruptions != 0;
502 8599ea4c Federico Simoncelli
    check->leaks                    = result.leaks;
503 8599ea4c Federico Simoncelli
    check->has_leaks                = result.leaks != 0;
504 8599ea4c Federico Simoncelli
    check->corruptions_fixed        = result.corruptions_fixed;
505 8599ea4c Federico Simoncelli
    check->has_corruptions_fixed    = result.corruptions != 0;
506 8599ea4c Federico Simoncelli
    check->leaks_fixed              = result.leaks_fixed;
507 8599ea4c Federico Simoncelli
    check->has_leaks_fixed          = result.leaks != 0;
508 8599ea4c Federico Simoncelli
    check->image_end_offset         = result.image_end_offset;
509 8599ea4c Federico Simoncelli
    check->has_image_end_offset     = result.image_end_offset != 0;
510 8599ea4c Federico Simoncelli
    check->total_clusters           = result.bfi.total_clusters;
511 8599ea4c Federico Simoncelli
    check->has_total_clusters       = result.bfi.total_clusters != 0;
512 8599ea4c Federico Simoncelli
    check->allocated_clusters       = result.bfi.allocated_clusters;
513 8599ea4c Federico Simoncelli
    check->has_allocated_clusters   = result.bfi.allocated_clusters != 0;
514 8599ea4c Federico Simoncelli
    check->fragmented_clusters      = result.bfi.fragmented_clusters;
515 8599ea4c Federico Simoncelli
    check->has_fragmented_clusters  = result.bfi.fragmented_clusters != 0;
516 e6439d78 Stefan Hajnoczi
    check->compressed_clusters      = result.bfi.compressed_clusters;
517 e6439d78 Stefan Hajnoczi
    check->has_compressed_clusters  = result.bfi.compressed_clusters != 0;
518 8599ea4c Federico Simoncelli
519 8599ea4c Federico Simoncelli
    return 0;
520 8599ea4c Federico Simoncelli
}
521 8599ea4c Federico Simoncelli
522 e076f338 Kevin Wolf
/*
523 e076f338 Kevin Wolf
 * Checks an image for consistency. Exit codes:
524 e076f338 Kevin Wolf
 *
525 e076f338 Kevin Wolf
 * 0 - Check completed, image is good
526 e076f338 Kevin Wolf
 * 1 - Check not completed because of internal errors
527 e076f338 Kevin Wolf
 * 2 - Check completed, image is corrupted
528 e076f338 Kevin Wolf
 * 3 - Check completed, image has leaked clusters, but is good otherwise
529 e076f338 Kevin Wolf
 */
530 1585969c aliguori
static int img_check(int argc, char **argv)
531 1585969c aliguori
{
532 1585969c aliguori
    int c, ret;
533 8599ea4c Federico Simoncelli
    OutputFormat output_format = OFORMAT_HUMAN;
534 8599ea4c Federico Simoncelli
    const char *filename, *fmt, *output;
535 1585969c aliguori
    BlockDriverState *bs;
536 4534ff54 Kevin Wolf
    int fix = 0;
537 058f8f16 Stefan Hajnoczi
    int flags = BDRV_O_FLAGS | BDRV_O_CHECK;
538 8599ea4c Federico Simoncelli
    ImageCheck *check;
539 f382d43a Miroslav Rezanina
    bool quiet = false;
540 1585969c aliguori
541 1585969c aliguori
    fmt = NULL;
542 8599ea4c Federico Simoncelli
    output = NULL;
543 1585969c aliguori
    for(;;) {
544 8599ea4c Federico Simoncelli
        int option_index = 0;
545 8599ea4c Federico Simoncelli
        static const struct option long_options[] = {
546 8599ea4c Federico Simoncelli
            {"help", no_argument, 0, 'h'},
547 8599ea4c Federico Simoncelli
            {"format", required_argument, 0, 'f'},
548 8599ea4c Federico Simoncelli
            {"repair", no_argument, 0, 'r'},
549 8599ea4c Federico Simoncelli
            {"output", required_argument, 0, OPTION_OUTPUT},
550 8599ea4c Federico Simoncelli
            {0, 0, 0, 0}
551 8599ea4c Federico Simoncelli
        };
552 f382d43a Miroslav Rezanina
        c = getopt_long(argc, argv, "f:hr:q",
553 8599ea4c Federico Simoncelli
                        long_options, &option_index);
554 b8fb60da Jes Sorensen
        if (c == -1) {
555 1585969c aliguori
            break;
556 b8fb60da Jes Sorensen
        }
557 1585969c aliguori
        switch(c) {
558 ef87394c Jes Sorensen
        case '?':
559 1585969c aliguori
        case 'h':
560 1585969c aliguori
            help();
561 1585969c aliguori
            break;
562 1585969c aliguori
        case 'f':
563 1585969c aliguori
            fmt = optarg;
564 1585969c aliguori
            break;
565 4534ff54 Kevin Wolf
        case 'r':
566 4534ff54 Kevin Wolf
            flags |= BDRV_O_RDWR;
567 4534ff54 Kevin Wolf
568 4534ff54 Kevin Wolf
            if (!strcmp(optarg, "leaks")) {
569 4534ff54 Kevin Wolf
                fix = BDRV_FIX_LEAKS;
570 4534ff54 Kevin Wolf
            } else if (!strcmp(optarg, "all")) {
571 4534ff54 Kevin Wolf
                fix = BDRV_FIX_LEAKS | BDRV_FIX_ERRORS;
572 4534ff54 Kevin Wolf
            } else {
573 4534ff54 Kevin Wolf
                help();
574 4534ff54 Kevin Wolf
            }
575 4534ff54 Kevin Wolf
            break;
576 8599ea4c Federico Simoncelli
        case OPTION_OUTPUT:
577 8599ea4c Federico Simoncelli
            output = optarg;
578 8599ea4c Federico Simoncelli
            break;
579 f382d43a Miroslav Rezanina
        case 'q':
580 f382d43a Miroslav Rezanina
            quiet = true;
581 f382d43a Miroslav Rezanina
            break;
582 1585969c aliguori
        }
583 1585969c aliguori
    }
584 fc11eb26 Kevin Wolf
    if (optind != argc - 1) {
585 1585969c aliguori
        help();
586 b8fb60da Jes Sorensen
    }
587 1585969c aliguori
    filename = argv[optind++];
588 1585969c aliguori
589 8599ea4c Federico Simoncelli
    if (output && !strcmp(output, "json")) {
590 8599ea4c Federico Simoncelli
        output_format = OFORMAT_JSON;
591 8599ea4c Federico Simoncelli
    } else if (output && !strcmp(output, "human")) {
592 8599ea4c Federico Simoncelli
        output_format = OFORMAT_HUMAN;
593 8599ea4c Federico Simoncelli
    } else if (output) {
594 8599ea4c Federico Simoncelli
        error_report("--output must be used with human or json as argument.");
595 8599ea4c Federico Simoncelli
        return 1;
596 8599ea4c Federico Simoncelli
    }
597 8599ea4c Federico Simoncelli
598 f382d43a Miroslav Rezanina
    bs = bdrv_new_open(filename, fmt, flags, true, quiet);
599 c2abccec MORITA Kazutaka
    if (!bs) {
600 c2abccec MORITA Kazutaka
        return 1;
601 c2abccec MORITA Kazutaka
    }
602 8599ea4c Federico Simoncelli
603 8599ea4c Federico Simoncelli
    check = g_new0(ImageCheck, 1);
604 8599ea4c Federico Simoncelli
    ret = collect_image_check(bs, check, filename, fmt, fix);
605 e076f338 Kevin Wolf
606 e076f338 Kevin Wolf
    if (ret == -ENOTSUP) {
607 8599ea4c Federico Simoncelli
        if (output_format == OFORMAT_HUMAN) {
608 8599ea4c Federico Simoncelli
            error_report("This image format does not support checks");
609 8599ea4c Federico Simoncelli
        }
610 8599ea4c Federico Simoncelli
        ret = 1;
611 8599ea4c Federico Simoncelli
        goto fail;
612 e076f338 Kevin Wolf
    }
613 e076f338 Kevin Wolf
614 8599ea4c Federico Simoncelli
    if (check->corruptions_fixed || check->leaks_fixed) {
615 8599ea4c Federico Simoncelli
        int corruptions_fixed, leaks_fixed;
616 ccf34716 Kevin Wolf
617 8599ea4c Federico Simoncelli
        leaks_fixed         = check->leaks_fixed;
618 8599ea4c Federico Simoncelli
        corruptions_fixed   = check->corruptions_fixed;
619 e076f338 Kevin Wolf
620 8599ea4c Federico Simoncelli
        if (output_format == OFORMAT_HUMAN) {
621 f382d43a Miroslav Rezanina
            qprintf(quiet,
622 f382d43a Miroslav Rezanina
                    "The following inconsistencies were found and repaired:\n\n"
623 f382d43a Miroslav Rezanina
                    "    %" PRId64 " leaked clusters\n"
624 f382d43a Miroslav Rezanina
                    "    %" PRId64 " corruptions\n\n"
625 f382d43a Miroslav Rezanina
                    "Double checking the fixed image now...\n",
626 f382d43a Miroslav Rezanina
                    check->leaks_fixed,
627 f382d43a Miroslav Rezanina
                    check->corruptions_fixed);
628 e076f338 Kevin Wolf
        }
629 e076f338 Kevin Wolf
630 8599ea4c Federico Simoncelli
        ret = collect_image_check(bs, check, filename, fmt, 0);
631 1585969c aliguori
632 8599ea4c Federico Simoncelli
        check->leaks_fixed          = leaks_fixed;
633 8599ea4c Federico Simoncelli
        check->corruptions_fixed    = corruptions_fixed;
634 f8111c24 Dong Xu Wang
    }
635 f8111c24 Dong Xu Wang
636 8599ea4c Federico Simoncelli
    switch (output_format) {
637 8599ea4c Federico Simoncelli
    case OFORMAT_HUMAN:
638 f382d43a Miroslav Rezanina
        dump_human_image_check(check, quiet);
639 8599ea4c Federico Simoncelli
        break;
640 8599ea4c Federico Simoncelli
    case OFORMAT_JSON:
641 f382d43a Miroslav Rezanina
        dump_json_image_check(check, quiet);
642 8599ea4c Federico Simoncelli
        break;
643 c6bb9ad1 Federico Simoncelli
    }
644 c6bb9ad1 Federico Simoncelli
645 8599ea4c Federico Simoncelli
    if (ret || check->check_errors) {
646 8599ea4c Federico Simoncelli
        ret = 1;
647 8599ea4c Federico Simoncelli
        goto fail;
648 c2abccec MORITA Kazutaka
    }
649 e076f338 Kevin Wolf
650 8599ea4c Federico Simoncelli
    if (check->corruptions) {
651 8599ea4c Federico Simoncelli
        ret = 2;
652 8599ea4c Federico Simoncelli
    } else if (check->leaks) {
653 8599ea4c Federico Simoncelli
        ret = 3;
654 e076f338 Kevin Wolf
    } else {
655 8599ea4c Federico Simoncelli
        ret = 0;
656 e076f338 Kevin Wolf
    }
657 8599ea4c Federico Simoncelli
658 8599ea4c Federico Simoncelli
fail:
659 8599ea4c Federico Simoncelli
    qapi_free_ImageCheck(check);
660 4f6fd349 Fam Zheng
    bdrv_unref(bs);
661 8599ea4c Federico Simoncelli
662 8599ea4c Federico Simoncelli
    return ret;
663 1585969c aliguori
}
664 1585969c aliguori
665 ea2384d3 bellard
static int img_commit(int argc, char **argv)
666 ea2384d3 bellard
{
667 661a0f71 Federico Simoncelli
    int c, ret, flags;
668 661a0f71 Federico Simoncelli
    const char *filename, *fmt, *cache;
669 ea2384d3 bellard
    BlockDriverState *bs;
670 f382d43a Miroslav Rezanina
    bool quiet = false;
671 ea2384d3 bellard
672 ea2384d3 bellard
    fmt = NULL;
673 661a0f71 Federico Simoncelli
    cache = BDRV_DEFAULT_CACHE;
674 ea2384d3 bellard
    for(;;) {
675 f382d43a Miroslav Rezanina
        c = getopt(argc, argv, "f:ht:q");
676 b8fb60da Jes Sorensen
        if (c == -1) {
677 ea2384d3 bellard
            break;
678 b8fb60da Jes Sorensen
        }
679 ea2384d3 bellard
        switch(c) {
680 ef87394c Jes Sorensen
        case '?':
681 ea2384d3 bellard
        case 'h':
682 ea2384d3 bellard
            help();
683 ea2384d3 bellard
            break;
684 ea2384d3 bellard
        case 'f':
685 ea2384d3 bellard
            fmt = optarg;
686 ea2384d3 bellard
            break;
687 661a0f71 Federico Simoncelli
        case 't':
688 661a0f71 Federico Simoncelli
            cache = optarg;
689 661a0f71 Federico Simoncelli
            break;
690 f382d43a Miroslav Rezanina
        case 'q':
691 f382d43a Miroslav Rezanina
            quiet = true;
692 f382d43a Miroslav Rezanina
            break;
693 ea2384d3 bellard
        }
694 ea2384d3 bellard
    }
695 fc11eb26 Kevin Wolf
    if (optind != argc - 1) {
696 ea2384d3 bellard
        help();
697 b8fb60da Jes Sorensen
    }
698 ea2384d3 bellard
    filename = argv[optind++];
699 ea2384d3 bellard
700 661a0f71 Federico Simoncelli
    flags = BDRV_O_RDWR;
701 c3993cdc Stefan Hajnoczi
    ret = bdrv_parse_cache_flags(cache, &flags);
702 661a0f71 Federico Simoncelli
    if (ret < 0) {
703 661a0f71 Federico Simoncelli
        error_report("Invalid cache option: %s", cache);
704 661a0f71 Federico Simoncelli
        return -1;
705 661a0f71 Federico Simoncelli
    }
706 661a0f71 Federico Simoncelli
707 f382d43a Miroslav Rezanina
    bs = bdrv_new_open(filename, fmt, flags, true, quiet);
708 c2abccec MORITA Kazutaka
    if (!bs) {
709 c2abccec MORITA Kazutaka
        return 1;
710 c2abccec MORITA Kazutaka
    }
711 ea2384d3 bellard
    ret = bdrv_commit(bs);
712 ea2384d3 bellard
    switch(ret) {
713 ea2384d3 bellard
    case 0:
714 f382d43a Miroslav Rezanina
        qprintf(quiet, "Image committed.\n");
715 ea2384d3 bellard
        break;
716 ea2384d3 bellard
    case -ENOENT:
717 15654a6d Jes Sorensen
        error_report("No disk inserted");
718 ea2384d3 bellard
        break;
719 ea2384d3 bellard
    case -EACCES:
720 15654a6d Jes Sorensen
        error_report("Image is read-only");
721 ea2384d3 bellard
        break;
722 ea2384d3 bellard
    case -ENOTSUP:
723 15654a6d Jes Sorensen
        error_report("Image is already committed");
724 ea2384d3 bellard
        break;
725 ea2384d3 bellard
    default:
726 15654a6d Jes Sorensen
        error_report("Error while committing image");
727 ea2384d3 bellard
        break;
728 ea2384d3 bellard
    }
729 ea2384d3 bellard
730 4f6fd349 Fam Zheng
    bdrv_unref(bs);
731 c2abccec MORITA Kazutaka
    if (ret) {
732 c2abccec MORITA Kazutaka
        return 1;
733 c2abccec MORITA Kazutaka
    }
734 ea2384d3 bellard
    return 0;
735 ea2384d3 bellard
}
736 ea2384d3 bellard
737 f6a00aa1 Dmitry Konishchev
/*
738 f58c7b35 ths
 * Returns true iff the first sector pointed to by 'buf' contains at least
739 f58c7b35 ths
 * a non-NUL byte.
740 f58c7b35 ths
 *
741 f58c7b35 ths
 * 'pnum' is set to the number of sectors (including and immediately following
742 f58c7b35 ths
 * the first one) that are known to be in the same allocated/unallocated state.
743 f58c7b35 ths
 */
744 ea2384d3 bellard
static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
745 ea2384d3 bellard
{
746 1a6d39fd Stefan Hajnoczi
    bool is_zero;
747 1a6d39fd Stefan Hajnoczi
    int i;
748 ea2384d3 bellard
749 ea2384d3 bellard
    if (n <= 0) {
750 ea2384d3 bellard
        *pnum = 0;
751 ea2384d3 bellard
        return 0;
752 ea2384d3 bellard
    }
753 1a6d39fd Stefan Hajnoczi
    is_zero = buffer_is_zero(buf, 512);
754 ea2384d3 bellard
    for(i = 1; i < n; i++) {
755 ea2384d3 bellard
        buf += 512;
756 1a6d39fd Stefan Hajnoczi
        if (is_zero != buffer_is_zero(buf, 512)) {
757 ea2384d3 bellard
            break;
758 1a6d39fd Stefan Hajnoczi
        }
759 ea2384d3 bellard
    }
760 ea2384d3 bellard
    *pnum = i;
761 1a6d39fd Stefan Hajnoczi
    return !is_zero;
762 ea2384d3 bellard
}
763 ea2384d3 bellard
764 3e85c6fd Kevin Wolf
/*
765 a22f123c Kevin Wolf
 * Like is_allocated_sectors, but if the buffer starts with a used sector,
766 a22f123c Kevin Wolf
 * up to 'min' consecutive sectors containing zeros are ignored. This avoids
767 a22f123c Kevin Wolf
 * breaking up write requests for only small sparse areas.
768 a22f123c Kevin Wolf
 */
769 a22f123c Kevin Wolf
static int is_allocated_sectors_min(const uint8_t *buf, int n, int *pnum,
770 a22f123c Kevin Wolf
    int min)
771 a22f123c Kevin Wolf
{
772 a22f123c Kevin Wolf
    int ret;
773 a22f123c Kevin Wolf
    int num_checked, num_used;
774 a22f123c Kevin Wolf
775 a22f123c Kevin Wolf
    if (n < min) {
776 a22f123c Kevin Wolf
        min = n;
777 a22f123c Kevin Wolf
    }
778 a22f123c Kevin Wolf
779 a22f123c Kevin Wolf
    ret = is_allocated_sectors(buf, n, pnum);
780 a22f123c Kevin Wolf
    if (!ret) {
781 a22f123c Kevin Wolf
        return ret;
782 a22f123c Kevin Wolf
    }
783 a22f123c Kevin Wolf
784 a22f123c Kevin Wolf
    num_used = *pnum;
785 a22f123c Kevin Wolf
    buf += BDRV_SECTOR_SIZE * *pnum;
786 a22f123c Kevin Wolf
    n -= *pnum;
787 a22f123c Kevin Wolf
    num_checked = num_used;
788 a22f123c Kevin Wolf
789 a22f123c Kevin Wolf
    while (n > 0) {
790 a22f123c Kevin Wolf
        ret = is_allocated_sectors(buf, n, pnum);
791 a22f123c Kevin Wolf
792 a22f123c Kevin Wolf
        buf += BDRV_SECTOR_SIZE * *pnum;
793 a22f123c Kevin Wolf
        n -= *pnum;
794 a22f123c Kevin Wolf
        num_checked += *pnum;
795 a22f123c Kevin Wolf
        if (ret) {
796 a22f123c Kevin Wolf
            num_used = num_checked;
797 a22f123c Kevin Wolf
        } else if (*pnum >= min) {
798 a22f123c Kevin Wolf
            break;
799 a22f123c Kevin Wolf
        }
800 a22f123c Kevin Wolf
    }
801 a22f123c Kevin Wolf
802 a22f123c Kevin Wolf
    *pnum = num_used;
803 a22f123c Kevin Wolf
    return 1;
804 a22f123c Kevin Wolf
}
805 a22f123c Kevin Wolf
806 a22f123c Kevin Wolf
/*
807 3e85c6fd Kevin Wolf
 * Compares two buffers sector by sector. Returns 0 if the first sector of both
808 3e85c6fd Kevin Wolf
 * buffers matches, non-zero otherwise.
809 3e85c6fd Kevin Wolf
 *
810 3e85c6fd Kevin Wolf
 * pnum is set to the number of sectors (including and immediately following
811 3e85c6fd Kevin Wolf
 * the first one) that are known to have the same comparison result
812 3e85c6fd Kevin Wolf
 */
813 3e85c6fd Kevin Wolf
static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
814 3e85c6fd Kevin Wolf
    int *pnum)
815 3e85c6fd Kevin Wolf
{
816 3e85c6fd Kevin Wolf
    int res, i;
817 3e85c6fd Kevin Wolf
818 3e85c6fd Kevin Wolf
    if (n <= 0) {
819 3e85c6fd Kevin Wolf
        *pnum = 0;
820 3e85c6fd Kevin Wolf
        return 0;
821 3e85c6fd Kevin Wolf
    }
822 3e85c6fd Kevin Wolf
823 3e85c6fd Kevin Wolf
    res = !!memcmp(buf1, buf2, 512);
824 3e85c6fd Kevin Wolf
    for(i = 1; i < n; i++) {
825 3e85c6fd Kevin Wolf
        buf1 += 512;
826 3e85c6fd Kevin Wolf
        buf2 += 512;
827 3e85c6fd Kevin Wolf
828 3e85c6fd Kevin Wolf
        if (!!memcmp(buf1, buf2, 512) != res) {
829 3e85c6fd Kevin Wolf
            break;
830 3e85c6fd Kevin Wolf
        }
831 3e85c6fd Kevin Wolf
    }
832 3e85c6fd Kevin Wolf
833 3e85c6fd Kevin Wolf
    *pnum = i;
834 3e85c6fd Kevin Wolf
    return res;
835 3e85c6fd Kevin Wolf
}
836 3e85c6fd Kevin Wolf
837 80ee15a6 Kevin Wolf
#define IO_BUF_SIZE (2 * 1024 * 1024)
838 ea2384d3 bellard
839 d14ed18c Miroslav Rezanina
static int64_t sectors_to_bytes(int64_t sectors)
840 d14ed18c Miroslav Rezanina
{
841 d14ed18c Miroslav Rezanina
    return sectors << BDRV_SECTOR_BITS;
842 d14ed18c Miroslav Rezanina
}
843 d14ed18c Miroslav Rezanina
844 d14ed18c Miroslav Rezanina
static int64_t sectors_to_process(int64_t total, int64_t from)
845 d14ed18c Miroslav Rezanina
{
846 d14ed18c Miroslav Rezanina
    return MIN(total - from, IO_BUF_SIZE >> BDRV_SECTOR_BITS);
847 d14ed18c Miroslav Rezanina
}
848 d14ed18c Miroslav Rezanina
849 d14ed18c Miroslav Rezanina
/*
850 d14ed18c Miroslav Rezanina
 * Check if passed sectors are empty (not allocated or contain only 0 bytes)
851 d14ed18c Miroslav Rezanina
 *
852 d14ed18c Miroslav Rezanina
 * Returns 0 in case sectors are filled with 0, 1 if sectors contain non-zero
853 d14ed18c Miroslav Rezanina
 * data and negative value on error.
854 d14ed18c Miroslav Rezanina
 *
855 d14ed18c Miroslav Rezanina
 * @param bs:  Driver used for accessing file
856 d14ed18c Miroslav Rezanina
 * @param sect_num: Number of first sector to check
857 d14ed18c Miroslav Rezanina
 * @param sect_count: Number of sectors to check
858 d14ed18c Miroslav Rezanina
 * @param filename: Name of disk file we are checking (logging purpose)
859 d14ed18c Miroslav Rezanina
 * @param buffer: Allocated buffer for storing read data
860 d14ed18c Miroslav Rezanina
 * @param quiet: Flag for quiet mode
861 d14ed18c Miroslav Rezanina
 */
862 d14ed18c Miroslav Rezanina
static int check_empty_sectors(BlockDriverState *bs, int64_t sect_num,
863 d14ed18c Miroslav Rezanina
                               int sect_count, const char *filename,
864 d14ed18c Miroslav Rezanina
                               uint8_t *buffer, bool quiet)
865 d14ed18c Miroslav Rezanina
{
866 d14ed18c Miroslav Rezanina
    int pnum, ret = 0;
867 d14ed18c Miroslav Rezanina
    ret = bdrv_read(bs, sect_num, buffer, sect_count);
868 d14ed18c Miroslav Rezanina
    if (ret < 0) {
869 d14ed18c Miroslav Rezanina
        error_report("Error while reading offset %" PRId64 " of %s: %s",
870 d14ed18c Miroslav Rezanina
                     sectors_to_bytes(sect_num), filename, strerror(-ret));
871 d14ed18c Miroslav Rezanina
        return ret;
872 d14ed18c Miroslav Rezanina
    }
873 d14ed18c Miroslav Rezanina
    ret = is_allocated_sectors(buffer, sect_count, &pnum);
874 d14ed18c Miroslav Rezanina
    if (ret || pnum != sect_count) {
875 d14ed18c Miroslav Rezanina
        qprintf(quiet, "Content mismatch at offset %" PRId64 "!\n",
876 d14ed18c Miroslav Rezanina
                sectors_to_bytes(ret ? sect_num : sect_num + pnum));
877 d14ed18c Miroslav Rezanina
        return 1;
878 d14ed18c Miroslav Rezanina
    }
879 d14ed18c Miroslav Rezanina
880 d14ed18c Miroslav Rezanina
    return 0;
881 d14ed18c Miroslav Rezanina
}
882 d14ed18c Miroslav Rezanina
883 d14ed18c Miroslav Rezanina
/*
884 d14ed18c Miroslav Rezanina
 * Compares two images. Exit codes:
885 d14ed18c Miroslav Rezanina
 *
886 d14ed18c Miroslav Rezanina
 * 0 - Images are identical
887 d14ed18c Miroslav Rezanina
 * 1 - Images differ
888 d14ed18c Miroslav Rezanina
 * >1 - Error occurred
889 d14ed18c Miroslav Rezanina
 */
890 d14ed18c Miroslav Rezanina
static int img_compare(int argc, char **argv)
891 d14ed18c Miroslav Rezanina
{
892 d14ed18c Miroslav Rezanina
    const char *fmt1 = NULL, *fmt2 = NULL, *filename1, *filename2;
893 d14ed18c Miroslav Rezanina
    BlockDriverState *bs1, *bs2;
894 d14ed18c Miroslav Rezanina
    int64_t total_sectors1, total_sectors2;
895 d14ed18c Miroslav Rezanina
    uint8_t *buf1 = NULL, *buf2 = NULL;
896 d14ed18c Miroslav Rezanina
    int pnum1, pnum2;
897 d14ed18c Miroslav Rezanina
    int allocated1, allocated2;
898 d14ed18c Miroslav Rezanina
    int ret = 0; /* return value - 0 Ident, 1 Different, >1 Error */
899 d14ed18c Miroslav Rezanina
    bool progress = false, quiet = false, strict = false;
900 d14ed18c Miroslav Rezanina
    int64_t total_sectors;
901 d14ed18c Miroslav Rezanina
    int64_t sector_num = 0;
902 d14ed18c Miroslav Rezanina
    int64_t nb_sectors;
903 d14ed18c Miroslav Rezanina
    int c, pnum;
904 d14ed18c Miroslav Rezanina
    uint64_t bs_sectors;
905 d14ed18c Miroslav Rezanina
    uint64_t progress_base;
906 d14ed18c Miroslav Rezanina
907 d14ed18c Miroslav Rezanina
    for (;;) {
908 d14ed18c Miroslav Rezanina
        c = getopt(argc, argv, "hpf:F:sq");
909 d14ed18c Miroslav Rezanina
        if (c == -1) {
910 d14ed18c Miroslav Rezanina
            break;
911 d14ed18c Miroslav Rezanina
        }
912 d14ed18c Miroslav Rezanina
        switch (c) {
913 d14ed18c Miroslav Rezanina
        case '?':
914 d14ed18c Miroslav Rezanina
        case 'h':
915 d14ed18c Miroslav Rezanina
            help();
916 d14ed18c Miroslav Rezanina
            break;
917 d14ed18c Miroslav Rezanina
        case 'f':
918 d14ed18c Miroslav Rezanina
            fmt1 = optarg;
919 d14ed18c Miroslav Rezanina
            break;
920 d14ed18c Miroslav Rezanina
        case 'F':
921 d14ed18c Miroslav Rezanina
            fmt2 = optarg;
922 d14ed18c Miroslav Rezanina
            break;
923 d14ed18c Miroslav Rezanina
        case 'p':
924 d14ed18c Miroslav Rezanina
            progress = true;
925 d14ed18c Miroslav Rezanina
            break;
926 d14ed18c Miroslav Rezanina
        case 'q':
927 d14ed18c Miroslav Rezanina
            quiet = true;
928 d14ed18c Miroslav Rezanina
            break;
929 d14ed18c Miroslav Rezanina
        case 's':
930 d14ed18c Miroslav Rezanina
            strict = true;
931 d14ed18c Miroslav Rezanina
            break;
932 d14ed18c Miroslav Rezanina
        }
933 d14ed18c Miroslav Rezanina
    }
934 d14ed18c Miroslav Rezanina
935 d14ed18c Miroslav Rezanina
    /* Progress is not shown in Quiet mode */
936 d14ed18c Miroslav Rezanina
    if (quiet) {
937 d14ed18c Miroslav Rezanina
        progress = false;
938 d14ed18c Miroslav Rezanina
    }
939 d14ed18c Miroslav Rezanina
940 d14ed18c Miroslav Rezanina
941 fc11eb26 Kevin Wolf
    if (optind != argc - 2) {
942 d14ed18c Miroslav Rezanina
        help();
943 d14ed18c Miroslav Rezanina
    }
944 d14ed18c Miroslav Rezanina
    filename1 = argv[optind++];
945 d14ed18c Miroslav Rezanina
    filename2 = argv[optind++];
946 d14ed18c Miroslav Rezanina
947 d14ed18c Miroslav Rezanina
    /* Initialize before goto out */
948 d14ed18c Miroslav Rezanina
    qemu_progress_init(progress, 2.0);
949 d14ed18c Miroslav Rezanina
950 d14ed18c Miroslav Rezanina
    bs1 = bdrv_new_open(filename1, fmt1, BDRV_O_FLAGS, true, quiet);
951 d14ed18c Miroslav Rezanina
    if (!bs1) {
952 d14ed18c Miroslav Rezanina
        error_report("Can't open file %s", filename1);
953 d14ed18c Miroslav Rezanina
        ret = 2;
954 d14ed18c Miroslav Rezanina
        goto out3;
955 d14ed18c Miroslav Rezanina
    }
956 d14ed18c Miroslav Rezanina
957 d14ed18c Miroslav Rezanina
    bs2 = bdrv_new_open(filename2, fmt2, BDRV_O_FLAGS, true, quiet);
958 d14ed18c Miroslav Rezanina
    if (!bs2) {
959 d14ed18c Miroslav Rezanina
        error_report("Can't open file %s", filename2);
960 d14ed18c Miroslav Rezanina
        ret = 2;
961 d14ed18c Miroslav Rezanina
        goto out2;
962 d14ed18c Miroslav Rezanina
    }
963 d14ed18c Miroslav Rezanina
964 d14ed18c Miroslav Rezanina
    buf1 = qemu_blockalign(bs1, IO_BUF_SIZE);
965 d14ed18c Miroslav Rezanina
    buf2 = qemu_blockalign(bs2, IO_BUF_SIZE);
966 d14ed18c Miroslav Rezanina
    bdrv_get_geometry(bs1, &bs_sectors);
967 d14ed18c Miroslav Rezanina
    total_sectors1 = bs_sectors;
968 d14ed18c Miroslav Rezanina
    bdrv_get_geometry(bs2, &bs_sectors);
969 d14ed18c Miroslav Rezanina
    total_sectors2 = bs_sectors;
970 d14ed18c Miroslav Rezanina
    total_sectors = MIN(total_sectors1, total_sectors2);
971 d14ed18c Miroslav Rezanina
    progress_base = MAX(total_sectors1, total_sectors2);
972 d14ed18c Miroslav Rezanina
973 d14ed18c Miroslav Rezanina
    qemu_progress_print(0, 100);
974 d14ed18c Miroslav Rezanina
975 d14ed18c Miroslav Rezanina
    if (strict && total_sectors1 != total_sectors2) {
976 d14ed18c Miroslav Rezanina
        ret = 1;
977 d14ed18c Miroslav Rezanina
        qprintf(quiet, "Strict mode: Image size mismatch!\n");
978 d14ed18c Miroslav Rezanina
        goto out;
979 d14ed18c Miroslav Rezanina
    }
980 d14ed18c Miroslav Rezanina
981 d14ed18c Miroslav Rezanina
    for (;;) {
982 d14ed18c Miroslav Rezanina
        nb_sectors = sectors_to_process(total_sectors, sector_num);
983 d14ed18c Miroslav Rezanina
        if (nb_sectors <= 0) {
984 d14ed18c Miroslav Rezanina
            break;
985 d14ed18c Miroslav Rezanina
        }
986 d14ed18c Miroslav Rezanina
        allocated1 = bdrv_is_allocated_above(bs1, NULL, sector_num, nb_sectors,
987 d14ed18c Miroslav Rezanina
                                             &pnum1);
988 d14ed18c Miroslav Rezanina
        if (allocated1 < 0) {
989 d14ed18c Miroslav Rezanina
            ret = 3;
990 d14ed18c Miroslav Rezanina
            error_report("Sector allocation test failed for %s", filename1);
991 d14ed18c Miroslav Rezanina
            goto out;
992 d14ed18c Miroslav Rezanina
        }
993 d14ed18c Miroslav Rezanina
994 d14ed18c Miroslav Rezanina
        allocated2 = bdrv_is_allocated_above(bs2, NULL, sector_num, nb_sectors,
995 d14ed18c Miroslav Rezanina
                                             &pnum2);
996 d14ed18c Miroslav Rezanina
        if (allocated2 < 0) {
997 d14ed18c Miroslav Rezanina
            ret = 3;
998 d14ed18c Miroslav Rezanina
            error_report("Sector allocation test failed for %s", filename2);
999 d14ed18c Miroslav Rezanina
            goto out;
1000 d14ed18c Miroslav Rezanina
        }
1001 d14ed18c Miroslav Rezanina
        nb_sectors = MIN(pnum1, pnum2);
1002 d14ed18c Miroslav Rezanina
1003 d14ed18c Miroslav Rezanina
        if (allocated1 == allocated2) {
1004 d14ed18c Miroslav Rezanina
            if (allocated1) {
1005 d14ed18c Miroslav Rezanina
                ret = bdrv_read(bs1, sector_num, buf1, nb_sectors);
1006 d14ed18c Miroslav Rezanina
                if (ret < 0) {
1007 d14ed18c Miroslav Rezanina
                    error_report("Error while reading offset %" PRId64 " of %s:"
1008 d14ed18c Miroslav Rezanina
                                 " %s", sectors_to_bytes(sector_num), filename1,
1009 d14ed18c Miroslav Rezanina
                                 strerror(-ret));
1010 d14ed18c Miroslav Rezanina
                    ret = 4;
1011 d14ed18c Miroslav Rezanina
                    goto out;
1012 d14ed18c Miroslav Rezanina
                }
1013 d14ed18c Miroslav Rezanina
                ret = bdrv_read(bs2, sector_num, buf2, nb_sectors);
1014 d14ed18c Miroslav Rezanina
                if (ret < 0) {
1015 d14ed18c Miroslav Rezanina
                    error_report("Error while reading offset %" PRId64
1016 d14ed18c Miroslav Rezanina
                                 " of %s: %s", sectors_to_bytes(sector_num),
1017 d14ed18c Miroslav Rezanina
                                 filename2, strerror(-ret));
1018 d14ed18c Miroslav Rezanina
                    ret = 4;
1019 d14ed18c Miroslav Rezanina
                    goto out;
1020 d14ed18c Miroslav Rezanina
                }
1021 d14ed18c Miroslav Rezanina
                ret = compare_sectors(buf1, buf2, nb_sectors, &pnum);
1022 d14ed18c Miroslav Rezanina
                if (ret || pnum != nb_sectors) {
1023 d14ed18c Miroslav Rezanina
                    ret = 1;
1024 d14ed18c Miroslav Rezanina
                    qprintf(quiet, "Content mismatch at offset %" PRId64 "!\n",
1025 d14ed18c Miroslav Rezanina
                            sectors_to_bytes(
1026 d14ed18c Miroslav Rezanina
                                ret ? sector_num : sector_num + pnum));
1027 d14ed18c Miroslav Rezanina
                    goto out;
1028 d14ed18c Miroslav Rezanina
                }
1029 d14ed18c Miroslav Rezanina
            }
1030 d14ed18c Miroslav Rezanina
        } else {
1031 d14ed18c Miroslav Rezanina
            if (strict) {
1032 d14ed18c Miroslav Rezanina
                ret = 1;
1033 d14ed18c Miroslav Rezanina
                qprintf(quiet, "Strict mode: Offset %" PRId64
1034 d14ed18c Miroslav Rezanina
                        " allocation mismatch!\n",
1035 d14ed18c Miroslav Rezanina
                        sectors_to_bytes(sector_num));
1036 d14ed18c Miroslav Rezanina
                goto out;
1037 d14ed18c Miroslav Rezanina
            }
1038 d14ed18c Miroslav Rezanina
1039 d14ed18c Miroslav Rezanina
            if (allocated1) {
1040 d14ed18c Miroslav Rezanina
                ret = check_empty_sectors(bs1, sector_num, nb_sectors,
1041 d14ed18c Miroslav Rezanina
                                          filename1, buf1, quiet);
1042 d14ed18c Miroslav Rezanina
            } else {
1043 d14ed18c Miroslav Rezanina
                ret = check_empty_sectors(bs2, sector_num, nb_sectors,
1044 d14ed18c Miroslav Rezanina
                                          filename2, buf1, quiet);
1045 d14ed18c Miroslav Rezanina
            }
1046 d14ed18c Miroslav Rezanina
            if (ret) {
1047 d14ed18c Miroslav Rezanina
                if (ret < 0) {
1048 d14ed18c Miroslav Rezanina
                    ret = 4;
1049 d14ed18c Miroslav Rezanina
                    error_report("Error while reading offset %" PRId64 ": %s",
1050 d14ed18c Miroslav Rezanina
                                 sectors_to_bytes(sector_num), strerror(-ret));
1051 d14ed18c Miroslav Rezanina
                }
1052 d14ed18c Miroslav Rezanina
                goto out;
1053 d14ed18c Miroslav Rezanina
            }
1054 d14ed18c Miroslav Rezanina
        }
1055 d14ed18c Miroslav Rezanina
        sector_num += nb_sectors;
1056 d14ed18c Miroslav Rezanina
        qemu_progress_print(((float) nb_sectors / progress_base)*100, 100);
1057 d14ed18c Miroslav Rezanina
    }
1058 d14ed18c Miroslav Rezanina
1059 d14ed18c Miroslav Rezanina
    if (total_sectors1 != total_sectors2) {
1060 d14ed18c Miroslav Rezanina
        BlockDriverState *bs_over;
1061 d14ed18c Miroslav Rezanina
        int64_t total_sectors_over;
1062 d14ed18c Miroslav Rezanina
        const char *filename_over;
1063 d14ed18c Miroslav Rezanina
1064 d14ed18c Miroslav Rezanina
        qprintf(quiet, "Warning: Image size mismatch!\n");
1065 d14ed18c Miroslav Rezanina
        if (total_sectors1 > total_sectors2) {
1066 d14ed18c Miroslav Rezanina
            total_sectors_over = total_sectors1;
1067 d14ed18c Miroslav Rezanina
            bs_over = bs1;
1068 d14ed18c Miroslav Rezanina
            filename_over = filename1;
1069 d14ed18c Miroslav Rezanina
        } else {
1070 d14ed18c Miroslav Rezanina
            total_sectors_over = total_sectors2;
1071 d14ed18c Miroslav Rezanina
            bs_over = bs2;
1072 d14ed18c Miroslav Rezanina
            filename_over = filename2;
1073 d14ed18c Miroslav Rezanina
        }
1074 d14ed18c Miroslav Rezanina
1075 d14ed18c Miroslav Rezanina
        for (;;) {
1076 d14ed18c Miroslav Rezanina
            nb_sectors = sectors_to_process(total_sectors_over, sector_num);
1077 d14ed18c Miroslav Rezanina
            if (nb_sectors <= 0) {
1078 d14ed18c Miroslav Rezanina
                break;
1079 d14ed18c Miroslav Rezanina
            }
1080 d14ed18c Miroslav Rezanina
            ret = bdrv_is_allocated_above(bs_over, NULL, sector_num,
1081 d14ed18c Miroslav Rezanina
                                          nb_sectors, &pnum);
1082 d14ed18c Miroslav Rezanina
            if (ret < 0) {
1083 d14ed18c Miroslav Rezanina
                ret = 3;
1084 d14ed18c Miroslav Rezanina
                error_report("Sector allocation test failed for %s",
1085 d14ed18c Miroslav Rezanina
                             filename_over);
1086 d14ed18c Miroslav Rezanina
                goto out;
1087 d14ed18c Miroslav Rezanina
1088 d14ed18c Miroslav Rezanina
            }
1089 d14ed18c Miroslav Rezanina
            nb_sectors = pnum;
1090 d14ed18c Miroslav Rezanina
            if (ret) {
1091 d14ed18c Miroslav Rezanina
                ret = check_empty_sectors(bs_over, sector_num, nb_sectors,
1092 d14ed18c Miroslav Rezanina
                                          filename_over, buf1, quiet);
1093 d14ed18c Miroslav Rezanina
                if (ret) {
1094 d14ed18c Miroslav Rezanina
                    if (ret < 0) {
1095 d14ed18c Miroslav Rezanina
                        ret = 4;
1096 d14ed18c Miroslav Rezanina
                        error_report("Error while reading offset %" PRId64
1097 d14ed18c Miroslav Rezanina
                                     " of %s: %s", sectors_to_bytes(sector_num),
1098 d14ed18c Miroslav Rezanina
                                     filename_over, strerror(-ret));
1099 d14ed18c Miroslav Rezanina
                    }
1100 d14ed18c Miroslav Rezanina
                    goto out;
1101 d14ed18c Miroslav Rezanina
                }
1102 d14ed18c Miroslav Rezanina
            }
1103 d14ed18c Miroslav Rezanina
            sector_num += nb_sectors;
1104 d14ed18c Miroslav Rezanina
            qemu_progress_print(((float) nb_sectors / progress_base)*100, 100);
1105 d14ed18c Miroslav Rezanina
        }
1106 d14ed18c Miroslav Rezanina
    }
1107 d14ed18c Miroslav Rezanina
1108 d14ed18c Miroslav Rezanina
    qprintf(quiet, "Images are identical.\n");
1109 d14ed18c Miroslav Rezanina
    ret = 0;
1110 d14ed18c Miroslav Rezanina
1111 d14ed18c Miroslav Rezanina
out:
1112 4f6fd349 Fam Zheng
    bdrv_unref(bs2);
1113 d14ed18c Miroslav Rezanina
    qemu_vfree(buf1);
1114 d14ed18c Miroslav Rezanina
    qemu_vfree(buf2);
1115 d14ed18c Miroslav Rezanina
out2:
1116 4f6fd349 Fam Zheng
    bdrv_unref(bs1);
1117 d14ed18c Miroslav Rezanina
out3:
1118 d14ed18c Miroslav Rezanina
    qemu_progress_end();
1119 d14ed18c Miroslav Rezanina
    return ret;
1120 d14ed18c Miroslav Rezanina
}
1121 d14ed18c Miroslav Rezanina
1122 ea2384d3 bellard
static int img_convert(int argc, char **argv)
1123 ea2384d3 bellard
{
1124 b2e10493 Alexandre Derumier
    int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size,
1125 b2e10493 Alexandre Derumier
        cluster_sectors, skip_create;
1126 661a0f71 Federico Simoncelli
    int progress = 0, flags;
1127 661a0f71 Federico Simoncelli
    const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename;
1128 b50cbabc MORITA Kazutaka
    BlockDriver *drv, *proto_drv;
1129 c2abccec MORITA Kazutaka
    BlockDriverState **bs = NULL, *out_bs = NULL;
1130 96b8f136 ths
    int64_t total_sectors, nb_sectors, sector_num, bs_offset;
1131 96b8f136 ths
    uint64_t bs_sectors;
1132 c2abccec MORITA Kazutaka
    uint8_t * buf = NULL;
1133 ea2384d3 bellard
    const uint8_t *buf1;
1134 faea38e7 bellard
    BlockDriverInfo bdi;
1135 b50cbabc MORITA Kazutaka
    QEMUOptionParameter *param = NULL, *create_options = NULL;
1136 a18953fb Kevin Wolf
    QEMUOptionParameter *out_baseimg_param;
1137 efa84d43 Kevin Wolf
    char *options = NULL;
1138 51ef6727 edison
    const char *snapshot_name = NULL;
1139 1f710495 Kevin Wolf
    float local_progress = 0;
1140 a22f123c Kevin Wolf
    int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */
1141 f382d43a Miroslav Rezanina
    bool quiet = false;
1142 cc84d90f Max Reitz
    Error *local_err = NULL;
1143 ea2384d3 bellard
1144 ea2384d3 bellard
    fmt = NULL;
1145 ea2384d3 bellard
    out_fmt = "raw";
1146 661a0f71 Federico Simoncelli
    cache = "unsafe";
1147 f58c7b35 ths
    out_baseimg = NULL;
1148 eec77d9e Jes Sorensen
    compress = 0;
1149 b2e10493 Alexandre Derumier
    skip_create = 0;
1150 ea2384d3 bellard
    for(;;) {
1151 b2e10493 Alexandre Derumier
        c = getopt(argc, argv, "f:O:B:s:hce6o:pS:t:qn");
1152 b8fb60da Jes Sorensen
        if (c == -1) {
1153 ea2384d3 bellard
            break;
1154 b8fb60da Jes Sorensen
        }
1155 ea2384d3 bellard
        switch(c) {
1156 ef87394c Jes Sorensen
        case '?':
1157 ea2384d3 bellard
        case 'h':
1158 ea2384d3 bellard
            help();
1159 ea2384d3 bellard
            break;
1160 ea2384d3 bellard
        case 'f':
1161 ea2384d3 bellard
            fmt = optarg;
1162 ea2384d3 bellard
            break;
1163 ea2384d3 bellard
        case 'O':
1164 ea2384d3 bellard
            out_fmt = optarg;
1165 ea2384d3 bellard
            break;
1166 f58c7b35 ths
        case 'B':
1167 f58c7b35 ths
            out_baseimg = optarg;
1168 f58c7b35 ths
            break;
1169 ea2384d3 bellard
        case 'c':
1170 eec77d9e Jes Sorensen
            compress = 1;
1171 ea2384d3 bellard
            break;
1172 ea2384d3 bellard
        case 'e':
1173 9d42e15d Markus Armbruster
            error_report("option -e is deprecated, please use \'-o "
1174 eec77d9e Jes Sorensen
                  "encryption\' instead!");
1175 eec77d9e Jes Sorensen
            return 1;
1176 ec36ba14 ths
        case '6':
1177 9d42e15d Markus Armbruster
            error_report("option -6 is deprecated, please use \'-o "
1178 eec77d9e Jes Sorensen
                  "compat6\' instead!");
1179 eec77d9e Jes Sorensen
            return 1;
1180 efa84d43 Kevin Wolf
        case 'o':
1181 efa84d43 Kevin Wolf
            options = optarg;
1182 efa84d43 Kevin Wolf
            break;
1183 51ef6727 edison
        case 's':
1184 51ef6727 edison
            snapshot_name = optarg;
1185 51ef6727 edison
            break;
1186 a22f123c Kevin Wolf
        case 'S':
1187 a22f123c Kevin Wolf
        {
1188 a22f123c Kevin Wolf
            int64_t sval;
1189 e36b3695 Markus Armbruster
            char *end;
1190 e36b3695 Markus Armbruster
            sval = strtosz_suffix(optarg, &end, STRTOSZ_DEFSUFFIX_B);
1191 e36b3695 Markus Armbruster
            if (sval < 0 || *end) {
1192 a22f123c Kevin Wolf
                error_report("Invalid minimum zero buffer size for sparse output specified");
1193 a22f123c Kevin Wolf
                return 1;
1194 a22f123c Kevin Wolf
            }
1195 a22f123c Kevin Wolf
1196 a22f123c Kevin Wolf
            min_sparse = sval / BDRV_SECTOR_SIZE;
1197 a22f123c Kevin Wolf
            break;
1198 a22f123c Kevin Wolf
        }
1199 6b837bc4 Jes Sorensen
        case 'p':
1200 6b837bc4 Jes Sorensen
            progress = 1;
1201 6b837bc4 Jes Sorensen
            break;
1202 661a0f71 Federico Simoncelli
        case 't':
1203 661a0f71 Federico Simoncelli
            cache = optarg;
1204 661a0f71 Federico Simoncelli
            break;
1205 f382d43a Miroslav Rezanina
        case 'q':
1206 f382d43a Miroslav Rezanina
            quiet = true;
1207 f382d43a Miroslav Rezanina
            break;
1208 b2e10493 Alexandre Derumier
        case 'n':
1209 b2e10493 Alexandre Derumier
            skip_create = 1;
1210 b2e10493 Alexandre Derumier
            break;
1211 ea2384d3 bellard
        }
1212 ea2384d3 bellard
    }
1213 3b46e624 ths
1214 f382d43a Miroslav Rezanina
    if (quiet) {
1215 f382d43a Miroslav Rezanina
        progress = 0;
1216 f382d43a Miroslav Rezanina
    }
1217 f382d43a Miroslav Rezanina
1218 926c2d23 balrog
    bs_n = argc - optind - 1;
1219 b8fb60da Jes Sorensen
    if (bs_n < 1) {
1220 b8fb60da Jes Sorensen
        help();
1221 b8fb60da Jes Sorensen
    }
1222 926c2d23 balrog
1223 926c2d23 balrog
    out_filename = argv[argc - 1];
1224 f58c7b35 ths
1225 fa170c14 Charles Arnold
    /* Initialize before goto out */
1226 fa170c14 Charles Arnold
    qemu_progress_init(progress, 2.0);
1227 fa170c14 Charles Arnold
1228 c8057f95 Peter Maydell
    if (options && is_help_option(options)) {
1229 4ac8aacd Jes Sorensen
        ret = print_block_option_help(out_filename, out_fmt);
1230 4ac8aacd Jes Sorensen
        goto out;
1231 4ac8aacd Jes Sorensen
    }
1232 4ac8aacd Jes Sorensen
1233 c2abccec MORITA Kazutaka
    if (bs_n > 1 && out_baseimg) {
1234 15654a6d Jes Sorensen
        error_report("-B makes no sense when concatenating multiple input "
1235 15654a6d Jes Sorensen
                     "images");
1236 31ca34b8 Jes Sorensen
        ret = -1;
1237 31ca34b8 Jes Sorensen
        goto out;
1238 c2abccec MORITA Kazutaka
    }
1239 f8111c24 Dong Xu Wang
1240 6b837bc4 Jes Sorensen
    qemu_progress_print(0, 100);
1241 6b837bc4 Jes Sorensen
1242 7267c094 Anthony Liguori
    bs = g_malloc0(bs_n * sizeof(BlockDriverState *));
1243 926c2d23 balrog
1244 926c2d23 balrog
    total_sectors = 0;
1245 926c2d23 balrog
    for (bs_i = 0; bs_i < bs_n; bs_i++) {
1246 f382d43a Miroslav Rezanina
        bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS, true,
1247 f382d43a Miroslav Rezanina
                                 quiet);
1248 c2abccec MORITA Kazutaka
        if (!bs[bs_i]) {
1249 15654a6d Jes Sorensen
            error_report("Could not open '%s'", argv[optind + bs_i]);
1250 c2abccec MORITA Kazutaka
            ret = -1;
1251 c2abccec MORITA Kazutaka
            goto out;
1252 c2abccec MORITA Kazutaka
        }
1253 926c2d23 balrog
        bdrv_get_geometry(bs[bs_i], &bs_sectors);
1254 926c2d23 balrog
        total_sectors += bs_sectors;
1255 926c2d23 balrog
    }
1256 ea2384d3 bellard
1257 51ef6727 edison
    if (snapshot_name != NULL) {
1258 51ef6727 edison
        if (bs_n > 1) {
1259 6daf194d Markus Armbruster
            error_report("No support for concatenating multiple snapshot");
1260 51ef6727 edison
            ret = -1;
1261 51ef6727 edison
            goto out;
1262 51ef6727 edison
        }
1263 51ef6727 edison
        if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
1264 6daf194d Markus Armbruster
            error_report("Failed to load snapshot");
1265 51ef6727 edison
            ret = -1;
1266 51ef6727 edison
            goto out;
1267 51ef6727 edison
        }
1268 51ef6727 edison
    }
1269 51ef6727 edison
1270 efa84d43 Kevin Wolf
    /* Find driver and parse its options */
1271 ea2384d3 bellard
    drv = bdrv_find_format(out_fmt);
1272 c2abccec MORITA Kazutaka
    if (!drv) {
1273 15654a6d Jes Sorensen
        error_report("Unknown file format '%s'", out_fmt);
1274 c2abccec MORITA Kazutaka
        ret = -1;
1275 c2abccec MORITA Kazutaka
        goto out;
1276 c2abccec MORITA Kazutaka
    }
1277 efa84d43 Kevin Wolf
1278 98289620 Kevin Wolf
    proto_drv = bdrv_find_protocol(out_filename, true);
1279 c2abccec MORITA Kazutaka
    if (!proto_drv) {
1280 15654a6d Jes Sorensen
        error_report("Unknown protocol '%s'", out_filename);
1281 c2abccec MORITA Kazutaka
        ret = -1;
1282 c2abccec MORITA Kazutaka
        goto out;
1283 c2abccec MORITA Kazutaka
    }
1284 b50cbabc MORITA Kazutaka
1285 b50cbabc MORITA Kazutaka
    create_options = append_option_parameters(create_options,
1286 b50cbabc MORITA Kazutaka
                                              drv->create_options);
1287 b50cbabc MORITA Kazutaka
    create_options = append_option_parameters(create_options,
1288 b50cbabc MORITA Kazutaka
                                              proto_drv->create_options);
1289 db08adf5 Kevin Wolf
1290 efa84d43 Kevin Wolf
    if (options) {
1291 b50cbabc MORITA Kazutaka
        param = parse_option_parameters(options, create_options, param);
1292 efa84d43 Kevin Wolf
        if (param == NULL) {
1293 15654a6d Jes Sorensen
            error_report("Invalid options for file format '%s'.", out_fmt);
1294 c2abccec MORITA Kazutaka
            ret = -1;
1295 c2abccec MORITA Kazutaka
            goto out;
1296 efa84d43 Kevin Wolf
        }
1297 efa84d43 Kevin Wolf
    } else {
1298 b50cbabc MORITA Kazutaka
        param = parse_option_parameters("", create_options, param);
1299 efa84d43 Kevin Wolf
    }
1300 efa84d43 Kevin Wolf
1301 efa84d43 Kevin Wolf
    set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
1302 eec77d9e Jes Sorensen
    ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);
1303 c2abccec MORITA Kazutaka
    if (ret < 0) {
1304 c2abccec MORITA Kazutaka
        goto out;
1305 c2abccec MORITA Kazutaka
    }
1306 efa84d43 Kevin Wolf
1307 a18953fb Kevin Wolf
    /* Get backing file name if -o backing_file was used */
1308 a18953fb Kevin Wolf
    out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
1309 a18953fb Kevin Wolf
    if (out_baseimg_param) {
1310 a18953fb Kevin Wolf
        out_baseimg = out_baseimg_param->value.s;
1311 a18953fb Kevin Wolf
    }
1312 a18953fb Kevin Wolf
1313 efa84d43 Kevin Wolf
    /* Check if compression is supported */
1314 eec77d9e Jes Sorensen
    if (compress) {
1315 efa84d43 Kevin Wolf
        QEMUOptionParameter *encryption =
1316 efa84d43 Kevin Wolf
            get_option_parameter(param, BLOCK_OPT_ENCRYPT);
1317 41521fa4 Kevin Wolf
        QEMUOptionParameter *preallocation =
1318 41521fa4 Kevin Wolf
            get_option_parameter(param, BLOCK_OPT_PREALLOC);
1319 efa84d43 Kevin Wolf
1320 efa84d43 Kevin Wolf
        if (!drv->bdrv_write_compressed) {
1321 15654a6d Jes Sorensen
            error_report("Compression not supported for this file format");
1322 c2abccec MORITA Kazutaka
            ret = -1;
1323 c2abccec MORITA Kazutaka
            goto out;
1324 efa84d43 Kevin Wolf
        }
1325 efa84d43 Kevin Wolf
1326 efa84d43 Kevin Wolf
        if (encryption && encryption->value.n) {
1327 15654a6d Jes Sorensen
            error_report("Compression and encryption not supported at "
1328 15654a6d Jes Sorensen
                         "the same time");
1329 c2abccec MORITA Kazutaka
            ret = -1;
1330 c2abccec MORITA Kazutaka
            goto out;
1331 efa84d43 Kevin Wolf
        }
1332 41521fa4 Kevin Wolf
1333 41521fa4 Kevin Wolf
        if (preallocation && preallocation->value.s
1334 41521fa4 Kevin Wolf
            && strcmp(preallocation->value.s, "off"))
1335 41521fa4 Kevin Wolf
        {
1336 41521fa4 Kevin Wolf
            error_report("Compression and preallocation not supported at "
1337 41521fa4 Kevin Wolf
                         "the same time");
1338 41521fa4 Kevin Wolf
            ret = -1;
1339 41521fa4 Kevin Wolf
            goto out;
1340 41521fa4 Kevin Wolf
        }
1341 efa84d43 Kevin Wolf
    }
1342 efa84d43 Kevin Wolf
1343 b2e10493 Alexandre Derumier
    if (!skip_create) {
1344 b2e10493 Alexandre Derumier
        /* Create the new image */
1345 cc84d90f Max Reitz
        ret = bdrv_create(drv, out_filename, param, &local_err);
1346 b2e10493 Alexandre Derumier
        if (ret < 0) {
1347 cc84d90f Max Reitz
            error_report("%s: error while converting %s: %s",
1348 cc84d90f Max Reitz
                         out_filename, out_fmt, error_get_pretty(local_err));
1349 cc84d90f Max Reitz
            error_free(local_err);
1350 b2e10493 Alexandre Derumier
            goto out;
1351 ea2384d3 bellard
        }
1352 ea2384d3 bellard
    }
1353 3b46e624 ths
1354 661a0f71 Federico Simoncelli
    flags = BDRV_O_RDWR;
1355 c3993cdc Stefan Hajnoczi
    ret = bdrv_parse_cache_flags(cache, &flags);
1356 661a0f71 Federico Simoncelli
    if (ret < 0) {
1357 661a0f71 Federico Simoncelli
        error_report("Invalid cache option: %s", cache);
1358 661a0f71 Federico Simoncelli
        return -1;
1359 661a0f71 Federico Simoncelli
    }
1360 661a0f71 Federico Simoncelli
1361 f382d43a Miroslav Rezanina
    out_bs = bdrv_new_open(out_filename, out_fmt, flags, true, quiet);
1362 c2abccec MORITA Kazutaka
    if (!out_bs) {
1363 c2abccec MORITA Kazutaka
        ret = -1;
1364 c2abccec MORITA Kazutaka
        goto out;
1365 c2abccec MORITA Kazutaka
    }
1366 ea2384d3 bellard
1367 926c2d23 balrog
    bs_i = 0;
1368 926c2d23 balrog
    bs_offset = 0;
1369 926c2d23 balrog
    bdrv_get_geometry(bs[0], &bs_sectors);
1370 bb1c0597 Kevin Wolf
    buf = qemu_blockalign(out_bs, IO_BUF_SIZE);
1371 926c2d23 balrog
1372 b2e10493 Alexandre Derumier
    if (skip_create) {
1373 b2e10493 Alexandre Derumier
        int64_t output_length = bdrv_getlength(out_bs);
1374 b2e10493 Alexandre Derumier
        if (output_length < 0) {
1375 b2e10493 Alexandre Derumier
            error_report("unable to get output image length: %s\n",
1376 b2e10493 Alexandre Derumier
                         strerror(-output_length));
1377 b2e10493 Alexandre Derumier
            ret = -1;
1378 b2e10493 Alexandre Derumier
            goto out;
1379 b2e10493 Alexandre Derumier
        } else if (output_length < total_sectors << BDRV_SECTOR_BITS) {
1380 b2e10493 Alexandre Derumier
            error_report("output file is smaller than input file");
1381 b2e10493 Alexandre Derumier
            ret = -1;
1382 b2e10493 Alexandre Derumier
            goto out;
1383 b2e10493 Alexandre Derumier
        }
1384 b2e10493 Alexandre Derumier
    }
1385 b2e10493 Alexandre Derumier
1386 eec77d9e Jes Sorensen
    if (compress) {
1387 c2abccec MORITA Kazutaka
        ret = bdrv_get_info(out_bs, &bdi);
1388 c2abccec MORITA Kazutaka
        if (ret < 0) {
1389 15654a6d Jes Sorensen
            error_report("could not get block driver info");
1390 c2abccec MORITA Kazutaka
            goto out;
1391 c2abccec MORITA Kazutaka
        }
1392 faea38e7 bellard
        cluster_size = bdi.cluster_size;
1393 c2abccec MORITA Kazutaka
        if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
1394 15654a6d Jes Sorensen
            error_report("invalid cluster size");
1395 c2abccec MORITA Kazutaka
            ret = -1;
1396 c2abccec MORITA Kazutaka
            goto out;
1397 c2abccec MORITA Kazutaka
        }
1398 ea2384d3 bellard
        cluster_sectors = cluster_size >> 9;
1399 ea2384d3 bellard
        sector_num = 0;
1400 6b837bc4 Jes Sorensen
1401 6b837bc4 Jes Sorensen
        nb_sectors = total_sectors;
1402 1f710495 Kevin Wolf
        if (nb_sectors != 0) {
1403 1f710495 Kevin Wolf
            local_progress = (float)100 /
1404 1f710495 Kevin Wolf
                (nb_sectors / MIN(nb_sectors, cluster_sectors));
1405 1f710495 Kevin Wolf
        }
1406 6b837bc4 Jes Sorensen
1407 ea2384d3 bellard
        for(;;) {
1408 926c2d23 balrog
            int64_t bs_num;
1409 926c2d23 balrog
            int remainder;
1410 926c2d23 balrog
            uint8_t *buf2;
1411 926c2d23 balrog
1412 ea2384d3 bellard
            nb_sectors = total_sectors - sector_num;
1413 ea2384d3 bellard
            if (nb_sectors <= 0)
1414 ea2384d3 bellard
                break;
1415 ea2384d3 bellard
            if (nb_sectors >= cluster_sectors)
1416 ea2384d3 bellard
                n = cluster_sectors;
1417 ea2384d3 bellard
            else
1418 ea2384d3 bellard
                n = nb_sectors;
1419 926c2d23 balrog
1420 926c2d23 balrog
            bs_num = sector_num - bs_offset;
1421 926c2d23 balrog
            assert (bs_num >= 0);
1422 926c2d23 balrog
            remainder = n;
1423 926c2d23 balrog
            buf2 = buf;
1424 926c2d23 balrog
            while (remainder > 0) {
1425 926c2d23 balrog
                int nlow;
1426 926c2d23 balrog
                while (bs_num == bs_sectors) {
1427 926c2d23 balrog
                    bs_i++;
1428 926c2d23 balrog
                    assert (bs_i < bs_n);
1429 926c2d23 balrog
                    bs_offset += bs_sectors;
1430 926c2d23 balrog
                    bdrv_get_geometry(bs[bs_i], &bs_sectors);
1431 926c2d23 balrog
                    bs_num = 0;
1432 0bfcd599 Blue Swirl
                    /* printf("changing part: sector_num=%" PRId64 ", "
1433 0bfcd599 Blue Swirl
                       "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64
1434 0bfcd599 Blue Swirl
                       "\n", sector_num, bs_i, bs_offset, bs_sectors); */
1435 926c2d23 balrog
                }
1436 926c2d23 balrog
                assert (bs_num < bs_sectors);
1437 926c2d23 balrog
1438 926c2d23 balrog
                nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
1439 926c2d23 balrog
1440 c2abccec MORITA Kazutaka
                ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
1441 c2abccec MORITA Kazutaka
                if (ret < 0) {
1442 3fba9d81 Stefan Hajnoczi
                    error_report("error while reading sector %" PRId64 ": %s",
1443 3fba9d81 Stefan Hajnoczi
                                 bs_num, strerror(-ret));
1444 c2abccec MORITA Kazutaka
                    goto out;
1445 c2abccec MORITA Kazutaka
                }
1446 926c2d23 balrog
1447 926c2d23 balrog
                buf2 += nlow * 512;
1448 926c2d23 balrog
                bs_num += nlow;
1449 926c2d23 balrog
1450 926c2d23 balrog
                remainder -= nlow;
1451 926c2d23 balrog
            }
1452 926c2d23 balrog
            assert (remainder == 0);
1453 926c2d23 balrog
1454 54f106d5 Stefan Hajnoczi
            if (!buffer_is_zero(buf, n * BDRV_SECTOR_SIZE)) {
1455 54f106d5 Stefan Hajnoczi
                ret = bdrv_write_compressed(out_bs, sector_num, buf, n);
1456 c2abccec MORITA Kazutaka
                if (ret != 0) {
1457 3fba9d81 Stefan Hajnoczi
                    error_report("error while compressing sector %" PRId64
1458 3fba9d81 Stefan Hajnoczi
                                 ": %s", sector_num, strerror(-ret));
1459 c2abccec MORITA Kazutaka
                    goto out;
1460 c2abccec MORITA Kazutaka
                }
1461 ea2384d3 bellard
            }
1462 ea2384d3 bellard
            sector_num += n;
1463 6b837bc4 Jes Sorensen
            qemu_progress_print(local_progress, 100);
1464 ea2384d3 bellard
        }
1465 faea38e7 bellard
        /* signal EOF to align */
1466 faea38e7 bellard
        bdrv_write_compressed(out_bs, 0, NULL, 0);
1467 ea2384d3 bellard
    } else {
1468 f2feebbd Kevin Wolf
        int has_zero_init = bdrv_has_zero_init(out_bs);
1469 f2feebbd Kevin Wolf
1470 f58c7b35 ths
        sector_num = 0; // total number of sectors converted so far
1471 6b837bc4 Jes Sorensen
        nb_sectors = total_sectors - sector_num;
1472 1f710495 Kevin Wolf
        if (nb_sectors != 0) {
1473 1f710495 Kevin Wolf
            local_progress = (float)100 /
1474 1f710495 Kevin Wolf
                (nb_sectors / MIN(nb_sectors, IO_BUF_SIZE / 512));
1475 1f710495 Kevin Wolf
        }
1476 6b837bc4 Jes Sorensen
1477 ea2384d3 bellard
        for(;;) {
1478 ea2384d3 bellard
            nb_sectors = total_sectors - sector_num;
1479 b8fb60da Jes Sorensen
            if (nb_sectors <= 0) {
1480 ea2384d3 bellard
                break;
1481 b8fb60da Jes Sorensen
            }
1482 b8fb60da Jes Sorensen
            if (nb_sectors >= (IO_BUF_SIZE / 512)) {
1483 ea2384d3 bellard
                n = (IO_BUF_SIZE / 512);
1484 b8fb60da Jes Sorensen
            } else {
1485 ea2384d3 bellard
                n = nb_sectors;
1486 b8fb60da Jes Sorensen
            }
1487 926c2d23 balrog
1488 926c2d23 balrog
            while (sector_num - bs_offset >= bs_sectors) {
1489 926c2d23 balrog
                bs_i ++;
1490 926c2d23 balrog
                assert (bs_i < bs_n);
1491 926c2d23 balrog
                bs_offset += bs_sectors;
1492 926c2d23 balrog
                bdrv_get_geometry(bs[bs_i], &bs_sectors);
1493 0bfcd599 Blue Swirl
                /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "
1494 0bfcd599 Blue Swirl
                  "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",
1495 926c2d23 balrog
                   sector_num, bs_i, bs_offset, bs_sectors); */
1496 926c2d23 balrog
            }
1497 926c2d23 balrog
1498 b8fb60da Jes Sorensen
            if (n > bs_offset + bs_sectors - sector_num) {
1499 926c2d23 balrog
                n = bs_offset + bs_sectors - sector_num;
1500 b8fb60da Jes Sorensen
            }
1501 926c2d23 balrog
1502 e4a86f88 Paolo Bonzini
            /* If the output image is being created as a copy on write image,
1503 e4a86f88 Paolo Bonzini
               assume that sectors which are unallocated in the input image
1504 e4a86f88 Paolo Bonzini
               are present in both the output's and input's base images (no
1505 e4a86f88 Paolo Bonzini
               need to copy them). */
1506 e4a86f88 Paolo Bonzini
            if (out_baseimg) {
1507 e4a86f88 Paolo Bonzini
                ret = bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
1508 e4a86f88 Paolo Bonzini
                                        n, &n1);
1509 e4a86f88 Paolo Bonzini
                if (ret < 0) {
1510 e4a86f88 Paolo Bonzini
                    error_report("error while reading metadata for sector "
1511 e4a86f88 Paolo Bonzini
                                 "%" PRId64 ": %s",
1512 e4a86f88 Paolo Bonzini
                                 sector_num - bs_offset, strerror(-ret));
1513 e4a86f88 Paolo Bonzini
                    goto out;
1514 e4a86f88 Paolo Bonzini
                }
1515 e4a86f88 Paolo Bonzini
                if (!ret) {
1516 e4a86f88 Paolo Bonzini
                    sector_num += n1;
1517 e4a86f88 Paolo Bonzini
                    continue;
1518 93c65b47 aliguori
                }
1519 e4a86f88 Paolo Bonzini
                /* The next 'n1' sectors are allocated in the input image. Copy
1520 e4a86f88 Paolo Bonzini
                   only those as they may be followed by unallocated sectors. */
1521 e4a86f88 Paolo Bonzini
                n = n1;
1522 93c65b47 aliguori
            } else {
1523 93c65b47 aliguori
                n1 = n;
1524 f58c7b35 ths
            }
1525 f58c7b35 ths
1526 c2abccec MORITA Kazutaka
            ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
1527 c2abccec MORITA Kazutaka
            if (ret < 0) {
1528 3fba9d81 Stefan Hajnoczi
                error_report("error while reading sector %" PRId64 ": %s",
1529 3fba9d81 Stefan Hajnoczi
                             sector_num - bs_offset, strerror(-ret));
1530 c2abccec MORITA Kazutaka
                goto out;
1531 c2abccec MORITA Kazutaka
            }
1532 ea2384d3 bellard
            /* NOTE: at the same time we convert, we do not write zero
1533 ea2384d3 bellard
               sectors to have a chance to compress the image. Ideally, we
1534 ea2384d3 bellard
               should add a specific call to have the info to go faster */
1535 ea2384d3 bellard
            buf1 = buf;
1536 ea2384d3 bellard
            while (n > 0) {
1537 11212d8f Paolo Bonzini
                if (!has_zero_init ||
1538 a22f123c Kevin Wolf
                    is_allocated_sectors_min(buf1, n, &n1, min_sparse)) {
1539 c2abccec MORITA Kazutaka
                    ret = bdrv_write(out_bs, sector_num, buf1, n1);
1540 c2abccec MORITA Kazutaka
                    if (ret < 0) {
1541 3fba9d81 Stefan Hajnoczi
                        error_report("error while writing sector %" PRId64
1542 3fba9d81 Stefan Hajnoczi
                                     ": %s", sector_num, strerror(-ret));
1543 c2abccec MORITA Kazutaka
                        goto out;
1544 c2abccec MORITA Kazutaka
                    }
1545 ea2384d3 bellard
                }
1546 ea2384d3 bellard
                sector_num += n1;
1547 ea2384d3 bellard
                n -= n1;
1548 ea2384d3 bellard
                buf1 += n1 * 512;
1549 ea2384d3 bellard
            }
1550 6b837bc4 Jes Sorensen
            qemu_progress_print(local_progress, 100);
1551 ea2384d3 bellard
        }
1552 ea2384d3 bellard
    }
1553 c2abccec MORITA Kazutaka
out:
1554 6b837bc4 Jes Sorensen
    qemu_progress_end();
1555 c2abccec MORITA Kazutaka
    free_option_parameters(create_options);
1556 c2abccec MORITA Kazutaka
    free_option_parameters(param);
1557 bb1c0597 Kevin Wolf
    qemu_vfree(buf);
1558 c2abccec MORITA Kazutaka
    if (out_bs) {
1559 4f6fd349 Fam Zheng
        bdrv_unref(out_bs);
1560 c2abccec MORITA Kazutaka
    }
1561 31ca34b8 Jes Sorensen
    if (bs) {
1562 31ca34b8 Jes Sorensen
        for (bs_i = 0; bs_i < bs_n; bs_i++) {
1563 31ca34b8 Jes Sorensen
            if (bs[bs_i]) {
1564 4f6fd349 Fam Zheng
                bdrv_unref(bs[bs_i]);
1565 31ca34b8 Jes Sorensen
            }
1566 c2abccec MORITA Kazutaka
        }
1567 7267c094 Anthony Liguori
        g_free(bs);
1568 c2abccec MORITA Kazutaka
    }
1569 c2abccec MORITA Kazutaka
    if (ret) {
1570 c2abccec MORITA Kazutaka
        return 1;
1571 c2abccec MORITA Kazutaka
    }
1572 ea2384d3 bellard
    return 0;
1573 ea2384d3 bellard
}
1574 ea2384d3 bellard
1575 57d1a2b6 bellard
1576 faea38e7 bellard
static void dump_snapshots(BlockDriverState *bs)
1577 faea38e7 bellard
{
1578 faea38e7 bellard
    QEMUSnapshotInfo *sn_tab, *sn;
1579 faea38e7 bellard
    int nb_sns, i;
1580 faea38e7 bellard
1581 faea38e7 bellard
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1582 faea38e7 bellard
    if (nb_sns <= 0)
1583 faea38e7 bellard
        return;
1584 faea38e7 bellard
    printf("Snapshot list:\n");
1585 5b917044 Wenchao Xia
    bdrv_snapshot_dump(fprintf, stdout, NULL);
1586 5b917044 Wenchao Xia
    printf("\n");
1587 faea38e7 bellard
    for(i = 0; i < nb_sns; i++) {
1588 faea38e7 bellard
        sn = &sn_tab[i];
1589 5b917044 Wenchao Xia
        bdrv_snapshot_dump(fprintf, stdout, sn);
1590 5b917044 Wenchao Xia
        printf("\n");
1591 faea38e7 bellard
    }
1592 7267c094 Anthony Liguori
    g_free(sn_tab);
1593 faea38e7 bellard
}
1594 faea38e7 bellard
1595 9699bf0d Stefan Hajnoczi
static void dump_json_image_info_list(ImageInfoList *list)
1596 9699bf0d Stefan Hajnoczi
{
1597 9699bf0d Stefan Hajnoczi
    Error *errp = NULL;
1598 9699bf0d Stefan Hajnoczi
    QString *str;
1599 9699bf0d Stefan Hajnoczi
    QmpOutputVisitor *ov = qmp_output_visitor_new();
1600 9699bf0d Stefan Hajnoczi
    QObject *obj;
1601 9699bf0d Stefan Hajnoczi
    visit_type_ImageInfoList(qmp_output_get_visitor(ov),
1602 9699bf0d Stefan Hajnoczi
                             &list, NULL, &errp);
1603 9699bf0d Stefan Hajnoczi
    obj = qmp_output_get_qobject(ov);
1604 9699bf0d Stefan Hajnoczi
    str = qobject_to_json_pretty(obj);
1605 9699bf0d Stefan Hajnoczi
    assert(str != NULL);
1606 9699bf0d Stefan Hajnoczi
    printf("%s\n", qstring_get_str(str));
1607 9699bf0d Stefan Hajnoczi
    qobject_decref(obj);
1608 9699bf0d Stefan Hajnoczi
    qmp_output_visitor_cleanup(ov);
1609 9699bf0d Stefan Hajnoczi
    QDECREF(str);
1610 9699bf0d Stefan Hajnoczi
}
1611 9699bf0d Stefan Hajnoczi
1612 c054b3fd Benoît Canet
static void dump_json_image_info(ImageInfo *info)
1613 c054b3fd Benoît Canet
{
1614 c054b3fd Benoît Canet
    Error *errp = NULL;
1615 c054b3fd Benoît Canet
    QString *str;
1616 c054b3fd Benoît Canet
    QmpOutputVisitor *ov = qmp_output_visitor_new();
1617 c054b3fd Benoît Canet
    QObject *obj;
1618 c054b3fd Benoît Canet
    visit_type_ImageInfo(qmp_output_get_visitor(ov),
1619 c054b3fd Benoît Canet
                         &info, NULL, &errp);
1620 c054b3fd Benoît Canet
    obj = qmp_output_get_qobject(ov);
1621 c054b3fd Benoît Canet
    str = qobject_to_json_pretty(obj);
1622 c054b3fd Benoît Canet
    assert(str != NULL);
1623 c054b3fd Benoît Canet
    printf("%s\n", qstring_get_str(str));
1624 c054b3fd Benoît Canet
    qobject_decref(obj);
1625 c054b3fd Benoît Canet
    qmp_output_visitor_cleanup(ov);
1626 c054b3fd Benoît Canet
    QDECREF(str);
1627 c054b3fd Benoît Canet
}
1628 c054b3fd Benoît Canet
1629 9699bf0d Stefan Hajnoczi
static void dump_human_image_info_list(ImageInfoList *list)
1630 9699bf0d Stefan Hajnoczi
{
1631 9699bf0d Stefan Hajnoczi
    ImageInfoList *elem;
1632 9699bf0d Stefan Hajnoczi
    bool delim = false;
1633 9699bf0d Stefan Hajnoczi
1634 9699bf0d Stefan Hajnoczi
    for (elem = list; elem; elem = elem->next) {
1635 9699bf0d Stefan Hajnoczi
        if (delim) {
1636 9699bf0d Stefan Hajnoczi
            printf("\n");
1637 9699bf0d Stefan Hajnoczi
        }
1638 9699bf0d Stefan Hajnoczi
        delim = true;
1639 9699bf0d Stefan Hajnoczi
1640 5b917044 Wenchao Xia
        bdrv_image_info_dump(fprintf, stdout, elem->value);
1641 9699bf0d Stefan Hajnoczi
    }
1642 9699bf0d Stefan Hajnoczi
}
1643 9699bf0d Stefan Hajnoczi
1644 9699bf0d Stefan Hajnoczi
static gboolean str_equal_func(gconstpointer a, gconstpointer b)
1645 9699bf0d Stefan Hajnoczi
{
1646 9699bf0d Stefan Hajnoczi
    return strcmp(a, b) == 0;
1647 9699bf0d Stefan Hajnoczi
}
1648 9699bf0d Stefan Hajnoczi
1649 9699bf0d Stefan Hajnoczi
/**
1650 9699bf0d Stefan Hajnoczi
 * Open an image file chain and return an ImageInfoList
1651 9699bf0d Stefan Hajnoczi
 *
1652 9699bf0d Stefan Hajnoczi
 * @filename: topmost image filename
1653 9699bf0d Stefan Hajnoczi
 * @fmt: topmost image format (may be NULL to autodetect)
1654 9699bf0d Stefan Hajnoczi
 * @chain: true  - enumerate entire backing file chain
1655 9699bf0d Stefan Hajnoczi
 *         false - only topmost image file
1656 9699bf0d Stefan Hajnoczi
 *
1657 9699bf0d Stefan Hajnoczi
 * Returns a list of ImageInfo objects or NULL if there was an error opening an
1658 9699bf0d Stefan Hajnoczi
 * image file.  If there was an error a message will have been printed to
1659 9699bf0d Stefan Hajnoczi
 * stderr.
1660 9699bf0d Stefan Hajnoczi
 */
1661 9699bf0d Stefan Hajnoczi
static ImageInfoList *collect_image_info_list(const char *filename,
1662 9699bf0d Stefan Hajnoczi
                                              const char *fmt,
1663 9699bf0d Stefan Hajnoczi
                                              bool chain)
1664 9699bf0d Stefan Hajnoczi
{
1665 9699bf0d Stefan Hajnoczi
    ImageInfoList *head = NULL;
1666 9699bf0d Stefan Hajnoczi
    ImageInfoList **last = &head;
1667 9699bf0d Stefan Hajnoczi
    GHashTable *filenames;
1668 43526ec8 Wenchao Xia
    Error *err = NULL;
1669 9699bf0d Stefan Hajnoczi
1670 9699bf0d Stefan Hajnoczi
    filenames = g_hash_table_new_full(g_str_hash, str_equal_func, NULL, NULL);
1671 9699bf0d Stefan Hajnoczi
1672 9699bf0d Stefan Hajnoczi
    while (filename) {
1673 9699bf0d Stefan Hajnoczi
        BlockDriverState *bs;
1674 9699bf0d Stefan Hajnoczi
        ImageInfo *info;
1675 9699bf0d Stefan Hajnoczi
        ImageInfoList *elem;
1676 9699bf0d Stefan Hajnoczi
1677 9699bf0d Stefan Hajnoczi
        if (g_hash_table_lookup_extended(filenames, filename, NULL, NULL)) {
1678 9699bf0d Stefan Hajnoczi
            error_report("Backing file '%s' creates an infinite loop.",
1679 9699bf0d Stefan Hajnoczi
                         filename);
1680 9699bf0d Stefan Hajnoczi
            goto err;
1681 9699bf0d Stefan Hajnoczi
        }
1682 9699bf0d Stefan Hajnoczi
        g_hash_table_insert(filenames, (gpointer)filename, NULL);
1683 9699bf0d Stefan Hajnoczi
1684 9699bf0d Stefan Hajnoczi
        bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING,
1685 f382d43a Miroslav Rezanina
                           false, false);
1686 9699bf0d Stefan Hajnoczi
        if (!bs) {
1687 9699bf0d Stefan Hajnoczi
            goto err;
1688 9699bf0d Stefan Hajnoczi
        }
1689 9699bf0d Stefan Hajnoczi
1690 43526ec8 Wenchao Xia
        bdrv_query_image_info(bs, &info, &err);
1691 43526ec8 Wenchao Xia
        if (error_is_set(&err)) {
1692 43526ec8 Wenchao Xia
            error_report("%s", error_get_pretty(err));
1693 43526ec8 Wenchao Xia
            error_free(err);
1694 43526ec8 Wenchao Xia
            goto err;
1695 fb0ed453 Wenchao Xia
        }
1696 9699bf0d Stefan Hajnoczi
1697 9699bf0d Stefan Hajnoczi
        elem = g_new0(ImageInfoList, 1);
1698 9699bf0d Stefan Hajnoczi
        elem->value = info;
1699 9699bf0d Stefan Hajnoczi
        *last = elem;
1700 9699bf0d Stefan Hajnoczi
        last = &elem->next;
1701 9699bf0d Stefan Hajnoczi
1702 4f6fd349 Fam Zheng
        bdrv_unref(bs);
1703 9699bf0d Stefan Hajnoczi
1704 9699bf0d Stefan Hajnoczi
        filename = fmt = NULL;
1705 9699bf0d Stefan Hajnoczi
        if (chain) {
1706 9699bf0d Stefan Hajnoczi
            if (info->has_full_backing_filename) {
1707 9699bf0d Stefan Hajnoczi
                filename = info->full_backing_filename;
1708 9699bf0d Stefan Hajnoczi
            } else if (info->has_backing_filename) {
1709 9699bf0d Stefan Hajnoczi
                filename = info->backing_filename;
1710 9699bf0d Stefan Hajnoczi
            }
1711 9699bf0d Stefan Hajnoczi
            if (info->has_backing_filename_format) {
1712 9699bf0d Stefan Hajnoczi
                fmt = info->backing_filename_format;
1713 9699bf0d Stefan Hajnoczi
            }
1714 9699bf0d Stefan Hajnoczi
        }
1715 9699bf0d Stefan Hajnoczi
    }
1716 9699bf0d Stefan Hajnoczi
    g_hash_table_destroy(filenames);
1717 9699bf0d Stefan Hajnoczi
    return head;
1718 9699bf0d Stefan Hajnoczi
1719 9699bf0d Stefan Hajnoczi
err:
1720 9699bf0d Stefan Hajnoczi
    qapi_free_ImageInfoList(head);
1721 9699bf0d Stefan Hajnoczi
    g_hash_table_destroy(filenames);
1722 9699bf0d Stefan Hajnoczi
    return NULL;
1723 9699bf0d Stefan Hajnoczi
}
1724 9699bf0d Stefan Hajnoczi
1725 c054b3fd Benoît Canet
static int img_info(int argc, char **argv)
1726 c054b3fd Benoît Canet
{
1727 c054b3fd Benoît Canet
    int c;
1728 c054b3fd Benoît Canet
    OutputFormat output_format = OFORMAT_HUMAN;
1729 9699bf0d Stefan Hajnoczi
    bool chain = false;
1730 c054b3fd Benoît Canet
    const char *filename, *fmt, *output;
1731 9699bf0d Stefan Hajnoczi
    ImageInfoList *list;
1732 c054b3fd Benoît Canet
1733 ea2384d3 bellard
    fmt = NULL;
1734 c054b3fd Benoît Canet
    output = NULL;
1735 ea2384d3 bellard
    for(;;) {
1736 c054b3fd Benoît Canet
        int option_index = 0;
1737 c054b3fd Benoît Canet
        static const struct option long_options[] = {
1738 c054b3fd Benoît Canet
            {"help", no_argument, 0, 'h'},
1739 c054b3fd Benoît Canet
            {"format", required_argument, 0, 'f'},
1740 c054b3fd Benoît Canet
            {"output", required_argument, 0, OPTION_OUTPUT},
1741 9699bf0d Stefan Hajnoczi
            {"backing-chain", no_argument, 0, OPTION_BACKING_CHAIN},
1742 c054b3fd Benoît Canet
            {0, 0, 0, 0}
1743 c054b3fd Benoît Canet
        };
1744 c054b3fd Benoît Canet
        c = getopt_long(argc, argv, "f:h",
1745 c054b3fd Benoît Canet
                        long_options, &option_index);
1746 b8fb60da Jes Sorensen
        if (c == -1) {
1747 ea2384d3 bellard
            break;
1748 b8fb60da Jes Sorensen
        }
1749 ea2384d3 bellard
        switch(c) {
1750 ef87394c Jes Sorensen
        case '?':
1751 ea2384d3 bellard
        case 'h':
1752 ea2384d3 bellard
            help();
1753 ea2384d3 bellard
            break;
1754 ea2384d3 bellard
        case 'f':
1755 ea2384d3 bellard
            fmt = optarg;
1756 ea2384d3 bellard
            break;
1757 c054b3fd Benoît Canet
        case OPTION_OUTPUT:
1758 c054b3fd Benoît Canet
            output = optarg;
1759 c054b3fd Benoît Canet
            break;
1760 9699bf0d Stefan Hajnoczi
        case OPTION_BACKING_CHAIN:
1761 9699bf0d Stefan Hajnoczi
            chain = true;
1762 9699bf0d Stefan Hajnoczi
            break;
1763 ea2384d3 bellard
        }
1764 ea2384d3 bellard
    }
1765 fc11eb26 Kevin Wolf
    if (optind != argc - 1) {
1766 ea2384d3 bellard
        help();
1767 b8fb60da Jes Sorensen
    }
1768 ea2384d3 bellard
    filename = argv[optind++];
1769 ea2384d3 bellard
1770 c054b3fd Benoît Canet
    if (output && !strcmp(output, "json")) {
1771 c054b3fd Benoît Canet
        output_format = OFORMAT_JSON;
1772 c054b3fd Benoît Canet
    } else if (output && !strcmp(output, "human")) {
1773 c054b3fd Benoît Canet
        output_format = OFORMAT_HUMAN;
1774 c054b3fd Benoît Canet
    } else if (output) {
1775 c054b3fd Benoît Canet
        error_report("--output must be used with human or json as argument.");
1776 c2abccec MORITA Kazutaka
        return 1;
1777 c2abccec MORITA Kazutaka
    }
1778 c054b3fd Benoît Canet
1779 9699bf0d Stefan Hajnoczi
    list = collect_image_info_list(filename, fmt, chain);
1780 9699bf0d Stefan Hajnoczi
    if (!list) {
1781 c2abccec MORITA Kazutaka
        return 1;
1782 faea38e7 bellard
    }
1783 c054b3fd Benoît Canet
1784 c054b3fd Benoît Canet
    switch (output_format) {
1785 c054b3fd Benoît Canet
    case OFORMAT_HUMAN:
1786 9699bf0d Stefan Hajnoczi
        dump_human_image_info_list(list);
1787 c054b3fd Benoît Canet
        break;
1788 c054b3fd Benoît Canet
    case OFORMAT_JSON:
1789 9699bf0d Stefan Hajnoczi
        if (chain) {
1790 9699bf0d Stefan Hajnoczi
            dump_json_image_info_list(list);
1791 9699bf0d Stefan Hajnoczi
        } else {
1792 9699bf0d Stefan Hajnoczi
            dump_json_image_info(list->value);
1793 9699bf0d Stefan Hajnoczi
        }
1794 c054b3fd Benoît Canet
        break;
1795 faea38e7 bellard
    }
1796 c054b3fd Benoît Canet
1797 9699bf0d Stefan Hajnoczi
    qapi_free_ImageInfoList(list);
1798 ea2384d3 bellard
    return 0;
1799 ea2384d3 bellard
}
1800 ea2384d3 bellard
1801 4c93a13b Paolo Bonzini
1802 4c93a13b Paolo Bonzini
typedef struct MapEntry {
1803 4c93a13b Paolo Bonzini
    int flags;
1804 4c93a13b Paolo Bonzini
    int depth;
1805 4c93a13b Paolo Bonzini
    int64_t start;
1806 4c93a13b Paolo Bonzini
    int64_t length;
1807 4c93a13b Paolo Bonzini
    int64_t offset;
1808 4c93a13b Paolo Bonzini
    BlockDriverState *bs;
1809 4c93a13b Paolo Bonzini
} MapEntry;
1810 4c93a13b Paolo Bonzini
1811 4c93a13b Paolo Bonzini
static void dump_map_entry(OutputFormat output_format, MapEntry *e,
1812 4c93a13b Paolo Bonzini
                           MapEntry *next)
1813 4c93a13b Paolo Bonzini
{
1814 4c93a13b Paolo Bonzini
    switch (output_format) {
1815 4c93a13b Paolo Bonzini
    case OFORMAT_HUMAN:
1816 4c93a13b Paolo Bonzini
        if ((e->flags & BDRV_BLOCK_DATA) &&
1817 4c93a13b Paolo Bonzini
            !(e->flags & BDRV_BLOCK_OFFSET_VALID)) {
1818 4c93a13b Paolo Bonzini
            error_report("File contains external, encrypted or compressed clusters.");
1819 4c93a13b Paolo Bonzini
            exit(1);
1820 4c93a13b Paolo Bonzini
        }
1821 4c93a13b Paolo Bonzini
        if ((e->flags & (BDRV_BLOCK_DATA|BDRV_BLOCK_ZERO)) == BDRV_BLOCK_DATA) {
1822 4c93a13b Paolo Bonzini
            printf("%#-16"PRIx64"%#-16"PRIx64"%#-16"PRIx64"%s\n",
1823 4c93a13b Paolo Bonzini
                   e->start, e->length, e->offset, e->bs->filename);
1824 4c93a13b Paolo Bonzini
        }
1825 4c93a13b Paolo Bonzini
        /* This format ignores the distinction between 0, ZERO and ZERO|DATA.
1826 4c93a13b Paolo Bonzini
         * Modify the flags here to allow more coalescing.
1827 4c93a13b Paolo Bonzini
         */
1828 4c93a13b Paolo Bonzini
        if (next &&
1829 4c93a13b Paolo Bonzini
            (next->flags & (BDRV_BLOCK_DATA|BDRV_BLOCK_ZERO)) != BDRV_BLOCK_DATA) {
1830 4c93a13b Paolo Bonzini
            next->flags &= ~BDRV_BLOCK_DATA;
1831 4c93a13b Paolo Bonzini
            next->flags |= BDRV_BLOCK_ZERO;
1832 4c93a13b Paolo Bonzini
        }
1833 4c93a13b Paolo Bonzini
        break;
1834 4c93a13b Paolo Bonzini
    case OFORMAT_JSON:
1835 4c93a13b Paolo Bonzini
        printf("%s{ \"start\": %"PRId64", \"length\": %"PRId64", \"depth\": %d,"
1836 4c93a13b Paolo Bonzini
               " \"zero\": %s, \"data\": %s",
1837 4c93a13b Paolo Bonzini
               (e->start == 0 ? "[" : ",\n"),
1838 4c93a13b Paolo Bonzini
               e->start, e->length, e->depth,
1839 4c93a13b Paolo Bonzini
               (e->flags & BDRV_BLOCK_ZERO) ? "true" : "false",
1840 4c93a13b Paolo Bonzini
               (e->flags & BDRV_BLOCK_DATA) ? "true" : "false");
1841 4c93a13b Paolo Bonzini
        if (e->flags & BDRV_BLOCK_OFFSET_VALID) {
1842 4c93a13b Paolo Bonzini
            printf(", 'offset': %"PRId64"", e->offset);
1843 4c93a13b Paolo Bonzini
        }
1844 4c93a13b Paolo Bonzini
        putchar('}');
1845 4c93a13b Paolo Bonzini
1846 4c93a13b Paolo Bonzini
        if (!next) {
1847 4c93a13b Paolo Bonzini
            printf("]\n");
1848 4c93a13b Paolo Bonzini
        }
1849 4c93a13b Paolo Bonzini
        break;
1850 4c93a13b Paolo Bonzini
    }
1851 4c93a13b Paolo Bonzini
}
1852 4c93a13b Paolo Bonzini
1853 4c93a13b Paolo Bonzini
static int get_block_status(BlockDriverState *bs, int64_t sector_num,
1854 4c93a13b Paolo Bonzini
                            int nb_sectors, MapEntry *e)
1855 4c93a13b Paolo Bonzini
{
1856 4c93a13b Paolo Bonzini
    int64_t ret;
1857 4c93a13b Paolo Bonzini
    int depth;
1858 4c93a13b Paolo Bonzini
1859 4c93a13b Paolo Bonzini
    /* As an optimization, we could cache the current range of unallocated
1860 4c93a13b Paolo Bonzini
     * clusters in each file of the chain, and avoid querying the same
1861 4c93a13b Paolo Bonzini
     * range repeatedly.
1862 4c93a13b Paolo Bonzini
     */
1863 4c93a13b Paolo Bonzini
1864 4c93a13b Paolo Bonzini
    depth = 0;
1865 4c93a13b Paolo Bonzini
    for (;;) {
1866 4c93a13b Paolo Bonzini
        ret = bdrv_get_block_status(bs, sector_num, nb_sectors, &nb_sectors);
1867 4c93a13b Paolo Bonzini
        if (ret < 0) {
1868 4c93a13b Paolo Bonzini
            return ret;
1869 4c93a13b Paolo Bonzini
        }
1870 4c93a13b Paolo Bonzini
        assert(nb_sectors);
1871 4c93a13b Paolo Bonzini
        if (ret & (BDRV_BLOCK_ZERO|BDRV_BLOCK_DATA)) {
1872 4c93a13b Paolo Bonzini
            break;
1873 4c93a13b Paolo Bonzini
        }
1874 4c93a13b Paolo Bonzini
        bs = bs->backing_hd;
1875 4c93a13b Paolo Bonzini
        if (bs == NULL) {
1876 4c93a13b Paolo Bonzini
            ret = 0;
1877 4c93a13b Paolo Bonzini
            break;
1878 4c93a13b Paolo Bonzini
        }
1879 4c93a13b Paolo Bonzini
1880 4c93a13b Paolo Bonzini
        depth++;
1881 4c93a13b Paolo Bonzini
    }
1882 4c93a13b Paolo Bonzini
1883 4c93a13b Paolo Bonzini
    e->start = sector_num * BDRV_SECTOR_SIZE;
1884 4c93a13b Paolo Bonzini
    e->length = nb_sectors * BDRV_SECTOR_SIZE;
1885 4c93a13b Paolo Bonzini
    e->flags = ret & ~BDRV_BLOCK_OFFSET_MASK;
1886 4c93a13b Paolo Bonzini
    e->offset = ret & BDRV_BLOCK_OFFSET_MASK;
1887 4c93a13b Paolo Bonzini
    e->depth = depth;
1888 4c93a13b Paolo Bonzini
    e->bs = bs;
1889 4c93a13b Paolo Bonzini
    return 0;
1890 4c93a13b Paolo Bonzini
}
1891 4c93a13b Paolo Bonzini
1892 4c93a13b Paolo Bonzini
static int img_map(int argc, char **argv)
1893 4c93a13b Paolo Bonzini
{
1894 4c93a13b Paolo Bonzini
    int c;
1895 4c93a13b Paolo Bonzini
    OutputFormat output_format = OFORMAT_HUMAN;
1896 4c93a13b Paolo Bonzini
    BlockDriverState *bs;
1897 4c93a13b Paolo Bonzini
    const char *filename, *fmt, *output;
1898 4c93a13b Paolo Bonzini
    int64_t length;
1899 4c93a13b Paolo Bonzini
    MapEntry curr = { .length = 0 }, next;
1900 4c93a13b Paolo Bonzini
    int ret = 0;
1901 4c93a13b Paolo Bonzini
1902 4c93a13b Paolo Bonzini
    fmt = NULL;
1903 4c93a13b Paolo Bonzini
    output = NULL;
1904 4c93a13b Paolo Bonzini
    for (;;) {
1905 4c93a13b Paolo Bonzini
        int option_index = 0;
1906 4c93a13b Paolo Bonzini
        static const struct option long_options[] = {
1907 4c93a13b Paolo Bonzini
            {"help", no_argument, 0, 'h'},
1908 4c93a13b Paolo Bonzini
            {"format", required_argument, 0, 'f'},
1909 4c93a13b Paolo Bonzini
            {"output", required_argument, 0, OPTION_OUTPUT},
1910 4c93a13b Paolo Bonzini
            {0, 0, 0, 0}
1911 4c93a13b Paolo Bonzini
        };
1912 4c93a13b Paolo Bonzini
        c = getopt_long(argc, argv, "f:h",
1913 4c93a13b Paolo Bonzini
                        long_options, &option_index);
1914 4c93a13b Paolo Bonzini
        if (c == -1) {
1915 4c93a13b Paolo Bonzini
            break;
1916 4c93a13b Paolo Bonzini
        }
1917 4c93a13b Paolo Bonzini
        switch (c) {
1918 4c93a13b Paolo Bonzini
        case '?':
1919 4c93a13b Paolo Bonzini
        case 'h':
1920 4c93a13b Paolo Bonzini
            help();
1921 4c93a13b Paolo Bonzini
            break;
1922 4c93a13b Paolo Bonzini
        case 'f':
1923 4c93a13b Paolo Bonzini
            fmt = optarg;
1924 4c93a13b Paolo Bonzini
            break;
1925 4c93a13b Paolo Bonzini
        case OPTION_OUTPUT:
1926 4c93a13b Paolo Bonzini
            output = optarg;
1927 4c93a13b Paolo Bonzini
            break;
1928 4c93a13b Paolo Bonzini
        }
1929 4c93a13b Paolo Bonzini
    }
1930 4c93a13b Paolo Bonzini
    if (optind >= argc) {
1931 4c93a13b Paolo Bonzini
        help();
1932 4c93a13b Paolo Bonzini
    }
1933 4c93a13b Paolo Bonzini
    filename = argv[optind++];
1934 4c93a13b Paolo Bonzini
1935 4c93a13b Paolo Bonzini
    if (output && !strcmp(output, "json")) {
1936 4c93a13b Paolo Bonzini
        output_format = OFORMAT_JSON;
1937 4c93a13b Paolo Bonzini
    } else if (output && !strcmp(output, "human")) {
1938 4c93a13b Paolo Bonzini
        output_format = OFORMAT_HUMAN;
1939 4c93a13b Paolo Bonzini
    } else if (output) {
1940 4c93a13b Paolo Bonzini
        error_report("--output must be used with human or json as argument.");
1941 4c93a13b Paolo Bonzini
        return 1;
1942 4c93a13b Paolo Bonzini
    }
1943 4c93a13b Paolo Bonzini
1944 4c93a13b Paolo Bonzini
    bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS, true, false);
1945 4c93a13b Paolo Bonzini
    if (!bs) {
1946 4c93a13b Paolo Bonzini
        return 1;
1947 4c93a13b Paolo Bonzini
    }
1948 4c93a13b Paolo Bonzini
1949 4c93a13b Paolo Bonzini
    if (output_format == OFORMAT_HUMAN) {
1950 4c93a13b Paolo Bonzini
        printf("%-16s%-16s%-16s%s\n", "Offset", "Length", "Mapped to", "File");
1951 4c93a13b Paolo Bonzini
    }
1952 4c93a13b Paolo Bonzini
1953 4c93a13b Paolo Bonzini
    length = bdrv_getlength(bs);
1954 4c93a13b Paolo Bonzini
    while (curr.start + curr.length < length) {
1955 4c93a13b Paolo Bonzini
        int64_t nsectors_left;
1956 4c93a13b Paolo Bonzini
        int64_t sector_num;
1957 4c93a13b Paolo Bonzini
        int n;
1958 4c93a13b Paolo Bonzini
1959 4c93a13b Paolo Bonzini
        sector_num = (curr.start + curr.length) >> BDRV_SECTOR_BITS;
1960 4c93a13b Paolo Bonzini
1961 4c93a13b Paolo Bonzini
        /* Probe up to 1 GiB at a time.  */
1962 4c93a13b Paolo Bonzini
        nsectors_left = DIV_ROUND_UP(length, BDRV_SECTOR_SIZE) - sector_num;
1963 4c93a13b Paolo Bonzini
        n = MIN(1 << (30 - BDRV_SECTOR_BITS), nsectors_left);
1964 4c93a13b Paolo Bonzini
        ret = get_block_status(bs, sector_num, n, &next);
1965 4c93a13b Paolo Bonzini
1966 4c93a13b Paolo Bonzini
        if (ret < 0) {
1967 4c93a13b Paolo Bonzini
            error_report("Could not read file metadata: %s", strerror(-ret));
1968 4c93a13b Paolo Bonzini
            goto out;
1969 4c93a13b Paolo Bonzini
        }
1970 4c93a13b Paolo Bonzini
1971 4c93a13b Paolo Bonzini
        if (curr.length != 0 && curr.flags == next.flags &&
1972 4c93a13b Paolo Bonzini
            curr.depth == next.depth &&
1973 4c93a13b Paolo Bonzini
            ((curr.flags & BDRV_BLOCK_OFFSET_VALID) == 0 ||
1974 4c93a13b Paolo Bonzini
             curr.offset + curr.length == next.offset)) {
1975 4c93a13b Paolo Bonzini
            curr.length += next.length;
1976 4c93a13b Paolo Bonzini
            continue;
1977 4c93a13b Paolo Bonzini
        }
1978 4c93a13b Paolo Bonzini
1979 4c93a13b Paolo Bonzini
        if (curr.length > 0) {
1980 4c93a13b Paolo Bonzini
            dump_map_entry(output_format, &curr, &next);
1981 4c93a13b Paolo Bonzini
        }
1982 4c93a13b Paolo Bonzini
        curr = next;
1983 4c93a13b Paolo Bonzini
    }
1984 4c93a13b Paolo Bonzini
1985 4c93a13b Paolo Bonzini
    dump_map_entry(output_format, &curr, NULL);
1986 4c93a13b Paolo Bonzini
1987 4c93a13b Paolo Bonzini
out:
1988 4c93a13b Paolo Bonzini
    bdrv_unref(bs);
1989 4c93a13b Paolo Bonzini
    return ret < 0;
1990 4c93a13b Paolo Bonzini
}
1991 4c93a13b Paolo Bonzini
1992 f7b4a940 aliguori
#define SNAPSHOT_LIST   1
1993 f7b4a940 aliguori
#define SNAPSHOT_CREATE 2
1994 f7b4a940 aliguori
#define SNAPSHOT_APPLY  3
1995 f7b4a940 aliguori
#define SNAPSHOT_DELETE 4
1996 f7b4a940 aliguori
1997 153859be Stuart Brady
static int img_snapshot(int argc, char **argv)
1998 f7b4a940 aliguori
{
1999 f7b4a940 aliguori
    BlockDriverState *bs;
2000 f7b4a940 aliguori
    QEMUSnapshotInfo sn;
2001 f7b4a940 aliguori
    char *filename, *snapshot_name = NULL;
2002 c2abccec MORITA Kazutaka
    int c, ret = 0, bdrv_oflags;
2003 f7b4a940 aliguori
    int action = 0;
2004 f7b4a940 aliguori
    qemu_timeval tv;
2005 f382d43a Miroslav Rezanina
    bool quiet = false;
2006 a89d89d3 Wenchao Xia
    Error *err = NULL;
2007 f7b4a940 aliguori
2008 710da702 Kevin Wolf
    bdrv_oflags = BDRV_O_FLAGS | BDRV_O_RDWR;
2009 f7b4a940 aliguori
    /* Parse commandline parameters */
2010 f7b4a940 aliguori
    for(;;) {
2011 f382d43a Miroslav Rezanina
        c = getopt(argc, argv, "la:c:d:hq");
2012 b8fb60da Jes Sorensen
        if (c == -1) {
2013 f7b4a940 aliguori
            break;
2014 b8fb60da Jes Sorensen
        }
2015 f7b4a940 aliguori
        switch(c) {
2016 ef87394c Jes Sorensen
        case '?':
2017 f7b4a940 aliguori
        case 'h':
2018 f7b4a940 aliguori
            help();
2019 153859be Stuart Brady
            return 0;
2020 f7b4a940 aliguori
        case 'l':
2021 f7b4a940 aliguori
            if (action) {
2022 f7b4a940 aliguori
                help();
2023 153859be Stuart Brady
                return 0;
2024 f7b4a940 aliguori
            }
2025 f7b4a940 aliguori
            action = SNAPSHOT_LIST;
2026 f5edb014 Naphtali Sprei
            bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
2027 f7b4a940 aliguori
            break;
2028 f7b4a940 aliguori
        case 'a':
2029 f7b4a940 aliguori
            if (action) {
2030 f7b4a940 aliguori
                help();
2031 153859be Stuart Brady
                return 0;
2032 f7b4a940 aliguori
            }
2033 f7b4a940 aliguori
            action = SNAPSHOT_APPLY;
2034 f7b4a940 aliguori
            snapshot_name = optarg;
2035 f7b4a940 aliguori
            break;
2036 f7b4a940 aliguori
        case 'c':
2037 f7b4a940 aliguori
            if (action) {
2038 f7b4a940 aliguori
                help();
2039 153859be Stuart Brady
                return 0;
2040 f7b4a940 aliguori
            }
2041 f7b4a940 aliguori
            action = SNAPSHOT_CREATE;
2042 f7b4a940 aliguori
            snapshot_name = optarg;
2043 f7b4a940 aliguori
            break;
2044 f7b4a940 aliguori
        case 'd':
2045 f7b4a940 aliguori
            if (action) {
2046 f7b4a940 aliguori
                help();
2047 153859be Stuart Brady
                return 0;
2048 f7b4a940 aliguori
            }
2049 f7b4a940 aliguori
            action = SNAPSHOT_DELETE;
2050 f7b4a940 aliguori
            snapshot_name = optarg;
2051 f7b4a940 aliguori
            break;
2052 f382d43a Miroslav Rezanina
        case 'q':
2053 f382d43a Miroslav Rezanina
            quiet = true;
2054 f382d43a Miroslav Rezanina
            break;
2055 f7b4a940 aliguori
        }
2056 f7b4a940 aliguori
    }
2057 f7b4a940 aliguori
2058 fc11eb26 Kevin Wolf
    if (optind != argc - 1) {
2059 f7b4a940 aliguori
        help();
2060 b8fb60da Jes Sorensen
    }
2061 f7b4a940 aliguori
    filename = argv[optind++];
2062 f7b4a940 aliguori
2063 f7b4a940 aliguori
    /* Open the image */
2064 f382d43a Miroslav Rezanina
    bs = bdrv_new_open(filename, NULL, bdrv_oflags, true, quiet);
2065 c2abccec MORITA Kazutaka
    if (!bs) {
2066 c2abccec MORITA Kazutaka
        return 1;
2067 c2abccec MORITA Kazutaka
    }
2068 f7b4a940 aliguori
2069 f7b4a940 aliguori
    /* Perform the requested action */
2070 f7b4a940 aliguori
    switch(action) {
2071 f7b4a940 aliguori
    case SNAPSHOT_LIST:
2072 f7b4a940 aliguori
        dump_snapshots(bs);
2073 f7b4a940 aliguori
        break;
2074 f7b4a940 aliguori
2075 f7b4a940 aliguori
    case SNAPSHOT_CREATE:
2076 f7b4a940 aliguori
        memset(&sn, 0, sizeof(sn));
2077 f7b4a940 aliguori
        pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
2078 f7b4a940 aliguori
2079 f7b4a940 aliguori
        qemu_gettimeofday(&tv);
2080 f7b4a940 aliguori
        sn.date_sec = tv.tv_sec;
2081 f7b4a940 aliguori
        sn.date_nsec = tv.tv_usec * 1000;
2082 f7b4a940 aliguori
2083 f7b4a940 aliguori
        ret = bdrv_snapshot_create(bs, &sn);
2084 b8fb60da Jes Sorensen
        if (ret) {
2085 15654a6d Jes Sorensen
            error_report("Could not create snapshot '%s': %d (%s)",
2086 f7b4a940 aliguori
                snapshot_name, ret, strerror(-ret));
2087 b8fb60da Jes Sorensen
        }
2088 f7b4a940 aliguori
        break;
2089 f7b4a940 aliguori
2090 f7b4a940 aliguori
    case SNAPSHOT_APPLY:
2091 f7b4a940 aliguori
        ret = bdrv_snapshot_goto(bs, snapshot_name);
2092 b8fb60da Jes Sorensen
        if (ret) {
2093 15654a6d Jes Sorensen
            error_report("Could not apply snapshot '%s': %d (%s)",
2094 f7b4a940 aliguori
                snapshot_name, ret, strerror(-ret));
2095 b8fb60da Jes Sorensen
        }
2096 f7b4a940 aliguori
        break;
2097 f7b4a940 aliguori
2098 f7b4a940 aliguori
    case SNAPSHOT_DELETE:
2099 a89d89d3 Wenchao Xia
        bdrv_snapshot_delete_by_id_or_name(bs, snapshot_name, &err);
2100 a89d89d3 Wenchao Xia
        if (error_is_set(&err)) {
2101 a89d89d3 Wenchao Xia
            error_report("Could not delete snapshot '%s': (%s)",
2102 a89d89d3 Wenchao Xia
                         snapshot_name, error_get_pretty(err));
2103 a89d89d3 Wenchao Xia
            error_free(err);
2104 a89d89d3 Wenchao Xia
            ret = 1;
2105 b8fb60da Jes Sorensen
        }
2106 f7b4a940 aliguori
        break;
2107 f7b4a940 aliguori
    }
2108 f7b4a940 aliguori
2109 f7b4a940 aliguori
    /* Cleanup */
2110 4f6fd349 Fam Zheng
    bdrv_unref(bs);
2111 c2abccec MORITA Kazutaka
    if (ret) {
2112 c2abccec MORITA Kazutaka
        return 1;
2113 c2abccec MORITA Kazutaka
    }
2114 153859be Stuart Brady
    return 0;
2115 f7b4a940 aliguori
}
2116 f7b4a940 aliguori
2117 3e85c6fd Kevin Wolf
static int img_rebase(int argc, char **argv)
2118 3e85c6fd Kevin Wolf
{
2119 c2abccec MORITA Kazutaka
    BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
2120 f163d073 Stefan Hajnoczi
    BlockDriver *old_backing_drv, *new_backing_drv;
2121 3e85c6fd Kevin Wolf
    char *filename;
2122 661a0f71 Federico Simoncelli
    const char *fmt, *cache, *out_basefmt, *out_baseimg;
2123 3e85c6fd Kevin Wolf
    int c, flags, ret;
2124 3e85c6fd Kevin Wolf
    int unsafe = 0;
2125 6b837bc4 Jes Sorensen
    int progress = 0;
2126 f382d43a Miroslav Rezanina
    bool quiet = false;
2127 34b5d2c6 Max Reitz
    Error *local_err = NULL;
2128 3e85c6fd Kevin Wolf
2129 3e85c6fd Kevin Wolf
    /* Parse commandline parameters */
2130 e53dbee0 Kevin Wolf
    fmt = NULL;
2131 661a0f71 Federico Simoncelli
    cache = BDRV_DEFAULT_CACHE;
2132 3e85c6fd Kevin Wolf
    out_baseimg = NULL;
2133 3e85c6fd Kevin Wolf
    out_basefmt = NULL;
2134 3e85c6fd Kevin Wolf
    for(;;) {
2135 f382d43a Miroslav Rezanina
        c = getopt(argc, argv, "uhf:F:b:pt:q");
2136 b8fb60da Jes Sorensen
        if (c == -1) {
2137 3e85c6fd Kevin Wolf
            break;
2138 b8fb60da Jes Sorensen
        }
2139 3e85c6fd Kevin Wolf
        switch(c) {
2140 ef87394c Jes Sorensen
        case '?':
2141 3e85c6fd Kevin Wolf
        case 'h':
2142 3e85c6fd Kevin Wolf
            help();
2143 3e85c6fd Kevin Wolf
            return 0;
2144 e53dbee0 Kevin Wolf
        case 'f':
2145 e53dbee0 Kevin Wolf
            fmt = optarg;
2146 e53dbee0 Kevin Wolf
            break;
2147 3e85c6fd Kevin Wolf
        case 'F':
2148 3e85c6fd Kevin Wolf
            out_basefmt = optarg;
2149 3e85c6fd Kevin Wolf
            break;
2150 3e85c6fd Kevin Wolf
        case 'b':
2151 3e85c6fd Kevin Wolf
            out_baseimg = optarg;
2152 3e85c6fd Kevin Wolf
            break;
2153 3e85c6fd Kevin Wolf
        case 'u':
2154 3e85c6fd Kevin Wolf
            unsafe = 1;
2155 3e85c6fd Kevin Wolf
            break;
2156 6b837bc4 Jes Sorensen
        case 'p':
2157 6b837bc4 Jes Sorensen
            progress = 1;
2158 6b837bc4 Jes Sorensen
            break;
2159 661a0f71 Federico Simoncelli
        case 't':
2160 661a0f71 Federico Simoncelli
            cache = optarg;
2161 661a0f71 Federico Simoncelli
            break;
2162 f382d43a Miroslav Rezanina
        case 'q':
2163 f382d43a Miroslav Rezanina
            quiet = true;
2164 f382d43a Miroslav Rezanina
            break;
2165 3e85c6fd Kevin Wolf
        }
2166 3e85c6fd Kevin Wolf
    }
2167 3e85c6fd Kevin Wolf
2168 f382d43a Miroslav Rezanina
    if (quiet) {
2169 f382d43a Miroslav Rezanina
        progress = 0;
2170 f382d43a Miroslav Rezanina
    }
2171 f382d43a Miroslav Rezanina
2172 fc11eb26 Kevin Wolf
    if ((optind != argc - 1) || (!unsafe && !out_baseimg)) {
2173 3e85c6fd Kevin Wolf
        help();
2174 b8fb60da Jes Sorensen
    }
2175 3e85c6fd Kevin Wolf
    filename = argv[optind++];
2176 3e85c6fd Kevin Wolf
2177 6b837bc4 Jes Sorensen
    qemu_progress_init(progress, 2.0);
2178 6b837bc4 Jes Sorensen
    qemu_progress_print(0, 100);
2179 6b837bc4 Jes Sorensen
2180 661a0f71 Federico Simoncelli
    flags = BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
2181 c3993cdc Stefan Hajnoczi
    ret = bdrv_parse_cache_flags(cache, &flags);
2182 661a0f71 Federico Simoncelli
    if (ret < 0) {
2183 661a0f71 Federico Simoncelli
        error_report("Invalid cache option: %s", cache);
2184 661a0f71 Federico Simoncelli
        return -1;
2185 661a0f71 Federico Simoncelli
    }
2186 661a0f71 Federico Simoncelli
2187 3e85c6fd Kevin Wolf
    /*
2188 3e85c6fd Kevin Wolf
     * Open the images.
2189 3e85c6fd Kevin Wolf
     *
2190 3e85c6fd Kevin Wolf
     * Ignore the old backing file for unsafe rebase in case we want to correct
2191 3e85c6fd Kevin Wolf
     * the reference to a renamed or moved backing file.
2192 3e85c6fd Kevin Wolf
     */
2193 f382d43a Miroslav Rezanina
    bs = bdrv_new_open(filename, fmt, flags, true, quiet);
2194 c2abccec MORITA Kazutaka
    if (!bs) {
2195 c2abccec MORITA Kazutaka
        return 1;
2196 c2abccec MORITA Kazutaka
    }
2197 3e85c6fd Kevin Wolf
2198 3e85c6fd Kevin Wolf
    /* Find the right drivers for the backing files */
2199 3e85c6fd Kevin Wolf
    old_backing_drv = NULL;
2200 3e85c6fd Kevin Wolf
    new_backing_drv = NULL;
2201 3e85c6fd Kevin Wolf
2202 3e85c6fd Kevin Wolf
    if (!unsafe && bs->backing_format[0] != '\0') {
2203 3e85c6fd Kevin Wolf
        old_backing_drv = bdrv_find_format(bs->backing_format);
2204 3e85c6fd Kevin Wolf
        if (old_backing_drv == NULL) {
2205 15654a6d Jes Sorensen
            error_report("Invalid format name: '%s'", bs->backing_format);
2206 c2abccec MORITA Kazutaka
            ret = -1;
2207 c2abccec MORITA Kazutaka
            goto out;
2208 3e85c6fd Kevin Wolf
        }
2209 3e85c6fd Kevin Wolf
    }
2210 3e85c6fd Kevin Wolf
2211 3e85c6fd Kevin Wolf
    if (out_basefmt != NULL) {
2212 3e85c6fd Kevin Wolf
        new_backing_drv = bdrv_find_format(out_basefmt);
2213 3e85c6fd Kevin Wolf
        if (new_backing_drv == NULL) {
2214 15654a6d Jes Sorensen
            error_report("Invalid format name: '%s'", out_basefmt);
2215 c2abccec MORITA Kazutaka
            ret = -1;
2216 c2abccec MORITA Kazutaka
            goto out;
2217 3e85c6fd Kevin Wolf
        }
2218 3e85c6fd Kevin Wolf
    }
2219 3e85c6fd Kevin Wolf
2220 3e85c6fd Kevin Wolf
    /* For safe rebasing we need to compare old and new backing file */
2221 3e85c6fd Kevin Wolf
    if (unsafe) {
2222 3e85c6fd Kevin Wolf
        /* Make the compiler happy */
2223 3e85c6fd Kevin Wolf
        bs_old_backing = NULL;
2224 3e85c6fd Kevin Wolf
        bs_new_backing = NULL;
2225 3e85c6fd Kevin Wolf
    } else {
2226 3e85c6fd Kevin Wolf
        char backing_name[1024];
2227 3e85c6fd Kevin Wolf
2228 3e85c6fd Kevin Wolf
        bs_old_backing = bdrv_new("old_backing");
2229 3e85c6fd Kevin Wolf
        bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
2230 de9c0cec Kevin Wolf
        ret = bdrv_open(bs_old_backing, backing_name, NULL, BDRV_O_FLAGS,
2231 34b5d2c6 Max Reitz
                        old_backing_drv, &local_err);
2232 c2abccec MORITA Kazutaka
        if (ret) {
2233 34b5d2c6 Max Reitz
            error_report("Could not open old backing file '%s': %s",
2234 34b5d2c6 Max Reitz
                         backing_name, error_get_pretty(local_err));
2235 34b5d2c6 Max Reitz
            error_free(local_err);
2236 c2abccec MORITA Kazutaka
            goto out;
2237 3e85c6fd Kevin Wolf
        }
2238 a616673d Alex Bligh
        if (out_baseimg[0]) {
2239 a616673d Alex Bligh
            bs_new_backing = bdrv_new("new_backing");
2240 de9c0cec Kevin Wolf
            ret = bdrv_open(bs_new_backing, out_baseimg, NULL, BDRV_O_FLAGS,
2241 34b5d2c6 Max Reitz
                        new_backing_drv, &local_err);
2242 a616673d Alex Bligh
            if (ret) {
2243 34b5d2c6 Max Reitz
                error_report("Could not open new backing file '%s': %s",
2244 34b5d2c6 Max Reitz
                             out_baseimg, error_get_pretty(local_err));
2245 34b5d2c6 Max Reitz
                error_free(local_err);
2246 a616673d Alex Bligh
                goto out;
2247 a616673d Alex Bligh
            }
2248 3e85c6fd Kevin Wolf
        }
2249 3e85c6fd Kevin Wolf
    }
2250 3e85c6fd Kevin Wolf
2251 3e85c6fd Kevin Wolf
    /*
2252 3e85c6fd Kevin Wolf
     * Check each unallocated cluster in the COW file. If it is unallocated,
2253 3e85c6fd Kevin Wolf
     * accesses go to the backing file. We must therefore compare this cluster
2254 3e85c6fd Kevin Wolf
     * in the old and new backing file, and if they differ we need to copy it
2255 3e85c6fd Kevin Wolf
     * from the old backing file into the COW file.
2256 3e85c6fd Kevin Wolf
     *
2257 3e85c6fd Kevin Wolf
     * If qemu-img crashes during this step, no harm is done. The content of
2258 3e85c6fd Kevin Wolf
     * the image is the same as the original one at any time.
2259 3e85c6fd Kevin Wolf
     */
2260 3e85c6fd Kevin Wolf
    if (!unsafe) {
2261 3e85c6fd Kevin Wolf
        uint64_t num_sectors;
2262 87a1b3e3 Kevin Wolf
        uint64_t old_backing_num_sectors;
2263 a616673d Alex Bligh
        uint64_t new_backing_num_sectors = 0;
2264 3e85c6fd Kevin Wolf
        uint64_t sector;
2265 cc60e327 Kevin Wolf
        int n;
2266 d6771bfa TeLeMan
        uint8_t * buf_old;
2267 d6771bfa TeLeMan
        uint8_t * buf_new;
2268 1f710495 Kevin Wolf
        float local_progress = 0;
2269 d6771bfa TeLeMan
2270 bb1c0597 Kevin Wolf
        buf_old = qemu_blockalign(bs, IO_BUF_SIZE);
2271 bb1c0597 Kevin Wolf
        buf_new = qemu_blockalign(bs, IO_BUF_SIZE);
2272 3e85c6fd Kevin Wolf
2273 3e85c6fd Kevin Wolf
        bdrv_get_geometry(bs, &num_sectors);
2274 87a1b3e3 Kevin Wolf
        bdrv_get_geometry(bs_old_backing, &old_backing_num_sectors);
2275 a616673d Alex Bligh
        if (bs_new_backing) {
2276 a616673d Alex Bligh
            bdrv_get_geometry(bs_new_backing, &new_backing_num_sectors);
2277 a616673d Alex Bligh
        }
2278 3e85c6fd Kevin Wolf
2279 1f710495 Kevin Wolf
        if (num_sectors != 0) {
2280 1f710495 Kevin Wolf
            local_progress = (float)100 /
2281 1f710495 Kevin Wolf
                (num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512));
2282 1f710495 Kevin Wolf
        }
2283 1f710495 Kevin Wolf
2284 3e85c6fd Kevin Wolf
        for (sector = 0; sector < num_sectors; sector += n) {
2285 3e85c6fd Kevin Wolf
2286 3e85c6fd Kevin Wolf
            /* How many sectors can we handle with the next read? */
2287 3e85c6fd Kevin Wolf
            if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
2288 3e85c6fd Kevin Wolf
                n = (IO_BUF_SIZE / 512);
2289 3e85c6fd Kevin Wolf
            } else {
2290 3e85c6fd Kevin Wolf
                n = num_sectors - sector;
2291 3e85c6fd Kevin Wolf
            }
2292 3e85c6fd Kevin Wolf
2293 3e85c6fd Kevin Wolf
            /* If the cluster is allocated, we don't need to take action */
2294 cc60e327 Kevin Wolf
            ret = bdrv_is_allocated(bs, sector, n, &n);
2295 d663640c Paolo Bonzini
            if (ret < 0) {
2296 d663640c Paolo Bonzini
                error_report("error while reading image metadata: %s",
2297 d663640c Paolo Bonzini
                             strerror(-ret));
2298 d663640c Paolo Bonzini
                goto out;
2299 d663640c Paolo Bonzini
            }
2300 cc60e327 Kevin Wolf
            if (ret) {
2301 3e85c6fd Kevin Wolf
                continue;
2302 3e85c6fd Kevin Wolf
            }
2303 3e85c6fd Kevin Wolf
2304 87a1b3e3 Kevin Wolf
            /*
2305 87a1b3e3 Kevin Wolf
             * Read old and new backing file and take into consideration that
2306 87a1b3e3 Kevin Wolf
             * backing files may be smaller than the COW image.
2307 87a1b3e3 Kevin Wolf
             */
2308 87a1b3e3 Kevin Wolf
            if (sector >= old_backing_num_sectors) {
2309 87a1b3e3 Kevin Wolf
                memset(buf_old, 0, n * BDRV_SECTOR_SIZE);
2310 87a1b3e3 Kevin Wolf
            } else {
2311 87a1b3e3 Kevin Wolf
                if (sector + n > old_backing_num_sectors) {
2312 87a1b3e3 Kevin Wolf
                    n = old_backing_num_sectors - sector;
2313 87a1b3e3 Kevin Wolf
                }
2314 87a1b3e3 Kevin Wolf
2315 87a1b3e3 Kevin Wolf
                ret = bdrv_read(bs_old_backing, sector, buf_old, n);
2316 87a1b3e3 Kevin Wolf
                if (ret < 0) {
2317 87a1b3e3 Kevin Wolf
                    error_report("error while reading from old backing file");
2318 87a1b3e3 Kevin Wolf
                    goto out;
2319 87a1b3e3 Kevin Wolf
                }
2320 3e85c6fd Kevin Wolf
            }
2321 87a1b3e3 Kevin Wolf
2322 a616673d Alex Bligh
            if (sector >= new_backing_num_sectors || !bs_new_backing) {
2323 87a1b3e3 Kevin Wolf
                memset(buf_new, 0, n * BDRV_SECTOR_SIZE);
2324 87a1b3e3 Kevin Wolf
            } else {
2325 87a1b3e3 Kevin Wolf
                if (sector + n > new_backing_num_sectors) {
2326 87a1b3e3 Kevin Wolf
                    n = new_backing_num_sectors - sector;
2327 87a1b3e3 Kevin Wolf
                }
2328 87a1b3e3 Kevin Wolf
2329 87a1b3e3 Kevin Wolf
                ret = bdrv_read(bs_new_backing, sector, buf_new, n);
2330 87a1b3e3 Kevin Wolf
                if (ret < 0) {
2331 87a1b3e3 Kevin Wolf
                    error_report("error while reading from new backing file");
2332 87a1b3e3 Kevin Wolf
                    goto out;
2333 87a1b3e3 Kevin Wolf
                }
2334 3e85c6fd Kevin Wolf
            }
2335 3e85c6fd Kevin Wolf
2336 3e85c6fd Kevin Wolf
            /* If they differ, we need to write to the COW file */
2337 3e85c6fd Kevin Wolf
            uint64_t written = 0;
2338 3e85c6fd Kevin Wolf
2339 3e85c6fd Kevin Wolf
            while (written < n) {
2340 3e85c6fd Kevin Wolf
                int pnum;
2341 3e85c6fd Kevin Wolf
2342 3e85c6fd Kevin Wolf
                if (compare_sectors(buf_old + written * 512,
2343 60b1bd4f Kevin Wolf
                    buf_new + written * 512, n - written, &pnum))
2344 3e85c6fd Kevin Wolf
                {
2345 3e85c6fd Kevin Wolf
                    ret = bdrv_write(bs, sector + written,
2346 3e85c6fd Kevin Wolf
                        buf_old + written * 512, pnum);
2347 3e85c6fd Kevin Wolf
                    if (ret < 0) {
2348 15654a6d Jes Sorensen
                        error_report("Error while writing to COW image: %s",
2349 3e85c6fd Kevin Wolf
                            strerror(-ret));
2350 c2abccec MORITA Kazutaka
                        goto out;
2351 3e85c6fd Kevin Wolf
                    }
2352 3e85c6fd Kevin Wolf
                }
2353 3e85c6fd Kevin Wolf
2354 3e85c6fd Kevin Wolf
                written += pnum;
2355 3e85c6fd Kevin Wolf
            }
2356 6b837bc4 Jes Sorensen
            qemu_progress_print(local_progress, 100);
2357 3e85c6fd Kevin Wolf
        }
2358 d6771bfa TeLeMan
2359 bb1c0597 Kevin Wolf
        qemu_vfree(buf_old);
2360 bb1c0597 Kevin Wolf
        qemu_vfree(buf_new);
2361 3e85c6fd Kevin Wolf
    }
2362 3e85c6fd Kevin Wolf
2363 3e85c6fd Kevin Wolf
    /*
2364 3e85c6fd Kevin Wolf
     * Change the backing file. All clusters that are different from the old
2365 3e85c6fd Kevin Wolf
     * backing file are overwritten in the COW file now, so the visible content
2366 3e85c6fd Kevin Wolf
     * doesn't change when we switch the backing file.
2367 3e85c6fd Kevin Wolf
     */
2368 a616673d Alex Bligh
    if (out_baseimg && *out_baseimg) {
2369 a616673d Alex Bligh
        ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
2370 a616673d Alex Bligh
    } else {
2371 a616673d Alex Bligh
        ret = bdrv_change_backing_file(bs, NULL, NULL);
2372 a616673d Alex Bligh
    }
2373 a616673d Alex Bligh
2374 3e85c6fd Kevin Wolf
    if (ret == -ENOSPC) {
2375 15654a6d Jes Sorensen
        error_report("Could not change the backing file to '%s': No "
2376 15654a6d Jes Sorensen
                     "space left in the file header", out_baseimg);
2377 3e85c6fd Kevin Wolf
    } else if (ret < 0) {
2378 15654a6d Jes Sorensen
        error_report("Could not change the backing file to '%s': %s",
2379 3e85c6fd Kevin Wolf
            out_baseimg, strerror(-ret));
2380 3e85c6fd Kevin Wolf
    }
2381 3e85c6fd Kevin Wolf
2382 6b837bc4 Jes Sorensen
    qemu_progress_print(100, 0);
2383 3e85c6fd Kevin Wolf
    /*
2384 3e85c6fd Kevin Wolf
     * TODO At this point it is possible to check if any clusters that are
2385 3e85c6fd Kevin Wolf
     * allocated in the COW file are the same in the backing file. If so, they
2386 3e85c6fd Kevin Wolf
     * could be dropped from the COW file. Don't do this before switching the
2387 3e85c6fd Kevin Wolf
     * backing file, in case of a crash this would lead to corruption.
2388 3e85c6fd Kevin Wolf
     */
2389 c2abccec MORITA Kazutaka
out:
2390 6b837bc4 Jes Sorensen
    qemu_progress_end();
2391 3e85c6fd Kevin Wolf
    /* Cleanup */
2392 3e85c6fd Kevin Wolf
    if (!unsafe) {
2393 eb863add Kevin Wolf
        if (bs_old_backing != NULL) {
2394 4f6fd349 Fam Zheng
            bdrv_unref(bs_old_backing);
2395 eb863add Kevin Wolf
        }
2396 eb863add Kevin Wolf
        if (bs_new_backing != NULL) {
2397 4f6fd349 Fam Zheng
            bdrv_unref(bs_new_backing);
2398 eb863add Kevin Wolf
        }
2399 3e85c6fd Kevin Wolf
    }
2400 3e85c6fd Kevin Wolf
2401 4f6fd349 Fam Zheng
    bdrv_unref(bs);
2402 c2abccec MORITA Kazutaka
    if (ret) {
2403 c2abccec MORITA Kazutaka
        return 1;
2404 c2abccec MORITA Kazutaka
    }
2405 3e85c6fd Kevin Wolf
    return 0;
2406 3e85c6fd Kevin Wolf
}
2407 3e85c6fd Kevin Wolf
2408 ae6b0ed6 Stefan Hajnoczi
static int img_resize(int argc, char **argv)
2409 ae6b0ed6 Stefan Hajnoczi
{
2410 ae6b0ed6 Stefan Hajnoczi
    int c, ret, relative;
2411 ae6b0ed6 Stefan Hajnoczi
    const char *filename, *fmt, *size;
2412 ae6b0ed6 Stefan Hajnoczi
    int64_t n, total_size;
2413 f382d43a Miroslav Rezanina
    bool quiet = false;
2414 2a81998a Jes Sorensen
    BlockDriverState *bs = NULL;
2415 20caf0f7 Dong Xu Wang
    QemuOpts *param;
2416 20caf0f7 Dong Xu Wang
    static QemuOptsList resize_options = {
2417 20caf0f7 Dong Xu Wang
        .name = "resize_options",
2418 20caf0f7 Dong Xu Wang
        .head = QTAILQ_HEAD_INITIALIZER(resize_options.head),
2419 20caf0f7 Dong Xu Wang
        .desc = {
2420 20caf0f7 Dong Xu Wang
            {
2421 20caf0f7 Dong Xu Wang
                .name = BLOCK_OPT_SIZE,
2422 20caf0f7 Dong Xu Wang
                .type = QEMU_OPT_SIZE,
2423 20caf0f7 Dong Xu Wang
                .help = "Virtual disk size"
2424 20caf0f7 Dong Xu Wang
            }, {
2425 20caf0f7 Dong Xu Wang
                /* end of list */
2426 20caf0f7 Dong Xu Wang
            }
2427 ae6b0ed6 Stefan Hajnoczi
        },
2428 ae6b0ed6 Stefan Hajnoczi
    };
2429 ae6b0ed6 Stefan Hajnoczi
2430 e80fec7f Kevin Wolf
    /* Remove size from argv manually so that negative numbers are not treated
2431 e80fec7f Kevin Wolf
     * as options by getopt. */
2432 e80fec7f Kevin Wolf
    if (argc < 3) {
2433 e80fec7f Kevin Wolf
        help();
2434 e80fec7f Kevin Wolf
        return 1;
2435 e80fec7f Kevin Wolf
    }
2436 e80fec7f Kevin Wolf
2437 e80fec7f Kevin Wolf
    size = argv[--argc];
2438 e80fec7f Kevin Wolf
2439 e80fec7f Kevin Wolf
    /* Parse getopt arguments */
2440 ae6b0ed6 Stefan Hajnoczi
    fmt = NULL;
2441 ae6b0ed6 Stefan Hajnoczi
    for(;;) {
2442 f382d43a Miroslav Rezanina
        c = getopt(argc, argv, "f:hq");
2443 ae6b0ed6 Stefan Hajnoczi
        if (c == -1) {
2444 ae6b0ed6 Stefan Hajnoczi
            break;
2445 ae6b0ed6 Stefan Hajnoczi
        }
2446 ae6b0ed6 Stefan Hajnoczi
        switch(c) {
2447 ef87394c Jes Sorensen
        case '?':
2448 ae6b0ed6 Stefan Hajnoczi
        case 'h':
2449 ae6b0ed6 Stefan Hajnoczi
            help();
2450 ae6b0ed6 Stefan Hajnoczi
            break;
2451 ae6b0ed6 Stefan Hajnoczi
        case 'f':
2452 ae6b0ed6 Stefan Hajnoczi
            fmt = optarg;
2453 ae6b0ed6 Stefan Hajnoczi
            break;
2454 f382d43a Miroslav Rezanina
        case 'q':
2455 f382d43a Miroslav Rezanina
            quiet = true;
2456 f382d43a Miroslav Rezanina
            break;
2457 ae6b0ed6 Stefan Hajnoczi
        }
2458 ae6b0ed6 Stefan Hajnoczi
    }
2459 fc11eb26 Kevin Wolf
    if (optind != argc - 1) {
2460 ae6b0ed6 Stefan Hajnoczi
        help();
2461 ae6b0ed6 Stefan Hajnoczi
    }
2462 ae6b0ed6 Stefan Hajnoczi
    filename = argv[optind++];
2463 ae6b0ed6 Stefan Hajnoczi
2464 ae6b0ed6 Stefan Hajnoczi
    /* Choose grow, shrink, or absolute resize mode */
2465 ae6b0ed6 Stefan Hajnoczi
    switch (size[0]) {
2466 ae6b0ed6 Stefan Hajnoczi
    case '+':
2467 ae6b0ed6 Stefan Hajnoczi
        relative = 1;
2468 ae6b0ed6 Stefan Hajnoczi
        size++;
2469 ae6b0ed6 Stefan Hajnoczi
        break;
2470 ae6b0ed6 Stefan Hajnoczi
    case '-':
2471 ae6b0ed6 Stefan Hajnoczi
        relative = -1;
2472 ae6b0ed6 Stefan Hajnoczi
        size++;
2473 ae6b0ed6 Stefan Hajnoczi
        break;
2474 ae6b0ed6 Stefan Hajnoczi
    default:
2475 ae6b0ed6 Stefan Hajnoczi
        relative = 0;
2476 ae6b0ed6 Stefan Hajnoczi
        break;
2477 ae6b0ed6 Stefan Hajnoczi
    }
2478 ae6b0ed6 Stefan Hajnoczi
2479 ae6b0ed6 Stefan Hajnoczi
    /* Parse size */
2480 e478b448 Dong Xu Wang
    param = qemu_opts_create_nofail(&resize_options);
2481 20caf0f7 Dong Xu Wang
    if (qemu_opt_set(param, BLOCK_OPT_SIZE, size)) {
2482 ae6b0ed6 Stefan Hajnoczi
        /* Error message already printed when size parsing fails */
2483 2a81998a Jes Sorensen
        ret = -1;
2484 20caf0f7 Dong Xu Wang
        qemu_opts_del(param);
2485 2a81998a Jes Sorensen
        goto out;
2486 ae6b0ed6 Stefan Hajnoczi
    }
2487 20caf0f7 Dong Xu Wang
    n = qemu_opt_get_size(param, BLOCK_OPT_SIZE, 0);
2488 20caf0f7 Dong Xu Wang
    qemu_opts_del(param);
2489 ae6b0ed6 Stefan Hajnoczi
2490 f382d43a Miroslav Rezanina
    bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR, true, quiet);
2491 c2abccec MORITA Kazutaka
    if (!bs) {
2492 2a81998a Jes Sorensen
        ret = -1;
2493 2a81998a Jes Sorensen
        goto out;
2494 c2abccec MORITA Kazutaka
    }
2495 ae6b0ed6 Stefan Hajnoczi
2496 ae6b0ed6 Stefan Hajnoczi
    if (relative) {
2497 ae6b0ed6 Stefan Hajnoczi
        total_size = bdrv_getlength(bs) + n * relative;
2498 ae6b0ed6 Stefan Hajnoczi
    } else {
2499 ae6b0ed6 Stefan Hajnoczi
        total_size = n;
2500 ae6b0ed6 Stefan Hajnoczi
    }
2501 ae6b0ed6 Stefan Hajnoczi
    if (total_size <= 0) {
2502 15654a6d Jes Sorensen
        error_report("New image size must be positive");
2503 c2abccec MORITA Kazutaka
        ret = -1;
2504 c2abccec MORITA Kazutaka
        goto out;
2505 ae6b0ed6 Stefan Hajnoczi
    }
2506 ae6b0ed6 Stefan Hajnoczi
2507 ae6b0ed6 Stefan Hajnoczi
    ret = bdrv_truncate(bs, total_size);
2508 ae6b0ed6 Stefan Hajnoczi
    switch (ret) {
2509 ae6b0ed6 Stefan Hajnoczi
    case 0:
2510 f382d43a Miroslav Rezanina
        qprintf(quiet, "Image resized.\n");
2511 ae6b0ed6 Stefan Hajnoczi
        break;
2512 ae6b0ed6 Stefan Hajnoczi
    case -ENOTSUP:
2513 259b2173 Kevin Wolf
        error_report("This image does not support resize");
2514 ae6b0ed6 Stefan Hajnoczi
        break;
2515 ae6b0ed6 Stefan Hajnoczi
    case -EACCES:
2516 15654a6d Jes Sorensen
        error_report("Image is read-only");
2517 ae6b0ed6 Stefan Hajnoczi
        break;
2518 ae6b0ed6 Stefan Hajnoczi
    default:
2519 15654a6d Jes Sorensen
        error_report("Error resizing image (%d)", -ret);
2520 ae6b0ed6 Stefan Hajnoczi
        break;
2521 ae6b0ed6 Stefan Hajnoczi
    }
2522 c2abccec MORITA Kazutaka
out:
2523 2a81998a Jes Sorensen
    if (bs) {
2524 4f6fd349 Fam Zheng
        bdrv_unref(bs);
2525 2a81998a Jes Sorensen
    }
2526 c2abccec MORITA Kazutaka
    if (ret) {
2527 c2abccec MORITA Kazutaka
        return 1;
2528 c2abccec MORITA Kazutaka
    }
2529 ae6b0ed6 Stefan Hajnoczi
    return 0;
2530 ae6b0ed6 Stefan Hajnoczi
}
2531 ae6b0ed6 Stefan Hajnoczi
2532 6f176b48 Max Reitz
static int img_amend(int argc, char **argv)
2533 6f176b48 Max Reitz
{
2534 6f176b48 Max Reitz
    int c, ret = 0;
2535 6f176b48 Max Reitz
    char *options = NULL;
2536 6f176b48 Max Reitz
    QEMUOptionParameter *create_options = NULL, *options_param = NULL;
2537 6f176b48 Max Reitz
    const char *fmt = NULL, *filename;
2538 6f176b48 Max Reitz
    bool quiet = false;
2539 6f176b48 Max Reitz
    BlockDriverState *bs = NULL;
2540 6f176b48 Max Reitz
2541 6f176b48 Max Reitz
    for (;;) {
2542 6f176b48 Max Reitz
        c = getopt(argc, argv, "hqf:o:");
2543 6f176b48 Max Reitz
        if (c == -1) {
2544 6f176b48 Max Reitz
            break;
2545 6f176b48 Max Reitz
        }
2546 6f176b48 Max Reitz
2547 6f176b48 Max Reitz
        switch (c) {
2548 6f176b48 Max Reitz
            case 'h':
2549 6f176b48 Max Reitz
            case '?':
2550 6f176b48 Max Reitz
                help();
2551 6f176b48 Max Reitz
                break;
2552 6f176b48 Max Reitz
            case 'o':
2553 6f176b48 Max Reitz
                options = optarg;
2554 6f176b48 Max Reitz
                break;
2555 6f176b48 Max Reitz
            case 'f':
2556 6f176b48 Max Reitz
                fmt = optarg;
2557 6f176b48 Max Reitz
                break;
2558 6f176b48 Max Reitz
            case 'q':
2559 6f176b48 Max Reitz
                quiet = true;
2560 6f176b48 Max Reitz
                break;
2561 6f176b48 Max Reitz
        }
2562 6f176b48 Max Reitz
    }
2563 6f176b48 Max Reitz
2564 6f176b48 Max Reitz
    if (optind != argc - 1) {
2565 6f176b48 Max Reitz
        help();
2566 6f176b48 Max Reitz
    }
2567 6f176b48 Max Reitz
2568 6f176b48 Max Reitz
    if (!options) {
2569 6f176b48 Max Reitz
        help();
2570 6f176b48 Max Reitz
    }
2571 6f176b48 Max Reitz
2572 6f176b48 Max Reitz
    filename = argv[argc - 1];
2573 6f176b48 Max Reitz
2574 6f176b48 Max Reitz
    bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR, true, quiet);
2575 6f176b48 Max Reitz
    if (!bs) {
2576 6f176b48 Max Reitz
        error_report("Could not open image '%s'", filename);
2577 6f176b48 Max Reitz
        ret = -1;
2578 6f176b48 Max Reitz
        goto out;
2579 6f176b48 Max Reitz
    }
2580 6f176b48 Max Reitz
2581 6f176b48 Max Reitz
    fmt = bs->drv->format_name;
2582 6f176b48 Max Reitz
2583 6f176b48 Max Reitz
    if (is_help_option(options)) {
2584 6f176b48 Max Reitz
        ret = print_block_option_help(filename, fmt);
2585 6f176b48 Max Reitz
        goto out;
2586 6f176b48 Max Reitz
    }
2587 6f176b48 Max Reitz
2588 6f176b48 Max Reitz
    create_options = append_option_parameters(create_options,
2589 6f176b48 Max Reitz
            bs->drv->create_options);
2590 6f176b48 Max Reitz
    options_param = parse_option_parameters(options, create_options,
2591 6f176b48 Max Reitz
            options_param);
2592 6f176b48 Max Reitz
    if (options_param == NULL) {
2593 6f176b48 Max Reitz
        error_report("Invalid options for file format '%s'", fmt);
2594 6f176b48 Max Reitz
        ret = -1;
2595 6f176b48 Max Reitz
        goto out;
2596 6f176b48 Max Reitz
    }
2597 6f176b48 Max Reitz
2598 6f176b48 Max Reitz
    ret = bdrv_amend_options(bs, options_param);
2599 6f176b48 Max Reitz
    if (ret < 0) {
2600 6f176b48 Max Reitz
        error_report("Error while amending options: %s", strerror(-ret));
2601 6f176b48 Max Reitz
        goto out;
2602 6f176b48 Max Reitz
    }
2603 6f176b48 Max Reitz
2604 6f176b48 Max Reitz
out:
2605 6f176b48 Max Reitz
    if (bs) {
2606 6f176b48 Max Reitz
        bdrv_unref(bs);
2607 6f176b48 Max Reitz
    }
2608 6f176b48 Max Reitz
    free_option_parameters(create_options);
2609 6f176b48 Max Reitz
    free_option_parameters(options_param);
2610 6f176b48 Max Reitz
    if (ret) {
2611 6f176b48 Max Reitz
        return 1;
2612 6f176b48 Max Reitz
    }
2613 6f176b48 Max Reitz
    return 0;
2614 6f176b48 Max Reitz
}
2615 6f176b48 Max Reitz
2616 c227f099 Anthony Liguori
static const img_cmd_t img_cmds[] = {
2617 153859be Stuart Brady
#define DEF(option, callback, arg_string)        \
2618 153859be Stuart Brady
    { option, callback },
2619 153859be Stuart Brady
#include "qemu-img-cmds.h"
2620 153859be Stuart Brady
#undef DEF
2621 153859be Stuart Brady
#undef GEN_DOCS
2622 153859be Stuart Brady
    { NULL, NULL, },
2623 153859be Stuart Brady
};
2624 153859be Stuart Brady
2625 ea2384d3 bellard
int main(int argc, char **argv)
2626 ea2384d3 bellard
{
2627 c227f099 Anthony Liguori
    const img_cmd_t *cmd;
2628 153859be Stuart Brady
    const char *cmdname;
2629 ea2384d3 bellard
2630 526eda14 MORITA Kazutaka
#ifdef CONFIG_POSIX
2631 526eda14 MORITA Kazutaka
    signal(SIGPIPE, SIG_IGN);
2632 526eda14 MORITA Kazutaka
#endif
2633 526eda14 MORITA Kazutaka
2634 53f76e58 Kevin Wolf
    error_set_progname(argv[0]);
2635 53f76e58 Kevin Wolf
2636 2592c59a Paolo Bonzini
    qemu_init_main_loop();
2637 ea2384d3 bellard
    bdrv_init();
2638 ea2384d3 bellard
    if (argc < 2)
2639 ea2384d3 bellard
        help();
2640 153859be Stuart Brady
    cmdname = argv[1];
2641 8f9b157e aurel32
    argc--; argv++;
2642 153859be Stuart Brady
2643 153859be Stuart Brady
    /* find the command */
2644 153859be Stuart Brady
    for(cmd = img_cmds; cmd->name != NULL; cmd++) {
2645 153859be Stuart Brady
        if (!strcmp(cmdname, cmd->name)) {
2646 153859be Stuart Brady
            return cmd->handler(argc, argv);
2647 153859be Stuart Brady
        }
2648 ea2384d3 bellard
    }
2649 153859be Stuart Brady
2650 153859be Stuart Brady
    /* not found */
2651 153859be Stuart Brady
    help();
2652 ea2384d3 bellard
    return 0;
2653 ea2384d3 bellard
}