Statistics
| Branch: | Revision:

root / qemu-img.c @ e9b4b432

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

942 93c65b47 aliguori
                   If the output is to a host device, we also write out
943 93c65b47 aliguori
                   sectors that are entirely 0, since whatever data was
944 93c65b47 aliguori
                   already there is garbage, not 0s. */
945 f2feebbd Kevin Wolf
                if (!has_zero_init || out_baseimg ||
946 93c65b47 aliguori
                    is_allocated_sectors(buf1, n, &n1)) {
947 c2abccec MORITA Kazutaka
                    ret = bdrv_write(out_bs, sector_num, buf1, n1);
948 c2abccec MORITA Kazutaka
                    if (ret < 0) {
949 15654a6d Jes Sorensen
                        error_report("error while writing");
950 c2abccec MORITA Kazutaka
                        goto out;
951 c2abccec MORITA Kazutaka
                    }
952 ea2384d3 bellard
                }
953 ea2384d3 bellard
                sector_num += n1;
954 ea2384d3 bellard
                n -= n1;
955 ea2384d3 bellard
                buf1 += n1 * 512;
956 ea2384d3 bellard
            }
957 6b837bc4 Jes Sorensen
            qemu_progress_print(local_progress, 100);
958 ea2384d3 bellard
        }
959 ea2384d3 bellard
    }
960 c2abccec MORITA Kazutaka
out:
961 6b837bc4 Jes Sorensen
    qemu_progress_end();
962 c2abccec MORITA Kazutaka
    free_option_parameters(create_options);
963 c2abccec MORITA Kazutaka
    free_option_parameters(param);
964 d6771bfa TeLeMan
    qemu_free(buf);
965 c2abccec MORITA Kazutaka
    if (out_bs) {
966 c2abccec MORITA Kazutaka
        bdrv_delete(out_bs);
967 c2abccec MORITA Kazutaka
    }
968 31ca34b8 Jes Sorensen
    if (bs) {
969 31ca34b8 Jes Sorensen
        for (bs_i = 0; bs_i < bs_n; bs_i++) {
970 31ca34b8 Jes Sorensen
            if (bs[bs_i]) {
971 31ca34b8 Jes Sorensen
                bdrv_delete(bs[bs_i]);
972 31ca34b8 Jes Sorensen
            }
973 c2abccec MORITA Kazutaka
        }
974 31ca34b8 Jes Sorensen
        qemu_free(bs);
975 c2abccec MORITA Kazutaka
    }
976 c2abccec MORITA Kazutaka
    if (ret) {
977 c2abccec MORITA Kazutaka
        return 1;
978 c2abccec MORITA Kazutaka
    }
979 ea2384d3 bellard
    return 0;
980 ea2384d3 bellard
}
981 ea2384d3 bellard
982 57d1a2b6 bellard
#ifdef _WIN32
983 57d1a2b6 bellard
static int64_t get_allocated_file_size(const char *filename)
984 57d1a2b6 bellard
{
985 e8445331 bellard
    typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
986 e8445331 bellard
    get_compressed_t get_compressed;
987 57d1a2b6 bellard
    struct _stati64 st;
988 e8445331 bellard
989 e8445331 bellard
    /* WinNT support GetCompressedFileSize to determine allocate size */
990 e8445331 bellard
    get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
991 e8445331 bellard
    if (get_compressed) {
992 e8445331 bellard
            DWORD high, low;
993 e8445331 bellard
            low = get_compressed(filename, &high);
994 e8445331 bellard
            if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
995 e8445331 bellard
            return (((int64_t) high) << 32) + low;
996 e8445331 bellard
    }
997 e8445331 bellard
998 5fafdf24 ths
    if (_stati64(filename, &st) < 0)
999 57d1a2b6 bellard
        return -1;
1000 57d1a2b6 bellard
    return st.st_size;
1001 57d1a2b6 bellard
}
1002 57d1a2b6 bellard
#else
1003 57d1a2b6 bellard
static int64_t get_allocated_file_size(const char *filename)
1004 57d1a2b6 bellard
{
1005 57d1a2b6 bellard
    struct stat st;
1006 5fafdf24 ths
    if (stat(filename, &st) < 0)
1007 57d1a2b6 bellard
        return -1;
1008 57d1a2b6 bellard
    return (int64_t)st.st_blocks * 512;
1009 57d1a2b6 bellard
}
1010 57d1a2b6 bellard
#endif
1011 57d1a2b6 bellard
1012 faea38e7 bellard
static void dump_snapshots(BlockDriverState *bs)
1013 faea38e7 bellard
{
1014 faea38e7 bellard
    QEMUSnapshotInfo *sn_tab, *sn;
1015 faea38e7 bellard
    int nb_sns, i;
1016 faea38e7 bellard
    char buf[256];
1017 faea38e7 bellard
1018 faea38e7 bellard
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
1019 faea38e7 bellard
    if (nb_sns <= 0)
1020 faea38e7 bellard
        return;
1021 faea38e7 bellard
    printf("Snapshot list:\n");
1022 faea38e7 bellard
    printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
1023 faea38e7 bellard
    for(i = 0; i < nb_sns; i++) {
1024 faea38e7 bellard
        sn = &sn_tab[i];
1025 faea38e7 bellard
        printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
1026 faea38e7 bellard
    }
1027 faea38e7 bellard
    qemu_free(sn_tab);
1028 faea38e7 bellard
}
1029 faea38e7 bellard
1030 ea2384d3 bellard
static int img_info(int argc, char **argv)
1031 ea2384d3 bellard
{
1032 ea2384d3 bellard
    int c;
1033 ea2384d3 bellard
    const char *filename, *fmt;
1034 ea2384d3 bellard
    BlockDriverState *bs;
1035 ea2384d3 bellard
    char fmt_name[128], size_buf[128], dsize_buf[128];
1036 96b8f136 ths
    uint64_t total_sectors;
1037 96b8f136 ths
    int64_t allocated_size;
1038 93b6b2a3 bellard
    char backing_filename[1024];
1039 93b6b2a3 bellard
    char backing_filename2[1024];
1040 faea38e7 bellard
    BlockDriverInfo bdi;
1041 ea2384d3 bellard
1042 ea2384d3 bellard
    fmt = NULL;
1043 ea2384d3 bellard
    for(;;) {
1044 ea2384d3 bellard
        c = getopt(argc, argv, "f:h");
1045 b8fb60da Jes Sorensen
        if (c == -1) {
1046 ea2384d3 bellard
            break;
1047 b8fb60da Jes Sorensen
        }
1048 ea2384d3 bellard
        switch(c) {
1049 ef87394c Jes Sorensen
        case '?':
1050 ea2384d3 bellard
        case 'h':
1051 ea2384d3 bellard
            help();
1052 ea2384d3 bellard
            break;
1053 ea2384d3 bellard
        case 'f':
1054 ea2384d3 bellard
            fmt = optarg;
1055 ea2384d3 bellard
            break;
1056 ea2384d3 bellard
        }
1057 ea2384d3 bellard
    }
1058 b8fb60da Jes Sorensen
    if (optind >= argc) {
1059 ea2384d3 bellard
        help();
1060 b8fb60da Jes Sorensen
    }
1061 ea2384d3 bellard
    filename = argv[optind++];
1062 ea2384d3 bellard
1063 adfe078e Stefan Hajnoczi
    bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING);
