Statistics
| Branch: | Revision:

root / qemu-img.c @ 1ffc346f

History | View | Annotate | Download (19.9 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 ec36ba14 ths
#include "block_int.h"
26 926c2d23 balrog
#include <assert.h>
27 ea2384d3 bellard
28 e8445331 bellard
#ifdef _WIN32
29 4fddf62a ths
#define WIN32_LEAN_AND_MEAN
30 e8445331 bellard
#include <windows.h>
31 e8445331 bellard
#endif
32 e8445331 bellard
33 3f379ab1 pbrook
static void __attribute__((noreturn)) error(const char *fmt, ...)
34 ea2384d3 bellard
{
35 ea2384d3 bellard
    va_list ap;
36 ea2384d3 bellard
    va_start(ap, fmt);
37 57d1a2b6 bellard
    fprintf(stderr, "qemu-img: ");
38 ea2384d3 bellard
    vfprintf(stderr, fmt, ap);
39 ea2384d3 bellard
    fprintf(stderr, "\n");
40 ea2384d3 bellard
    exit(1);
41 ea2384d3 bellard
    va_end(ap);
42 ea2384d3 bellard
}
43 ea2384d3 bellard
44 ea2384d3 bellard
static void format_print(void *opaque, const char *name)
45 ea2384d3 bellard
{
46 ea2384d3 bellard
    printf(" %s", name);
47 ea2384d3 bellard
}
48 ea2384d3 bellard
49 3f379ab1 pbrook
static void help(void)
50 ea2384d3 bellard
{
51 68d0f70e bellard
    printf("qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fabrice Bellard\n"
52 57d1a2b6 bellard
           "usage: qemu-img command [command options]\n"
53 ea2384d3 bellard
           "QEMU disk image utility\n"
54 ea2384d3 bellard
           "\n"
55 ea2384d3 bellard
           "Command syntax:\n"
56 ec36ba14 ths
           "  create [-e] [-6] [-b base_image] [-f fmt] filename [size]\n"
57 ea2384d3 bellard
           "  commit [-f fmt] filename\n"
58 c0be16d3 balrog
           "  convert [-c] [-e] [-6] [-f fmt] [-O output_fmt] filename [filename2 [...]] output_filename\n"
59 ea2384d3 bellard
           "  info [-f fmt] filename\n"
60 ea2384d3 bellard
           "\n"
61 ea2384d3 bellard
           "Command parameters:\n"
62 ea2384d3 bellard
           "  'filename' is a disk image filename\n"
63 ea2384d3 bellard
           "  'base_image' is the read-only disk image which is used as base for a copy on\n"
64 ea2384d3 bellard
           "    write image; the copy on write image only stores the modified data\n"
65 ea2384d3 bellard
           "  'fmt' is the disk image format. It is guessed automatically in most cases\n"
66 ea2384d3 bellard
           "  'size' is the disk image size in kilobytes. Optional suffixes 'M' (megabyte)\n"
67 ea2384d3 bellard
           "    and 'G' (gigabyte) are supported\n"
68 ea2384d3 bellard
           "  'output_filename' is the destination disk image filename\n"
69 ea2384d3 bellard
           "  'output_fmt' is the destination format\n"
70 ea2384d3 bellard
           "  '-c' indicates that target image must be compressed (qcow format only)\n"
71 ea2384d3 bellard
           "  '-e' indicates that the target image must be encrypted (qcow format only)\n"
72 ec36ba14 ths
           "  '-6' indicates that the target image must use compatibility level 6 (vmdk format only)\n"
73 ea2384d3 bellard
           );
74 ea2384d3 bellard
    printf("\nSupported format:");
75 ea2384d3 bellard
    bdrv_iterate_format(format_print, NULL);
76 ea2384d3 bellard
    printf("\n");
77 ea2384d3 bellard
    exit(1);
78 ea2384d3 bellard
}
79 ea2384d3 bellard
80 ea2384d3 bellard
#if defined(WIN32)
81 ea2384d3 bellard
/* XXX: put correct support for win32 */
82 ea2384d3 bellard
static int read_password(char *buf, int buf_size)
83 ea2384d3 bellard
{
84 ea2384d3 bellard
    int c, i;
85 ea2384d3 bellard
    printf("Password: ");
86 ea2384d3 bellard
    fflush(stdout);
87 ea2384d3 bellard
    i = 0;
88 ea2384d3 bellard
    for(;;) {
89 ea2384d3 bellard
        c = getchar();
90 ea2384d3 bellard
        if (c == '\n')
91 ea2384d3 bellard
            break;
92 ea2384d3 bellard
        if (i < (buf_size - 1))
93 ea2384d3 bellard
            buf[i++] = c;
94 ea2384d3 bellard
    }
95 ea2384d3 bellard
    buf[i] = '\0';
96 ea2384d3 bellard
    return 0;
97 ea2384d3 bellard
}
98 ea2384d3 bellard
99 ea2384d3 bellard
#else
100 ea2384d3 bellard
101 ea2384d3 bellard
#include <termios.h>
102 ea2384d3 bellard
103 ea2384d3 bellard
static struct termios oldtty;
104 ea2384d3 bellard
105 ea2384d3 bellard
static void term_exit(void)
106 ea2384d3 bellard
{
107 ea2384d3 bellard
    tcsetattr (0, TCSANOW, &oldtty);
108 ea2384d3 bellard
}
109 ea2384d3 bellard
110 ea2384d3 bellard
static void term_init(void)
111 ea2384d3 bellard
{
112 ea2384d3 bellard
    struct termios tty;
113 ea2384d3 bellard
114 ea2384d3 bellard
    tcgetattr (0, &tty);
115 ea2384d3 bellard
    oldtty = tty;
116 ea2384d3 bellard
117 ea2384d3 bellard
    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
118 ea2384d3 bellard
                          |INLCR|IGNCR|ICRNL|IXON);
119 ea2384d3 bellard
    tty.c_oflag |= OPOST;
120 ea2384d3 bellard
    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
121 ea2384d3 bellard
    tty.c_cflag &= ~(CSIZE|PARENB);
122 ea2384d3 bellard
    tty.c_cflag |= CS8;
123 ea2384d3 bellard
    tty.c_cc[VMIN] = 1;
124 ea2384d3 bellard
    tty.c_cc[VTIME] = 0;
125 3b46e624 ths
126 ea2384d3 bellard
    tcsetattr (0, TCSANOW, &tty);
127 ea2384d3 bellard
128 ea2384d3 bellard
    atexit(term_exit);
129 ea2384d3 bellard
}
130 ea2384d3 bellard
131 3f379ab1 pbrook
static int read_password(char *buf, int buf_size)
132 ea2384d3 bellard
{
133 ea2384d3 bellard
    uint8_t ch;
134 ea2384d3 bellard
    int i, ret;
135 ea2384d3 bellard
136 ea2384d3 bellard
    printf("password: ");
137 ea2384d3 bellard
    fflush(stdout);
138 ea2384d3 bellard
    term_init();
139 ea2384d3 bellard
    i = 0;
140 ea2384d3 bellard
    for(;;) {
141 ea2384d3 bellard
        ret = read(0, &ch, 1);
142 ea2384d3 bellard
        if (ret == -1) {
143 ea2384d3 bellard
            if (errno == EAGAIN || errno == EINTR) {
144 ea2384d3 bellard
                continue;
145 ea2384d3 bellard
            } else {
146 ea2384d3 bellard
                ret = -1;
147 ea2384d3 bellard
                break;
148 ea2384d3 bellard
            }
149 ea2384d3 bellard
        } else if (ret == 0) {
150 ea2384d3 bellard
            ret = -1;
151 ea2384d3 bellard
            break;
152 ea2384d3 bellard
        } else {
153 ea2384d3 bellard
            if (ch == '\r') {
154 ea2384d3 bellard
                ret = 0;
155 ea2384d3 bellard
                break;
156 ea2384d3 bellard
            }
157 ea2384d3 bellard
            if (i < (buf_size - 1))
158 ea2384d3 bellard
                buf[i++] = ch;
159 ea2384d3 bellard
        }
160 ea2384d3 bellard
    }
161 ea2384d3 bellard
    term_exit();
162 ea2384d3 bellard
    buf[i] = '\0';
163 ea2384d3 bellard
    printf("\n");
164 ea2384d3 bellard
    return ret;
165 ea2384d3 bellard
}
166 ea2384d3 bellard
#endif
167 ea2384d3 bellard
168 75c23805 bellard
static BlockDriverState *bdrv_new_open(const char *filename,
169 75c23805 bellard
                                       const char *fmt)
