Statistics
| Branch: | Revision:

root / qemu-img.c @ 34b5d2c6

History | View | Annotate | Download (75.1 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 ea2384d3 bellard
1143 ea2384d3 bellard
    fmt = NULL;
1144 ea2384d3 bellard
    out_fmt = "raw";
1145 661a0f71 Federico Simoncelli
    cache = "unsafe";
1146 f58c7b35 ths
    out_baseimg = NULL;
1147 eec77d9e Jes Sorensen
    compress = 0;
1148 b2e10493 Alexandre Derumier
    skip_create = 0;
1149 ea2384d3 bellard
    for(;;) {
1150 b2e10493 Alexandre Derumier
        c = getopt(argc, argv, "f:O:B:s:hce6o:pS:t:qn");
1151 b8fb60da Jes Sorensen
        if (c == -1) {
1152 ea2384d3 bellard
            break;
1153 b8fb60da Jes Sorensen
        }
1154 ea2384d3 bellard
        switch(c) {
1155 ef87394c Jes Sorensen
        case '?':
1156 ea2384d3 bellard
        case 'h':
1157 ea2384d3 bellard
            help();
1158 ea2384d3 bellard
            break;
1159 ea2384d3 bellard
        case 'f':
1160 ea2384d3 bellard
            fmt = optarg;
1161 ea2384d3 bellard
            break;
1162 ea2384d3 bellard
        case 'O':
1163 ea2384d3 bellard
            out_fmt = optarg;
1164 ea2384d3 bellard
            break;
1165 f58c7b35 ths
        case 'B':
1166 f58c7b35 ths
            out_baseimg = optarg;
1167 f58c7b35 ths
            break;
1168 ea2384d3 bellard
        case 'c':
1169 eec77d9e Jes Sorensen
            compress = 1;
1170 ea2384d3 bellard
            break;
1171 ea2384d3 bellard
        case 'e':
1172 9d42e15d Markus Armbruster
            error_report("option -e is deprecated, please use \'-o "
1173 eec77d9e Jes Sorensen
                  "encryption\' instead!");
1174 eec77d9e Jes Sorensen
            return 1;
1175 ec36ba14 ths
        case '6':
1176 9d42e15d Markus Armbruster
            error_report("option -6 is deprecated, please use \'-o "
1177 eec77d9e Jes Sorensen
                  "compat6\' instead!");
1178 eec77d9e Jes Sorensen
            return 1;
1179 efa84d43 Kevin Wolf
        case 'o':
1180 efa84d43 Kevin Wolf
            options = optarg;
1181 efa84d43 Kevin Wolf
            break;
1182 51ef6727 edison
        case 's':
1183 51ef6727 edison
            snapshot_name = optarg;
1184 51ef6727 edison
            break;
1185 a22f123c Kevin Wolf
        case 'S':
1186 a22f123c Kevin Wolf
        {
1187 a22f123c Kevin Wolf
            int64_t sval;
1188 e36b3695 Markus Armbruster
            char *end;
1189 e36b3695 Markus Armbruster
            sval = strtosz_suffix(optarg, &end, STRTOSZ_DEFSUFFIX_B);
1190 e36b3695 Markus Armbruster
            if (sval < 0 || *end) {
1191 a22f123c Kevin Wolf
                error_report("Invalid minimum zero buffer size for sparse output specified");
1192 a22f123c Kevin Wolf
                return 1;
1193 a22f123c Kevin Wolf
            }
1194 a22f123c Kevin Wolf
1195 a22f123c Kevin Wolf
            min_sparse = sval / BDRV_SECTOR_SIZE;
1196 a22f123c Kevin Wolf
            break;
1197 a22f123c Kevin Wolf
        }
1198 6b837bc4 Jes Sorensen
        case 'p':
1199 6b837bc4 Jes Sorensen
            progress = 1;
1200 6b837bc4 Jes Sorensen
            break;
1201 661a0f71 Federico Simoncelli
        case 't':
1202 661a0f71 Federico Simoncelli
            cache = optarg;
1203 661a0f71 Federico Simoncelli
            break;
1204 f382d43a Miroslav Rezanina
        case 'q':
1205 f382d43a Miroslav Rezanina
            quiet = true;
1206 f382d43a Miroslav Rezanina
            break;
1207 b2e10493 Alexandre Derumier
        case 'n':
1208 b2e10493 Alexandre Derumier
            skip_create = 1;
1209 b2e10493 Alexandre Derumier
            break;
1210 ea2384d3 bellard
        }
1211 ea2384d3 bellard
    }
1212 3b46e624 ths
1213 f382d43a Miroslav Rezanina
    if (quiet) {
1214 f382d43a Miroslav Rezanina
        progress = 0;
1215 f382d43a Miroslav Rezanina
    }
1216 f382d43a Miroslav Rezanina
1217 926c2d23 balrog
    bs_n = argc - optind - 1;
1218 b8fb60da Jes Sorensen
    if (bs_n < 1) {
1219 b8fb60da Jes Sorensen
        help();
1220 b8fb60da Jes Sorensen
    }
1221 926c2d23 balrog
1222 926c2d23 balrog
    out_filename = argv[argc - 1];
1223 f58c7b35 ths
1224 fa170c14 Charles Arnold
    /* Initialize before goto out */
1225 fa170c14 Charles Arnold
    qemu_progress_init(progress, 2.0);
1226 fa170c14 Charles Arnold
1227 c8057f95 Peter Maydell
    if (options && is_help_option(options)) {
1228 4ac8aacd Jes Sorensen
        ret = print_block_option_help(out_filename, out_fmt);
1229 4ac8aacd Jes Sorensen
        goto out;
1230 4ac8aacd Jes Sorensen
    }
1231 4ac8aacd Jes Sorensen
1232 c2abccec MORITA Kazutaka
    if (bs_n > 1 && out_baseimg) {
1233 15654a6d Jes Sorensen
        error_report("-B makes no sense when concatenating multiple input "
1234 15654a6d Jes Sorensen
                     "images");
1235 31ca34b8 Jes Sorensen
        ret = -1;
1236 31ca34b8 Jes Sorensen
        goto out;
1237 c2abccec MORITA Kazutaka
    }
1238 f8111c24 Dong Xu Wang
1239 6b837bc4 Jes Sorensen
    qemu_progress_print(0, 100);
1240 6b837bc4 Jes Sorensen
1241 7267c094 Anthony Liguori
    bs = g_malloc0(bs_n * sizeof(BlockDriverState *));
1242 926c2d23 balrog
1243 926c2d23 balrog
    total_sectors = 0;
1244 926c2d23 balrog
    for (bs_i = 0; bs_i < bs_n; bs_i++) {
1245 f382d43a Miroslav Rezanina
        bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS, true,
1246 f382d43a Miroslav Rezanina
                                 quiet);
1247 c2abccec MORITA Kazutaka
        if (!bs[bs_i]) {
1248 15654a6d Jes Sorensen
            error_report("Could not open '%s'", argv[optind + bs_i]);
1249 c2abccec MORITA Kazutaka
            ret = -1;
1250 c2abccec MORITA Kazutaka
            goto out;
1251 c2abccec MORITA Kazutaka
        }
1252 926c2d23 balrog
        bdrv_get_geometry(bs[bs_i], &bs_sectors);
1253 926c2d23 balrog
        total_sectors += bs_sectors;
1254 926c2d23 balrog
    }
1255 ea2384d3 bellard
1256 51ef6727 edison
    if (snapshot_name != NULL) {
1257 51ef6727 edison
        if (bs_n > 1) {
1258 6daf194d Markus Armbruster
            error_report("No support for concatenating multiple snapshot");
1259 51ef6727 edison
            ret = -1;
1260 51ef6727 edison
            goto out;
1261 51ef6727 edison
        }
1262 51ef6727 edison
        if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
1263 6daf194d Markus Armbruster
            error_report("Failed to load snapshot");
1264 51ef6727 edison
            ret = -1;
1265 51ef6727 edison
            goto out;
1266 51ef6727 edison
        }
1267 51ef6727 edison
    }
1268 51ef6727 edison
1269 efa84d43 Kevin Wolf
    /* Find driver and parse its options */
1270 ea2384d3 bellard
    drv = bdrv_find_format(out_fmt);
1271 c2abccec MORITA Kazutaka
    if (!drv) {
1272 15654a6d Jes Sorensen
        error_report("Unknown file format '%s'", out_fmt);
1273 c2abccec MORITA Kazutaka
        ret = -1;
1274 c2abccec MORITA Kazutaka
        goto out;
1275 c2abccec MORITA Kazutaka
    }
1276 efa84d43 Kevin Wolf
1277 98289620 Kevin Wolf
    proto_drv = bdrv_find_protocol(out_filename, true);
1278 c2abccec MORITA Kazutaka
    if (!proto_drv) {
1279 15654a6d Jes Sorensen
        error_report("Unknown protocol '%s'", out_filename);
1280 c2abccec MORITA Kazutaka
        ret = -1;
1281 c2abccec MORITA Kazutaka
        goto out;
1282 c2abccec MORITA Kazutaka
    }
1283 b50cbabc MORITA Kazutaka
1284 b50cbabc MORITA Kazutaka
    create_options = append_option_parameters(create_options,
1285 b50cbabc MORITA Kazutaka
                                              drv->create_options);
1286 b50cbabc MORITA Kazutaka
    create_options = append_option_parameters(create_options,
1287 b50cbabc MORITA Kazutaka
                                              proto_drv->create_options);
1288 db08adf5 Kevin Wolf
1289 efa84d43 Kevin Wolf
    if (options) {
1290 b50cbabc MORITA Kazutaka
        param = parse_option_parameters(options, create_options, param);
1291 efa84d43 Kevin Wolf
        if (param == NULL) {
1292 15654a6d Jes Sorensen
            error_report("Invalid options for file format '%s'.", out_fmt);
1293 c2abccec MORITA Kazutaka
            ret = -1;
1294 c2abccec MORITA Kazutaka
            goto out;
1295 efa84d43 Kevin Wolf
        }
1296 efa84d43 Kevin Wolf
    } else {
1297 b50cbabc MORITA Kazutaka
        param = parse_option_parameters("", create_options, param);
1298 efa84d43 Kevin Wolf
    }
1299 efa84d43 Kevin Wolf
1300 efa84d43 Kevin Wolf
    set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
1301 eec77d9e Jes Sorensen
    ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);
1302 c2abccec MORITA Kazutaka
    if (ret < 0) {
1303 c2abccec MORITA Kazutaka
        goto out;
1304 c2abccec MORITA Kazutaka
    }
1305 efa84d43 Kevin Wolf
1306 a18953fb Kevin Wolf
    /* Get backing file name if -o backing_file was used */
1307 a18953fb Kevin Wolf
    out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
1308 a18953fb Kevin Wolf
    if (out_baseimg_param) {
1309 a18953fb Kevin Wolf
        out_baseimg = out_baseimg_param->value.s;
1310 a18953fb Kevin Wolf
    }
1311 a18953fb Kevin Wolf
1312 efa84d43 Kevin Wolf
    /* Check if compression is supported */
1313 eec77d9e Jes Sorensen
    if (compress) {
1314 efa84d43 Kevin Wolf
        QEMUOptionParameter *encryption =
1315 efa84d43 Kevin Wolf
            get_option_parameter(param, BLOCK_OPT_ENCRYPT);
1316 41521fa4 Kevin Wolf
        QEMUOptionParameter *preallocation =
1317 41521fa4 Kevin Wolf
            get_option_parameter(param, BLOCK_OPT_PREALLOC);
1318 efa84d43 Kevin Wolf
1319 efa84d43 Kevin Wolf
        if (!drv->bdrv_write_compressed) {
1320 15654a6d Jes Sorensen
            error_report("Compression not supported for this file format");
1321 c2abccec MORITA Kazutaka
            ret = -1;
1322 c2abccec MORITA Kazutaka
            goto out;
1323 efa84d43 Kevin Wolf
        }
1324 efa84d43 Kevin Wolf
1325 efa84d43 Kevin Wolf
        if (encryption && encryption->value.n) {
1326 15654a6d Jes Sorensen
            error_report("Compression and encryption not supported at "
1327 15654a6d Jes Sorensen
                         "the same time");
1328 c2abccec MORITA Kazutaka
            ret = -1;
1329 c2abccec MORITA Kazutaka
            goto out;
1330 efa84d43 Kevin Wolf
        }
1331 41521fa4 Kevin Wolf
1332 41521fa4 Kevin Wolf
        if (preallocation && preallocation->value.s
1333 41521fa4 Kevin Wolf
            && strcmp(preallocation->value.s, "off"))
1334 41521fa4 Kevin Wolf
        {
1335 41521fa4 Kevin Wolf
            error_report("Compression and preallocation not supported at "
1336 41521fa4 Kevin Wolf
                         "the same time");
1337 41521fa4 Kevin Wolf
            ret = -1;
1338 41521fa4 Kevin Wolf
            goto out;
1339 41521fa4 Kevin Wolf
        }
1340 efa84d43 Kevin Wolf
    }
