Statistics
| Branch: | Revision:

root / qemu-img.c @ 689a1921

History | View | Annotate | Download (44.1 kB)

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

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