1064 c2abccec MORITA Kazutaka
    if (!bs) {
1065 c2abccec MORITA Kazutaka
        return 1;
1066 c2abccec MORITA Kazutaka
    }
1067 ea2384d3 bellard
    bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
1068 ea2384d3 bellard
    bdrv_get_geometry(bs, &total_sectors);
1069 ea2384d3 bellard
    get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
1070 57d1a2b6 bellard
    allocated_size = get_allocated_file_size(filename);
1071 b8fb60da Jes Sorensen
    if (allocated_size < 0) {
1072 a10ea30b blueswir1
        snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
1073 b8fb60da Jes Sorensen
    } else {
1074 5fafdf24 ths
        get_human_readable_size(dsize_buf, sizeof(dsize_buf),
1075 de167e41 bellard
                                allocated_size);
1076 b8fb60da Jes Sorensen
    }
1077 ea2384d3 bellard
    printf("image: %s\n"
1078 ea2384d3 bellard
           "file format: %s\n"
1079 ec3757de bellard
           "virtual size: %s (%" PRId64 " bytes)\n"
1080 ea2384d3 bellard
           "disk size: %s\n",
1081 5fafdf24 ths
           filename, fmt_name, size_buf,
1082 ec3757de bellard
           (total_sectors * 512),
1083 ea2384d3 bellard
           dsize_buf);
1084 b8fb60da Jes Sorensen
    if (bdrv_is_encrypted(bs)) {
1085 ea2384d3 bellard
        printf("encrypted: yes\n");
1086 b8fb60da Jes Sorensen
    }
1087 faea38e7 bellard
    if (bdrv_get_info(bs, &bdi) >= 0) {
1088 b8fb60da Jes Sorensen
        if (bdi.cluster_size != 0) {
1089 faea38e7 bellard
            printf("cluster_size: %d\n", bdi.cluster_size);
1090 b8fb60da Jes Sorensen
        }
1091 faea38e7 bellard
    }
1092 93b6b2a3 bellard
    bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
1093 faea38e7 bellard
    if (backing_filename[0] != '\0') {
1094 93b6b2a3 bellard
        path_combine(backing_filename2, sizeof(backing_filename2),
1095 93b6b2a3 bellard
                     filename, backing_filename);
1096 5fafdf24 ths
        printf("backing file: %s (actual path: %s)\n",
1097 93b6b2a3 bellard
               backing_filename,
1098 93b6b2a3 bellard
               backing_filename2);
1099 faea38e7 bellard
    }
1100 faea38e7 bellard
    dump_snapshots(bs);
1101 ea2384d3 bellard
    bdrv_delete(bs);
1102 ea2384d3 bellard
    return 0;