1341 efa84d43 Kevin Wolf
1342 b2e10493 Alexandre Derumier
    if (!skip_create) {
1343 b2e10493 Alexandre Derumier
        /* Create the new image */
1344 b2e10493 Alexandre Derumier
        ret = bdrv_create(drv, out_filename, param);
1345 b2e10493 Alexandre Derumier
        if (ret < 0) {
1346 b2e10493 Alexandre Derumier
            if (ret == -ENOTSUP) {
1347 b2e10493 Alexandre Derumier
                error_report("Formatting not supported for file format '%s'",
1348 b2e10493 Alexandre Derumier
                             out_fmt);
1349 b2e10493 Alexandre Derumier
            } else if (ret == -EFBIG) {
1350 b2e10493 Alexandre Derumier
                error_report("The image size is too large for file format '%s'",
1351 b2e10493 Alexandre Derumier
                             out_fmt);
1352 b2e10493 Alexandre Derumier
            } else {
1353 b2e10493 Alexandre Derumier
                error_report("%s: error while converting %s: %s",
1354 b2e10493 Alexandre Derumier
                             out_filename, out_fmt, strerror(-ret));
1355 b2e10493 Alexandre Derumier
            }
1356 b2e10493 Alexandre Derumier
            goto out;
1357 ea2384d3 bellard
        }
1358 ea2384d3 bellard
    }
1359 3b46e624 ths
1360 661a0f71 Federico Simoncelli
    flags = BDRV_O_RDWR;
1361 c3993cdc Stefan Hajnoczi
    ret = bdrv_parse_cache_flags(cache, &flags);
1362 661a0f71 Federico Simoncelli
    if (ret < 0) {
1363 661a0f71 Federico Simoncelli
        error_report("Invalid cache option: %s", cache);
1364 661a0f71 Federico Simoncelli
        return -1;
1365 661a0f71 Federico Simoncelli
    }
1366 661a0f71 Federico Simoncelli
1367 f382d43a Miroslav Rezanina
    out_bs = bdrv_new_open(out_filename, out_fmt, flags, true, quiet);
1368 c2abccec MORITA Kazutaka
    if (!out_bs) {
1369 c2abccec MORITA Kazutaka
        ret = -1;
1370 c2abccec MORITA Kazutaka
        goto out;
1371 c2abccec MORITA Kazutaka
    }
1372 ea2384d3 bellard
1373 926c2d23 balrog
    bs_i = 0;
1374 926c2d23 balrog
    bs_offset = 0;
1375 926c2d23 balrog
    bdrv_get_geometry(bs[0], &bs_sectors);
1376 bb1c0597 Kevin Wolf
    buf = qemu_blockalign(out_bs, IO_BUF_SIZE);
1377 926c2d23 balrog
1378 b2e10493 Alexandre Derumier
    if (skip_create) {
1379 b2e10493 Alexandre Derumier
        int64_t output_length = bdrv_getlength(out_bs);
1380 b2e10493 Alexandre Derumier
        if (output_length < 0) {
1381 b2e10493 Alexandre Derumier
            error_report("unable to get output image length: %s\n",
1382 b2e10493 Alexandre Derumier
                         strerror(-output_length));
1383 b2e10493 Alexandre Derumier
            ret = -1;
1384 b2e10493 Alexandre Derumier
            goto out;
1385 b2e10493 Alexandre Derumier
        } else if (output_length < total_sectors << BDRV_SECTOR_BITS) {
1386 b2e10493 Alexandre Derumier
            error_report("output file is smaller than input file");
1387 b2e10493 Alexandre Derumier
            ret = -1;
1388 b2e10493 Alexandre Derumier
            goto out;
1389 b2e10493 Alexandre Derumier
        }
1390 b2e10493 Alexandre Derumier
    }
1391 b2e10493 Alexandre Derumier
1392 eec77d9e Jes Sorensen
    if (compress) {
1393 c2abccec MORITA Kazutaka
        ret = bdrv_get_info(out_bs, &bdi);
1394 c2abccec MORITA Kazutaka
        if (ret < 0) {
1395 15654a6d Jes Sorensen
            error_report("could not get block driver info");
1396 c2abccec MORITA Kazutaka
            goto out;
1397 c2abccec MORITA Kazutaka
        }
1398 faea38e7 bellard
        cluster_size = bdi.cluster_size;
1399 c2abccec MORITA Kazutaka
        if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
1400 15654a6d Jes Sorensen
            error_report("invalid cluster size");
1401 c2abccec MORITA Kazutaka
            ret = -1;
1402 c2abccec MORITA Kazutaka
            goto out;
1403 c2abccec MORITA Kazutaka
        }
1404 ea2384d3 bellard
        cluster_sectors = cluster_size >> 9;
1405 ea2384d3 bellard
        sector_num = 0;
1406 6b837bc4 Jes Sorensen
1407 6b837bc4 Jes Sorensen
        nb_sectors = total_sectors;
1408 1f710495 Kevin Wolf
        if (nb_sectors != 0) {
1409 1f710495 Kevin Wolf
            local_progress = (float)100 /
1410 1f710495 Kevin Wolf
                (nb_sectors / MIN(nb_sectors, cluster_sectors));
1411 1f710495 Kevin Wolf
        }
1412 6b837bc4 Jes Sorensen
1413 ea2384d3 bellard
        for(;;) {
1414 926c2d23 balrog
            int64_t bs_num;
1415 926c2d23 balrog
            int remainder;
1416 926c2d23 balrog
            uint8_t *buf2;
1417 926c2d23 balrog
1418 ea2384d3 bellard
            nb_sectors = total_sectors - sector_num;
1419 ea2384d3 bellard
            if (nb_sectors <= 0)
1420 ea2384d3 bellard
                break;
1421 ea2384d3 bellard
            if (nb_sectors >= cluster_sectors)
1422 ea2384d3 bellard
                n = cluster_sectors;
1423 ea2384d3 bellard
            else
1424 ea2384d3 bellard
                n = nb_sectors;
1425 926c2d23 balrog
1426 926c2d23 balrog
            bs_num = sector_num - bs_offset;
1427 926c2d23 balrog
            assert (bs_num >= 0);
1428 926c2d23 balrog
            remainder = n;
1429 926c2d23 balrog
            buf2 = buf;
1430 926c2d23 balrog
            while (remainder > 0) {
1431 926c2d23 balrog
                int nlow;
1432 926c2d23 balrog
                while (bs_num == bs_sectors) {
1433 926c2d23 balrog
                    bs_i++;
1434 926c2d23 balrog
                    assert (bs_i < bs_n);
1435 926c2d23 balrog
                    bs_offset += bs_sectors;
1436 926c2d23 balrog
                    bdrv_get_geometry(bs[bs_i], &bs_sectors);
1437 926c2d23 balrog
                    bs_num = 0;
1438 0bfcd599 Blue Swirl
                    /* printf("changing part: sector_num=%" PRId64 ", "
1439 0bfcd599 Blue Swirl
                       "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64
1440 0bfcd599 Blue Swirl
                       "\n", sector_num, bs_i, bs_offset, bs_sectors); */
1441 926c2d23 balrog
                }
1442 926c2d23 balrog
                assert (bs_num < bs_sectors);
1443 926c2d23 balrog
1444 926c2d23 balrog
                nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
1445 926c2d23 balrog
1446 c2abccec MORITA Kazutaka
                ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
1447 c2abccec MORITA Kazutaka
                if (ret < 0) {
1448 3fba9d81 Stefan Hajnoczi
                    error_report("error while reading sector %" PRId64 ": %s",
1449 3fba9d81 Stefan Hajnoczi
                                 bs_num, strerror(-ret));
1450 c2abccec MORITA Kazutaka
                    goto out;
1451 c2abccec MORITA Kazutaka
                }
1452 926c2d23 balrog
1453 926c2d23 balrog
                buf2 += nlow * 512;
1454 926c2d23 balrog
                bs_num += nlow;
1455 926c2d23 balrog
1456 926c2d23 balrog
                remainder -= nlow;
1457 926c2d23 balrog
            }
1458 926c2d23 balrog
            assert (remainder == 0);
1459 926c2d23 balrog
1460 54f106d5 Stefan Hajnoczi
            if (!buffer_is_zero(buf, n * BDRV_SECTOR_SIZE)) {
1461 54f106d5 Stefan Hajnoczi
                ret = bdrv_write_compressed(out_bs, sector_num, buf, n);
1462 c2abccec MORITA Kazutaka
                if (ret != 0) {
1463 3fba9d81 Stefan Hajnoczi
                    error_report("error while compressing sector %" PRId64
1464 3fba9d81 Stefan Hajnoczi
                                 ": %s", sector_num, strerror(-ret));
1465 c2abccec MORITA Kazutaka
                    goto out;
1466 c2abccec MORITA Kazutaka
                }
1467 ea2384d3 bellard
            }
1468 ea2384d3 bellard
            sector_num += n;
1469 6b837bc4 Jes Sorensen
            qemu_progress_print(local_progress, 100);
1470 ea2384d3 bellard
        }
1471 faea38e7 bellard
        /* signal EOF to align */
1472 faea38e7 bellard
        bdrv_write_compressed(out_bs, 0, NULL, 0);
1473 ea2384d3 bellard
    } else {
1474 f2feebbd Kevin Wolf
        int has_zero_init = bdrv_has_zero_init(out_bs);
1475 f2feebbd Kevin Wolf
1476 f58c7b35 ths
        sector_num = 0; // total number of sectors converted so far
1477 6b837bc4 Jes Sorensen
        nb_sectors = total_sectors - sector_num;
1478 1f710495 Kevin Wolf
        if (nb_sectors != 0) {
1479 1f710495 Kevin Wolf
            local_progress = (float)100 /
1480 1f710495 Kevin Wolf
                (nb_sectors / MIN(nb_sectors, IO_BUF_SIZE / 512));
1481 1f710495 Kevin Wolf
        }
1482 6b837bc4 Jes Sorensen
1483 ea2384d3 bellard
        for(;;) {
1484 ea2384d3 bellard
            nb_sectors = total_sectors - sector_num;
1485 b8fb60da Jes Sorensen
            if (nb_sectors <= 0) {
1486 ea2384d3 bellard
                break;
1487 b8fb60da Jes Sorensen
            }
1488 b8fb60da Jes Sorensen
            if (nb_sectors >= (IO_BUF_SIZE / 512)) {
1489 ea2384d3 bellard
                n = (IO_BUF_SIZE / 512);
1490 b8fb60da Jes Sorensen
            } else {
1491 ea2384d3 bellard
                n = nb_sectors;
1492 b8fb60da Jes Sorensen
            }
1493 926c2d23 balrog
1494 926c2d23 balrog
            while (sector_num - bs_offset >= bs_sectors) {
1495 926c2d23 balrog
                bs_i ++;
1496 926c2d23 balrog
                assert (bs_i < bs_n);
1497 926c2d23 balrog
                bs_offset += bs_sectors;
1498 926c2d23 balrog
                bdrv_get_geometry(bs[bs_i], &bs_sectors);
1499 0bfcd599 Blue Swirl
                /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "
1500 0bfcd599 Blue Swirl
                  "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",
1501 926c2d23 balrog
                   sector_num, bs_i, bs_offset, bs_sectors); */
1502 926c2d23 balrog
            }
1503 926c2d23 balrog
1504 b8fb60da Jes Sorensen
            if (n > bs_offset + bs_sectors - sector_num) {
1505 926c2d23 balrog
                n = bs_offset + bs_sectors - sector_num;
1506 b8fb60da Jes Sorensen
            }
1507 926c2d23 balrog
1508 e4a86f88 Paolo Bonzini
            /* If the output image is being created as a copy on write image,
1509 e4a86f88 Paolo Bonzini
               assume that sectors which are unallocated in the input image
1510 e4a86f88 Paolo Bonzini
               are present in both the output's and input's base images (no
1511 e4a86f88 Paolo Bonzini
               need to copy them). */
1512 e4a86f88 Paolo Bonzini
            if (out_baseimg) {
1513 e4a86f88 Paolo Bonzini
                ret = bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
1514 e4a86f88 Paolo Bonzini
                                        n, &n1);
1515 e4a86f88 Paolo Bonzini
                if (ret < 0) {
1516 e4a86f88 Paolo Bonzini
                    error_report("error while reading metadata for sector "
1517 e4a86f88 Paolo Bonzini
                                 "%" PRId64 ": %s",
1518 e4a86f88 Paolo Bonzini
                                 sector_num - bs_offset, strerror(-ret));
1519 e4a86f88 Paolo Bonzini
                    goto out;
1520 e4a86f88 Paolo Bonzini
                }
1521 e4a86f88 Paolo Bonzini
                if (!ret) {
1522 e4a86f88 Paolo Bonzini
                    sector_num += n1;
1523 e4a86f88 Paolo Bonzini
                    continue;
1524 93c65b47 aliguori
                }
1525 e4a86f88 Paolo Bonzini
                /* The next 'n1' sectors are allocated in the input image. Copy
1526 e4a86f88 Paolo Bonzini
                   only those as they may be followed by unallocated sectors. */
1527 e4a86f88 Paolo Bonzini
                n = n1;
1528 93c65b47 aliguori
            } else {
1529 93c65b47 aliguori
                n1 = n;
1530 f58c7b35 ths
            }
1531 f58c7b35 ths
1532 c2abccec MORITA Kazutaka
            ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
