Statistics
| Branch: | Revision:

root / qemu-img.c @ d6771bfa

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

818 93c65b47 aliguori
                   If the output is to a host device, we also write out
819 93c65b47 aliguori
                   sectors that are entirely 0, since whatever data was
820 93c65b47 aliguori
                   already there is garbage, not 0s. */
821 12c09b8c Kevin Wolf
                if (drv->no_zero_init || out_baseimg ||
822 93c65b47 aliguori
                    is_allocated_sectors(buf1, n, &n1)) {
823 5fafdf24 ths
                    if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
824 ea2384d3 bellard
                        error("error while writing");
825 ea2384d3 bellard
                }
826 ea2384d3 bellard
                sector_num += n1;
827 ea2384d3 bellard
                n -= n1;
828 ea2384d3 bellard
                buf1 += n1 * 512;
829 ea2384d3 bellard
            }
830 ea2384d3 bellard
        }
831 ea2384d3 bellard
    }
832 d6771bfa TeLeMan
    qemu_free(buf);
833 ea2384d3 bellard
    bdrv_delete(out_bs);
834 926c2d23 balrog
    for (bs_i = 0; bs_i < bs_n; bs_i++)
835 926c2d23 balrog
        bdrv_delete(bs[bs_i]);
836 926c2d23 balrog
    free(bs);
837 ea2384d3 bellard
    return 0;