1103 ea2384d3 bellard
}
1104 ea2384d3 bellard
1105 f7b4a940 aliguori
#define SNAPSHOT_LIST   1
1106 f7b4a940 aliguori
#define SNAPSHOT_CREATE 2
1107 f7b4a940 aliguori
#define SNAPSHOT_APPLY  3
1108 f7b4a940 aliguori
#define SNAPSHOT_DELETE 4
1109 f7b4a940 aliguori
1110 153859be Stuart Brady
static int img_snapshot(int argc, char **argv)
1111 f7b4a940 aliguori
{
1112 f7b4a940 aliguori
    BlockDriverState *bs;
1113 f7b4a940 aliguori
    QEMUSnapshotInfo sn;
1114 f7b4a940 aliguori
    char *filename, *snapshot_name = NULL;
1115 c2abccec MORITA Kazutaka
    int c, ret = 0, bdrv_oflags;
1116 f7b4a940 aliguori
    int action = 0;
1117 f7b4a940 aliguori
    qemu_timeval tv;
1118 f7b4a940 aliguori
1119 710da702 Kevin Wolf
    bdrv_oflags = BDRV_O_FLAGS | BDRV_O_RDWR;
1120 f7b4a940 aliguori
    /* Parse commandline parameters */
1121 f7b4a940 aliguori
    for(;;) {
1122 f7b4a940 aliguori
        c = getopt(argc, argv, "la:c:d:h");
1123 b8fb60da Jes Sorensen
        if (c == -1) {
1124 f7b4a940 aliguori
            break;
1125 b8fb60da Jes Sorensen
        }
1126 f7b4a940 aliguori
        switch(c) {
1127 ef87394c Jes Sorensen
        case '?':
1128 f7b4a940 aliguori
        case 'h':
1129 f7b4a940 aliguori
            help();
1130 153859be Stuart Brady
            return 0;
1131 f7b4a940 aliguori
        case 'l':
1132 f7b4a940 aliguori
            if (action) {
1133 f7b4a940 aliguori
                help();
1134 153859be Stuart Brady
                return 0;
1135 f7b4a940 aliguori
            }
1136 f7b4a940 aliguori
            action = SNAPSHOT_LIST;
1137 f5edb014 Naphtali Sprei
            bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
1138 f7b4a940 aliguori
            break;
1139 f7b4a940 aliguori
        case 'a':
1140 f7b4a940 aliguori
            if (action) {
1141 f7b4a940 aliguori
                help();
1142 153859be Stuart Brady
                return 0;
1143 f7b4a940 aliguori
            }
1144 f7b4a940 aliguori
            action = SNAPSHOT_APPLY;
1145 f7b4a940 aliguori
            snapshot_name = optarg;
1146 f7b4a940 aliguori
            break;
1147 f7b4a940 aliguori
        case 'c':
1148 f7b4a940 aliguori
            if (action) {
1149 f7b4a940 aliguori
                help();
1150 153859be Stuart Brady
                return 0;
1151 f7b4a940 aliguori
            }
1152 f7b4a940 aliguori
            action = SNAPSHOT_CREATE;
1153 f7b4a940 aliguori
            snapshot_name = optarg;
1154 f7b4a940 aliguori
            break;
1155 f7b4a940 aliguori
        case 'd':
1156 f7b4a940 aliguori
            if (action) {
1157 f7b4a940 aliguori
                help();
1158 153859be Stuart Brady
                return 0;
1159 f7b4a940 aliguori
            }
1160 f7b4a940 aliguori
            action = SNAPSHOT_DELETE;
1161 f7b4a940 aliguori
            snapshot_name = optarg;
1162 f7b4a940 aliguori
            break;
1163 f7b4a940 aliguori
        }
1164 f7b4a940 aliguori
    }
1165 f7b4a940 aliguori
1166 b8fb60da Jes Sorensen
    if (optind >= argc) {
1167 f7b4a940 aliguori
        help();
1168 b8fb60da Jes Sorensen
    }
1169 f7b4a940 aliguori
    filename = argv[optind++];
1170 f7b4a940 aliguori
1171 f7b4a940 aliguori
    /* Open the image */
1172 f163d073 Stefan Hajnoczi
    bs = bdrv_new_open(filename, NULL, bdrv_oflags);
1173 c2abccec MORITA Kazutaka
    if (!bs) {
1174 c2abccec MORITA Kazutaka
        return 1;
1175 c2abccec MORITA Kazutaka
    }
1176 f7b4a940 aliguori
1177 f7b4a940 aliguori
    /* Perform the requested action */
1178 f7b4a940 aliguori
    switch(action) {
1179 f7b4a940 aliguori
    case SNAPSHOT_LIST:
1180 f7b4a940 aliguori
        dump_snapshots(bs);
1181 f7b4a940 aliguori
        break;
1182 f7b4a940 aliguori
1183 f7b4a940 aliguori
    case SNAPSHOT_CREATE:
1184 f7b4a940 aliguori
        memset(&sn, 0, sizeof(sn));
1185 f7b4a940 aliguori
        pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
1186 f7b4a940 aliguori
1187 f7b4a940 aliguori
        qemu_gettimeofday(&tv);
1188 f7b4a940 aliguori
        sn.date_sec = tv.tv_sec;
1189 f7b4a940 aliguori
        sn.date_nsec = tv.tv_usec * 1000;
1190 f7b4a940 aliguori
1191 f7b4a940 aliguori
        ret = bdrv_snapshot_create(bs, &sn);
1192 b8fb60da Jes Sorensen
        if (ret) {
1193 15654a6d Jes Sorensen
            error_report("Could not create snapshot '%s': %d (%s)",
1194 f7b4a940 aliguori
                snapshot_name, ret, strerror(-ret));
1195 b8fb60da Jes Sorensen
        }
1196 f7b4a940 aliguori
        break;
1197 f7b4a940 aliguori
1198 f7b4a940 aliguori
    case SNAPSHOT_APPLY:
1199 f7b4a940 aliguori
        ret = bdrv_snapshot_goto(bs, snapshot_name);
1200 b8fb60da Jes Sorensen
        if (ret) {
1201 15654a6d Jes Sorensen
            error_report("Could not apply snapshot '%s': %d (%s)",
1202 f7b4a940 aliguori
                snapshot_name, ret, strerror(-ret));
1203 b8fb60da Jes Sorensen
        }
1204 f7b4a940 aliguori
        break;
1205 f7b4a940 aliguori
1206 f7b4a940 aliguori
    case SNAPSHOT_DELETE:
1207 f7b4a940 aliguori
        ret = bdrv_snapshot_delete(bs, snapshot_name);
1208 b8fb60da Jes Sorensen
        if (ret) {
1209 15654a6d Jes Sorensen
            error_report("Could not delete snapshot '%s': %d (%s)",
1210 f7b4a940 aliguori
                snapshot_name, ret, strerror(-ret));
1211 b8fb60da Jes Sorensen
        }
1212 f7b4a940 aliguori
        break;
1213 f7b4a940 aliguori
    }
1214 f7b4a940 aliguori
1215 f7b4a940 aliguori
    /* Cleanup */
1216 f7b4a940 aliguori
    bdrv_delete(bs);
1217 c2abccec MORITA Kazutaka
    if (ret) {
1218 c2abccec MORITA Kazutaka
        return 1;
1219 c2abccec MORITA Kazutaka
    }
1220 153859be Stuart Brady
    return 0;
1221 f7b4a940 aliguori
}
1222 f7b4a940 aliguori
1223 3e85c6fd Kevin Wolf
static int img_rebase(int argc, char **argv)
1224 3e85c6fd Kevin Wolf
{
1225 c2abccec MORITA Kazutaka
    BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
1226 f163d073 Stefan Hajnoczi
    BlockDriver *old_backing_drv, *new_backing_drv;
1227 3e85c6fd Kevin Wolf
    char *filename;
1228 e53dbee0 Kevin Wolf
    const char *fmt, *out_basefmt, *out_baseimg;
1229 3e85c6fd Kevin Wolf
    int c, flags, ret;
1230 3e85c6fd Kevin Wolf
    int unsafe = 0;
1231 6b837bc4 Jes Sorensen
    int progress = 0;
1232 3e85c6fd Kevin Wolf
1233 3e85c6fd Kevin Wolf
    /* Parse commandline parameters */
1234 e53dbee0 Kevin Wolf
    fmt = NULL;
1235 3e85c6fd Kevin Wolf
    out_baseimg = NULL;
1236 3e85c6fd Kevin Wolf
    out_basefmt = NULL;
1237 3e85c6fd Kevin Wolf
1238 3e85c6fd Kevin Wolf
    for(;;) {
1239 6b837bc4 Jes Sorensen
        c = getopt(argc, argv, "uhf:F:b:p");
1240 b8fb60da Jes Sorensen
        if (c == -1) {
1241 3e85c6fd Kevin Wolf
            break;
1242 b8fb60da Jes Sorensen
        }
1243 3e85c6fd Kevin Wolf
        switch(c) {
1244 ef87394c Jes Sorensen
        case '?':
1245 3e85c6fd Kevin Wolf
        case 'h':
1246 3e85c6fd Kevin Wolf
            help();
1247 3e85c6fd Kevin Wolf
            return 0;
1248 e53dbee0 Kevin Wolf
        case 'f':
1249 e53dbee0 Kevin Wolf
            fmt = optarg;
1250 e53dbee0 Kevin Wolf
            break;
1251 3e85c6fd Kevin Wolf
        case 'F':
1252 3e85c6fd Kevin Wolf
            out_basefmt = optarg;
1253 3e85c6fd Kevin Wolf
            break;
1254 3e85c6fd Kevin Wolf
        case 'b':
1255 3e85c6fd Kevin Wolf
            out_baseimg = optarg;
1256 3e85c6fd Kevin Wolf
            break;
1257 3e85c6fd Kevin Wolf
        case 'u':
1258 3e85c6fd Kevin Wolf
            unsafe = 1;
1259 3e85c6fd Kevin Wolf
            break;
1260 6b837bc4 Jes Sorensen
        case 'p':
1261 6b837bc4 Jes Sorensen
            progress = 1;
1262 6b837bc4 Jes Sorensen
            break;
1263 3e85c6fd Kevin Wolf
        }
1264 3e85c6fd Kevin Wolf
    }
1265 3e85c6fd Kevin Wolf
1266 9a9d9dba Anthony Liguori
    if ((optind >= argc) || (!unsafe && !out_baseimg)) {
1267 3e85c6fd Kevin Wolf
        help();
1268 b8fb60da Jes Sorensen
    }
1269 3e85c6fd Kevin Wolf
    filename = argv[optind++];
1270 3e85c6fd Kevin Wolf
1271 6b837bc4 Jes Sorensen
    qemu_progress_init(progress, 2.0);
1272 6b837bc4 Jes Sorensen
    qemu_progress_print(0, 100);
1273 6b837bc4 Jes Sorensen
1274 3e85c6fd Kevin Wolf
    /*
1275 3e85c6fd Kevin Wolf
     * Open the images.
1276 3e85c6fd Kevin Wolf
     *
1277 3e85c6fd Kevin Wolf
     * Ignore the old backing file for unsafe rebase in case we want to correct
1278 3e85c6fd Kevin Wolf
     * the reference to a renamed or moved backing file.
1279 3e85c6fd Kevin Wolf
     */
1280 adfe078e Stefan Hajnoczi
    flags = BDRV_O_FLAGS | BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
1281 f163d073 Stefan Hajnoczi
    bs = bdrv_new_open(filename, fmt, flags);
1282 c2abccec MORITA Kazutaka
    if (!bs) {
1283 c2abccec MORITA Kazutaka
        return 1;
1284 c2abccec MORITA Kazutaka
    }
1285 3e85c6fd Kevin Wolf
1286 3e85c6fd Kevin Wolf
    /* Find the right drivers for the backing files */
1287 3e85c6fd Kevin Wolf
    old_backing_drv = NULL;
1288 3e85c6fd Kevin Wolf
    new_backing_drv = NULL;
1289 3e85c6fd Kevin Wolf
1290 3e85c6fd Kevin Wolf
    if (!unsafe && bs->backing_format[0] != '\0') {
1291 3e85c6fd Kevin Wolf
        old_backing_drv = bdrv_find_format(bs->backing_format);
1292 3e85c6fd Kevin Wolf
        if (old_backing_drv == NULL) {
1293 15654a6d Jes Sorensen
            error_report("Invalid format name: '%s'", bs->backing_format);
1294 c2abccec MORITA Kazutaka
            ret = -1;
1295 c2abccec MORITA Kazutaka
            goto out;
1296 3e85c6fd Kevin Wolf
        }
1297 3e85c6fd Kevin Wolf
    }
1298 3e85c6fd Kevin Wolf
1299 3e85c6fd Kevin Wolf
    if (out_basefmt != NULL) {
1300 3e85c6fd Kevin Wolf
        new_backing_drv = bdrv_find_format(out_basefmt);
1301 3e85c6fd Kevin Wolf
        if (new_backing_drv == NULL) {
1302 15654a6d Jes Sorensen
            error_report("Invalid format name: '%s'", out_basefmt);
1303 c2abccec MORITA Kazutaka
            ret = -1;
1304 c2abccec MORITA Kazutaka
            goto out;
1305 3e85c6fd Kevin Wolf
        }
1306 3e85c6fd Kevin Wolf
    }
1307 3e85c6fd Kevin Wolf
1308 3e85c6fd Kevin Wolf
    /* For safe rebasing we need to compare old and new backing file */
1309 3e85c6fd Kevin Wolf
    if (unsafe) {
1310 3e85c6fd Kevin Wolf
        /* Make the compiler happy */
1311 3e85c6fd Kevin Wolf
        bs_old_backing = NULL;
1312 3e85c6fd Kevin Wolf
        bs_new_backing = NULL;
1313 3e85c6fd Kevin Wolf
    } else {
1314 3e85c6fd Kevin Wolf
        char backing_name[1024];
1315 3e85c6fd Kevin Wolf
1316 3e85c6fd Kevin Wolf
        bs_old_backing = bdrv_new("old_backing");
1317 3e85c6fd Kevin Wolf
        bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
1318 c2abccec MORITA Kazutaka
        ret = bdrv_open(bs_old_backing, backing_name, BDRV_O_FLAGS,
1319 c2abccec MORITA Kazutaka
                        old_backing_drv);
1320 c2abccec MORITA Kazutaka
        if (ret) {
1321 15654a6d Jes Sorensen
            error_report("Could not open old backing file '%s'", backing_name);
1322 c2abccec MORITA Kazutaka
            goto out;
1323 3e85c6fd Kevin Wolf
        }
1324 3e85c6fd Kevin Wolf
1325 3e85c6fd Kevin Wolf
        bs_new_backing = bdrv_new("new_backing");
1326 cdbae851 Kevin Wolf
        ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS,
1327 c2abccec MORITA Kazutaka
                        new_backing_drv);
1328 c2abccec MORITA Kazutaka
        if (ret) {
1329 15654a6d Jes Sorensen
            error_report("Could not open new backing file '%s'", out_baseimg);
1330 c2abccec MORITA Kazutaka
            goto out;
1331 3e85c6fd Kevin Wolf
        }
1332 3e85c6fd Kevin Wolf
    }