1533 c2abccec MORITA Kazutaka
            if (ret < 0) {
1534 3fba9d81 Stefan Hajnoczi
                error_report("error while reading sector %" PRId64 ": %s",
1535 3fba9d81 Stefan Hajnoczi
                             sector_num - bs_offset, strerror(-ret));
1536 c2abccec MORITA Kazutaka
                goto out;
1537 c2abccec MORITA Kazutaka
            }
1538 ea2384d3 bellard
            /* NOTE: at the same time we convert, we do not write zero
1539 ea2384d3 bellard
               sectors to have a chance to compress the image. Ideally, we
1540 ea2384d3 bellard
               should add a specific call to have the info to go faster */
1541 ea2384d3 bellard
            buf1 = buf;
1542 ea2384d3 bellard
            while (n > 0) {
1543 11212d8f Paolo Bonzini
                if (!has_zero_init ||
1544 a22f123c Kevin Wolf
                    is_allocated_sectors_min(buf1, n, &n1, min_sparse)) {
1545 c2abccec MORITA Kazutaka
                    ret = bdrv_write(out_bs, sector_num, buf1, n1);
1546 c2abccec MORITA Kazutaka
                    if (ret < 0) {
1547 3fba9d81 Stefan Hajnoczi
                        error_report("error while writing sector %" PRId64
1548 3fba9d81 Stefan Hajnoczi
                                     ": %s", sector_num, strerror(-ret));
1549 c2abccec MORITA Kazutaka
                        goto out;
1550 c2abccec MORITA Kazutaka
                    }
1551 ea2384d3 bellard
                }
1552 ea2384d3 bellard
                sector_num += n1;
1553 ea2384d3 bellard
                n -= n1;
1554 ea2384d3 bellard
                buf1 += n1 * 512;
1555 ea2384d3 bellard
            }
1556 6b837bc4 Jes Sorensen
            qemu_progress_print(local_progress, 100);
1557 ea2384d3 bellard
        }
1558 ea2384d3 bellard
    }
1559 c2abccec MORITA Kazutaka
out:
1560 6b837bc4 Jes Sorensen
    qemu_progress_end();
1561 c2abccec MORITA Kazutaka
    free_option_parameters(create_options);
1562 c2abccec MORITA Kazutaka
    free_option_parameters(param);
1563 bb1c0597 Kevin Wolf
    qemu_vfree(buf);
1564 c2abccec MORITA Kazutaka
    if (out_bs) {
1565 4f6fd349 Fam Zheng
        bdrv_unref(out_bs);
1566 c2abccec MORITA Kazutaka
    }
1567 31ca34b8 Jes Sorensen
    if (bs) {
1568 31ca34b8 Jes Sorensen
        for (bs_i = 0; bs_i < bs_n; bs_i++) {
1569 31ca34b8 Jes Sorensen
            if (bs[bs_i]) {
1570 4f6fd349 Fam Zheng
                bdrv_unref(bs[bs_i]);
1571 31ca34b8 Jes Sorensen
            }
1572 c2abccec MORITA Kazutaka
        }
1573 7267c094 Anthony Liguori
        g_free(bs);
1574 c2abccec MORITA Kazutaka
    }
1575 c2abccec MORITA Kazutaka
    if (ret) {
1576 c2abccec MORITA Kazutaka
        return 1;
1577 c2abccec MORITA Kazutaka
    }
1578 ea2384d3 bellard
    return 0;
1579 ea2384d3 bellard
}
1580 ea2384d3 bellard
1581 57d1a2b6 bellard
1582 faea38e7 bellard
static void dump_snapshots(BlockDriverState *bs)
1583 faea38e7 bellard
{
1584 faea38e7 bellard
    QEMUSnapshotInfo *sn_tab, *sn;
1585 faea38e7 bellard
    int nb_sns, i;
1586 faea38e7 bellard
1587 faea38e7 bellard
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1588 faea38e7 bellard
    if (nb_sns <= 0)
1589 faea38e7 bellard
        return;
1590 faea38e7 bellard
    printf("Snapshot list:\n");
1591 5b917044 Wenchao Xia
    bdrv_snapshot_dump(fprintf, stdout, NULL);
1592 5b917044 Wenchao Xia
    printf("\n");
1593 faea38e7 bellard
    for(i = 0; i < nb_sns; i++) {
1594 faea38e7 bellard
        sn = &sn_tab[i];
1595 5b917044 Wenchao Xia
        bdrv_snapshot_dump(fprintf, stdout, sn);
1596 5b917044 Wenchao Xia
        printf("\n");
1597 faea38e7 bellard
    }
1598 7267c094 Anthony Liguori
    g_free(sn_tab);
1599 faea38e7 bellard
}
1600 faea38e7 bellard
1601 9699bf0d Stefan Hajnoczi
static void dump_json_image_info_list(ImageInfoList *list)
1602 9699bf0d Stefan Hajnoczi
{
1603 9699bf0d Stefan Hajnoczi
    Error *errp = NULL;
1604 9699bf0d Stefan Hajnoczi
    QString *str;
1605 9699bf0d Stefan Hajnoczi
    QmpOutputVisitor *ov = qmp_output_visitor_new();
1606 9699bf0d Stefan Hajnoczi
    QObject *obj;
1607 9699bf0d Stefan Hajnoczi
    visit_type_ImageInfoList(qmp_output_get_visitor(ov),
1608 9699bf0d Stefan Hajnoczi
                             &list, NULL, &errp);
1609 9699bf0d Stefan Hajnoczi
    obj = qmp_output_get_qobject(ov);
1610 9699bf0d Stefan Hajnoczi
    str = qobject_to_json_pretty(obj);
1611 9699bf0d Stefan Hajnoczi
    assert(str != NULL);
1612 9699bf0d Stefan Hajnoczi
    printf("%s\n", qstring_get_str(str));
1613 9699bf0d Stefan Hajnoczi
    qobject_decref(obj);
1614 9699bf0d Stefan Hajnoczi
    qmp_output_visitor_cleanup(ov);
1615 9699bf0d Stefan Hajnoczi
    QDECREF(str);
1616 9699bf0d Stefan Hajnoczi
}
1617 9699bf0d Stefan Hajnoczi
1618 c054b3fd Benoît Canet
static void dump_json_image_info(ImageInfo *info)
1619 c054b3fd Benoît Canet
{
1620 c054b3fd Benoît Canet
    Error *errp = NULL;
1621 c054b3fd Benoît Canet
    QString *str;
1622 c054b3fd Benoît Canet
    QmpOutputVisitor *ov = qmp_output_visitor_new();
1623 c054b3fd Benoît Canet
    QObject *obj;
1624 c054b3fd Benoît Canet
    visit_type_ImageInfo(qmp_output_get_visitor(ov),
1625 c054b3fd Benoît Canet
                         &info, NULL, &errp);
1626 c054b3fd Benoît Canet
    obj = qmp_output_get_qobject(ov);
1627 c054b3fd Benoît Canet
    str = qobject_to_json_pretty(obj);
1628 c054b3fd Benoît Canet
    assert(str != NULL);
1629 c054b3fd Benoît Canet
    printf("%s\n", qstring_get_str(str));
1630 c054b3fd Benoît Canet
    qobject_decref(obj);
1631 c054b3fd Benoît Canet
    qmp_output_visitor_cleanup(ov);
1632 c054b3fd Benoît Canet
    QDECREF(str);
1633 c054b3fd Benoît Canet
}
1634 c054b3fd Benoît Canet
1635 9699bf0d Stefan Hajnoczi
static void dump_human_image_info_list(ImageInfoList *list)
1636 9699bf0d Stefan Hajnoczi
{
1637 9699bf0d Stefan Hajnoczi
    ImageInfoList *elem;
1638 9699bf0d Stefan Hajnoczi
    bool delim = false;
1639 9699bf0d Stefan Hajnoczi
1640 9699bf0d Stefan Hajnoczi
    for (elem = list; elem; elem = elem->next) {
1641 9699bf0d Stefan Hajnoczi
        if (delim) {
1642 9699bf0d Stefan Hajnoczi
            printf("\n");
1643 9699bf0d Stefan Hajnoczi
        }
1644 9699bf0d Stefan Hajnoczi
        delim = true;
1645 9699bf0d Stefan Hajnoczi
1646 5b917044 Wenchao Xia
        bdrv_image_info_dump(fprintf, stdout, elem->value);
1647 9699bf0d Stefan Hajnoczi
    }
1648 9699bf0d Stefan Hajnoczi
}
1649 9699bf0d Stefan Hajnoczi
1650 9699bf0d Stefan Hajnoczi
static gboolean str_equal_func(gconstpointer a, gconstpointer b)
1651 9699bf0d Stefan Hajnoczi
{
1652 9699bf0d Stefan Hajnoczi
    return strcmp(a, b) == 0;
1653 9699bf0d Stefan Hajnoczi
}
1654 9699bf0d Stefan Hajnoczi
1655 9699bf0d Stefan Hajnoczi
/**
1656 9699bf0d Stefan Hajnoczi
 * Open an image file chain and return an ImageInfoList
1657 9699bf0d Stefan Hajnoczi
 *
1658 9699bf0d Stefan Hajnoczi
 * @filename: topmost image filename
1659 9699bf0d Stefan Hajnoczi
 * @fmt: topmost image format (may be NULL to autodetect)
1660 9699bf0d Stefan Hajnoczi
 * @chain: true  - enumerate entire backing file chain
1661 9699bf0d Stefan Hajnoczi
 *         false - only topmost image file
1662 9699bf0d Stefan Hajnoczi
 *
1663 9699bf0d Stefan Hajnoczi
 * Returns a list of ImageInfo objects or NULL if there was an error opening an
1664 9699bf0d Stefan Hajnoczi
 * image file.  If there was an error a message will have been printed to
1665 9699bf0d Stefan Hajnoczi
 * stderr.
1666 9699bf0d Stefan Hajnoczi
 */
1667 9699bf0d Stefan Hajnoczi
static ImageInfoList *collect_image_info_list(const char *filename,
1668 9699bf0d Stefan Hajnoczi
                                              const char *fmt,
1669 9699bf0d Stefan Hajnoczi
                                              bool chain)
1670 9699bf0d Stefan Hajnoczi
{
1671 9699bf0d Stefan Hajnoczi
    ImageInfoList *head = NULL;
1672 9699bf0d Stefan Hajnoczi
    ImageInfoList **last = &head;
1673 9699bf0d Stefan Hajnoczi
    GHashTable *filenames;
1674 43526ec8 Wenchao Xia
    Error *err = NULL;
1675 9699bf0d Stefan Hajnoczi
1676 9699bf0d Stefan Hajnoczi
    filenames = g_hash_table_new_full(g_str_hash, str_equal_func, NULL, NULL);
1677 9699bf0d Stefan Hajnoczi
1678 9699bf0d Stefan Hajnoczi
    while (filename) {
1679 9699bf0d Stefan Hajnoczi
        BlockDriverState *bs;
1680 9699bf0d Stefan Hajnoczi
        ImageInfo *info;
1681 9699bf0d Stefan Hajnoczi
        ImageInfoList *elem;
1682 9699bf0d Stefan Hajnoczi
1683 9699bf0d Stefan Hajnoczi
        if (g_hash_table_lookup_extended(filenames, filename, NULL, NULL)) {
1684 9699bf0d Stefan Hajnoczi
            error_report("Backing file '%s' creates an infinite loop.",
1685 9699bf0d Stefan Hajnoczi
                         filename);
1686 9699bf0d Stefan Hajnoczi
            goto err;
1687 9699bf0d Stefan Hajnoczi
        }
1688 9699bf0d Stefan Hajnoczi
        g_hash_table_insert(filenames, (gpointer)filename, NULL);
1689 9699bf0d Stefan Hajnoczi
1690 9699bf0d Stefan Hajnoczi
        bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING,
1691 f382d43a Miroslav Rezanina
                           false, false);
1692 9699bf0d Stefan Hajnoczi
        if (!bs) {
1693 9699bf0d Stefan Hajnoczi
            goto err;
1694 9699bf0d Stefan Hajnoczi
        }
1695 9699bf0d Stefan Hajnoczi
1696 43526ec8 Wenchao Xia
        bdrv_query_image_info(bs, &info, &err);
1697 43526ec8 Wenchao Xia
        if (error_is_set(&err)) {
1698 43526ec8 Wenchao Xia
            error_report("%s", error_get_pretty(err));
1699 43526ec8 Wenchao Xia
            error_free(err);
1700 43526ec8 Wenchao Xia
            goto err;
1701 fb0ed453 Wenchao Xia
        }
1702 9699bf0d Stefan Hajnoczi
1703 9699bf0d Stefan Hajnoczi
        elem = g_new0(ImageInfoList, 1);
1704 9699bf0d Stefan Hajnoczi
        elem->value = info;
1705 9699bf0d Stefan Hajnoczi
        *last = elem;
1706 9699bf0d Stefan Hajnoczi
        last = &elem->next;
1707 9699bf0d Stefan Hajnoczi
1708 4f6fd349 Fam Zheng
        bdrv_unref(bs);
1709 9699bf0d Stefan Hajnoczi
1710 9699bf0d Stefan Hajnoczi
        filename = fmt = NULL;
1711 9699bf0d Stefan Hajnoczi
        if (chain) {
1712 9699bf0d Stefan Hajnoczi
            if (info->has_full_backing_filename) {
1713 9699bf0d Stefan Hajnoczi
                filename = info->full_backing_filename;
1714 9699bf0d Stefan Hajnoczi
            } else if (info->has_backing_filename) {
1715 9699bf0d Stefan Hajnoczi
                filename = info->backing_filename;
1716 9699bf0d Stefan Hajnoczi
            }
1717 9699bf0d Stefan Hajnoczi
            if (info->has_backing_filename_format) {
1718 9699bf0d Stefan Hajnoczi
                fmt = info->backing_filename_format;
1719 9699bf0d Stefan Hajnoczi
            }
1720 9699bf0d Stefan Hajnoczi
        }
1721 9699bf0d Stefan Hajnoczi
    }