838 ea2384d3 bellard
}
839 ea2384d3 bellard
840 57d1a2b6 bellard
#ifdef _WIN32
841 57d1a2b6 bellard
static int64_t get_allocated_file_size(const char *filename)
842 57d1a2b6 bellard
{
843 e8445331 bellard
    typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
844 e8445331 bellard
    get_compressed_t get_compressed;
845 57d1a2b6 bellard
    struct _stati64 st;
846 e8445331 bellard
847 e8445331 bellard
    /* WinNT support GetCompressedFileSize to determine allocate size */
848 e8445331 bellard
    get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
849 e8445331 bellard
    if (get_compressed) {
850 e8445331 bellard
            DWORD high, low;
851 e8445331 bellard
            low = get_compressed(filename, &high);
852 e8445331 bellard
            if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
853 e8445331 bellard
            return (((int64_t) high) << 32) + low;
854 e8445331 bellard
    }
855 e8445331 bellard
856 5fafdf24 ths
    if (_stati64(filename, &st) < 0)
857 57d1a2b6 bellard
        return -1;
858 57d1a2b6 bellard
    return st.st_size;
859 57d1a2b6 bellard
}
860 57d1a2b6 bellard
#else
861 57d1a2b6 bellard
static int64_t get_allocated_file_size(const char *filename)
862 57d1a2b6 bellard
{
863 57d1a2b6 bellard
    struct stat st;
864 5fafdf24 ths
    if (stat(filename, &st) < 0)
865 57d1a2b6 bellard
        return -1;
866 57d1a2b6 bellard
    return (int64_t)st.st_blocks * 512;
867 57d1a2b6 bellard
}
868 57d1a2b6 bellard
#endif
869 57d1a2b6 bellard
870 faea38e7 bellard
static void dump_snapshots(BlockDriverState *bs)
871 faea38e7 bellard
{
872 faea38e7 bellard
    QEMUSnapshotInfo *sn_tab, *sn;
873 faea38e7 bellard
    int nb_sns, i;
874 faea38e7 bellard
    char buf[256];
875 faea38e7 bellard
876 faea38e7 bellard
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
877 faea38e7 bellard
    if (nb_sns <= 0)
878 faea38e7 bellard
        return;
879 faea38e7 bellard
    printf("Snapshot list:\n");
880 faea38e7 bellard
    printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
881 faea38e7 bellard
    for(i = 0; i < nb_sns; i++) {
882 faea38e7 bellard
        sn = &sn_tab[i];
883 faea38e7 bellard
        printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
884 faea38e7 bellard
    }
885 faea38e7 bellard
    qemu_free(sn_tab);
886 faea38e7 bellard
}
887 faea38e7 bellard
888 ea2384d3 bellard
static int img_info(int argc, char **argv)
889 ea2384d3 bellard
{
890 ea2384d3 bellard
    int c;
891 ea2384d3 bellard
    const char *filename, *fmt;
892 ea2384d3 bellard
    BlockDriver *drv;
893 ea2384d3 bellard
    BlockDriverState *bs;
894 ea2384d3 bellard
    char fmt_name[128], size_buf[128], dsize_buf[128];
895 96b8f136 ths
    uint64_t total_sectors;
896 96b8f136 ths
    int64_t allocated_size;
897 93b6b2a3 bellard
    char backing_filename[1024];
898 93b6b2a3 bellard
    char backing_filename2[1024];
899 faea38e7 bellard
    BlockDriverInfo bdi;
900 ea2384d3 bellard
901 ea2384d3 bellard
    fmt = NULL;
902 ea2384d3 bellard
    for(;;) {
903 ea2384d3 bellard
        c = getopt(argc, argv, "f:h");
904 ea2384d3 bellard
        if (c == -1)
905 ea2384d3 bellard
            break;
906 ea2384d3 bellard
        switch(c) {
907 ea2384d3 bellard
        case 'h':
908 ea2384d3 bellard
            help();
909 ea2384d3 bellard
            break;
910 ea2384d3 bellard
        case 'f':
911 ea2384d3 bellard
            fmt = optarg;
912 ea2384d3 bellard
            break;
913 ea2384d3 bellard
        }
914 ea2384d3 bellard
    }
915 5fafdf24 ths
    if (optind >= argc)
916 ea2384d3 bellard
        help();
917 ea2384d3 bellard
    filename = argv[optind++];
918 ea2384d3 bellard
919 ea2384d3 bellard
    bs = bdrv_new("");
920 ea2384d3 bellard
    if (!bs)
921 ea2384d3 bellard
        error("Not enough memory");
922 ea2384d3 bellard
    if (fmt) {
923 ea2384d3 bellard
        drv = bdrv_find_format(fmt);
924 ea2384d3 bellard
        if (!drv)
925 ea2384d3 bellard
            error("Unknown file format '%s'", fmt);
926 ea2384d3 bellard
    } else {
927 ea2384d3 bellard
        drv = NULL;
928 ea2384d3 bellard
    }
929 b783e409 Kevin Wolf
    if (bdrv_open2(bs, filename, BRDV_O_FLAGS | BDRV_O_NO_BACKING, drv) < 0) {
930 ea2384d3 bellard
        error("Could not open '%s'", filename);
931 ea2384d3 bellard
    }
932 ea2384d3 bellard
    bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
933 ea2384d3 bellard
    bdrv_get_geometry(bs, &total_sectors);
934 ea2384d3 bellard
    get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
935 57d1a2b6 bellard
    allocated_size = get_allocated_file_size(filename);
936 57d1a2b6 bellard
    if (allocated_size < 0)
937 a10ea30b blueswir1
        snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
938 de167e41 bellard
    else
939 5fafdf24 ths
        get_human_readable_size(dsize_buf, sizeof(dsize_buf),
940 de167e41 bellard
                                allocated_size);
941 ea2384d3 bellard
    printf("image: %s\n"
942 ea2384d3 bellard
           "file format: %s\n"
943 ec3757de bellard
           "virtual size: %s (%" PRId64 " bytes)\n"
944 ea2384d3 bellard
           "disk size: %s\n",
945 5fafdf24 ths
           filename, fmt_name, size_buf,
946 ec3757de bellard
           (total_sectors * 512),
947 ea2384d3 bellard
           dsize_buf);
948 ea2384d3 bellard
    if (bdrv_is_encrypted(bs))
949 ea2384d3 bellard
        printf("encrypted: yes\n");
950 faea38e7 bellard
    if (bdrv_get_info(bs, &bdi) >= 0) {
951 5fafdf24 ths
        if (bdi.cluster_size != 0)
952 faea38e7 bellard
            printf("cluster_size: %d\n", bdi.cluster_size);
953 faea38e7 bellard
    }
954 93b6b2a3 bellard
    bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
955 faea38e7 bellard
    if (backing_filename[0] != '\0') {
956 93b6b2a3 bellard
        path_combine(backing_filename2, sizeof(backing_filename2),
957 93b6b2a3 bellard
                     filename, backing_filename);
958 5fafdf24 ths
        printf("backing file: %s (actual path: %s)\n",
959 93b6b2a3 bellard
               backing_filename,
960 93b6b2a3 bellard
               backing_filename2);
961 faea38e7 bellard
    }
962 faea38e7 bellard
    dump_snapshots(bs);
963 ea2384d3 bellard
    bdrv_delete(bs);
964 ea2384d3 bellard
    return 0;
965 ea2384d3 bellard
}
966 ea2384d3 bellard
967 f7b4a940 aliguori
#define SNAPSHOT_LIST   1
968 f7b4a940 aliguori
#define SNAPSHOT_CREATE 2
969 f7b4a940 aliguori
#define SNAPSHOT_APPLY  3
970 f7b4a940 aliguori
#define SNAPSHOT_DELETE 4
971 f7b4a940 aliguori
972 153859be Stuart Brady
static int img_snapshot(int argc, char **argv)
973 f7b4a940 aliguori
{
974 f7b4a940 aliguori
    BlockDriverState *bs;
975 f7b4a940 aliguori
    QEMUSnapshotInfo sn;
976 f7b4a940 aliguori
    char *filename, *snapshot_name = NULL;
977 f5edb014 Naphtali Sprei
    int c, ret, bdrv_oflags;
978 f7b4a940 aliguori
    int action = 0;
979 f7b4a940 aliguori
    qemu_timeval tv;
980 f7b4a940 aliguori
981 f5edb014 Naphtali Sprei
    bdrv_oflags = BDRV_O_RDWR;
982 f7b4a940 aliguori
    /* Parse commandline parameters */
983 f7b4a940 aliguori
    for(;;) {
984 f7b4a940 aliguori
        c = getopt(argc, argv, "la:c:d:h");
985 f7b4a940 aliguori
        if (c == -1)
986 f7b4a940 aliguori
            break;
987 f7b4a940 aliguori
        switch(c) {
988 f7b4a940 aliguori
        case 'h':
989 f7b4a940 aliguori
            help();
990 153859be Stuart Brady
            return 0;
991 f7b4a940 aliguori
        case 'l':
992 f7b4a940 aliguori
            if (action) {
993 f7b4a940 aliguori
                help();
994 153859be Stuart Brady
                return 0;
995 f7b4a940 aliguori
            }
996 f7b4a940 aliguori
            action = SNAPSHOT_LIST;
997 f5edb014 Naphtali Sprei
            bdrv_oflags &= ~BDRV_O_RDWR; /* no need for RW */
998 f7b4a940 aliguori
            break;
999 f7b4a940 aliguori
        case 'a':
1000 f7b4a940 aliguori
            if (action) {
1001 f7b4a940 aliguori
                help();
1002 153859be Stuart Brady
                return 0;
1003 f7b4a940 aliguori
            }
1004 f7b4a940 aliguori
            action = SNAPSHOT_APPLY;
1005 f7b4a940 aliguori
            snapshot_name = optarg;
1006 f7b4a940 aliguori
            break;
1007 f7b4a940 aliguori
        case 'c':
1008 f7b4a940 aliguori
            if (action) {
1009 f7b4a940 aliguori
                help();
1010 153859be Stuart Brady
                return 0;
1011 f7b4a940 aliguori
            }
1012 f7b4a940 aliguori
            action = SNAPSHOT_CREATE;
1013 f7b4a940 aliguori
            snapshot_name = optarg;
1014 f7b4a940 aliguori
            break;
1015 f7b4a940 aliguori
        case 'd':
1016 f7b4a940 aliguori
            if (action) {
1017 f7b4a940 aliguori
                help();
1018 153859be Stuart Brady
                return 0;
1019 f7b4a940 aliguori
            }
1020 f7b4a940 aliguori
            action = SNAPSHOT_DELETE;
1021 f7b4a940 aliguori
            snapshot_name = optarg;
1022 f7b4a940 aliguori
            break;
1023 f7b4a940 aliguori
        }
1024 f7b4a940 aliguori
    }
1025 f7b4a940 aliguori
1026 f7b4a940 aliguori
    if (optind >= argc)
1027 f7b4a940 aliguori
        help();
1028 f7b4a940 aliguori
    filename = argv[optind++];
1029 f7b4a940 aliguori
1030 f7b4a940 aliguori
    /* Open the image */
1031 f7b4a940 aliguori
    bs = bdrv_new("");
1032 f7b4a940 aliguori
    if (!bs)
1033 f7b4a940 aliguori
        error("Not enough memory");
1034 f7b4a940 aliguori
1035 f5edb014 Naphtali Sprei
    if (bdrv_open2(bs, filename, bdrv_oflags, NULL) < 0) {
1036 f7b4a940 aliguori
        error("Could not open '%s'", filename);
1037 f7b4a940 aliguori
    }
1038 f7b4a940 aliguori
1039 f7b4a940 aliguori
    /* Perform the requested action */
1040 f7b4a940 aliguori
    switch(action) {
1041 f7b4a940 aliguori
    case SNAPSHOT_LIST:
1042 f7b4a940 aliguori
        dump_snapshots(bs);
1043 f7b4a940 aliguori
        break;
1044 f7b4a940 aliguori
1045 f7b4a940 aliguori
    case SNAPSHOT_CREATE:
1046 f7b4a940 aliguori
        memset(&sn, 0, sizeof(sn));
1047 f7b4a940 aliguori
        pstrcpy(sn.name, sizeof(sn.name), snapshot_name);
1048 f7b4a940 aliguori
1049 f7b4a940 aliguori
        qemu_gettimeofday(&tv);
1050 f7b4a940 aliguori
        sn.date_sec = tv.tv_sec;
1051 f7b4a940 aliguori
        sn.date_nsec = tv.tv_usec * 1000;
1052 f7b4a940 aliguori
1053 f7b4a940 aliguori
        ret = bdrv_snapshot_create(bs, &sn);
1054 f7b4a940 aliguori
        if (ret)
1055 f7b4a940 aliguori
            error("Could not create snapshot '%s': %d (%s)",
1056 f7b4a940 aliguori
                snapshot_name, ret, strerror(-ret));
1057 f7b4a940 aliguori
        break;
1058 f7b4a940 aliguori
1059 f7b4a940 aliguori
    case SNAPSHOT_APPLY:
1060 f7b4a940 aliguori
        ret = bdrv_snapshot_goto(bs, snapshot_name);
1061 f7b4a940 aliguori
        if (ret)
1062 f7b4a940 aliguori
            error("Could not apply snapshot '%s': %d (%s)",
1063 f7b4a940 aliguori
                snapshot_name, ret, strerror(-ret));
1064 f7b4a940 aliguori
        break;
1065 f7b4a940 aliguori
1066 f7b4a940 aliguori
    case SNAPSHOT_DELETE:
1067 f7b4a940 aliguori
        ret = bdrv_snapshot_delete(bs, snapshot_name);
1068 f7b4a940 aliguori
        if (ret)
1069 f7b4a940 aliguori
            error("Could not delete snapshot '%s': %d (%s)",
1070 f7b4a940 aliguori
                snapshot_name, ret, strerror(-ret));
1071 f7b4a940 aliguori
        break;
1072 f7b4a940 aliguori
    }
1073 f7b4a940 aliguori
1074 f7b4a940 aliguori
    /* Cleanup */
1075 f7b4a940 aliguori
    bdrv_delete(bs);
1076 153859be Stuart Brady
1077 153859be Stuart Brady
    return 0;
1078 f7b4a940 aliguori
}
1079 f7b4a940 aliguori
1080 3e85c6fd Kevin Wolf
static int img_rebase(int argc, char **argv)
1081 3e85c6fd Kevin Wolf
{
1082 3e85c6fd Kevin Wolf
    BlockDriverState *bs, *bs_old_backing, *bs_new_backing;
1083 3e85c6fd Kevin Wolf
    BlockDriver *old_backing_drv, *new_backing_drv;
1084 3e85c6fd Kevin Wolf
    char *filename;
1085 3e85c6fd Kevin Wolf
    const char *out_basefmt, *out_baseimg;
1086 3e85c6fd Kevin Wolf
    int c, flags, ret;
1087 3e85c6fd Kevin Wolf
    int unsafe = 0;
1088 3e85c6fd Kevin Wolf
1089 3e85c6fd Kevin Wolf
    /* Parse commandline parameters */
1090 3e85c6fd Kevin Wolf
    out_baseimg = NULL;
1091 3e85c6fd Kevin Wolf
    out_basefmt = NULL;
1092 3e85c6fd Kevin Wolf
1093 3e85c6fd Kevin Wolf
    for(;;) {
1094 3e85c6fd Kevin Wolf
        c = getopt(argc, argv, "uhF:b:");
1095 3e85c6fd Kevin Wolf
        if (c == -1)
1096 3e85c6fd Kevin Wolf
            break;
1097 3e85c6fd Kevin Wolf
        switch(c) {
1098 3e85c6fd Kevin Wolf
        case 'h':
1099 3e85c6fd Kevin Wolf
            help();
1100 3e85c6fd Kevin Wolf
            return 0;
1101 3e85c6fd Kevin Wolf
        case 'F':
1102 3e85c6fd Kevin Wolf
            out_basefmt = optarg;
1103 3e85c6fd Kevin Wolf
            break;
1104 3e85c6fd Kevin Wolf
        case 'b':
1105 3e85c6fd Kevin Wolf
            out_baseimg = optarg;
1106 3e85c6fd Kevin Wolf
            break;
1107 3e85c6fd Kevin Wolf
        case 'u':
1108 3e85c6fd Kevin Wolf
            unsafe = 1;
1109 3e85c6fd Kevin Wolf
            break;
1110 3e85c6fd Kevin Wolf
        }
1111 3e85c6fd Kevin Wolf
    }
1112 3e85c6fd Kevin Wolf
1113 3e85c6fd Kevin Wolf
    if ((optind >= argc) || !out_baseimg)
1114 3e85c6fd Kevin Wolf
        help();
1115 3e85c6fd Kevin Wolf
    filename = argv[optind++];
1116 3e85c6fd Kevin Wolf
1117 3e85c6fd Kevin Wolf
    /*
1118 3e85c6fd Kevin Wolf
     * Open the images.
1119 3e85c6fd Kevin Wolf
     *
1120 3e85c6fd Kevin Wolf
     * Ignore the old backing file for unsafe rebase in case we want to correct
1121 3e85c6fd Kevin Wolf
     * the reference to a renamed or moved backing file.
1122 3e85c6fd Kevin Wolf
     */
1123 3e85c6fd Kevin Wolf
    bs = bdrv_new("");
1124 3e85c6fd Kevin Wolf
    if (!bs)
1125 3e85c6fd Kevin Wolf
        error("Not enough memory");
1126 3e85c6fd Kevin Wolf
1127 058fc8c7 Naphtali Sprei
    flags = BRDV_O_FLAGS | BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
1128 3e85c6fd Kevin Wolf
    if (bdrv_open2(bs, filename, flags, NULL) < 0) {
1129 3e85c6fd Kevin Wolf
        error("Could not open '%s'", filename);
1130 3e85c6fd Kevin Wolf
    }
1131 3e85c6fd Kevin Wolf
1132 3e85c6fd Kevin Wolf
    /* Find the right drivers for the backing files */
1133 3e85c6fd Kevin Wolf
    old_backing_drv = NULL;
1134 3e85c6fd Kevin Wolf
    new_backing_drv = NULL;
1135 3e85c6fd Kevin Wolf
1136 3e85c6fd Kevin Wolf
    if (!unsafe && bs->backing_format[0] != '\0') {
1137 3e85c6fd Kevin Wolf
        old_backing_drv = bdrv_find_format(bs->backing_format);
1138 3e85c6fd Kevin Wolf
        if (old_backing_drv == NULL) {
1139 3e85c6fd Kevin Wolf
            error("Invalid format name: '%s'", bs->backing_format);
1140 3e85c6fd Kevin Wolf
        }
1141 3e85c6fd Kevin Wolf
    }
1142 3e85c6fd Kevin Wolf
1143 3e85c6fd Kevin Wolf
    if (out_basefmt != NULL) {
1144 3e85c6fd Kevin Wolf
        new_backing_drv = bdrv_find_format(out_basefmt);
1145 3e85c6fd Kevin Wolf
        if (new_backing_drv == NULL) {
1146 3e85c6fd Kevin Wolf
            error("Invalid format name: '%s'", out_basefmt);
1147 3e85c6fd Kevin Wolf
        }
1148 3e85c6fd Kevin Wolf
    }
1149 3e85c6fd Kevin Wolf
1150 3e85c6fd Kevin Wolf
    /* For safe rebasing we need to compare old and new backing file */
1151 3e85c6fd Kevin Wolf
    if (unsafe) {
1152 3e85c6fd Kevin Wolf
        /* Make the compiler happy */
1153 3e85c6fd Kevin Wolf
        bs_old_backing = NULL;
1154 3e85c6fd Kevin Wolf
        bs_new_backing = NULL;
1155 3e85c6fd Kevin Wolf
    } else {
1156 3e85c6fd Kevin Wolf
        char backing_name[1024];
1157 3e85c6fd Kevin Wolf
1158 3e85c6fd Kevin Wolf
        bs_old_backing = bdrv_new("old_backing");
1159 3e85c6fd Kevin Wolf
        bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
1160 3e85c6fd Kevin Wolf
        if (bdrv_open2(bs_old_backing, backing_name, BRDV_O_FLAGS,
1161 3e85c6fd Kevin Wolf
            old_backing_drv))
1162 3e85c6fd Kevin Wolf
        {
1163 3e85c6fd Kevin Wolf
            error("Could not open old backing file '%s'", backing_name);
1164 3e85c6fd Kevin Wolf
            return -1;
1165 3e85c6fd Kevin Wolf
        }
1166 3e85c6fd Kevin Wolf
1167 3e85c6fd Kevin Wolf
        bs_new_backing = bdrv_new("new_backing");
1168 058fc8c7 Naphtali Sprei
        if (bdrv_open2(bs_new_backing, out_baseimg, BRDV_O_FLAGS | BDRV_O_RDWR,
1169 3e85c6fd Kevin Wolf
            new_backing_drv))
1170 3e85c6fd Kevin Wolf
        {
1171 3e85c6fd Kevin Wolf
            error("Could not open new backing file '%s'", backing_name);
1172 3e85c6fd Kevin Wolf
            return -1;
1173 3e85c6fd Kevin Wolf
        }
1174 3e85c6fd Kevin Wolf
    }
1175 3e85c6fd Kevin Wolf
1176 3e85c6fd Kevin Wolf
    /*
1177 3e85c6fd Kevin Wolf
     * Check each unallocated cluster in the COW file. If it is unallocated,
1178 3e85c6fd Kevin Wolf
     * accesses go to the backing file. We must therefore compare this cluster
1179 3e85c6fd Kevin Wolf
     * in the old and new backing file, and if they differ we need to copy it
1180 3e85c6fd Kevin Wolf
     * from the old backing file into the COW file.
1181 3e85c6fd Kevin Wolf
     *
1182 3e85c6fd Kevin Wolf
     * If qemu-img crashes during this step, no harm is done. The content of
1183 3e85c6fd Kevin Wolf
     * the image is the same as the original one at any time.
1184 3e85c6fd Kevin Wolf
     */
1185 3e85c6fd Kevin Wolf
    if (!unsafe) {
1186 3e85c6fd Kevin Wolf
        uint64_t num_sectors;
1187 3e85c6fd Kevin Wolf
        uint64_t sector;
1188 3e85c6fd Kevin Wolf
        int n, n1;
1189 d6771bfa TeLeMan
        uint8_t * buf_old;
1190 d6771bfa TeLeMan
        uint8_t * buf_new;
1191 d6771bfa TeLeMan
1192 d6771bfa TeLeMan
        buf_old = qemu_malloc(IO_BUF_SIZE);
1193 d6771bfa TeLeMan
        buf_new = qemu_malloc(IO_BUF_SIZE);
1194 3e85c6fd Kevin Wolf
1195 3e85c6fd Kevin Wolf
        bdrv_get_geometry(bs, &num_sectors);
1196 3e85c6fd Kevin Wolf
1197 3e85c6fd Kevin Wolf
        for (sector = 0; sector < num_sectors; sector += n) {
1198 3e85c6fd Kevin Wolf
1199 3e85c6fd Kevin Wolf
            /* How many sectors can we handle with the next read? */
1200 3e85c6fd Kevin Wolf
            if (sector + (IO_BUF_SIZE / 512) <= num_sectors) {
1201 3e85c6fd Kevin Wolf
                n = (IO_BUF_SIZE / 512);
1202 3e85c6fd Kevin Wolf
            } else {
1203 3e85c6fd Kevin Wolf
                n = num_sectors - sector;
1204 3e85c6fd Kevin Wolf
            }
1205 3e85c6fd Kevin Wolf
1206 3e85c6fd Kevin Wolf
            /* If the cluster is allocated, we don't need to take action */
1207 3e85c6fd Kevin Wolf
            if (bdrv_is_allocated(bs, sector, n, &n1)) {
1208 3e85c6fd Kevin Wolf
                n = n1;
1209 3e85c6fd Kevin Wolf
                continue;
1210 3e85c6fd Kevin Wolf
            }
1211 3e85c6fd Kevin Wolf
1212 3e85c6fd Kevin Wolf
            /* Read old and new backing file */
1213 3e85c6fd Kevin Wolf
            if (bdrv_read(bs_old_backing, sector, buf_old, n) < 0) {
1214 3e85c6fd Kevin Wolf
                error("error while reading from old backing file");
1215 3e85c6fd Kevin Wolf
            }
1216 3e85c6fd Kevin Wolf
            if (bdrv_read(bs_new_backing, sector, buf_new, n) < 0) {
1217 3e85c6fd Kevin Wolf
                error("error while reading from new backing file");
1218 3e85c6fd Kevin Wolf
            }
1219 3e85c6fd Kevin Wolf
1220 3e85c6fd Kevin Wolf
            /* If they differ, we need to write to the COW file */
1221 3e85c6fd Kevin Wolf
            uint64_t written = 0;
1222 3e85c6fd Kevin Wolf
1223 3e85c6fd Kevin Wolf
            while (written < n) {
1224 3e85c6fd Kevin Wolf
                int pnum;
1225 3e85c6fd Kevin Wolf
1226 3e85c6fd Kevin Wolf
                if (compare_sectors(buf_old + written * 512,
1227 3e85c6fd Kevin Wolf
                    buf_new + written * 512, n, &pnum))
1228 3e85c6fd Kevin Wolf
                {
1229 3e85c6fd Kevin Wolf
                    ret = bdrv_write(bs, sector + written,
1230 3e85c6fd Kevin Wolf
                        buf_old + written * 512, pnum);
1231 3e85c6fd Kevin Wolf
                    if (ret < 0) {
1232 3e85c6fd Kevin Wolf
                        error("Error while writing to COW image: %s",
1233 3e85c6fd Kevin Wolf
                            strerror(-ret));
1234 3e85c6fd Kevin Wolf
                    }
1235 3e85c6fd Kevin Wolf
                }
1236 3e85c6fd Kevin Wolf
1237 3e85c6fd Kevin Wolf
                written += pnum;
1238 3e85c6fd Kevin Wolf
            }
1239 3e85c6fd Kevin Wolf
        }
1240 d6771bfa TeLeMan
1241 d6771bfa TeLeMan
        qemu_free(buf_old);
1242 d6771bfa TeLeMan
        qemu_free(buf_new);
1243 3e85c6fd Kevin Wolf
    }
1244 3e85c6fd Kevin Wolf
1245 3e85c6fd Kevin Wolf
    /*
1246 3e85c6fd Kevin Wolf
     * Change the backing file. All clusters that are different from the old
1247 3e85c6fd Kevin Wolf
     * backing file are overwritten in the COW file now, so the visible content
1248 3e85c6fd Kevin Wolf
     * doesn't change when we switch the backing file.
1249 3e85c6fd Kevin Wolf
     */
1250 3e85c6fd Kevin Wolf
    ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt);