170 75c23805 bellard
{
171 75c23805 bellard
    BlockDriverState *bs;
172 75c23805 bellard
    BlockDriver *drv;
173 75c23805 bellard
    char password[256];
174 75c23805 bellard
175 75c23805 bellard
    bs = bdrv_new("");
176 75c23805 bellard
    if (!bs)
177 75c23805 bellard
        error("Not enough memory");
178 75c23805 bellard
    if (fmt) {
179 75c23805 bellard
        drv = bdrv_find_format(fmt);
180 75c23805 bellard
        if (!drv)
181 75c23805 bellard
            error("Unknown file format '%s'", fmt);
182 75c23805 bellard
    } else {
183 75c23805 bellard
        drv = NULL;
184 75c23805 bellard
    }
185 75c23805 bellard
    if (bdrv_open2(bs, filename, 0, drv) < 0) {
186 75c23805 bellard
        error("Could not open '%s'", filename);
187 75c23805 bellard
    }
188 75c23805 bellard
    if (bdrv_is_encrypted(bs)) {
189 75c23805 bellard
        printf("Disk image '%s' is encrypted.\n", filename);
190 75c23805 bellard
        if (read_password(password, sizeof(password)) < 0)
191 75c23805 bellard
            error("No password given");
192 75c23805 bellard
        if (bdrv_set_key(bs, password) < 0)
193 75c23805 bellard
            error("invalid password");
194 75c23805 bellard
    }
195 75c23805 bellard
    return bs;
196 75c23805 bellard
}
197 75c23805 bellard
198 ea2384d3 bellard
static int img_create(int argc, char **argv)
199 ea2384d3 bellard
{
200 ec36ba14 ths
    int c, ret, flags;
201 ea2384d3 bellard
    const char *fmt = "raw";
202 ea2384d3 bellard
    const char *filename;
203 ea2384d3 bellard
    const char *base_filename = NULL;
204 96b8f136 ths
    uint64_t size;
205 ea2384d3 bellard
    const char *p;
206 ea2384d3 bellard
    BlockDriver *drv;
207 3b46e624 ths
208 ec36ba14 ths
    flags = 0;
209 ea2384d3 bellard
    for(;;) {
210 ec36ba14 ths
        c = getopt(argc, argv, "b:f:he6");
211 ea2384d3 bellard
        if (c == -1)
212 ea2384d3 bellard
            break;
213 ea2384d3 bellard
        switch(c) {
214 ea2384d3 bellard
        case 'h':
215 ea2384d3 bellard
            help();
216 ea2384d3 bellard
            break;
217 ea2384d3 bellard
        case 'b':
218 ea2384d3 bellard
            base_filename = optarg;
219 ea2384d3 bellard
            break;
220 ea2384d3 bellard
        case 'f':
221 ea2384d3 bellard
            fmt = optarg;
222 ea2384d3 bellard
            break;
223 ea2384d3 bellard
        case 'e':
224 ec36ba14 ths
            flags |= BLOCK_FLAG_ENCRYPT;
225 ea2384d3 bellard
            break;
226 d8871c5a ths
        case '6':
227 ec36ba14 ths
            flags |= BLOCK_FLAG_COMPAT6;
228 d8871c5a ths
            break;
229 ea2384d3 bellard
        }
230 ea2384d3 bellard
    }
231 5fafdf24 ths
    if (optind >= argc)
232 ea2384d3 bellard
        help();
233 ea2384d3 bellard
    filename = argv[optind++];
234 ea2384d3 bellard
    size = 0;
235 75c23805 bellard
    if (base_filename) {
236 75c23805 bellard
        BlockDriverState *bs;
237 75c23805 bellard
        bs = bdrv_new_open(base_filename, NULL);
238 75c23805 bellard
        bdrv_get_geometry(bs, &size);
239 75c23805 bellard
        size *= 512;
240 75c23805 bellard
        bdrv_delete(bs);
241 75c23805 bellard
    } else {
242 ea2384d3 bellard
        if (optind >= argc)
243 ea2384d3 bellard
            help();
244 ea2384d3 bellard
        p = argv[optind];
245 ea2384d3 bellard
        size = strtoul(p, (char **)&p, 0);
246 ea2384d3 bellard
        if (*p == 'M') {
247 ea2384d3 bellard
            size *= 1024 * 1024;
248 ea2384d3 bellard
        } else if (*p == 'G') {
249 ea2384d3 bellard
            size *= 1024 * 1024 * 1024;
250 ea2384d3 bellard
        } else if (*p == 'k' || *p == 'K' || *p == '\0') {
251 ea2384d3 bellard
            size *= 1024;
252 ea2384d3 bellard
        } else {
253 ea2384d3 bellard
            help();
254 ea2384d3 bellard
        }
255 ea2384d3 bellard
    }
256 ea2384d3 bellard
    drv = bdrv_find_format(fmt);
257 ea2384d3 bellard
    if (!drv)
258 ea2384d3 bellard
        error("Unknown file format '%s'", fmt);
259 0cfec834 ths
    printf("Formatting '%s', fmt=%s",
260 ea2384d3 bellard
           filename, fmt);
261 ec36ba14 ths
    if (flags & BLOCK_FLAG_ENCRYPT)
262 ea2384d3 bellard
        printf(", encrypted");
263 ec36ba14 ths
    if (flags & BLOCK_FLAG_COMPAT6)
264 ec36ba14 ths
        printf(", compatibility level=6");
265 75c23805 bellard
    if (base_filename) {
266 75c23805 bellard
        printf(", backing_file=%s",
267 ea2384d3 bellard
               base_filename);
268 75c23805 bellard
    }
269 96b8f136 ths
    printf(", size=%" PRIu64 " kB\n", size / 1024);
270 ec36ba14 ths
    ret = bdrv_create(drv, filename, size / 512, base_filename, flags);
271 ea2384d3 bellard
    if (ret < 0) {
272 ea2384d3 bellard
        if (ret == -ENOTSUP) {
273 3c56521b bellard
            error("Formatting or formatting option not supported for file format '%s'", fmt);
274 ea2384d3 bellard
        } else {
275 ea2384d3 bellard
            error("Error while formatting");
276 ea2384d3 bellard
        }
277 ea2384d3 bellard
    }
278 ea2384d3 bellard
    return 0;
279 ea2384d3 bellard
}
280 ea2384d3 bellard
281 ea2384d3 bellard
static int img_commit(int argc, char **argv)
282 ea2384d3 bellard
{
283 ea2384d3 bellard
    int c, ret;
284 ea2384d3 bellard
    const char *filename, *fmt;
285 ea2384d3 bellard
    BlockDriver *drv;
286 ea2384d3 bellard
    BlockDriverState *bs;
287 ea2384d3 bellard
288 ea2384d3 bellard
    fmt = NULL;
289 ea2384d3 bellard
    for(;;) {
290 ea2384d3 bellard
        c = getopt(argc, argv, "f:h");
291 ea2384d3 bellard
        if (c == -1)
292 ea2384d3 bellard
            break;
293 ea2384d3 bellard
        switch(c) {
294 ea2384d3 bellard
        case 'h':
295 ea2384d3 bellard
            help();
296 ea2384d3 bellard
            break;
297 ea2384d3 bellard
        case 'f':
298 ea2384d3 bellard
            fmt = optarg;
299 ea2384d3 bellard
            break;
300 ea2384d3 bellard
        }
301 ea2384d3 bellard
    }
302 5fafdf24 ths
    if (optind >= argc)
303 ea2384d3 bellard
        help();
304 ea2384d3 bellard
    filename = argv[optind++];
305 ea2384d3 bellard
306 ea2384d3 bellard
    bs = bdrv_new("");
307 ea2384d3 bellard
    if (!bs)
308 ea2384d3 bellard
        error("Not enough memory");
309 ea2384d3 bellard
    if (fmt) {
310 ea2384d3 bellard
        drv = bdrv_find_format(fmt);
311 ea2384d3 bellard
        if (!drv)
312 ea2384d3 bellard
            error("Unknown file format '%s'", fmt);
313 ea2384d3 bellard
    } else {
314 ea2384d3 bellard
        drv = NULL;
315 ea2384d3 bellard
    }
316 ea2384d3 bellard
    if (bdrv_open2(bs, filename, 0, drv) < 0) {
317 ea2384d3 bellard
        error("Could not open '%s'", filename);
318 ea2384d3 bellard
    }
319 ea2384d3 bellard
    ret = bdrv_commit(bs);
320 ea2384d3 bellard
    switch(ret) {
321 ea2384d3 bellard
    case 0:
322 ea2384d3 bellard
        printf("Image committed.\n");
323 ea2384d3 bellard
        break;
324 ea2384d3 bellard
    case -ENOENT:
325 ea2384d3 bellard
        error("No disk inserted");
326 ea2384d3 bellard
        break;
327 ea2384d3 bellard
    case -EACCES:
328 ea2384d3 bellard
        error("Image is read-only");
329 ea2384d3 bellard
        break;
330 ea2384d3 bellard
    case -ENOTSUP:
331 ea2384d3 bellard
        error("Image is already committed");
332 ea2384d3 bellard
        break;
333 ea2384d3 bellard
    default:
334 ea2384d3 bellard
        error("Error while committing image");
335 ea2384d3 bellard
        break;
336 ea2384d3 bellard
    }
337 ea2384d3 bellard
338 ea2384d3 bellard
    bdrv_delete(bs);
339 ea2384d3 bellard
    return 0;
340 ea2384d3 bellard
}
341 ea2384d3 bellard
342 ea2384d3 bellard
static int is_not_zero(const uint8_t *sector, int len)
343 ea2384d3 bellard
{
344 ea2384d3 bellard
    int i;
345 ea2384d3 bellard
    len >>= 2;
346 ea2384d3 bellard
    for(i = 0;i < len; i++) {
347 ea2384d3 bellard
        if (((uint32_t *)sector)[i] != 0)
348 ea2384d3 bellard
            return 1;
349 ea2384d3 bellard
    }
350 ea2384d3 bellard
    return 0;
351 ea2384d3 bellard
}
352 ea2384d3 bellard
353 ea2384d3 bellard
static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
354 ea2384d3 bellard
{
355 ea2384d3 bellard
    int v, i;
356 ea2384d3 bellard
357 ea2384d3 bellard
    if (n <= 0) {
358 ea2384d3 bellard
        *pnum = 0;
359 ea2384d3 bellard
        return 0;
360 ea2384d3 bellard
    }
361 ea2384d3 bellard
    v = is_not_zero(buf, 512);
362 ea2384d3 bellard
    for(i = 1; i < n; i++) {
363 ea2384d3 bellard
        buf += 512;
364 ea2384d3 bellard
        if (v != is_not_zero(buf, 512))
365 ea2384d3 bellard
            break;
366 ea2384d3 bellard
    }
367 ea2384d3 bellard
    *pnum = i;
368 ea2384d3 bellard
    return v;
369 ea2384d3 bellard
}
370 ea2384d3 bellard
371 ea2384d3 bellard
#define IO_BUF_SIZE 65536
372 ea2384d3 bellard
373 ea2384d3 bellard
static int img_convert(int argc, char **argv)
374 ea2384d3 bellard
{
375 926c2d23 balrog
    int c, ret, n, n1, bs_n, bs_i, flags, cluster_size, cluster_sectors;
376 926c2d23 balrog
    const char *fmt, *out_fmt, *out_filename;
377 ea2384d3 bellard
    BlockDriver *drv;
378 926c2d23 balrog
    BlockDriverState **bs, *out_bs;
379 96b8f136 ths
    int64_t total_sectors, nb_sectors, sector_num, bs_offset;
380 96b8f136 ths
    uint64_t bs_sectors;
381 ea2384d3 bellard
    uint8_t buf[IO_BUF_SIZE];
382 ea2384d3 bellard
    const uint8_t *buf1;
383 faea38e7 bellard
    BlockDriverInfo bdi;
384 ea2384d3 bellard
385 ea2384d3 bellard
    fmt = NULL;
386 ea2384d3 bellard
    out_fmt = "raw";
387 ec36ba14 ths
    flags = 0;
388 ea2384d3 bellard
    for(;;) {
389 ec36ba14 ths
        c = getopt(argc, argv, "f:O:hce6");
390 ea2384d3 bellard
        if (c == -1)
391 ea2384d3 bellard
            break;
392 ea2384d3 bellard
        switch(c) {
393 ea2384d3 bellard
        case 'h':
394 ea2384d3 bellard
            help();
395 ea2384d3 bellard
            break;
396 ea2384d3 bellard
        case 'f':
397 ea2384d3 bellard
            fmt = optarg;
398 ea2384d3 bellard
            break;
399 ea2384d3 bellard
        case 'O':
400 ea2384d3 bellard
            out_fmt = optarg;
401 ea2384d3 bellard
            break;
402 ea2384d3 bellard
        case 'c':
403 ec36ba14 ths
            flags |= BLOCK_FLAG_COMPRESS;
404 ea2384d3 bellard
            break;
405 ea2384d3 bellard
        case 'e':
406 ec36ba14 ths
            flags |= BLOCK_FLAG_ENCRYPT;
407 ec36ba14 ths
            break;
408 ec36ba14 ths
        case '6':
409 ec36ba14 ths
            flags |= BLOCK_FLAG_COMPAT6;
410 ea2384d3 bellard
            break;
411 ea2384d3 bellard
        }
412 ea2384d3 bellard
    }
413 3b46e624 ths
414 926c2d23 balrog
    bs_n = argc - optind - 1;
415 926c2d23 balrog
    if (bs_n < 1) help();
416 926c2d23 balrog
417 926c2d23 balrog
    out_filename = argv[argc - 1];
418 926c2d23 balrog
        
419 926c2d23 balrog
    bs = calloc(bs_n, sizeof(BlockDriverState *));
420 926c2d23 balrog
    if (!bs)
421 926c2d23 balrog
        error("Out of memory");
422 926c2d23 balrog
423 926c2d23 balrog
    total_sectors = 0;
424 926c2d23 balrog
    for (bs_i = 0; bs_i < bs_n; bs_i++) {
425 926c2d23 balrog
        bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt);
426 926c2d23 balrog
        if (!bs[bs_i])
427 926c2d23 balrog
            error("Could not open '%s'", argv[optind + bs_i]);
428 926c2d23 balrog
        bdrv_get_geometry(bs[bs_i], &bs_sectors);
429 926c2d23 balrog
        total_sectors += bs_sectors;
430 926c2d23 balrog
    }