1722 9699bf0d Stefan Hajnoczi
    g_hash_table_destroy(filenames);
1723 9699bf0d Stefan Hajnoczi
    return head;
1724 9699bf0d Stefan Hajnoczi
1725 9699bf0d Stefan Hajnoczi
err:
1726 9699bf0d Stefan Hajnoczi
    qapi_free_ImageInfoList(head);
1727 9699bf0d Stefan Hajnoczi
    g_hash_table_destroy(filenames);
1728 9699bf0d Stefan Hajnoczi
    return NULL;
1729 9699bf0d Stefan Hajnoczi
}
1730 9699bf0d Stefan Hajnoczi
1731 c054b3fd Benoît Canet
static int img_info(int argc, char **argv)
1732 c054b3fd Benoît Canet
{
1733 c054b3fd Benoît Canet
    int c;
1734 c054b3fd Benoît Canet
    OutputFormat output_format = OFORMAT_HUMAN;
1735 9699bf0d Stefan Hajnoczi
    bool chain = false;
1736 c054b3fd Benoît Canet
    const char *filename, *fmt, *output;
1737 9699bf0d Stefan Hajnoczi
    ImageInfoList *list;
1738 c054b3fd Benoît Canet
1739 ea2384d3 bellard
    fmt = NULL;
1740 c054b3fd Benoît Canet
    output = NULL;
1741 ea2384d3 bellard
    for(;;) {
1742 c054b3fd Benoît Canet
        int option_index = 0;
1743 c054b3fd Benoît Canet
        static const struct option long_options[] = {
1744 c054b3fd Benoît Canet
            {"help", no_argument, 0, 'h'},
1745 c054b3fd Benoît Canet
            {"format", required_argument, 0, 'f'},
1746 c054b3fd Benoît Canet
            {"output", required_argument, 0, OPTION_OUTPUT},
1747 9699bf0d Stefan Hajnoczi
            {"backing-chain", no_argument, 0, OPTION_BACKING_CHAIN},
1748 c054b3fd Benoît Canet
            {0, 0, 0, 0}
1749 c054b3fd Benoît Canet
        };
1750 c054b3fd Benoît Canet
        c = getopt_long(argc, argv, "f:h",
1751 c054b3fd Benoît Canet
                        long_options, &option_index);
1752 b8fb60da Jes Sorensen
        if (c == -1) {
1753 ea2384d3 bellard
            break;
1754 b8fb60da Jes Sorensen
        }
1755 ea2384d3 bellard
        switch(c) {
1756 ef87394c Jes Sorensen
        case '?':
1757 ea2384d3 bellard
        case 'h':
1758 ea2384d3 bellard
            help();
1759 ea2384d3 bellard
            break;
1760 ea2384d3 bellard
        case 'f':
1761 ea2384d3 bellard
            fmt = optarg;
1762 ea2384d3 bellard
            break;
1763 c054b3fd Benoît Canet
        case OPTION_OUTPUT:
1764 c054b3fd Benoît Canet
            output = optarg;
1765 c054b3fd Benoît Canet
            break;
1766 9699bf0d Stefan Hajnoczi
        case OPTION_BACKING_CHAIN:
1767 9699bf0d Stefan Hajnoczi
            chain = true;
1768 9699bf0d Stefan Hajnoczi
            break;
1769 ea2384d3 bellard
        }
1770 ea2384d3 bellard
    }
1771 fc11eb26 Kevin Wolf
    if (optind != argc - 1) {
1772 ea2384d3 bellard
        help();
1773 b8fb60da Jes Sorensen
    }
1774 ea2384d3 bellard
    filename = argv[optind++];
1775 ea2384d3 bellard
1776 c054b3fd Benoît Canet
    if (output && !strcmp(output, "json")) {
1777 c054b3fd Benoît Canet
        output_format = OFORMAT_JSON;
1778 c054b3fd Benoît Canet
    } else if (output && !strcmp(output, "human")) {
1779 c054b3fd Benoît Canet
        output_format = OFORMAT_HUMAN;
1780 c054b3fd Benoît Canet
    } else if (output) {
1781 c054b3fd Benoît Canet
        error_report("--output must be used with human or json as argument.");
1782 c2abccec MORITA Kazutaka
        return 1;
1783 c2abccec MORITA Kazutaka
    }
1784 c054b3fd Benoît Canet
1785 9699bf0d Stefan Hajnoczi
    list = collect_image_info_list(filename, fmt, chain);
1786 9699bf0d Stefan Hajnoczi
    if (!list) {
1787 c2abccec MORITA Kazutaka
        return 1;
1788 faea38e7 bellard
    }
1789 c054b3fd Benoît Canet
1790 c054b3fd Benoît Canet
    switch (output_format) {
1791 c054b3fd Benoît Canet
    case OFORMAT_HUMAN:
1792 9699bf0d Stefan Hajnoczi
        dump_human_image_info_list(list);
1793 c054b3fd Benoît Canet
        break;
1794 c054b3fd Benoît Canet
    case OFORMAT_JSON:
1795 9699bf0d Stefan Hajnoczi
        if (chain) {
1796 9699bf0d Stefan Hajnoczi
            dump_json_image_info_list(list);
1797 9699bf0d Stefan Hajnoczi
        } else {
1798 9699bf0d Stefan Hajnoczi
            dump_json_image_info(list->value);
1799 9699bf0d Stefan Hajnoczi
        }
1800 c054b3fd Benoît Canet
        break;
1801 faea38e7 bellard
    }
1802 c054b3fd Benoît Canet
1803 9699bf0d Stefan Hajnoczi
    qapi_free_ImageInfoList(list);
1804 ea2384d3 bellard
    return 0;
1805 ea2384d3 bellard
}
1806 ea2384d3 bellard
1807 4c93a13b Paolo Bonzini
1808 4c93a13b Paolo Bonzini
typedef struct MapEntry {
1809 4c93a13b Paolo Bonzini
    int flags;
1810 4c93a13b Paolo Bonzini
    int depth;
1811 4c93a13b Paolo Bonzini
    int64_t start;
1812 4c93a13b Paolo Bonzini
    int64_t length;
1813 4c93a13b Paolo Bonzini
    int64_t offset;
1814 4c93a13b Paolo Bonzini
    BlockDriverState *bs;
1815 4c93a13b Paolo Bonzini
} MapEntry;
1816 4c93a13b Paolo Bonzini
1817 4c93a13b Paolo Bonzini
static void dump_map_entry(OutputFormat output_format, MapEntry *e,
1818 4c93a13b Paolo Bonzini
                           MapEntry *next)
1819 4c93a13b Paolo Bonzini
{
1820 4c93a13b Paolo Bonzini
    switch (output_format) {
1821 4c93a13b Paolo Bonzini
    case OFORMAT_HUMAN:
1822 4c93a13b Paolo Bonzini
        if ((e->flags & BDRV_BLOCK_DATA) &&
1823 4c93a13b Paolo Bonzini
            !(e->flags & BDRV_BLOCK_OFFSET_VALID)) {
1824 4c93a13b Paolo Bonzini
            error_report("File contains external, encrypted or compressed clusters.");
1825 4c93a13b Paolo Bonzini
            exit(1);
1826 4c93a13b Paolo Bonzini
        }
1827 4c93a13b Paolo Bonzini
        if ((e->flags & (BDRV_BLOCK_DATA|BDRV_BLOCK_ZERO)) == BDRV_BLOCK_DATA) {
1828 4c93a13b Paolo Bonzini
            printf("%#-16"PRIx64"%#-16"PRIx64"%#-16"PRIx64"%s\n",
1829 4c93a13b Paolo Bonzini
                   e->start, e->length, e->offset, e->bs->filename);
1830 4c93a13b Paolo Bonzini
        }
1831 4c93a13b Paolo Bonzini
        /* This format ignores the distinction between 0, ZERO and ZERO|DATA.
1832 4c93a13b Paolo Bonzini
         * Modify the flags here to allow more coalescing.
1833 4c93a13b Paolo Bonzini
         */
1834 4c93a13b Paolo Bonzini
        if (next &&
1835 4c93a13b Paolo Bonzini
            (next->flags & (BDRV_BLOCK_DATA|BDRV_BLOCK_ZERO)) != BDRV_BLOCK_DATA) {
1836 4c93a13b Paolo Bonzini
            next->flags &= ~BDRV_BLOCK_DATA;
1837 4c93a13b Paolo Bonzini
            next->flags |= BDRV_BLOCK_ZERO;
1838 4c93a13b Paolo Bonzini
        }
1839 4c93a13b Paolo Bonzini
        break;
1840 4c93a13b Paolo Bonzini
    case OFORMAT_JSON:
1841 4c93a13b Paolo Bonzini
        printf("%s{ \"start\": %"PRId64", \"length\": %"PRId64", \"depth\": %d,"
1842 4c93a13b Paolo Bonzini
               " \"zero\": %s, \"data\": %s",
1843 4c93a13b Paolo Bonzini
               (e->start == 0 ? "[" : ",\n"),
1844 4c93a13b Paolo Bonzini
               e->start, e->length, e->depth,
1845 4c93a13b Paolo Bonzini
               (e->flags & BDRV_BLOCK_ZERO) ? "true" : "false",
1846 4c93a13b Paolo Bonzini
               (e->flags & BDRV_BLOCK_DATA) ? "true" : "false");
1847 4c93a13b Paolo Bonzini
        if (e->flags & BDRV_BLOCK_OFFSET_VALID) {
1848 4c93a13b Paolo Bonzini
            printf(", 'offset': %"PRId64"", e->offset);
1849 4c93a13b Paolo Bonzini
        }
1850 4c93a13b Paolo Bonzini
        putchar('}');
1851 4c93a13b Paolo Bonzini
1852 4c93a13b Paolo Bonzini
        if (!next) {
1853 4c93a13b Paolo Bonzini
            printf("]\n");
1854 4c93a13b Paolo Bonzini
        }
1855 4c93a13b Paolo Bonzini
        break;
1856 4c93a13b Paolo Bonzini
    }
1857 4c93a13b Paolo Bonzini
}
1858 4c93a13b Paolo Bonzini
1859 4c93a13b Paolo Bonzini
static int get_block_status(BlockDriverState *bs, int64_t sector_num,
1860 4c93a13b Paolo Bonzini
                            int nb_sectors, MapEntry *e)