1333 3e85c6fd Kevin Wolf
1334 3e85c6fd Kevin Wolf
    /*
1335 3e85c6fd Kevin Wolf
     * Check each unallocated cluster in the COW file. If it is unallocated,
1336 3e85c6fd Kevin Wolf
     * accesses go to the backing file. We must therefore compare this cluster
1337 3e85c6fd Kevin Wolf
     * in the old and new backing file, and if they differ we need to copy it
1338 3e85c6fd Kevin Wolf
     * from the old backing file into the COW file.
1339 3e85c6fd Kevin Wolf
     *
1340 3e85c6fd Kevin Wolf
     * If qemu-img crashes during this step, no harm is done. The content of
1341 3e85c6fd Kevin Wolf
     * the image is the same as the original one at any time.
1342 3e85c6fd Kevin Wolf
     */
1343 3e85c6fd Kevin Wolf
    if (!unsafe) {
1344 3e85c6fd Kevin Wolf
        uint64_t num_sectors;
1345 3e85c6fd Kevin Wolf
        uint64_t sector;
1346 cc60e327 Kevin Wolf
        int n;
1347 d6771bfa TeLeMan
        uint8_t * buf_old;
1348 d6771bfa TeLeMan
        uint8_t * buf_new;
1349 6b837bc4 Jes Sorensen
        float local_progress;
1350 d6771bfa TeLeMan
1351 d6771bfa TeLeMan
        buf_old = qemu_malloc(IO_BUF_SIZE);
1352 d6771bfa TeLeMan
        buf_new = qemu_malloc(IO_BUF_SIZE);
1353 3e85c6fd Kevin Wolf
1354 3e85c6fd Kevin Wolf
        bdrv_get_geometry(bs, &num_sectors);
1355 3e85c6fd Kevin Wolf
1356 6b837bc4 Jes Sorensen
        local_progress = (float)100 /
1357 4ee96418 Jes Sorensen
            (num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512));