431 ea2384d3 bellard
432 ea2384d3 bellard
    drv = bdrv_find_format(out_fmt);
433 ea2384d3 bellard
    if (!drv)
434 d34dda5e ths
        error("Unknown file format '%s'", out_fmt);
435 ec36ba14 ths
    if (flags & BLOCK_FLAG_COMPRESS && drv != &bdrv_qcow && drv != &bdrv_qcow2)
436 ea2384d3 bellard
        error("Compression not supported for this file format");
437 ec36ba14 ths
    if (flags & BLOCK_FLAG_ENCRYPT && drv != &bdrv_qcow && drv != &bdrv_qcow2)
438 ea2384d3 bellard
        error("Encryption not supported for this file format");
439 d8871c5a ths
    if (flags & BLOCK_FLAG_COMPAT6 && drv != &bdrv_vmdk)
440 ec36ba14 ths
        error("Alternative compatibility level not supported for this file format");
441 ec36ba14 ths
    if (flags & BLOCK_FLAG_ENCRYPT && flags & BLOCK_FLAG_COMPRESS)
442 ea2384d3 bellard
        error("Compression and encryption not supported at the same time");
443 926c2d23 balrog
444 ec36ba14 ths
    ret = bdrv_create(drv, out_filename, total_sectors, NULL, flags);