1251 3e85c6fd Kevin Wolf
    if (ret == -ENOSPC) {
1252 3e85c6fd Kevin Wolf
        error("Could not change the backing file to '%s': No space left in "
1253 3e85c6fd Kevin Wolf
            "the file header", out_baseimg);
1254 3e85c6fd Kevin Wolf
    } else if (ret < 0) {
1255 3e85c6fd Kevin Wolf
        error("Could not change the backing file to '%s': %s",
1256 3e85c6fd Kevin Wolf
            out_baseimg, strerror(-ret));
1257 3e85c6fd Kevin Wolf
    }
1258 3e85c6fd Kevin Wolf
1259 3e85c6fd Kevin Wolf
    /*
1260 3e85c6fd Kevin Wolf
     * TODO At this point it is possible to check if any clusters that are
1261 3e85c6fd Kevin Wolf
     * allocated in the COW file are the same in the backing file. If so, they
1262 3e85c6fd Kevin Wolf
     * could be dropped from the COW file. Don't do this before switching the
1263 3e85c6fd Kevin Wolf
     * backing file, in case of a crash this would lead to corruption.
1264 3e85c6fd Kevin Wolf
     */
1265 3e85c6fd Kevin Wolf
1266 3e85c6fd Kevin Wolf
    /* Cleanup */