1358 3e85c6fd Kevin Wolf
        for (sector = 0; sector < num_sectors; sector += n) {
1359 3e85c6fd Kevin Wolf
1360 3e85c6fd Kevin Wolf
            /* How many sectors can we handle with the next read? */
1361 3e85c6fd Kevin Wolf
            if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
1362 3e85c6fd Kevin Wolf
                n = (IO_BUF_SIZE / 512);
1363 3e85c6fd Kevin Wolf
            } else {
1364 3e85c6fd Kevin Wolf
                n = num_sectors - sector;
1365 3e85c6fd Kevin Wolf
            }
1366 3e85c6fd Kevin Wolf
1367 3e85c6fd Kevin Wolf
            /* If the cluster is allocated, we don't need to take action */
1368 cc60e327 Kevin Wolf
            ret = bdrv_is_allocated(bs, sector, n, &n);
1369 cc60e327 Kevin Wolf
            if (ret) {
1370 3e85c6fd Kevin Wolf
                continue;
1371 3e85c6fd Kevin Wolf
            }
1372 3e85c6fd Kevin Wolf
1373 3e85c6fd Kevin Wolf
            /* Read old and new backing file */
1374 c2abccec MORITA Kazutaka
            ret = bdrv_read(bs_old_backing, sector, buf_old, n);