445 ea2384d3 bellard
    if (ret < 0) {
446 ea2384d3 bellard
        if (ret == -ENOTSUP) {
447 3c56521b bellard
            error("Formatting not supported for file format '%s'", fmt);
448 ea2384d3 bellard
        } else {
449 ea2384d3 bellard
            error("Error while formatting '%s'", out_filename);
450 ea2384d3 bellard
        }
451 ea2384d3 bellard
    }
452 3b46e624 ths
453 ea2384d3 bellard
    out_bs = bdrv_new_open(out_filename, out_fmt);
454 ea2384d3 bellard
455 926c2d23 balrog
    bs_i = 0;
456 926c2d23 balrog
    bs_offset = 0;
457 926c2d23 balrog
    bdrv_get_geometry(bs[0], &bs_sectors);
458 926c2d23 balrog
459 926c2d23 balrog
    if (flags & BLOCK_FLAG_COMPRESS) {
460 faea38e7 bellard
        if (bdrv_get_info(out_bs, &bdi) < 0)
461 faea38e7 bellard
            error("could not get block driver info");
462 faea38e7 bellard
        cluster_size = bdi.cluster_size;
463 ea2384d3 bellard
        if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE)
464 ea2384d3 bellard
            error("invalid cluster size");
465 ea2384d3 bellard
        cluster_sectors = cluster_size >> 9;