1861 4c93a13b Paolo Bonzini
{
1862 4c93a13b Paolo Bonzini
    int64_t ret;
1863 4c93a13b Paolo Bonzini
    int depth;
1864 4c93a13b Paolo Bonzini
1865 4c93a13b Paolo Bonzini
    /* As an optimization, we could cache the current range of unallocated
1866 4c93a13b Paolo Bonzini
     * clusters in each file of the chain, and avoid querying the same
1867 4c93a13b Paolo Bonzini
     * range repeatedly.
1868 4c93a13b Paolo Bonzini
     */
1869 4c93a13b Paolo Bonzini
1870 4c93a13b Paolo Bonzini
    depth = 0;
1871 4c93a13b Paolo Bonzini
    for (;;) {
1872 4c93a13b Paolo Bonzini
        ret = bdrv_get_block_status(bs, sector_num, nb_sectors, &nb_sectors);
1873 4c93a13b Paolo Bonzini
        if (ret < 0) {
1874 4c93a13b Paolo Bonzini
            return ret;
1875 4c93a13b Paolo Bonzini
        }
1876 4c93a13b Paolo Bonzini
        assert(nb_sectors);
1877 4c93a13b Paolo Bonzini
        if (ret & (BDRV_BLOCK_ZERO|BDRV_BLOCK_DATA)) {
1878 4c93a13b Paolo Bonzini
            break;
1879 4c93a13b Paolo Bonzini
        }
1880 4c93a13b Paolo Bonzini
        bs = bs->backing_hd;
1881 4c93a13b Paolo Bonzini
        if (bs == NULL) {
1882 4c93a13b Paolo Bonzini
            ret = 0;
1883 4c93a13b Paolo Bonzini
            break;
1884 4c93a13b Paolo Bonzini
        }
1885 4c93a13b Paolo Bonzini
1886 4c93a13b Paolo Bonzini
        depth++;
1887 4c93a13b Paolo Bonzini
    }
1888 4c93a13b Paolo Bonzini
1889 4c93a13b Paolo Bonzini
    e->start = sector_num * BDRV_SECTOR_SIZE;
1890 4c93a13b Paolo Bonzini
    e->length = nb_sectors * BDRV_SECTOR_SIZE;
1891 4c93a13b Paolo Bonzini
    e->flags = ret & ~BDRV_BLOCK_OFFSET_MASK;
1892 4c93a13b Paolo Bonzini
    e->offset = ret & BDRV_BLOCK_OFFSET_MASK;
1893 4c93a13b Paolo Bonzini
    e->depth = depth;
1894 4c93a13b Paolo Bonzini
    e->bs = bs;
1895 4c93a13b Paolo Bonzini
    return 0;
1896 4c93a13b Paolo Bonzini
}
1897 4c93a13b Paolo Bonzini
1898 4c93a13b Paolo Bonzini
static int img_map(int argc, char **argv)
1899 4c93a13b Paolo Bonzini
{
1900 4c93a13b Paolo Bonzini
    int c;
1901 4c93a13b Paolo Bonzini
    OutputFormat output_format = OFORMAT_HUMAN;
1902 4c93a13b Paolo Bonzini
    BlockDriverState *bs;
1903 4c93a13b Paolo Bonzini
    const char *filename, *fmt, *output;
1904 4c93a13b Paolo Bonzini
    int64_t length;
1905 4c93a13b Paolo Bonzini
    MapEntry curr = { .length = 0 }, next;
1906 4c93a13b Paolo Bonzini
    int ret = 0;
1907 4c93a13b Paolo Bonzini
1908 4c93a13b Paolo Bonzini
    fmt = NULL;
1909 4c93a13b Paolo Bonzini
    output = NULL;
1910 4c93a13b Paolo Bonzini
    for (;;) {
1911 4c93a13b Paolo Bonzini
        int option_index = 0;
1912 4c93a13b Paolo Bonzini
        static const struct option long_options[] = {
1913 4c93a13b Paolo Bonzini
            {"help", no_argument, 0, 'h'},
1914 4c93a13b Paolo Bonzini
            {"format", required_argument, 0, 'f'},
1915 4c93a13b Paolo Bonzini
            {"output", required_argument, 0, OPTION_OUTPUT},
1916 4c93a13b Paolo Bonzini
            {0, 0, 0, 0}
1917 4c93a13b Paolo Bonzini
        };
1918 4c93a13b Paolo Bonzini
        c = getopt_long(argc, argv, "f:h",
1919 4c93a13b Paolo Bonzini
                        long_options, &option_index);
1920 4c93a13b Paolo Bonzini
        if (c == -1) {
1921 4c93a13b Paolo Bonzini
            break;
1922 4c93a13b Paolo Bonzini
        }
1923 4c93a13b Paolo Bonzini
        switch (c) {
1924 4c93a13b Paolo Bonzini
        case '?':
1925 4c93a13b Paolo Bonzini
        case 'h':
1926 4c93a13b Paolo Bonzini
            help();
1927 4c93a13b Paolo Bonzini
            break;
1928 4c93a13b Paolo Bonzini
        case 'f':
1929 4c93a13b Paolo Bonzini
            fmt = optarg;
1930 4c93a13b Paolo Bonzini
            break;
1931 4c93a13b Paolo Bonzini
        case OPTION_OUTPUT:
1932 4c93a13b Paolo Bonzini
            output = optarg;
1933 4c93a13b Paolo Bonzini
            break;
1934 4c93a13b Paolo Bonzini
        }
1935 4c93a13b Paolo Bonzini
    }
1936 4c93a13b Paolo Bonzini
    if (optind >= argc) {
1937 4c93a13b Paolo Bonzini
        help();
1938 4c93a13b Paolo Bonzini
    }
1939 4c93a13b Paolo Bonzini
    filename = argv[optind++];
1940 4c93a13b Paolo Bonzini
1941 4c93a13b Paolo Bonzini
    if (output && !strcmp(output, "json")) {
1942 4c93a13b Paolo Bonzini
        output_format = OFORMAT_JSON;
1943 4c93a13b Paolo Bonzini
    } else if (output && !strcmp(output, "human")) {
1944 4c93a13b Paolo Bonzini
        output_format = OFORMAT_HUMAN;
1945 4c93a13b Paolo Bonzini
    } else if (output) {
1946 4c93a13b Paolo Bonzini
        error_report("--output must be used with human or json as argument.");
1947 4c93a13b Paolo Bonzini
        return 1;
1948 4c93a13b Paolo Bonzini
    }
1949 4c93a13b Paolo Bonzini
1950 4c93a13b Paolo Bonzini
    bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS, true, false);
1951 4c93a13b Paolo Bonzini
    if (!bs) {
1952 4c93a13b Paolo Bonzini
        return 1;
1953 4c93a13b Paolo Bonzini
    }
1954 4c93a13b Paolo Bonzini
1955 4c93a13b Paolo Bonzini
    if (output_format == OFORMAT_HUMAN) {
1956 4c93a13b Paolo Bonzini
        printf("%-16s%-16s%-16s%s\n", "Offset", "Length", "Mapped to", "File");
1957 4c93a13b Paolo Bonzini
    }
1958 4c93a13b Paolo Bonzini
1959 4c93a13b Paolo Bonzini
    length = bdrv_getlength(bs);
1960 4c93a13b Paolo Bonzini
    while (curr.start + curr.length < length) {
1961 4c93a13b Paolo Bonzini
        int64_t nsectors_left;
1962 4c93a13b Paolo Bonzini
        int64_t sector_num;
1963 4c93a13b Paolo Bonzini
        int n;
1964 4c93a13b Paolo Bonzini
1965 4c93a13b Paolo Bonzini
        sector_num = (curr.start + curr.length) >> BDRV_SECTOR_BITS;
1966 4c93a13b Paolo Bonzini
1967 4c93a13b Paolo Bonzini
        /* Probe up to 1 GiB at a time.  */
1968 4c93a13b Paolo Bonzini
        nsectors_left = DIV_ROUND_UP(length, BDRV_SECTOR_SIZE) - sector_num;
1969 4c93a13b Paolo Bonzini
        n = MIN(1 << (30 - BDRV_SECTOR_BITS), nsectors_left);
1970 4c93a13b Paolo Bonzini
        ret = get_block_status(bs, sector_num, n, &next);
1971 4c93a13b Paolo Bonzini
1972 4c93a13b Paolo Bonzini
        if (ret < 0) {
1973 4c93a13b Paolo Bonzini
            error_report("Could not read file metadata: %s", strerror(-ret));
1974 4c93a13b Paolo Bonzini
            goto out;
1975 4c93a13b Paolo Bonzini
        }
1976 4c93a13b Paolo Bonzini
1977 4c93a13b Paolo Bonzini
        if (curr.length != 0 && curr.flags == next.flags &&
1978 4c93a13b Paolo Bonzini
            curr.depth == next.depth &&
1979 4c93a13b Paolo Bonzini
            ((curr.flags & BDRV_BLOCK_OFFSET_VALID) == 0 ||
1980 4c93a13b Paolo Bonzini
             curr.offset + curr.length == next.offset)) {
1981 4c93a13b Paolo Bonzini
            curr.length += next.length;
1982 4c93a13b Paolo Bonzini
            continue;
1983 4c93a13b Paolo Bonzini
        }
1984 4c93a13b Paolo Bonzini
1985 4c93a13b Paolo Bonzini
        if (curr.length > 0) {
1986 4c93a13b Paolo Bonzini
            dump_map_entry(output_format, &curr, &next);
1987 4c93a13b Paolo Bonzini
        }
1988 4c93a13b Paolo Bonzini
        curr = next;
1989 4c93a13b Paolo Bonzini
    }
1990 4c93a13b Paolo Bonzini
1991 4c93a13b Paolo Bonzini
    dump_map_entry(output_format, &curr, NULL);
1992 4c93a13b Paolo Bonzini
1993 4c93a13b Paolo Bonzini
out:
1994 4c93a13b Paolo Bonzini
    bdrv_unref(bs);
1995 4c93a13b Paolo Bonzini
    return ret < 0;
