Statistics
| Branch: | Revision:

root / qemu-img.c @ c054b3fd

History | View | Annotate | Download (52.6 kB)

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

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