466 ea2384d3 bellard
        sector_num = 0;
467 ea2384d3 bellard
        for(;;) {
468 926c2d23 balrog
            int64_t bs_num;
469 926c2d23 balrog
            int remainder;
470 926c2d23 balrog
            uint8_t *buf2;
471 926c2d23 balrog
472 ea2384d3 bellard
            nb_sectors = total_sectors - sector_num;
473 ea2384d3 bellard
            if (nb_sectors <= 0)
474 ea2384d3 bellard
                break;
475 ea2384d3 bellard
            if (nb_sectors >= cluster_sectors)
476 ea2384d3 bellard
                n = cluster_sectors;
477 ea2384d3 bellard
            else
478 ea2384d3 bellard
                n = nb_sectors;
479 926c2d23 balrog
480 926c2d23 balrog
            bs_num = sector_num - bs_offset;
481 926c2d23 balrog
            assert (bs_num >= 0);
482 926c2d23 balrog
            remainder = n;
483 926c2d23 balrog
            buf2 = buf;
484 926c2d23 balrog
            while (remainder > 0) {
485 926c2d23 balrog
                int nlow;
486 926c2d23 balrog
                while (bs_num == bs_sectors) {
487 926c2d23 balrog
                    bs_i++;
488 926c2d23 balrog
                    assert (bs_i < bs_n);
489 926c2d23 balrog
                    bs_offset += bs_sectors;
490 926c2d23 balrog
                    bdrv_get_geometry(bs[bs_i], &bs_sectors);
491 926c2d23 balrog
                    bs_num = 0;
492 926c2d23 balrog
                    /* printf("changing part: sector_num=%lld, "
493 926c2d23 balrog
                       "bs_i=%d, bs_offset=%lld, bs_sectors=%lld\n",
494 926c2d23 balrog
                       sector_num, bs_i, bs_offset, bs_sectors); */
495 926c2d23 balrog
                }
496 926c2d23 balrog
                assert (bs_num < bs_sectors);
497 926c2d23 balrog
498 926c2d23 balrog
                nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;
499 926c2d23 balrog
500 926c2d23 balrog
                if (bdrv_read(bs[bs_i], bs_num, buf2, nlow) < 0) 
501 926c2d23 balrog
                    error("error while reading");
502 926c2d23 balrog
503 926c2d23 balrog
                buf2 += nlow * 512;
504 926c2d23 balrog
                bs_num += nlow;
505 926c2d23 balrog
506 926c2d23 balrog
                remainder -= nlow;
507 926c2d23 balrog
            }
508 926c2d23 balrog
            assert (remainder == 0);
509 926c2d23 balrog
510 ea2384d3 bellard
            if (n < cluster_sectors)
511 ea2384d3 bellard
                memset(buf + n * 512, 0, cluster_size - n * 512);
512 ea2384d3 bellard
            if (is_not_zero(buf, cluster_size)) {
513 5fafdf24 ths
                if (bdrv_write_compressed(out_bs, sector_num, buf,
514 faea38e7 bellard
                                          cluster_sectors) != 0)
515 ec3757de bellard
                    error("error while compressing sector %" PRId64,
516 ec3757de bellard
                          sector_num);
517 ea2384d3 bellard
            }
518 ea2384d3 bellard
            sector_num += n;
519 ea2384d3 bellard
        }