1267 3e85c6fd Kevin Wolf
    if (!unsafe) {
1268 3e85c6fd Kevin Wolf
        bdrv_delete(bs_old_backing);
1269 3e85c6fd Kevin Wolf
        bdrv_delete(bs_new_backing);
1270 3e85c6fd Kevin Wolf
    }
1271 3e85c6fd Kevin Wolf
1272 3e85c6fd Kevin Wolf
    bdrv_delete(bs);
1273 3e85c6fd Kevin Wolf
1274 3e85c6fd Kevin Wolf
    return 0;
1275 3e85c6fd Kevin Wolf
}
1276 3e85c6fd Kevin Wolf
1277 c227f099 Anthony Liguori
static const img_cmd_t img_cmds[] = {
1278 153859be Stuart Brady
#define DEF(option, callback, arg_string)        \
1279 153859be Stuart Brady
    { option, callback },
1280 153859be Stuart Brady
#include "qemu-img-cmds.h"
1281 153859be Stuart Brady
#undef DEF
1282 153859be Stuart Brady
#undef GEN_DOCS
1283 153859be Stuart Brady
    { NULL, NULL, },
1284 153859be Stuart Brady
};
1285 153859be Stuart Brady
1286 ea2384d3 bellard
int main(int argc, char **argv)
1287 ea2384d3 bellard
{
1288 c227f099 Anthony Liguori
    const img_cmd_t *cmd;
1289 153859be Stuart Brady
    const char *cmdname;
1290 ea2384d3 bellard
1291 ea2384d3 bellard
    bdrv_init();
1292 ea2384d3 bellard
    if (argc < 2)
1293 ea2384d3 bellard
        help();
1294 153859be Stuart Brady
    cmdname = argv[1];
1295 8f9b157e aurel32
    argc--; argv++;
1296 153859be Stuart Brady
1297 153859be Stuart Brady
    /* find the command */
1298 153859be Stuart Brady
    for(cmd = img_cmds; cmd->name != NULL; cmd++) {
1299 153859be Stuart Brady
        if (!strcmp(cmdname, cmd->name)) {
1300 153859be Stuart Brady
            return cmd->handler(argc, argv);
1301 153859be Stuart Brady
        }
1302 ea2384d3 bellard
    }
1303 153859be Stuart Brady
1304 153859be Stuart Brady
    /* not found */
1305 153859be Stuart Brady
    help();
1306 ea2384d3 bellard
    return 0;
1307 ea2384d3 bellard
}