1996 4c93a13b Paolo Bonzini
}
1997 4c93a13b Paolo Bonzini
1998 f7b4a940 aliguori
#define SNAPSHOT_LIST   1
1999 f7b4a940 aliguori
#define SNAPSHOT_CREATE 2
2000 f7b4a940 aliguori
#define SNAPSHOT_APPLY  3
2001 f7b4a940 aliguori
#define SNAPSHOT_DELETE 4
2002 f7b4a940 aliguori
2003 153859be Stuart Brady
static int img_snapshot(int argc, char **argv)
2004 f7b4a940 aliguori
{
2005 f7b4a940 aliguori
    BlockDriverState *bs;
2006 f7b4a940 aliguori
    QEMUSnapshotInfo sn;
2007 f7b4a940 aliguori
    char *filename, *snapshot_name = NULL;
2008 c2abccec MORITA Kazutaka
    int c, ret = 0, bdrv_oflags;
2009 f7b4a940 aliguori
    int action = 0;
2010 f7b4a940 aliguori
    qemu_timeval tv;
2011 f382d43a Miroslav Rezanina
    bool quiet = false;
2012 a89d89d3 Wenchao Xia
    Error *err = NULL;
2013 f7b4a940 aliguori
2014 710da702 Kevin Wolf
    bdrv_oflags = BDRV_O_FLAGS | BDRV_O_RDWR;
2015 f7b4a940 aliguori
    /* Parse commandline parameters */
2016 f7b4a940 aliguori
    for(;;) {
2017 f382d43a Miroslav Rezanina
        c = getopt(argc, argv, "la:c:d:hq");
2018 b8fb60da Jes Sorensen
        if (c == -1) {
2019 f7b4a940 aliguori
            break;
2020 b8fb60da Jes Sorensen
        }
2021 f7b4a940 aliguori
        switch(c) {
2022 ef87394c Jes Sorensen
        case '?':
2023 f7b4a940 aliguori
        case 'h':
2024 f7b4a940 aliguori
            help();
2025 153859be Stuart Brady
            return 0;
2026 f7b4a940 aliguori
        case 'l':
2027 f7b4a940 aliguori
            if (action) {
2028 f7b4a940 aliguori
                help();
2029 153859be Stuart Brady
                return 0;
2030 f7b4a940 aliguori
            }
2031 f7b4a940 aliguori
            action = SNAPSHOT_LIST;
2032 f5edb014 Naphtali Sprei
            bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
2033 f7b4a940 aliguori
            break;
2034 f7b4a940 aliguori
        case 'a':
2035 f7b4a940 aliguori
            if (action) {
2036 f7b4a940 aliguori
                help();
2037 153859be Stuart Brady
                return 0;
2038 f7b4a940 aliguori
            }
2039 f7b4a940 aliguori
            action = SNAPSHOT_APPLY;
2040 f7b4a940 aliguori
            snapshot_name = optarg;
2041 f7b4a940 aliguori
            break;
2042 f7b4a940 aliguori
        case 'c':
2043 f7b4a940 aliguori
            if (action) {
2044 f7b4a940 aliguori
                help();
2045 153859be Stuart Brady
                return 0;
2046 f7b4a940 aliguori
            }
2047 f7b4a940 aliguori
            action = SNAPSHOT_CREATE;
2048 f7b4a940 aliguori
            snapshot_name = optarg;
2049 f7b4a940 aliguori
            break;
2050 f7b4a940 aliguori
        case 'd':
2051 f7b4a940 aliguori
            if (action) {
2052 f7b4a940 aliguori
                help();
2053 153859be Stuart Brady
                return 0;
2054 f7b4a940 aliguori
            }
2055 f7b4a940 aliguori
            action = SNAPSHOT_DELETE;
2056 f7b4a940 aliguori
            snapshot_name = optarg;
2057 f7b4a940 aliguori
            break;
2058 f382d43a Miroslav Rezanina
        case 'q':
2059 f382d43a Miroslav Rezanina
            quiet = true;
2060 f382d43a Miroslav Rezanina
            break;
2061 f7b4a940 aliguori
        }
2062 f7b4a940 aliguori
    }
2063 f7b4a940 aliguori
2064 fc11eb26 Kevin Wolf
    if (optind != argc - 1) {
2065 f7b4a940 aliguori
        help();
2066 b8fb60da Jes Sorensen
    }
2067 f7b4a940 aliguori
    filename = argv[optind++];
2068 f7b4a940 aliguori
2069 f7b4a940 aliguori
    /* Open the image */
2070 f382d43a Miroslav Rezanina
    bs = bdrv_new_open(filename, NULL, bdrv_oflags, true, quiet);
2071 c2abccec MORITA Kazutaka
    if (!bs) {
2072 c2abccec MORITA Kazutaka
        return 1;
2073 c2abccec MORITA Kazutaka
    }
2074 f7b4a940 aliguori
2075 f7b4a940 aliguori
    /* Perform the requested action */
2076 f7b4a940 aliguori
    switch(action) {
2077 f7b4a940 aliguori
    case SNAPSHOT_LIST:
2078 f7b4a940 aliguori
        dump_snapshots(bs);
2079 f7b4a940 aliguori
        break;
2080 f7b4a940 aliguori
2081 f7b4a940 aliguori
    case SNAPSHOT_CREATE:
2082 f7b4a940 aliguori
        memset(&sn, 0, sizeof(sn));
2083 f7b4a940 aliguori
        pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
2084 f7b4a940 aliguori
2085 f7b4a940 aliguori
        qemu_gettimeofday(&tv);
2086 f7b4a940 aliguori
        sn.date_sec = tv.tv_sec;
2087 f7b4a940 aliguori
        sn.date_nsec = tv.tv_usec * 1000;
2088 f7b4a940 aliguori
2089 f7b4a940 aliguori
        ret = bdrv_snapshot_create(bs, &sn);
2090 b8fb60da Jes Sorensen
        if (ret) {
2091 15654a6d Jes Sorensen
            error_report("Could not create snapshot '%s': %d (%s)",
2092 f7b4a940 aliguori
                snapshot_name, ret, strerror(-ret));
2093 b8fb60da Jes Sorensen
        }
2094 f7b4a940 aliguori
        break;
2095 f7b4a940 aliguori
2096 f7b4a940 aliguori
    case SNAPSHOT_APPLY:
2097 f7b4a940 aliguori
        ret = bdrv_snapshot_goto(bs, snapshot_name);
2098 b8fb60da Jes Sorensen
        if (ret) {
2099 15654a6d Jes Sorensen
            error_report("Could not apply snapshot '%s': %d (%s)",
2100 f7b4a940 aliguori
                snapshot_name, ret, strerror(-ret));
2101 b8fb60da Jes Sorensen
        }
2102 f7b4a940 aliguori
        break;
2103 f7b4a940 aliguori
2104 f7b4a940 aliguori
    case SNAPSHOT_DELETE:
2105 a89d89d3 Wenchao Xia
        bdrv_snapshot_delete_by_id_or_name(bs, snapshot_name, &err);
2106 a89d89d3 Wenchao Xia
        if (error_is_set(&err)) {
2107 a89d89d3 Wenchao Xia
            error_report("Could not delete snapshot '%s': (%s)",
2108 a89d89d3 Wenchao Xia
                         snapshot_name, error_get_pretty(err));
2109 a89d89d3 Wenchao Xia
            error_free(err);
2110 a89d89d3 Wenchao Xia
            ret = 1;
2111 b8fb60da Jes Sorensen
        }
2112 f7b4a940 aliguori
        break;
2113 f7b4a940 aliguori
    }
2114 f7b4a940 aliguori
2115 f7b4a940 aliguori
    /* Cleanup */
2116 4f6fd349 Fam Zheng
    bdrv_unref(bs);
2117 c2abccec MORITA Kazutaka
    if (ret) {
2118 c2abccec MORITA Kazutaka
        return 1;
2119 c2abccec MORITA Kazutaka
    }
2120 153859be Stuart Brady
    return 0;
2121 f7b4a940 aliguori
}
2122 f7b4a940 aliguori
2123 3e85c6fd Kevin Wolf
static int img_rebase(int argc, char **argv)
2124 3e85c6fd Kevin Wolf
{
2125 c2abccec MORITA Kazutaka
    BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
2126 f163d073 Stefan Hajnoczi
    BlockDriver *old_backing_drv, *new_backing_drv;
2127 3e85c6fd Kevin Wolf
    char *filename;
2128 661a0f71 Federico Simoncelli
    const char *fmt, *cache, *out_basefmt, *out_baseimg;
2129 3e85c6fd Kevin Wolf
    int c, flags, ret;
2130 3e85c6fd Kevin Wolf
    int unsafe = 0;
2131 6b837bc4 Jes Sorensen
    int progress = 0;
2132 f382d43a Miroslav Rezanina
    bool quiet = false;
2133 34b5d2c6 Max Reitz
    Error *local_err = NULL;
2134 3e85c6fd Kevin Wolf
2135 3e85c6fd Kevin Wolf
    /* Parse commandline parameters */
2136 e53dbee0 Kevin Wolf
    fmt = NULL;
2137 661a0f71 Federico Simoncelli
    cache = BDRV_DEFAULT_CACHE;
2138 3e85c6fd Kevin Wolf
    out_baseimg = NULL;
2139 3e85c6fd Kevin Wolf
    out_basefmt = NULL;
2140 3e85c6fd Kevin Wolf
    for(;;) {
2141 f382d43a Miroslav Rezanina
        c = getopt(argc, argv, "uhf:F:b:pt:q");
2142 b8fb60da Jes Sorensen
        if (c == -1) {
2143 3e85c6fd Kevin Wolf
            break;
2144 b8fb60da Jes Sorensen
        }
2145 3e85c6fd Kevin Wolf
        switch(c) {
2146 ef87394c Jes Sorensen
        case '?':
2147 3e85c6fd Kevin Wolf
        case 'h':
2148 3e85c6fd Kevin Wolf
            help();
2149 3e85c6fd Kevin Wolf
            return 0;
2150 e53dbee0 Kevin Wolf
        case 'f':
2151 e53dbee0 Kevin Wolf
            fmt = optarg;
2152 e53dbee0 Kevin Wolf
            break;
2153 3e85c6fd Kevin Wolf
        case 'F':
2154 3e85c6fd Kevin Wolf
            out_basefmt = optarg;
2155 3e85c6fd Kevin Wolf
            break;
2156 3e85c6fd Kevin Wolf
        case 'b':
2157 3e85c6fd Kevin Wolf
            out_baseimg = optarg;
2158 3e85c6fd Kevin Wolf
            break;
2159 3e85c6fd Kevin Wolf
        case 'u':
2160 3e85c6fd Kevin Wolf
            unsafe = 1;
2161 3e85c6fd Kevin Wolf
            break;
2162 6b837bc4 Jes Sorensen
        case 'p':
2163 6b837bc4 Jes Sorensen
            progress = 1;
2164 6b837bc4 Jes Sorensen
            break;
2165 661a0f71 Federico Simoncelli
        case 't':
2166 661a0f71 Federico Simoncelli
            cache = optarg;
2167 661a0f71 Federico Simoncelli
            break;
2168 f382d43a Miroslav Rezanina
        case 'q':
2169 f382d43a Miroslav Rezanina
            quiet = true;
2170 f382d43a Miroslav Rezanina
            break;
2171 3e85c6fd Kevin Wolf
        }
2172 3e85c6fd Kevin Wolf
    }
2173 3e85c6fd Kevin Wolf
2174 f382d43a Miroslav Rezanina
    if (quiet) {
2175 f382d43a Miroslav Rezanina
        progress = 0;
2176 f382d43a Miroslav Rezanina
    }
2177 f382d43a Miroslav Rezanina
2178 fc11eb26 Kevin Wolf
    if ((optind != argc - 1) || (!unsafe && !out_baseimg)) {
2179 3e85c6fd Kevin Wolf
        help();
2180 b8fb60da Jes Sorensen
    }
2181 3e85c6fd Kevin Wolf
    filename = argv[optind++];
2182 3e85c6fd Kevin Wolf
2183 6b837bc4 Jes Sorensen
    qemu_progress_init(progress, 2.0);
2184 6b837bc4 Jes Sorensen
    qemu_progress_print(0, 100);
2185 6b837bc4 Jes Sorensen
2186 661a0f71 Federico Simoncelli
    flags = BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
2187 c3993cdc Stefan Hajnoczi
    ret = bdrv_parse_cache_flags(cache, &flags);
2188 661a0f71 Federico Simoncelli
    if (ret < 0) {
2189 661a0f71 Federico Simoncelli
        error_report("Invalid cache option: %s", cache);
2190 661a0f71 Federico Simoncelli
        return -1;
2191 661a0f71 Federico Simoncelli
    }
2192 661a0f71 Federico Simoncelli
2193 3e85c6fd Kevin Wolf
    /*
2194 3e85c6fd Kevin Wolf
     * Open the images.
2195 3e85c6fd Kevin Wolf
     *
2196 3e85c6fd Kevin Wolf
     * Ignore the old backing file for unsafe rebase in case we want to correct
2197 3e85c6fd Kevin Wolf
     * the reference to a renamed or moved backing file.
2198 3e85c6fd Kevin Wolf
     */
2199 f382d43a Miroslav Rezanina
    bs = bdrv_new_open(filename, fmt, flags, true, quiet);
2200 c2abccec MORITA Kazutaka
    if (!bs) {
2201 c2abccec MORITA Kazutaka
        return 1;
2202 c2abccec MORITA Kazutaka
    }
2203 3e85c6fd Kevin Wolf
2204 3e85c6fd Kevin Wolf
    /* Find the right drivers for the backing files */
2205 3e85c6fd Kevin Wolf
    old_backing_drv = NULL;
2206 3e85c6fd Kevin Wolf
    new_backing_drv = NULL;
2207 3e85c6fd Kevin Wolf
2208 3e85c6fd Kevin Wolf
    if (!unsafe && bs->backing_format[0] != '\0') {
2209 3e85c6fd Kevin Wolf
        old_backing_drv = bdrv_find_format(bs->backing_format);
2210 3e85c6fd Kevin Wolf
        if (old_backing_drv == NULL) {
2211 15654a6d Jes Sorensen
            error_report("Invalid format name: '%s'", bs->backing_format);
2212 c2abccec MORITA Kazutaka
            ret = -1;
2213 c2abccec MORITA Kazutaka
            goto out;
2214 3e85c6fd Kevin Wolf
        }
2215 3e85c6fd Kevin Wolf
    }
2216 3e85c6fd Kevin Wolf
2217 3e85c6fd Kevin Wolf
    if (out_basefmt != NULL) {
2218 3e85c6fd Kevin Wolf
        new_backing_drv = bdrv_find_format(out_basefmt);
2219 3e85c6fd Kevin Wolf
        if (new_backing_drv == NULL) {
2220 15654a6d Jes Sorensen
            error_report("Invalid format name: '%s'", out_basefmt);
2221 c2abccec MORITA Kazutaka
            ret = -1;
2222 c2abccec MORITA Kazutaka
            goto out;
2223 3e85c6fd Kevin Wolf
        }
2224 3e85c6fd Kevin Wolf
    }
2225 3e85c6fd Kevin Wolf
2226 3e85c6fd Kevin Wolf
    /* For safe rebasing we need to compare old and new backing file */
2227 3e85c6fd Kevin Wolf
    if (unsafe) {
2228 3e85c6fd Kevin Wolf
        /* Make the compiler happy */
2229 3e85c6fd Kevin Wolf
        bs_old_backing = NULL;
2230 3e85c6fd Kevin Wolf
        bs_new_backing = NULL;
2231 3e85c6fd Kevin Wolf
    } else {
2232 3e85c6fd Kevin Wolf
        char backing_name[1024];
2233 3e85c6fd Kevin Wolf
2234 3e85c6fd Kevin Wolf
        bs_old_backing = bdrv_new("old_backing");
2235 3e85c6fd Kevin Wolf
        bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
2236 de9c0cec Kevin Wolf
        ret = bdrv_open(bs_old_backing, backing_name, NULL, BDRV_O_FLAGS,
2237 34b5d2c6 Max Reitz
                        old_backing_drv, &local_err);
2238 c2abccec MORITA Kazutaka
        if (ret) {
2239 34b5d2c6 Max Reitz
            error_report("Could not open old backing file '%s': %s",
2240 34b5d2c6 Max Reitz
                         backing_name, error_get_pretty(local_err));
2241 34b5d2c6 Max Reitz
            error_free(local_err);
2242 c2abccec MORITA Kazutaka
            goto out;
2243 3e85c6fd Kevin Wolf
        }
2244 a616673d Alex Bligh
        if (out_baseimg[0]) {
2245 a616673d Alex Bligh
            bs_new_backing = bdrv_new("new_backing");
2246 de9c0cec Kevin Wolf
            ret = bdrv_open(bs_new_backing, out_baseimg, NULL, BDRV_O_FLAGS,
2247 34b5d2c6 Max Reitz
                        new_backing_drv, &local_err);
2248 a616673d Alex Bligh
            if (ret) {
2249 34b5d2c6 Max Reitz
                error_report("Could not open new backing file '%s': %s",
2250 34b5d2c6 Max Reitz
                             out_baseimg, error_get_pretty(local_err));
2251 34b5d2c6 Max Reitz
                error_free(local_err);
2252 a616673d Alex Bligh
                goto out;
2253 a616673d Alex Bligh
            }
2254 3e85c6fd Kevin Wolf
        }
2255 3e85c6fd Kevin Wolf
    }
2256 3e85c6fd Kevin Wolf
2257 3e85c6fd Kevin Wolf
    /*
2258 3e85c6fd Kevin Wolf
     * Check each unallocated cluster in the COW file. If it is unallocated,
2259 3e85c6fd Kevin Wolf
     * accesses go to the backing file. We must therefore compare this cluster
2260 3e85c6fd Kevin Wolf
     * in the old and new backing file, and if they differ we need to copy it
2261 3e85c6fd Kevin Wolf
     * from the old backing file into the COW file.
2262 3e85c6fd Kevin Wolf
     *
2263 3e85c6fd Kevin Wolf
     * If qemu-img crashes during this step, no harm is done. The content of
2264 3e85c6fd Kevin Wolf
     * the image is the same as the original one at any time.
2265 3e85c6fd Kevin Wolf
     */
2266 3e85c6fd Kevin Wolf
    if (!unsafe) {
2267 3e85c6fd Kevin Wolf
        uint64_t num_sectors;
2268 87a1b3e3 Kevin Wolf
        uint64_t old_backing_num_sectors;
2269 a616673d Alex Bligh
        uint64_t new_backing_num_sectors = 0;
2270 3e85c6fd Kevin Wolf
        uint64_t sector;
2271 cc60e327 Kevin Wolf
        int n;
2272 d6771bfa TeLeMan
        uint8_t * buf_old;
2273 d6771bfa TeLeMan
        uint8_t * buf_new;
2274 1f710495 Kevin Wolf
        float local_progress = 0;
2275 d6771bfa TeLeMan
2276 bb1c0597 Kevin Wolf
        buf_old = qemu_blockalign(bs, IO_BUF_SIZE);
2277 bb1c0597 Kevin Wolf
        buf_new = qemu_blockalign(bs, IO_BUF_SIZE);
2278 3e85c6fd Kevin Wolf
2279 3e85c6fd Kevin Wolf
        bdrv_get_geometry(bs, &num_sectors);
2280 87a1b3e3 Kevin Wolf
        bdrv_get_geometry(bs_old_backing, &old_backing_num_sectors);
2281 a616673d Alex Bligh
        if (bs_new_backing) {
2282 a616673d Alex Bligh
            bdrv_get_geometry(bs_new_backing, &new_backing_num_sectors);
2283 a616673d Alex Bligh
        }
2284 3e85c6fd Kevin Wolf
2285 1f710495 Kevin Wolf
        if (num_sectors != 0) {
2286 1f710495 Kevin Wolf
            local_progress = (float)100 /
2287 1f710495 Kevin Wolf
                (num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512));
2288 1f710495 Kevin Wolf
        }
2289 1f710495 Kevin Wolf
2290 3e85c6fd Kevin Wolf
        for (sector = 0; sector < num_sectors; sector += n) {
2291 3e85c6fd Kevin Wolf
2292 3e85c6fd Kevin Wolf
            /* How many sectors can we handle with the next read? */
2293 3e85c6fd Kevin Wolf
            if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
2294 3e85c6fd Kevin Wolf
                n = (IO_BUF_SIZE / 512);
2295 3e85c6fd Kevin Wolf
            } else {
2296 3e85c6fd Kevin Wolf
                n = num_sectors - sector;
2297 3e85c6fd Kevin Wolf
            }
2298 3e85c6fd Kevin Wolf
2299 3e85c6fd Kevin Wolf
            /* If the cluster is allocated, we don't need to take action */
2300 cc60e327 Kevin Wolf
            ret = bdrv_is_allocated(bs, sector, n, &n);
2301 d663640c Paolo Bonzini
            if (ret < 0) {
2302 d663640c Paolo Bonzini
                error_report("error while reading image metadata: %s",
2303 d663640c Paolo Bonzini
                             strerror(-ret));
2304 d663640c Paolo Bonzini
                goto out;
2305 d663640c Paolo Bonzini
            }
2306 cc60e327 Kevin Wolf
            if (ret) {
2307 3e85c6fd Kevin Wolf
                continue;
2308 3e85c6fd Kevin Wolf
            }
2309 3e85c6fd Kevin Wolf
2310 87a1b3e3 Kevin Wolf
            /*
2311 87a1b3e3 Kevin Wolf
             * Read old and new backing file and take into consideration that
2312 87a1b3e3 Kevin Wolf
             * backing files may be smaller than the COW image.
2313 87a1b3e3 Kevin Wolf
             */
2314 87a1b3e3 Kevin Wolf
            if (sector >= old_backing_num_sectors) {
2315 87a1b3e3 Kevin Wolf
                memset(buf_old, 0, n * BDRV_SECTOR_SIZE);
2316 87a1b3e3 Kevin Wolf
            } else {
2317 87a1b3e3 Kevin Wolf
                if (sector + n > old_backing_num_sectors) {
2318 87a1b3e3 Kevin Wolf
                    n = old_backing_num_sectors - sector;
2319 87a1b3e3 Kevin Wolf
                }
2320 87a1b3e3 Kevin Wolf
2321 87a1b3e3 Kevin Wolf
                ret = bdrv_read(bs_old_backing, sector, buf_old, n);
2322 87a1b3e3 Kevin Wolf
                if (ret < 0) {
2323 87a1b3e3 Kevin Wolf
                    error_report("error while reading from old backing file");
2324 87a1b3e3 Kevin Wolf
                    goto out;
2325 87a1b3e3 Kevin Wolf
                }
2326 3e85c6fd Kevin Wolf
            }
2327 87a1b3e3 Kevin Wolf
2328 a616673d Alex Bligh
            if (sector >= new_backing_num_sectors || !bs_new_backing) {
2329 87a1b3e3 Kevin Wolf
                memset(buf_new, 0, n * BDRV_SECTOR_SIZE);
2330 87a1b3e3 Kevin Wolf
            } else {
2331 87a1b3e3 Kevin Wolf
                if (sector + n > new_backing_num_sectors) {
2332 87a1b3e3 Kevin Wolf
                    n = new_backing_num_sectors - sector;
2333 87a1b3e3 Kevin Wolf
                }
2334 87a1b3e3 Kevin Wolf
2335 87a1b3e3 Kevin Wolf
                ret = bdrv_read(bs_new_backing, sector, buf_new, n);
2336 87a1b3e3 Kevin Wolf
                if (ret < 0) {
2337 87a1b3e3 Kevin Wolf
                    error_report("error while reading from new backing file");
2338 87a1b3e3 Kevin Wolf
                    goto out;
2339 87a1b3e3 Kevin Wolf
                }
2340 3e85c6fd Kevin Wolf
            }
2341 3e85c6fd Kevin Wolf
2342 3e85c6fd Kevin Wolf
            /* If they differ, we need to write to the COW file */
2343 3e85c6fd Kevin Wolf
            uint64_t written = 0;
2344 3e85c6fd Kevin Wolf
2345 3e85c6fd Kevin Wolf
            while (written < n) {
2346 3e85c6fd Kevin Wolf
                int pnum;
2347 3e85c6fd Kevin Wolf
2348 3e85c6fd Kevin Wolf
                if (compare_sectors(buf_old + written * 512,
2349 60b1bd4f Kevin Wolf
                    buf_new + written * 512, n - written, &pnum))
2350 3e85c6fd Kevin Wolf
                {
2351 3e85c6fd Kevin Wolf
                    ret = bdrv_write(bs, sector + written,
2352 3e85c6fd Kevin Wolf
                        buf_old + written * 512, pnum);
2353 3e85c6fd Kevin Wolf
                    if (ret < 0) {
2354 15654a6d Jes Sorensen
                        error_report("Error while writing to COW image: %s",
2355 3e85c6fd Kevin Wolf
                            strerror(-ret));
2356 c2abccec MORITA Kazutaka
                        goto out;
2357 3e85c6fd Kevin Wolf
                    }
2358 3e85c6fd Kevin Wolf
                }
2359 3e85c6fd Kevin Wolf
2360 3e85c6fd Kevin Wolf
                written += pnum;
2361 3e85c6fd Kevin Wolf
            }
2362 6b837bc4 Jes Sorensen
            qemu_progress_print(local_progress, 100);
2363 3e85c6fd Kevin Wolf
        }