520 faea38e7 bellard
        /* signal EOF to align */
521 faea38e7 bellard
        bdrv_write_compressed(out_bs, 0, NULL, 0);
522 ea2384d3 bellard
    } else {
523 ea2384d3 bellard
        sector_num = 0;
524 ea2384d3 bellard
        for(;;) {
525 ea2384d3 bellard
            nb_sectors = total_sectors - sector_num;
526 ea2384d3 bellard
            if (nb_sectors <= 0)
527 ea2384d3 bellard
                break;
528 ea2384d3 bellard
            if (nb_sectors >= (IO_BUF_SIZE / 512))
529 ea2384d3 bellard
                n = (IO_BUF_SIZE / 512);
530 ea2384d3 bellard
            else
531 ea2384d3 bellard
                n = nb_sectors;
532 926c2d23 balrog
533 926c2d23 balrog
            while (sector_num - bs_offset >= bs_sectors) {
534 926c2d23 balrog
                bs_i ++;
535 926c2d23 balrog
                assert (bs_i < bs_n);
536 926c2d23 balrog
                bs_offset += bs_sectors;
537 926c2d23 balrog
                bdrv_get_geometry(bs[bs_i], &bs_sectors);
538 926c2d23 balrog
                /* printf("changing part: sector_num=%lld, bs_i=%d, "
539 926c2d23 balrog
                  "bs_offset=%lld, bs_sectors=%lld\n",
540 926c2d23 balrog
                   sector_num, bs_i, bs_offset, bs_sectors); */
541 926c2d23 balrog
            }
542 926c2d23 balrog
543 926c2d23 balrog
            if (n > bs_offset + bs_sectors - sector_num)
544 926c2d23 balrog
                n = bs_offset + bs_sectors - sector_num;
545 926c2d23 balrog
546 926c2d23 balrog
            if (bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n) < 0) 
547 ea2384d3 bellard
                error("error while reading");
548 ea2384d3 bellard
            /* NOTE: at the same time we convert, we do not write zero
549 ea2384d3 bellard
               sectors to have a chance to compress the image. Ideally, we
550 ea2384d3 bellard
               should add a specific call to have the info to go faster */
551 ea2384d3 bellard
            buf1 = buf;
552 ea2384d3 bellard
            while (n > 0) {
553 ea2384d3 bellard
                if (is_allocated_sectors(buf1, n, &n1)) {
554 5fafdf24 ths
                    if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
555 ea2384d3 bellard
                        error("error while writing");
556 ea2384d3 bellard
                }
557 ea2384d3 bellard
                sector_num += n1;
558 ea2384d3 bellard
                n -= n1;
559 ea2384d3 bellard
                buf1 += n1 * 512;
560 ea2384d3 bellard
            }
561 ea2384d3 bellard
        }