1375 c2abccec MORITA Kazutaka
            if (ret < 0) {
1376 15654a6d Jes Sorensen
                error_report("error while reading from old backing file");
1377 c2abccec MORITA Kazutaka
                goto out;
1378 3e85c6fd Kevin Wolf
            }
1379 c2abccec MORITA Kazutaka
            ret = bdrv_read(bs_new_backing, sector, buf_new, n);
1380 c2abccec MORITA Kazutaka
            if (ret < 0) {
1381 15654a6d Jes Sorensen
                error_report("error while reading from new backing file");
1382 c2abccec MORITA Kazutaka
                goto out;
1383 3e85c6fd Kevin Wolf
            }
1384 3e85c6fd Kevin Wolf
1385 3e85c6fd Kevin Wolf
            /* If they differ, we need to write to the COW file */
1386 3e85c6fd Kevin Wolf
            uint64_t written = 0;
1387 3e85c6fd Kevin Wolf
1388 3e85c6fd Kevin Wolf
            while (written < n) {
1389 3e85c6fd Kevin Wolf
                int pnum;
1390 3e85c6fd Kevin Wolf
1391 3e85c6fd Kevin Wolf
                if (compare_sectors(buf_old + written * 512,
1392 60b1bd4f Kevin Wolf
                    buf_new + written * 512, n - written, &pnum))
1393 3e85c6fd Kevin Wolf
                {
1394 3e85c6fd Kevin Wolf
                    ret = bdrv_write(bs, sector + written,
1395 3e85c6fd Kevin Wolf
                        buf_old + written * 512, pnum);
1396 3e85c6fd Kevin Wolf
                    if (ret < 0) {
1397 15654a6d Jes Sorensen
                        error_report("Error while writing to COW image: %s",
1398 3e85c6fd Kevin Wolf
                            strerror(-ret));
1399 c2abccec MORITA Kazutaka
                        goto out;
1400 3e85c6fd Kevin Wolf
                    }
1401 3e85c6fd Kevin Wolf
                }
1402 3e85c6fd Kevin Wolf
1403 3e85c6fd Kevin Wolf
                written += pnum;
1404 3e85c6fd Kevin Wolf
            }
1405 6b837bc4 Jes Sorensen
            qemu_progress_print(local_progress, 100);
1406 3e85c6fd Kevin Wolf
        }
1407 d6771bfa TeLeMan
1408 d6771bfa TeLeMan
        qemu_free(buf_old);
1409 d6771bfa TeLeMan
        qemu_free(buf_new);
1410 3e85c6fd Kevin Wolf
    }
1411 3e85c6fd Kevin Wolf
1412 3e85c6fd Kevin Wolf
    /*
1413 3e85c6fd Kevin Wolf
     * Change the backing file. All clusters that are different from the old
1414 3e85c6fd Kevin Wolf
     * backing file are overwritten in the COW file now, so the visible content
1415 3e85c6fd Kevin Wolf
     * doesn't change when we switch the backing file.
1416 3e85c6fd Kevin Wolf
     */
1417 3e85c6fd Kevin Wolf
    ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
1418 3e85c6fd Kevin Wolf
    if (ret == -ENOSPC) {
1419 15654a6d Jes Sorensen
        error_report("Could not change the backing file to '%s': No "
1420 15654a6d Jes Sorensen
                     "space left in the file header", out_baseimg);
1421 3e85c6fd Kevin Wolf
    } else if (ret < 0) {
1422 15654a6d Jes Sorensen
        error_report("Could not change the backing file to '%s': %s",
1423 3e85c6fd Kevin Wolf
            out_baseimg, strerror(-ret));
1424 3e85c6fd Kevin Wolf
    }
1425 3e85c6fd Kevin Wolf
1426 6b837bc4 Jes Sorensen
    qemu_progress_print(100, 0);
1427 3e85c6fd Kevin Wolf
    /*
1428 3e85c6fd Kevin Wolf
     * TODO At this point it is possible to check if any clusters that are
1429 3e85c6fd Kevin Wolf
     * allocated in the COW file are the same in the backing file. If so, they
1430 3e85c6fd Kevin Wolf
     * could be dropped from the COW file. Don't do this before switching the
1431 3e85c6fd Kevin Wolf
     * backing file, in case of a crash this would lead to corruption.
1432 3e85c6fd Kevin Wolf
     */
1433 c2abccec MORITA Kazutaka
out:
1434 6b837bc4 Jes Sorensen
    qemu_progress_end();
1435 3e85c6fd Kevin Wolf
    /* Cleanup */
1436 3e85c6fd Kevin Wolf
    if (!unsafe) {
1437 eb863add Kevin Wolf
        if (bs_old_backing != NULL) {
1438 eb863add Kevin Wolf
            bdrv_delete(bs_old_backing);
1439 eb863add Kevin Wolf
        }
1440 eb863add Kevin Wolf
        if (bs_new_backing != NULL) {
1441 eb863add Kevin Wolf
            bdrv_delete(bs_new_backing);
1442 eb863add Kevin Wolf
        }
1443 3e85c6fd Kevin Wolf
    }