2364 d6771bfa TeLeMan
2365 bb1c0597 Kevin Wolf
        qemu_vfree(buf_old);
2366 bb1c0597 Kevin Wolf
        qemu_vfree(buf_new);
2367 3e85c6fd Kevin Wolf
    }
2368 3e85c6fd Kevin Wolf
2369 3e85c6fd Kevin Wolf
    /*
2370 3e85c6fd Kevin Wolf
     * Change the backing file. All clusters that are different from the old
2371 3e85c6fd Kevin Wolf
     * backing file are overwritten in the COW file now, so the visible content
2372 3e85c6fd Kevin Wolf
     * doesn't change when we switch the backing file.
2373 3e85c6fd Kevin Wolf
     */
2374 a616673d Alex Bligh
    if (out_baseimg && *out_baseimg) {
2375 a616673d Alex Bligh
        ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
2376 a616673d Alex Bligh
    } else {
2377 a616673d Alex Bligh
        ret = bdrv_change_backing_file(bs, NULL, NULL);
2378 a616673d Alex Bligh
    }
2379 a616673d Alex Bligh
2380 3e85c6fd Kevin Wolf
    if (ret == -ENOSPC) {
2381 15654a6d Jes Sorensen
        error_report("Could not change the backing file to '%s': No "
2382 15654a6d Jes Sorensen
                     "space left in the file header", out_baseimg);
2383 3e85c6fd Kevin Wolf
    } else if (ret < 0) {
2384 15654a6d Jes Sorensen
        error_report("Could not change the backing file to '%s': %s",
2385 3e85c6fd Kevin Wolf
            out_baseimg, strerror(-ret));
2386 3e85c6fd Kevin Wolf
    }
2387 3e85c6fd Kevin Wolf
2388 6b837bc4 Jes Sorensen
    qemu_progress_print(100, 0);
2389 3e85c6fd Kevin Wolf
    /*
2390 3e85c6fd Kevin Wolf
     * TODO At this point it is possible to check if any clusters that are
2391 3e85c6fd Kevin Wolf
     * allocated in the COW file are the same in the backing file. If so, they
2392 3e85c6fd Kevin Wolf
     * could be dropped from the COW file. Don't do this before switching the
2393 3e85c6fd Kevin Wolf
     * backing file, in case of a crash this would lead to corruption.
2394 3e85c6fd Kevin Wolf
     */
2395 c2abccec MORITA Kazutaka
out:
2396 6b837bc4 Jes Sorensen
    qemu_progress_end();
2397 3e85c6fd Kevin Wolf
    /* Cleanup */
2398 3e85c6fd Kevin Wolf
    if (!unsafe) {
2399 eb863add Kevin Wolf
        if (bs_old_backing != NULL) {
2400 4f6fd349 Fam Zheng
            bdrv_unref(bs_old_backing);
2401 eb863add Kevin Wolf
        }
2402 eb863add Kevin Wolf
        if (bs_new_backing != NULL) {
2403 4f6fd349 Fam Zheng
            bdrv_unref(bs_new_backing);
2404 eb863add Kevin Wolf
        }
2405 3e85c6fd Kevin Wolf
    }
2406 3e85c6fd Kevin Wolf
2407 4f6fd349 Fam Zheng
    bdrv_unref(bs);
2408 c2abccec MORITA Kazutaka
    if (ret) {
2409 c2abccec MORITA Kazutaka
        return 1;
2410 c2abccec MORITA Kazutaka
    }
2411 3e85c6fd Kevin Wolf
    return 0;
2412 3e85c6fd Kevin Wolf
}
2413 3e85c6fd Kevin Wolf
2414 ae6b0ed6 Stefan Hajnoczi
static int img_resize(int argc, char **argv)
2415 ae6b0ed6 Stefan Hajnoczi
{
2416 ae6b0ed6 Stefan Hajnoczi
    int c, ret, relative;
2417 ae6b0ed6 Stefan Hajnoczi
    const char *filename, *fmt, *size;
2418 ae6b0ed6 Stefan Hajnoczi
    int64_t n, total_size;
2419 f382d43a Miroslav Rezanina
    bool quiet = false;
2420 2a81998a Jes Sorensen
    BlockDriverState *bs = NULL;
2421 20caf0f7 Dong Xu Wang
    QemuOpts *param;
2422 20caf0f7 Dong Xu Wang
    static QemuOptsList resize_options = {
2423 20caf0f7 Dong Xu Wang
        .name = "resize_options",
2424 20caf0f7 Dong Xu Wang
        .head = QTAILQ_HEAD_INITIALIZER(resize_options.head),
2425 20caf0f7 Dong Xu Wang
        .desc = {
2426 20caf0f7 Dong Xu Wang
            {
2427 20caf0f7 Dong Xu Wang
                .name = BLOCK_OPT_SIZE,
2428 20caf0f7 Dong Xu Wang
                .type = QEMU_OPT_SIZE,
2429 20caf0f7 Dong Xu Wang
                .help = "Virtual disk size"
2430 20caf0f7 Dong Xu Wang
            }, {
2431 20caf0f7 Dong Xu Wang
                /* end of list */
2432 20caf0f7 Dong Xu Wang
            }
2433 ae6b0ed6 Stefan Hajnoczi
        },
2434 ae6b0ed6 Stefan Hajnoczi
    };
2435 ae6b0ed6 Stefan Hajnoczi
2436 e80fec7f Kevin Wolf
    /* Remove size from argv manually so that negative numbers are not treated
2437 e80fec7f Kevin Wolf
     * as options by getopt. */
2438 e80fec7f Kevin Wolf
    if (argc < 3) {
2439 e80fec7f Kevin Wolf
        help();
2440 e80fec7f Kevin Wolf
        return 1;
2441 e80fec7f Kevin Wolf
    }
2442 e80fec7f Kevin Wolf
2443 e80fec7f Kevin Wolf
    size = argv[--argc];
2444 e80fec7f Kevin Wolf
2445 e80fec7f Kevin Wolf
    /* Parse getopt arguments */
2446 ae6b0ed6 Stefan Hajnoczi
    fmt = NULL;
2447 ae6b0ed6 Stefan Hajnoczi
    for(;;) {
2448 f382d43a Miroslav Rezanina
        c = getopt(argc, argv, "f:hq");
2449 ae6b0ed6 Stefan Hajnoczi
        if (c == -1) {
2450 ae6b0ed6 Stefan Hajnoczi
            break;
2451 ae6b0ed6 Stefan Hajnoczi
        }
2452 ae6b0ed6 Stefan Hajnoczi
        switch(c) {
2453 ef87394c Jes Sorensen
        case '?':
2454 ae6b0ed6 Stefan Hajnoczi
        case 'h':
2455 ae6b0ed6 Stefan Hajnoczi
            help();
2456 ae6b0ed6 Stefan Hajnoczi
            break;
2457 ae6b0ed6 Stefan Hajnoczi
        case 'f':
2458 ae6b0ed6 Stefan Hajnoczi
            fmt = optarg;
2459 ae6b0ed6 Stefan Hajnoczi
            break;
2460 f382d43a Miroslav Rezanina
        case 'q':
2461 f382d43a Miroslav Rezanina
            quiet = true;
2462 f382d43a Miroslav Rezanina
            break;
2463 ae6b0ed6 Stefan Hajnoczi
        }
2464 ae6b0ed6 Stefan Hajnoczi
    }
2465 fc11eb26 Kevin Wolf
    if (optind != argc - 1) {
2466 ae6b0ed6 Stefan Hajnoczi
        help();
2467 ae6b0ed6 Stefan Hajnoczi
    }
2468 ae6b0ed6 Stefan Hajnoczi
    filename = argv[optind++];
2469 ae6b0ed6 Stefan Hajnoczi
2470 ae6b0ed6 Stefan Hajnoczi
    /* Choose grow, shrink, or absolute resize mode */
2471 ae6b0ed6 Stefan Hajnoczi
    switch (size[0]) {
2472 ae6b0ed6 Stefan Hajnoczi
    case '+':
2473 ae6b0ed6 Stefan Hajnoczi
        relative = 1;
2474 ae6b0ed6 Stefan Hajnoczi
        size++;
2475 ae6b0ed6 Stefan Hajnoczi
        break;
2476 ae6b0ed6 Stefan Hajnoczi
    case '-':
2477 ae6b0ed6 Stefan Hajnoczi
        relative = -1;
2478 ae6b0ed6 Stefan Hajnoczi
        size++;
2479 ae6b0ed6 Stefan Hajnoczi
        break;
2480 ae6b0ed6 Stefan Hajnoczi
    default:
2481 ae6b0ed6 Stefan Hajnoczi
        relative = 0;
2482 ae6b0ed6 Stefan Hajnoczi
        break;
2483 ae6b0ed6 Stefan Hajnoczi
    }
2484 ae6b0ed6 Stefan Hajnoczi
2485 ae6b0ed6 Stefan Hajnoczi
    /* Parse size */
2486 e478b448 Dong Xu Wang
    param = qemu_opts_create_nofail(&resize_options);
2487 20caf0f7 Dong Xu Wang
    if (qemu_opt_set(param, BLOCK_OPT_SIZE, size)) {
2488 ae6b0ed6 Stefan Hajnoczi
        /* Error message already printed when size parsing fails */
2489 2a81998a Jes Sorensen
        ret = -1;
2490 20caf0f7 Dong Xu Wang
        qemu_opts_del(param);
2491 2a81998a Jes Sorensen
        goto out;
2492 ae6b0ed6 Stefan Hajnoczi
    }
2493 20caf0f7 Dong Xu Wang
    n = qemu_opt_get_size(param, BLOCK_OPT_SIZE, 0);
2494 20caf0f7 Dong Xu Wang
    qemu_opts_del(param);
2495 ae6b0ed6 Stefan Hajnoczi
2496 f382d43a Miroslav Rezanina
    bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR, true, quiet);