562 ea2384d3 bellard
    }
563 ea2384d3 bellard
    bdrv_delete(out_bs);
564 926c2d23 balrog
    for (bs_i = 0; bs_i < bs_n; bs_i++)
565 926c2d23 balrog
        bdrv_delete(bs[bs_i]);
566 926c2d23 balrog
    free(bs);
567 ea2384d3 bellard
    return 0;
568 ea2384d3 bellard
}
569 ea2384d3 bellard
570 57d1a2b6 bellard
#ifdef _WIN32
571 57d1a2b6 bellard
static int64_t get_allocated_file_size(const char *filename)
572 57d1a2b6 bellard
{
573 e8445331 bellard
    typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
574 e8445331 bellard
    get_compressed_t get_compressed;
575 57d1a2b6 bellard
    struct _stati64 st;
576 e8445331 bellard
577 e8445331 bellard
    /* WinNT support GetCompressedFileSize to determine allocate size */
578 e8445331 bellard
    get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
579 e8445331 bellard
    if (get_compressed) {
580 e8445331 bellard
            DWORD high, low;
581 e8445331 bellard
            low = get_compressed(filename, &high);
582 e8445331 bellard
            if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
583 e8445331 bellard
            return (((int64_t) high) << 32) + low;
584 e8445331 bellard
    }
585 e8445331 bellard
586 5fafdf24 ths
    if (_stati64(filename, &st) < 0)
587 57d1a2b6 bellard
        return -1;
588 57d1a2b6 bellard
    return st.st_size;
589 57d1a2b6 bellard
}
590 57d1a2b6 bellard
#else
591 57d1a2b6 bellard
static int64_t get_allocated_file_size(const char *filename)
592 57d1a2b6 bellard
{
593 57d1a2b6 bellard
    struct stat st;
594 5fafdf24 ths
    if (stat(filename, &st) < 0)
595 57d1a2b6 bellard
        return -1;
596 57d1a2b6 bellard
    return (int64_t)st.st_blocks * 512;
597 57d1a2b6 bellard
}
598 57d1a2b6 bellard
#endif
599 57d1a2b6 bellard
600 faea38e7 bellard
static void dump_snapshots(BlockDriverState *bs)
601 faea38e7 bellard
{
602 faea38e7 bellard
    QEMUSnapshotInfo *sn_tab, *sn;
603 faea38e7 bellard
    int nb_sns, i;
604 faea38e7 bellard
    char buf[256];
605 faea38e7 bellard
606 faea38e7 bellard
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
607 faea38e7 bellard
    if (nb_sns <= 0)
608 faea38e7 bellard
        return;
609 faea38e7 bellard
    printf("Snapshot list:\n");
610 faea38e7 bellard
    printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
611 faea38e7 bellard
    for(i = 0; i < nb_sns; i++) {
612 faea38e7 bellard
        sn = &sn_tab[i];
613 faea38e7 bellard
        printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
614 faea38e7 bellard
    }
615 faea38e7 bellard
    qemu_free(sn_tab);
616 faea38e7 bellard
}
617 faea38e7 bellard
618 ea2384d3 bellard
static int img_info(int argc, char **argv)
619 ea2384d3 bellard
{
620 ea2384d3 bellard
    int c;
621 ea2384d3 bellard
    const char *filename, *fmt;
622 ea2384d3 bellard
    BlockDriver *drv;
623 ea2384d3 bellard
    BlockDriverState *bs;
624 ea2384d3 bellard
    char fmt_name[128], size_buf[128], dsize_buf[128];
625 96b8f136 ths
    uint64_t total_sectors;
626 96b8f136 ths
    int64_t allocated_size;
627 93b6b2a3 bellard
    char backing_filename[1024];
628 93b6b2a3 bellard
    char backing_filename2[1024];
629 faea38e7 bellard
    BlockDriverInfo bdi;
630 ea2384d3 bellard
631 ea2384d3 bellard
    fmt = NULL;
632 ea2384d3 bellard
    for(;;) {
633 ea2384d3 bellard
        c = getopt(argc, argv, "f:h");
634 ea2384d3 bellard
        if (c == -1)
635 ea2384d3 bellard
            break;
636 ea2384d3 bellard
        switch(c) {
637 ea2384d3 bellard
        case 'h':
638 ea2384d3 bellard
            help();
639 ea2384d3 bellard
            break;
640 ea2384d3 bellard
        case 'f':
641 ea2384d3 bellard
            fmt = optarg;
642 ea2384d3 bellard
            break;
643 ea2384d3 bellard
        }
644 ea2384d3 bellard
    }
645 5fafdf24 ths
    if (optind >= argc)
646 ea2384d3 bellard
        help();
647 ea2384d3 bellard
    filename = argv[optind++];
648 ea2384d3 bellard
649 ea2384d3 bellard
    bs = bdrv_new("");
650 ea2384d3 bellard
    if (!bs)
651 ea2384d3 bellard
        error("Not enough memory");
652 ea2384d3 bellard
    if (fmt) {
653 ea2384d3 bellard
        drv = bdrv_find_format(fmt);
654 ea2384d3 bellard
        if (!drv)
655 ea2384d3 bellard
            error("Unknown file format '%s'", fmt);
656 ea2384d3 bellard
    } else {
657 ea2384d3 bellard
        drv = NULL;
658 ea2384d3 bellard
    }
659 ea2384d3 bellard
    if (bdrv_open2(bs, filename, 0, drv) < 0) {
660 ea2384d3 bellard
        error("Could not open '%s'", filename);
661 ea2384d3 bellard
    }
662 ea2384d3 bellard
    bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
663 ea2384d3 bellard
    bdrv_get_geometry(bs, &total_sectors);
664 ea2384d3 bellard
    get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
665 57d1a2b6 bellard
    allocated_size = get_allocated_file_size(filename);
666 57d1a2b6 bellard
    if (allocated_size < 0)
667 de167e41 bellard
        sprintf(dsize_buf, "unavailable");
668 de167e41 bellard
    else
669 5fafdf24 ths
        get_human_readable_size(dsize_buf, sizeof(dsize_buf),
670 de167e41 bellard
                                allocated_size);
671 ea2384d3 bellard
    printf("image: %s\n"
672 ea2384d3 bellard
           "file format: %s\n"
673 ec3757de bellard
           "virtual size: %s (%" PRId64 " bytes)\n"
674 ea2384d3 bellard
           "disk size: %s\n",
675 5fafdf24 ths
           filename, fmt_name, size_buf,
676 ec3757de bellard
           (total_sectors * 512),
677 ea2384d3 bellard
           dsize_buf);
678 ea2384d3 bellard
    if (bdrv_is_encrypted(bs))
679 ea2384d3 bellard
        printf("encrypted: yes\n");
680 faea38e7 bellard
    if (bdrv_get_info(bs, &bdi) >= 0) {
681 5fafdf24 ths
        if (bdi.cluster_size != 0)
682 faea38e7 bellard
            printf("cluster_size: %d\n", bdi.cluster_size);
683 faea38e7 bellard
    }
684 93b6b2a3 bellard
    bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
685 faea38e7 bellard
    if (backing_filename[0] != '\0') {
686 93b6b2a3 bellard
        path_combine(backing_filename2, sizeof(backing_filename2),
687 93b6b2a3 bellard
                     filename, backing_filename);
688 5fafdf24 ths
        printf("backing file: %s (actual path: %s)\n",
689 93b6b2a3 bellard
               backing_filename,
690 93b6b2a3 bellard
               backing_filename2);
691 faea38e7 bellard
    }
692 faea38e7 bellard
    dump_snapshots(bs);
693 ea2384d3 bellard
    bdrv_delete(bs);
694 ea2384d3 bellard
    return 0;
695 ea2384d3 bellard
}
696 ea2384d3 bellard
697 ea2384d3 bellard
int main(int argc, char **argv)
698 ea2384d3 bellard
{
699 ea2384d3 bellard
    const char *cmd;
700 ea2384d3 bellard
701 ea2384d3 bellard
    bdrv_init();
702 ea2384d3 bellard
    if (argc < 2)
703 ea2384d3 bellard
        help();
704 ea2384d3 bellard
    cmd = argv[1];
705 e3888186 bellard
    optind++;
706 ea2384d3 bellard
    if (!strcmp(cmd, "create")) {
707 ea2384d3 bellard
        img_create(argc, argv);
708 ea2384d3 bellard
    } else if (!strcmp(cmd, "commit")) {
709 ea2384d3 bellard
        img_commit(argc, argv);
710 ea2384d3 bellard
    } else if (!strcmp(cmd, "convert")) {
711 ea2384d3 bellard
        img_convert(argc, argv);
712 ea2384d3 bellard
    } else if (!strcmp(cmd, "info")) {
713 ea2384d3 bellard
        img_info(argc, argv);
714 ea2384d3 bellard
    } else {
715 ea2384d3 bellard
        help();
716 ea2384d3 bellard
    }
717 ea2384d3 bellard
    return 0;
718 ea2384d3 bellard
}