1444 3e85c6fd Kevin Wolf
1445 3e85c6fd Kevin Wolf
    bdrv_delete(bs);
1446 c2abccec MORITA Kazutaka
    if (ret) {
1447 c2abccec MORITA Kazutaka
        return 1;
1448 c2abccec MORITA Kazutaka
    }
1449 3e85c6fd Kevin Wolf
    return 0;
1450 3e85c6fd Kevin Wolf
}
1451 3e85c6fd Kevin Wolf
1452 ae6b0ed6 Stefan Hajnoczi
static int img_resize(int argc, char **argv)
1453 ae6b0ed6 Stefan Hajnoczi
{
1454 ae6b0ed6 Stefan Hajnoczi
    int c, ret, relative;
1455 ae6b0ed6 Stefan Hajnoczi
    const char *filename, *fmt, *size;
1456 ae6b0ed6 Stefan Hajnoczi
    int64_t n, total_size;
1457 2a81998a Jes Sorensen
    BlockDriverState *bs = NULL;
1458 ae6b0ed6 Stefan Hajnoczi
    QEMUOptionParameter *param;
1459 ae6b0ed6 Stefan Hajnoczi
    QEMUOptionParameter resize_options[] = {
1460 ae6b0ed6 Stefan Hajnoczi
        {
1461 ae6b0ed6 Stefan Hajnoczi
            .name = BLOCK_OPT_SIZE,
1462 ae6b0ed6 Stefan Hajnoczi
            .type = OPT_SIZE,
1463 ae6b0ed6 Stefan Hajnoczi
            .help = "Virtual disk size"
1464 ae6b0ed6 Stefan Hajnoczi
        },
1465 ae6b0ed6 Stefan Hajnoczi
        { NULL }
1466 ae6b0ed6 Stefan Hajnoczi
    };
1467 ae6b0ed6 Stefan Hajnoczi
1468 e80fec7f Kevin Wolf
    /* Remove size from argv manually so that negative numbers are not treated
1469 e80fec7f Kevin Wolf
     * as options by getopt. */
1470 e80fec7f Kevin Wolf
    if (argc < 3) {
1471 e80fec7f Kevin Wolf
        help();
1472 e80fec7f Kevin Wolf
        return 1;
1473 e80fec7f Kevin Wolf
    }
1474 e80fec7f Kevin Wolf
1475 e80fec7f Kevin Wolf
    size = argv[--argc];
1476 e80fec7f Kevin Wolf
1477 e80fec7f Kevin Wolf
    /* Parse getopt arguments */
1478 ae6b0ed6 Stefan Hajnoczi
    fmt = NULL;
1479 ae6b0ed6 Stefan Hajnoczi
    for(;;) {
1480 ae6b0ed6 Stefan Hajnoczi
        c = getopt(argc, argv, "f:h");
1481 ae6b0ed6 Stefan Hajnoczi
        if (c == -1) {
1482 ae6b0ed6 Stefan Hajnoczi
            break;
1483 ae6b0ed6 Stefan Hajnoczi
        }
1484 ae6b0ed6 Stefan Hajnoczi
        switch(c) {
1485 ef87394c Jes Sorensen
        case '?':
1486 ae6b0ed6 Stefan Hajnoczi
        case 'h':
1487 ae6b0ed6 Stefan Hajnoczi
            help();
1488 ae6b0ed6 Stefan Hajnoczi
            break;
1489 ae6b0ed6 Stefan Hajnoczi
        case 'f':
1490 ae6b0ed6 Stefan Hajnoczi
            fmt = optarg;
1491 ae6b0ed6 Stefan Hajnoczi
            break;
1492 ae6b0ed6 Stefan Hajnoczi
        }
1493 ae6b0ed6 Stefan Hajnoczi
    }
1494 e80fec7f Kevin Wolf
    if (optind >= argc) {
1495 ae6b0ed6 Stefan Hajnoczi
        help();
1496 ae6b0ed6 Stefan Hajnoczi
    }
1497 ae6b0ed6 Stefan Hajnoczi
    filename = argv[optind++];
1498 ae6b0ed6 Stefan Hajnoczi
1499 ae6b0ed6 Stefan Hajnoczi
    /* Choose grow, shrink, or absolute resize mode */
1500 ae6b0ed6 Stefan Hajnoczi
    switch (size[0]) {
1501 ae6b0ed6 Stefan Hajnoczi
    case '+':
1502 ae6b0ed6 Stefan Hajnoczi
        relative = 1;
1503 ae6b0ed6 Stefan Hajnoczi
        size++;
1504 ae6b0ed6 Stefan Hajnoczi
        break;
1505 ae6b0ed6 Stefan Hajnoczi
    case '-':
1506 ae6b0ed6 Stefan Hajnoczi
        relative = -1;
1507 ae6b0ed6 Stefan Hajnoczi
        size++;
1508 ae6b0ed6 Stefan Hajnoczi
        break;
1509 ae6b0ed6 Stefan Hajnoczi
    default:
1510 ae6b0ed6 Stefan Hajnoczi
        relative = 0;
1511 ae6b0ed6 Stefan Hajnoczi
        break;
1512 ae6b0ed6 Stefan Hajnoczi
    }
1513 ae6b0ed6 Stefan Hajnoczi
1514 ae6b0ed6 Stefan Hajnoczi
    /* Parse size */
1515 ae6b0ed6 Stefan Hajnoczi
    param = parse_option_parameters("", resize_options, NULL);
1516 ae6b0ed6 Stefan Hajnoczi
    if (set_option_parameter(param, BLOCK_OPT_SIZE, size)) {
1517 ae6b0ed6 Stefan Hajnoczi
        /* Error message already printed when size parsing fails */
1518 2a81998a Jes Sorensen
        ret = -1;
1519 2a81998a Jes Sorensen
        goto out;
1520 ae6b0ed6 Stefan Hajnoczi
    }
1521 ae6b0ed6 Stefan Hajnoczi
    n = get_option_parameter(param, BLOCK_OPT_SIZE)->value.n;
1522 ae6b0ed6 Stefan Hajnoczi
    free_option_parameters(param);
1523 ae6b0ed6 Stefan Hajnoczi
1524 ae6b0ed6 Stefan Hajnoczi
    bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
1525 c2abccec MORITA Kazutaka
    if (!bs) {
1526 2a81998a Jes Sorensen
        ret = -1;
1527 2a81998a Jes Sorensen
        goto out;
1528 c2abccec MORITA Kazutaka
    }
1529 ae6b0ed6 Stefan Hajnoczi
1530 ae6b0ed6 Stefan Hajnoczi
    if (relative) {
1531 ae6b0ed6 Stefan Hajnoczi
        total_size = bdrv_getlength(bs) + n * relative;
1532 ae6b0ed6 Stefan Hajnoczi
    } else {
1533 ae6b0ed6 Stefan Hajnoczi
        total_size = n;
1534 ae6b0ed6 Stefan Hajnoczi
    }
1535 ae6b0ed6 Stefan Hajnoczi
    if (total_size <= 0) {
1536 15654a6d Jes Sorensen
        error_report("New image size must be positive");
1537 c2abccec MORITA Kazutaka
        ret = -1;
1538 c2abccec MORITA Kazutaka
        goto out;
1539 ae6b0ed6 Stefan Hajnoczi
    }
1540 ae6b0ed6 Stefan Hajnoczi
1541 ae6b0ed6 Stefan Hajnoczi
    ret = bdrv_truncate(bs, total_size);
1542 ae6b0ed6 Stefan Hajnoczi
    switch (ret) {
1543 ae6b0ed6 Stefan Hajnoczi
    case 0:
1544 ae6b0ed6 Stefan Hajnoczi
        printf("Image resized.\n");
1545 ae6b0ed6 Stefan Hajnoczi
        break;
1546 ae6b0ed6 Stefan Hajnoczi
    case -ENOTSUP:
1547 15654a6d Jes Sorensen
        error_report("This image format does not support resize");
1548 ae6b0ed6 Stefan Hajnoczi
        break;
1549 ae6b0ed6 Stefan Hajnoczi
    case -EACCES:
1550 15654a6d Jes Sorensen
        error_report("Image is read-only");
1551 ae6b0ed6 Stefan Hajnoczi
        break;
1552 ae6b0ed6 Stefan Hajnoczi
    default:
1553 15654a6d Jes Sorensen
        error_report("Error resizing image (%d)", -ret);
1554 ae6b0ed6 Stefan Hajnoczi
        break;
1555 ae6b0ed6 Stefan Hajnoczi
    }
1556 c2abccec MORITA Kazutaka
out:
1557 2a81998a Jes Sorensen
    if (bs) {
1558 2a81998a Jes Sorensen
        bdrv_delete(bs);
1559 2a81998a Jes Sorensen
    }
1560 c2abccec MORITA Kazutaka
    if (ret) {
1561 c2abccec MORITA Kazutaka
        return 1;
1562 c2abccec MORITA Kazutaka
    }
1563 ae6b0ed6 Stefan Hajnoczi
    return 0;
1564 ae6b0ed6 Stefan Hajnoczi
}
1565 ae6b0ed6 Stefan Hajnoczi
1566 c227f099 Anthony Liguori
static const img_cmd_t img_cmds[] = {
1567 153859be Stuart Brady
#define DEF(option, callback, arg_string)        \
1568 153859be Stuart Brady
    { option, callback },
1569 153859be Stuart Brady
#include "qemu-img-cmds.h"
1570 153859be Stuart Brady
#undef DEF
1571 153859be Stuart Brady
#undef GEN_DOCS
1572 153859be Stuart Brady
    { NULL, NULL, },
1573 153859be Stuart Brady
};
1574 153859be Stuart Brady
1575 ea2384d3 bellard
int main(int argc, char **argv)
1576 ea2384d3 bellard
{
1577 c227f099 Anthony Liguori
    const img_cmd_t *cmd;
1578 153859be Stuart Brady
    const char *cmdname;
1579 ea2384d3 bellard
1580 53f76e58 Kevin Wolf
    error_set_progname(argv[0]);
1581 53f76e58 Kevin Wolf
1582 ea2384d3 bellard
    bdrv_init();
1583 ea2384d3 bellard
    if (argc < 2)
1584 ea2384d3 bellard
        help();
1585 153859be Stuart Brady
    cmdname = argv[1];
1586 8f9b157e aurel32
    argc--; argv++;
1587 153859be Stuart Brady
1588 153859be Stuart Brady
    /* find the command */
1589 153859be Stuart Brady
    for(cmd = img_cmds; cmd->name != NULL; cmd++) {
1590 153859be Stuart Brady
        if (!strcmp(cmdname, cmd->name)) {
1591 153859be Stuart Brady
            return cmd->handler(argc, argv);
1592 153859be Stuart Brady
        }
1593 ea2384d3 bellard
    }
1594 153859be Stuart Brady
1595 153859be Stuart Brady
    /* not found */
1596 153859be Stuart Brady
    help();
1597 ea2384d3 bellard
    return 0;
1598 ea2384d3 bellard
}