2497 c2abccec MORITA Kazutaka
    if (!bs) {
2498 2a81998a Jes Sorensen
        ret = -1;
2499 2a81998a Jes Sorensen
        goto out;
2500 c2abccec MORITA Kazutaka
    }
2501 ae6b0ed6 Stefan Hajnoczi
2502 ae6b0ed6 Stefan Hajnoczi
    if (relative) {
2503 ae6b0ed6 Stefan Hajnoczi
        total_size = bdrv_getlength(bs) + n * relative;
2504 ae6b0ed6 Stefan Hajnoczi
    } else {
2505 ae6b0ed6 Stefan Hajnoczi
        total_size = n;
2506 ae6b0ed6 Stefan Hajnoczi
    }
2507 ae6b0ed6 Stefan Hajnoczi
    if (total_size <= 0) {
2508 15654a6d Jes Sorensen
        error_report("New image size must be positive");
2509 c2abccec MORITA Kazutaka
        ret = -1;
2510 c2abccec MORITA Kazutaka
        goto out;
2511 ae6b0ed6 Stefan Hajnoczi
    }
2512 ae6b0ed6 Stefan Hajnoczi
2513 ae6b0ed6 Stefan Hajnoczi
    ret = bdrv_truncate(bs, total_size);
2514 ae6b0ed6 Stefan Hajnoczi
    switch (ret) {
2515 ae6b0ed6 Stefan Hajnoczi
    case 0:
2516 f382d43a Miroslav Rezanina
        qprintf(quiet, "Image resized.\n");
2517 ae6b0ed6 Stefan Hajnoczi
        break;
2518 ae6b0ed6 Stefan Hajnoczi
    case -ENOTSUP:
2519 259b2173 Kevin Wolf
        error_report("This image does not support resize");
2520 ae6b0ed6 Stefan Hajnoczi
        break;
2521 ae6b0ed6 Stefan Hajnoczi
    case -EACCES:
2522 15654a6d Jes Sorensen
        error_report("Image is read-only");
2523 ae6b0ed6 Stefan Hajnoczi
        break;
2524 ae6b0ed6 Stefan Hajnoczi
    default:
2525 15654a6d Jes Sorensen
        error_report("Error resizing image (%d)", -ret);
2526 ae6b0ed6 Stefan Hajnoczi
        break;
2527 ae6b0ed6 Stefan Hajnoczi
    }
2528 c2abccec MORITA Kazutaka
out:
2529 2a81998a Jes Sorensen
    if (bs) {
2530 4f6fd349 Fam Zheng
        bdrv_unref(bs);
2531 2a81998a Jes Sorensen
    }
2532 c2abccec MORITA Kazutaka
    if (ret) {
2533 c2abccec MORITA Kazutaka
        return 1;
2534 c2abccec MORITA Kazutaka
    }
2535 ae6b0ed6 Stefan Hajnoczi
    return 0;
2536 ae6b0ed6 Stefan Hajnoczi
}
2537 ae6b0ed6 Stefan Hajnoczi
2538 6f176b48 Max Reitz
static int img_amend(int argc, char **argv)
2539 6f176b48 Max Reitz
{
2540 6f176b48 Max Reitz
    int c, ret = 0;
2541 6f176b48 Max Reitz
    char *options = NULL;
2542 6f176b48 Max Reitz
    QEMUOptionParameter *create_options = NULL, *options_param = NULL;
2543 6f176b48 Max Reitz
    const char *fmt = NULL, *filename;
2544 6f176b48 Max Reitz
    bool quiet = false;
2545 6f176b48 Max Reitz
    BlockDriverState *bs = NULL;
2546 6f176b48 Max Reitz
2547 6f176b48 Max Reitz
    for (;;) {
2548 6f176b48 Max Reitz
        c = getopt(argc, argv, "hqf:o:");
2549 6f176b48 Max Reitz
        if (c == -1) {
2550 6f176b48 Max Reitz
            break;
2551 6f176b48 Max Reitz
        }
2552 6f176b48 Max Reitz
2553 6f176b48 Max Reitz
        switch (c) {
2554 6f176b48 Max Reitz
            case 'h':
2555 6f176b48 Max Reitz
            case '?':
2556 6f176b48 Max Reitz
                help();
2557 6f176b48 Max Reitz
                break;
2558 6f176b48 Max Reitz
            case 'o':
2559 6f176b48 Max Reitz
                options = optarg;
2560 6f176b48 Max Reitz
                break;
2561 6f176b48 Max Reitz
            case 'f':
2562 6f176b48 Max Reitz
                fmt = optarg;
2563 6f176b48 Max Reitz
                break;
2564 6f176b48 Max Reitz
            case 'q':
2565 6f176b48 Max Reitz
                quiet = true;
2566 6f176b48 Max Reitz
                break;
2567 6f176b48 Max Reitz
        }
2568 6f176b48 Max Reitz
    }
2569 6f176b48 Max Reitz
2570 6f176b48 Max Reitz
    if (optind != argc - 1) {
2571 6f176b48 Max Reitz
        help();
2572 6f176b48 Max Reitz
    }
2573 6f176b48 Max Reitz
2574 6f176b48 Max Reitz
    if (!options) {
2575 6f176b48 Max Reitz
        help();
2576 6f176b48 Max Reitz
    }
2577 6f176b48 Max Reitz
2578 6f176b48 Max Reitz
    filename = argv[argc - 1];
2579 6f176b48 Max Reitz
2580 6f176b48 Max Reitz
    bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR, true, quiet);
2581 6f176b48 Max Reitz
    if (!bs) {
2582 6f176b48 Max Reitz
        error_report("Could not open image '%s'", filename);
2583 6f176b48 Max Reitz
        ret = -1;
2584 6f176b48 Max Reitz
        goto out;
2585 6f176b48 Max Reitz
    }
2586 6f176b48 Max Reitz
2587 6f176b48 Max Reitz
    fmt = bs->drv->format_name;
2588 6f176b48 Max Reitz
2589 6f176b48 Max Reitz
    if (is_help_option(options)) {
2590 6f176b48 Max Reitz
        ret = print_block_option_help(filename, fmt);
2591 6f176b48 Max Reitz
        goto out;
2592 6f176b48 Max Reitz
    }
2593 6f176b48 Max Reitz
2594 6f176b48 Max Reitz
    create_options = append_option_parameters(create_options,
2595 6f176b48 Max Reitz
            bs->drv->create_options);
2596 6f176b48 Max Reitz
    options_param = parse_option_parameters(options, create_options,
2597 6f176b48 Max Reitz
            options_param);
2598 6f176b48 Max Reitz
    if (options_param == NULL) {
2599 6f176b48 Max Reitz
        error_report("Invalid options for file format '%s'", fmt);
2600 6f176b48 Max Reitz
        ret = -1;
2601 6f176b48 Max Reitz
        goto out;
2602 6f176b48 Max Reitz
    }
2603 6f176b48 Max Reitz
2604 6f176b48 Max Reitz
    ret = bdrv_amend_options(bs, options_param);
2605 6f176b48 Max Reitz
    if (ret < 0) {
2606 6f176b48 Max Reitz
        error_report("Error while amending options: %s", strerror(-ret));
2607 6f176b48 Max Reitz
        goto out;
2608 6f176b48 Max Reitz
    }
2609 6f176b48 Max Reitz
2610 6f176b48 Max Reitz
out:
2611 6f176b48 Max Reitz
    if (bs) {
2612 6f176b48 Max Reitz
        bdrv_unref(bs);
2613 6f176b48 Max Reitz
    }
2614 6f176b48 Max Reitz
    free_option_parameters(create_options);
2615 6f176b48 Max Reitz
    free_option_parameters(options_param);
2616 6f176b48 Max Reitz
    if (ret) {
2617 6f176b48 Max Reitz
        return 1;
2618 6f176b48 Max Reitz
    }
2619 6f176b48 Max Reitz
    return 0;
2620 6f176b48 Max Reitz
}
2621 6f176b48 Max Reitz
2622 c227f099 Anthony Liguori
static const img_cmd_t img_cmds[] = {
2623 153859be Stuart Brady
#define DEF(option, callback, arg_string)        \
2624 153859be Stuart Brady
    { option, callback },
2625 153859be Stuart Brady
#include "qemu-img-cmds.h"
2626 153859be Stuart Brady
#undef DEF
2627 153859be Stuart Brady
#undef GEN_DOCS
2628 153859be Stuart Brady
    { NULL, NULL, },
2629 153859be Stuart Brady
};
2630 153859be Stuart Brady
2631 ea2384d3 bellard
int main(int argc, char **argv)
2632 ea2384d3 bellard
{
2633 c227f099 Anthony Liguori
    const img_cmd_t *cmd;
2634 153859be Stuart Brady
    const char *cmdname;
2635 ea2384d3 bellard
2636 526eda14 MORITA Kazutaka
#ifdef CONFIG_POSIX
2637 526eda14 MORITA Kazutaka
    signal(SIGPIPE, SIG_IGN);
2638 526eda14 MORITA Kazutaka
#endif
2639 526eda14 MORITA Kazutaka
2640 53f76e58 Kevin Wolf
    error_set_progname(argv[0]);
2641 53f76e58 Kevin Wolf
2642 2592c59a Paolo Bonzini
    qemu_init_main_loop();
2643 ea2384d3 bellard
    bdrv_init();
2644 ea2384d3 bellard
    if (argc < 2)
2645 ea2384d3 bellard
        help();
2646 153859be Stuart Brady
    cmdname = argv[1];
2647 8f9b157e aurel32
    argc--; argv++;
2648 153859be Stuart Brady
2649 153859be Stuart Brady
    /* find the command */
2650 153859be Stuart Brady
    for(cmd = img_cmds; cmd->name != NULL; cmd++) {
2651 153859be Stuart Brady
        if (!strcmp(cmdname, cmd->name)) {
2652 153859be Stuart Brady
            return cmd->handler(argc, argv);
2653 153859be Stuart Brady
        }
2654 ea2384d3 bellard
    }
2655 153859be Stuart Brady
2656 153859be Stuart Brady
    /* not found */
2657 153859be Stuart Brady
    help();
2658 ea2384d3 bellard
    return 0;
2659 ea2384d3 bellard
}