Commit ea2384d36e1e5f6dfd44b748d290762181c38350

Authored by bellard
1 parent e4d4fe3c

new disk image layer


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1037 c046a42c-6fe2-441c-8c8c-71466251a162
block-cow.c 0 → 100644
  1 +/*
  2 + * Block driver for the COW format
  3 + *
  4 + * Copyright (c) 2004 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#ifndef _WIN32
  25 +#include "vl.h"
  26 +#include "block_int.h"
  27 +#include <sys/mman.h>
  28 +
  29 +/**************************************************************/
  30 +/* COW block driver using file system holes */
  31 +
  32 +/* user mode linux compatible COW file */
  33 +#define COW_MAGIC 0x4f4f4f4d /* MOOO */
  34 +#define COW_VERSION 2
  35 +
  36 +struct cow_header_v2 {
  37 + uint32_t magic;
  38 + uint32_t version;
  39 + char backing_file[1024];
  40 + int32_t mtime;
  41 + uint64_t size;
  42 + uint32_t sectorsize;
  43 +};
  44 +
  45 +typedef struct BDRVCowState {
  46 + int fd;
  47 + uint8_t *cow_bitmap; /* if non NULL, COW mappings are used first */
  48 + uint8_t *cow_bitmap_addr; /* mmap address of cow_bitmap */
  49 + int cow_bitmap_size;
  50 + int64_t cow_sectors_offset;
  51 +} BDRVCowState;
  52 +
  53 +static int cow_probe(const uint8_t *buf, int buf_size, const char *filename)
  54 +{
  55 + const struct cow_header_v2 *cow_header = (const void *)buf;
  56 +
  57 + if (be32_to_cpu(cow_header->magic) == COW_MAGIC &&
  58 + be32_to_cpu(cow_header->version) == COW_VERSION)
  59 + return 100;
  60 + else
  61 + return 0;
  62 +}
  63 +
  64 +static int cow_open(BlockDriverState *bs, const char *filename)
  65 +{
  66 + BDRVCowState *s = bs->opaque;
  67 + int fd;
  68 + struct cow_header_v2 cow_header;
  69 + int64_t size;
  70 +
  71 + fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
  72 + if (fd < 0) {
  73 + fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
  74 + if (fd < 0)
  75 + return -1;
  76 + }
  77 + s->fd = fd;
  78 + /* see if it is a cow image */
  79 + if (read(fd, &cow_header, sizeof(cow_header)) != sizeof(cow_header)) {
  80 + goto fail;
  81 + }
  82 +
  83 + if (be32_to_cpu(cow_header.magic) != COW_MAGIC ||
  84 + be32_to_cpu(cow_header.version) != COW_VERSION) {
  85 + goto fail;
  86 + }
  87 +
  88 + /* cow image found */
  89 + size = be64_to_cpu(cow_header.size);
  90 + bs->total_sectors = size / 512;
  91 +
  92 + pstrcpy(bs->backing_file, sizeof(bs->backing_file),
  93 + cow_header.backing_file);
  94 +
  95 +#if 0
  96 + if (cow_header.backing_file[0] != '\0') {
  97 + if (stat(cow_header.backing_file, &st) != 0) {
  98 + fprintf(stderr, "%s: could not find original disk image '%s'\n", filename, cow_header.backing_file);
  99 + goto fail;
  100 + }
  101 + if (st.st_mtime != be32_to_cpu(cow_header.mtime)) {
  102 + fprintf(stderr, "%s: original raw disk image '%s' does not match saved timestamp\n", filename, cow_header.backing_file);
  103 + goto fail;
  104 + }
  105 + fd = open(cow_header.backing_file, O_RDONLY | O_LARGEFILE);
  106 + if (fd < 0)
  107 + goto fail;
  108 + bs->fd = fd;
  109 + }
  110 +#endif
  111 + /* mmap the bitmap */
  112 + s->cow_bitmap_size = ((bs->total_sectors + 7) >> 3) + sizeof(cow_header);
  113 + s->cow_bitmap_addr = mmap(get_mmap_addr(s->cow_bitmap_size),
  114 + s->cow_bitmap_size,
  115 + PROT_READ | PROT_WRITE,
  116 + MAP_SHARED, s->fd, 0);
  117 + if (s->cow_bitmap_addr == MAP_FAILED)
  118 + goto fail;
  119 + s->cow_bitmap = s->cow_bitmap_addr + sizeof(cow_header);
  120 + s->cow_sectors_offset = (s->cow_bitmap_size + 511) & ~511;
  121 + return 0;
  122 + fail:
  123 + close(fd);
  124 + return -1;
  125 +}
  126 +
  127 +static inline void set_bit(uint8_t *bitmap, int64_t bitnum)
  128 +{
  129 + bitmap[bitnum / 8] |= (1 << (bitnum%8));
  130 +}
  131 +
  132 +static inline int is_bit_set(const uint8_t *bitmap, int64_t bitnum)
  133 +{
  134 + return !!(bitmap[bitnum / 8] & (1 << (bitnum%8)));
  135 +}
  136 +
  137 +
  138 +/* Return true if first block has been changed (ie. current version is
  139 + * in COW file). Set the number of continuous blocks for which that
  140 + * is true. */
  141 +static inline int is_changed(uint8_t *bitmap,
  142 + int64_t sector_num, int nb_sectors,
  143 + int *num_same)
  144 +{
  145 + int changed;
  146 +
  147 + if (!bitmap || nb_sectors == 0) {
  148 + *num_same = nb_sectors;
  149 + return 0;
  150 + }
  151 +
  152 + changed = is_bit_set(bitmap, sector_num);
  153 + for (*num_same = 1; *num_same < nb_sectors; (*num_same)++) {
  154 + if (is_bit_set(bitmap, sector_num + *num_same) != changed)
  155 + break;
  156 + }
  157 +
  158 + return changed;
  159 +}
  160 +
  161 +static int cow_is_allocated(BlockDriverState *bs, int64_t sector_num,
  162 + int nb_sectors, int *pnum)
  163 +{
  164 + BDRVCowState *s = bs->opaque;
  165 + return is_changed(s->cow_bitmap, sector_num, nb_sectors, pnum);
  166 +}
  167 +
  168 +static int cow_read(BlockDriverState *bs, int64_t sector_num,
  169 + uint8_t *buf, int nb_sectors)
  170 +{
  171 + BDRVCowState *s = bs->opaque;
  172 + int ret, n;
  173 +
  174 + while (nb_sectors > 0) {
  175 + if (is_changed(s->cow_bitmap, sector_num, nb_sectors, &n)) {
  176 + lseek64(s->fd, s->cow_sectors_offset + sector_num * 512, SEEK_SET);
  177 + ret = read(s->fd, buf, n * 512);
  178 + if (ret != n * 512)
  179 + return -1;
  180 + } else {
  181 + memset(buf, 0, n * 512);
  182 + }
  183 + nb_sectors -= n;
  184 + sector_num += n;
  185 + buf += n * 512;
  186 + }
  187 + return 0;
  188 +}
  189 +
  190 +static int cow_write(BlockDriverState *bs, int64_t sector_num,
  191 + const uint8_t *buf, int nb_sectors)
  192 +{
  193 + BDRVCowState *s = bs->opaque;
  194 + int ret, i;
  195 +
  196 + lseek64(s->fd, s->cow_sectors_offset + sector_num * 512, SEEK_SET);
  197 + ret = write(s->fd, buf, nb_sectors * 512);
  198 + if (ret != nb_sectors * 512)
  199 + return -1;
  200 + for (i = 0; i < nb_sectors; i++)
  201 + set_bit(s->cow_bitmap, sector_num + i);
  202 + return 0;
  203 +}
  204 +
  205 +static int cow_close(BlockDriverState *bs)
  206 +{
  207 + BDRVCowState *s = bs->opaque;
  208 + munmap(s->cow_bitmap_addr, s->cow_bitmap_size);
  209 + close(s->fd);
  210 +}
  211 +
  212 +static int cow_create(const char *filename, int64_t image_sectors,
  213 + const char *image_filename, int flags)
  214 +{
  215 + int fd, cow_fd;
  216 + struct cow_header_v2 cow_header;
  217 + struct stat st;
  218 +
  219 + if (flags)
  220 + return -ENOTSUP;
  221 +
  222 + cow_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
  223 + 0644);
  224 + if (cow_fd < 0)
  225 + return -1;
  226 + memset(&cow_header, 0, sizeof(cow_header));
  227 + cow_header.magic = cpu_to_be32(COW_MAGIC);
  228 + cow_header.version = cpu_to_be32(COW_VERSION);
  229 + if (image_filename) {
  230 + fd = open(image_filename, O_RDONLY | O_BINARY);
  231 + if (fd < 0) {
  232 + close(cow_fd);
  233 + return -1;
  234 + }
  235 + if (fstat(fd, &st) != 0) {
  236 + close(fd);
  237 + return -1;
  238 + }
  239 + close(fd);
  240 + cow_header.mtime = cpu_to_be32(st.st_mtime);
  241 + realpath(image_filename, cow_header.backing_file);
  242 + }
  243 + cow_header.sectorsize = cpu_to_be32(512);
  244 + cow_header.size = cpu_to_be64(image_sectors * 512);
  245 + write(cow_fd, &cow_header, sizeof(cow_header));
  246 + /* resize to include at least all the bitmap */
  247 + ftruncate(cow_fd, sizeof(cow_header) + ((image_sectors + 7) >> 3));
  248 + close(cow_fd);
  249 + return 0;
  250 +}
  251 +
  252 +BlockDriver bdrv_cow = {
  253 + "cow",
  254 + sizeof(BDRVCowState),
  255 + cow_probe,
  256 + cow_open,
  257 + cow_read,
  258 + cow_write,
  259 + cow_close,
  260 + cow_create,
  261 + cow_is_allocated,
  262 +};
  263 +#endif
... ...
block-qcow.c 0 → 100644
  1 +/*
  2 + * Block driver for the QCOW format
  3 + *
  4 + * Copyright (c) 2004 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#include "vl.h"
  25 +#include "block_int.h"
  26 +#include "zlib.h"
  27 +#include "aes.h"
  28 +
  29 +/**************************************************************/
  30 +/* QEMU COW block driver with compression and encryption support */
  31 +
  32 +#define QCOW_MAGIC (('Q' << 24) | ('F' << 16) | ('I' << 8) | 0xfb)
  33 +#define QCOW_VERSION 1
  34 +
  35 +#define QCOW_CRYPT_NONE 0
  36 +#define QCOW_CRYPT_AES 1
  37 +
  38 +#define QCOW_OFLAG_COMPRESSED (1LL << 63)
  39 +
  40 +typedef struct QCowHeader {
  41 + uint32_t magic;
  42 + uint32_t version;
  43 + uint64_t backing_file_offset;
  44 + uint32_t backing_file_size;
  45 + uint32_t mtime;
  46 + uint64_t size; /* in bytes */
  47 + uint8_t cluster_bits;
  48 + uint8_t l2_bits;
  49 + uint32_t crypt_method;
  50 + uint64_t l1_table_offset;
  51 +} QCowHeader;
  52 +
  53 +#define L2_CACHE_SIZE 16
  54 +
  55 +typedef struct BDRVQcowState {
  56 + int fd;
  57 + int cluster_bits;
  58 + int cluster_size;
  59 + int cluster_sectors;
  60 + int l2_bits;
  61 + int l2_size;
  62 + int l1_size;
  63 + uint64_t cluster_offset_mask;
  64 + uint64_t l1_table_offset;
  65 + uint64_t *l1_table;
  66 + uint64_t *l2_cache;
  67 + uint64_t l2_cache_offsets[L2_CACHE_SIZE];
  68 + uint32_t l2_cache_counts[L2_CACHE_SIZE];
  69 + uint8_t *cluster_cache;
  70 + uint8_t *cluster_data;
  71 + uint64_t cluster_cache_offset;
  72 + uint32_t crypt_method; /* current crypt method, 0 if no key yet */
  73 + uint32_t crypt_method_header;
  74 + AES_KEY aes_encrypt_key;
  75 + AES_KEY aes_decrypt_key;
  76 +} BDRVQcowState;
  77 +
  78 +static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset);
  79 +
  80 +static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
  81 +{
  82 + const QCowHeader *cow_header = (const void *)buf;
  83 +
  84 + if (be32_to_cpu(cow_header->magic) == QCOW_MAGIC &&
  85 + be32_to_cpu(cow_header->version) == QCOW_VERSION)
  86 + return 100;
  87 + else
  88 + return 0;
  89 +}
  90 +
  91 +static int qcow_open(BlockDriverState *bs, const char *filename)
  92 +{
  93 + BDRVQcowState *s = bs->opaque;
  94 + int fd, len, i, shift;
  95 + QCowHeader header;
  96 +
  97 + fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
  98 + if (fd < 0) {
  99 + fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
  100 + if (fd < 0)
  101 + return -1;
  102 + }
  103 + s->fd = fd;
  104 + if (read(fd, &header, sizeof(header)) != sizeof(header))
  105 + goto fail;
  106 + be32_to_cpus(&header.magic);
  107 + be32_to_cpus(&header.version);
  108 + be64_to_cpus(&header.backing_file_offset);
  109 + be32_to_cpus(&header.backing_file_size);
  110 + be32_to_cpus(&header.mtime);
  111 + be64_to_cpus(&header.size);
  112 + be32_to_cpus(&header.crypt_method);
  113 + be64_to_cpus(&header.l1_table_offset);
  114 +
  115 + if (header.magic != QCOW_MAGIC || header.version != QCOW_VERSION)
  116 + goto fail;
  117 + if (header.size <= 1 || header.cluster_bits < 9)
  118 + goto fail;
  119 + if (header.crypt_method > QCOW_CRYPT_AES)
  120 + goto fail;
  121 + s->crypt_method_header = header.crypt_method;
  122 + if (s->crypt_method_header)
  123 + bs->encrypted = 1;
  124 + s->cluster_bits = header.cluster_bits;
  125 + s->cluster_size = 1 << s->cluster_bits;
  126 + s->cluster_sectors = 1 << (s->cluster_bits - 9);
  127 + s->l2_bits = header.l2_bits;
  128 + s->l2_size = 1 << s->l2_bits;
  129 + bs->total_sectors = header.size / 512;
  130 + s->cluster_offset_mask = (1LL << (63 - s->cluster_bits)) - 1;
  131 +
  132 + /* read the level 1 table */
  133 + shift = s->cluster_bits + s->l2_bits;
  134 + s->l1_size = (header.size + (1LL << shift) - 1) >> shift;
  135 +
  136 + s->l1_table_offset = header.l1_table_offset;
  137 + s->l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t));
  138 + if (!s->l1_table)
  139 + goto fail;
  140 + lseek64(fd, s->l1_table_offset, SEEK_SET);
  141 + if (read(fd, s->l1_table, s->l1_size * sizeof(uint64_t)) !=
  142 + s->l1_size * sizeof(uint64_t))
  143 + goto fail;
  144 + for(i = 0;i < s->l1_size; i++) {
  145 + be64_to_cpus(&s->l1_table[i]);
  146 + }
  147 + /* alloc L2 cache */
  148 + s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
  149 + if (!s->l2_cache)
  150 + goto fail;
  151 + s->cluster_cache = qemu_malloc(s->cluster_size);
  152 + if (!s->cluster_cache)
  153 + goto fail;
  154 + s->cluster_data = qemu_malloc(s->cluster_size);
  155 + if (!s->cluster_data)
  156 + goto fail;
  157 + s->cluster_cache_offset = -1;
  158 +
  159 + /* read the backing file name */
  160 + if (header.backing_file_offset != 0) {
  161 + len = header.backing_file_size;
  162 + if (len > 1023)
  163 + len = 1023;
  164 + lseek64(fd, header.backing_file_offset, SEEK_SET);
  165 + if (read(fd, bs->backing_file, len) != len)
  166 + goto fail;
  167 + bs->backing_file[len] = '\0';
  168 + }
  169 + return 0;
  170 +
  171 + fail:
  172 + qemu_free(s->l1_table);
  173 + qemu_free(s->l2_cache);
  174 + qemu_free(s->cluster_cache);
  175 + qemu_free(s->cluster_data);
  176 + close(fd);
  177 + return -1;
  178 +}
  179 +
  180 +static int qcow_set_key(BlockDriverState *bs, const char *key)
  181 +{
  182 + BDRVQcowState *s = bs->opaque;
  183 + uint8_t keybuf[16];
  184 + int len, i;
  185 +
  186 + memset(keybuf, 0, 16);
  187 + len = strlen(key);
  188 + if (len > 16)
  189 + len = 16;
  190 + /* XXX: we could compress the chars to 7 bits to increase
  191 + entropy */
  192 + for(i = 0;i < len;i++) {
  193 + keybuf[i] = key[i];
  194 + }
  195 + s->crypt_method = s->crypt_method_header;
  196 +
  197 + if (AES_set_encrypt_key(keybuf, 128, &s->aes_encrypt_key) != 0)
  198 + return -1;
  199 + if (AES_set_decrypt_key(keybuf, 128, &s->aes_decrypt_key) != 0)
  200 + return -1;
  201 +#if 0
  202 + /* test */
  203 + {
  204 + uint8_t in[16];
  205 + uint8_t out[16];
  206 + uint8_t tmp[16];
  207 + for(i=0;i<16;i++)
  208 + in[i] = i;
  209 + AES_encrypt(in, tmp, &s->aes_encrypt_key);
  210 + AES_decrypt(tmp, out, &s->aes_decrypt_key);
  211 + for(i = 0; i < 16; i++)
  212 + printf(" %02x", tmp[i]);
  213 + printf("\n");
  214 + for(i = 0; i < 16; i++)
  215 + printf(" %02x", out[i]);
  216 + printf("\n");
  217 + }
  218 +#endif
  219 + return 0;
  220 +}
  221 +
  222 +/* The crypt function is compatible with the linux cryptoloop
  223 + algorithm for < 4 GB images. NOTE: out_buf == in_buf is
  224 + supported */
  225 +static void encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
  226 + uint8_t *out_buf, const uint8_t *in_buf,
  227 + int nb_sectors, int enc,
  228 + const AES_KEY *key)
  229 +{
  230 + union {
  231 + uint64_t ll[2];
  232 + uint8_t b[16];
  233 + } ivec;
  234 + int i;
  235 +
  236 + for(i = 0; i < nb_sectors; i++) {
  237 + ivec.ll[0] = cpu_to_le64(sector_num);
  238 + ivec.ll[1] = 0;
  239 + AES_cbc_encrypt(in_buf, out_buf, 512, key,
  240 + ivec.b, enc);
  241 + sector_num++;
  242 + in_buf += 512;
  243 + out_buf += 512;
  244 + }
  245 +}
  246 +
  247 +/* 'allocate' is:
  248 + *
  249 + * 0 to not allocate.
  250 + *
  251 + * 1 to allocate a normal cluster (for sector indexes 'n_start' to
  252 + * 'n_end')
  253 + *
  254 + * 2 to allocate a compressed cluster of size
  255 + * 'compressed_size'. 'compressed_size' must be > 0 and <
  256 + * cluster_size
  257 + *
  258 + * return 0 if not allocated.
  259 + */
  260 +static uint64_t get_cluster_offset(BlockDriverState *bs,
  261 + uint64_t offset, int allocate,
  262 + int compressed_size,
  263 + int n_start, int n_end)
  264 +{
  265 + BDRVQcowState *s = bs->opaque;
  266 + int min_index, i, j, l1_index, l2_index;
  267 + uint64_t l2_offset, *l2_table, cluster_offset, tmp;
  268 + uint32_t min_count;
  269 + int new_l2_table;
  270 +
  271 + l1_index = offset >> (s->l2_bits + s->cluster_bits);
  272 + l2_offset = s->l1_table[l1_index];
  273 + new_l2_table = 0;
  274 + if (!l2_offset) {
  275 + if (!allocate)
  276 + return 0;
  277 + /* allocate a new l2 entry */
  278 + l2_offset = lseek64(s->fd, 0, SEEK_END);
  279 + /* round to cluster size */
  280 + l2_offset = (l2_offset + s->cluster_size - 1) & ~(s->cluster_size - 1);
  281 + /* update the L1 entry */
  282 + s->l1_table[l1_index] = l2_offset;
  283 + tmp = cpu_to_be64(l2_offset);
  284 + lseek64(s->fd, s->l1_table_offset + l1_index * sizeof(tmp), SEEK_SET);
  285 + if (write(s->fd, &tmp, sizeof(tmp)) != sizeof(tmp))
  286 + return 0;
  287 + new_l2_table = 1;
  288 + }
  289 + for(i = 0; i < L2_CACHE_SIZE; i++) {
  290 + if (l2_offset == s->l2_cache_offsets[i]) {
  291 + /* increment the hit count */
  292 + if (++s->l2_cache_counts[i] == 0xffffffff) {
  293 + for(j = 0; j < L2_CACHE_SIZE; j++) {
  294 + s->l2_cache_counts[j] >>= 1;
  295 + }
  296 + }
  297 + l2_table = s->l2_cache + (i << s->l2_bits);
  298 + goto found;
  299 + }
  300 + }
  301 + /* not found: load a new entry in the least used one */
  302 + min_index = 0;
  303 + min_count = 0xffffffff;
  304 + for(i = 0; i < L2_CACHE_SIZE; i++) {
  305 + if (s->l2_cache_counts[i] < min_count) {
  306 + min_count = s->l2_cache_counts[i];
  307 + min_index = i;
  308 + }
  309 + }
  310 + l2_table = s->l2_cache + (min_index << s->l2_bits);
  311 + lseek(s->fd, l2_offset, SEEK_SET);
  312 + if (new_l2_table) {
  313 + memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
  314 + if (write(s->fd, l2_table, s->l2_size * sizeof(uint64_t)) !=
  315 + s->l2_size * sizeof(uint64_t))
  316 + return 0;
  317 + } else {
  318 + if (read(s->fd, l2_table, s->l2_size * sizeof(uint64_t)) !=
  319 + s->l2_size * sizeof(uint64_t))
  320 + return 0;
  321 + }
  322 + s->l2_cache_offsets[min_index] = l2_offset;
  323 + s->l2_cache_counts[min_index] = 1;
  324 + found:
  325 + l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
  326 + cluster_offset = be64_to_cpu(l2_table[l2_index]);
  327 + if (!cluster_offset ||
  328 + ((cluster_offset & QCOW_OFLAG_COMPRESSED) && allocate == 1)) {
  329 + if (!allocate)
  330 + return 0;
  331 + /* allocate a new cluster */
  332 + if ((cluster_offset & QCOW_OFLAG_COMPRESSED) &&
  333 + (n_end - n_start) < s->cluster_sectors) {
  334 + /* if the cluster is already compressed, we must
  335 + decompress it in the case it is not completely
  336 + overwritten */
  337 + if (decompress_cluster(s, cluster_offset) < 0)
  338 + return 0;
  339 + cluster_offset = lseek64(s->fd, 0, SEEK_END);
  340 + cluster_offset = (cluster_offset + s->cluster_size - 1) &
  341 + ~(s->cluster_size - 1);
  342 + /* write the cluster content */
  343 + lseek64(s->fd, cluster_offset, SEEK_SET);
  344 + if (write(s->fd, s->cluster_cache, s->cluster_size) !=
  345 + s->cluster_size)
  346 + return -1;
  347 + } else {
  348 + cluster_offset = lseek64(s->fd, 0, SEEK_END);
  349 + if (allocate == 1) {
  350 + /* round to cluster size */
  351 + cluster_offset = (cluster_offset + s->cluster_size - 1) &
  352 + ~(s->cluster_size - 1);
  353 + ftruncate(s->fd, cluster_offset + s->cluster_size);
  354 + /* if encrypted, we must initialize the cluster
  355 + content which won't be written */
  356 + if (s->crypt_method &&
  357 + (n_end - n_start) < s->cluster_sectors) {
  358 + uint64_t start_sect;
  359 + start_sect = (offset & ~(s->cluster_size - 1)) >> 9;
  360 + memset(s->cluster_data + 512, 0xaa, 512);
  361 + for(i = 0; i < s->cluster_sectors; i++) {
  362 + if (i < n_start || i >= n_end) {
  363 + encrypt_sectors(s, start_sect + i,
  364 + s->cluster_data,
  365 + s->cluster_data + 512, 1, 1,
  366 + &s->aes_encrypt_key);
  367 + lseek64(s->fd, cluster_offset + i * 512, SEEK_SET);
  368 + if (write(s->fd, s->cluster_data, 512) != 512)
  369 + return -1;
  370 + }
  371 + }
  372 + }
  373 + } else {
  374 + cluster_offset |= QCOW_OFLAG_COMPRESSED |
  375 + (uint64_t)compressed_size << (63 - s->cluster_bits);
  376 + }
  377 + }
  378 + /* update L2 table */
  379 + tmp = cpu_to_be64(cluster_offset);
  380 + l2_table[l2_index] = tmp;
  381 + lseek64(s->fd, l2_offset + l2_index * sizeof(tmp), SEEK_SET);
  382 + if (write(s->fd, &tmp, sizeof(tmp)) != sizeof(tmp))
  383 + return 0;
  384 + }
  385 + return cluster_offset;
  386 +}
  387 +
  388 +static int qcow_is_allocated(BlockDriverState *bs, int64_t sector_num,
  389 + int nb_sectors, int *pnum)
  390 +{
  391 + BDRVQcowState *s = bs->opaque;
  392 + int index_in_cluster, n;
  393 + uint64_t cluster_offset;
  394 +
  395 + cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
  396 + index_in_cluster = sector_num & (s->cluster_sectors - 1);
  397 + n = s->cluster_sectors - index_in_cluster;
  398 + if (n > nb_sectors)
  399 + n = nb_sectors;
  400 + *pnum = n;
  401 + return (cluster_offset != 0);
  402 +}
  403 +
  404 +static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
  405 + const uint8_t *buf, int buf_size)
  406 +{
  407 + z_stream strm1, *strm = &strm1;
  408 + int ret, out_len;
  409 +
  410 + memset(strm, 0, sizeof(*strm));
  411 +
  412 + strm->next_in = (uint8_t *)buf;
  413 + strm->avail_in = buf_size;
  414 + strm->next_out = out_buf;
  415 + strm->avail_out = out_buf_size;
  416 +
  417 + ret = inflateInit2(strm, -12);
  418 + if (ret != Z_OK)
  419 + return -1;
  420 + ret = inflate(strm, Z_FINISH);
  421 + out_len = strm->next_out - out_buf;
  422 + if ((ret != Z_STREAM_END && ret != Z_BUF_ERROR) ||
  423 + out_len != out_buf_size) {
  424 + inflateEnd(strm);
  425 + return -1;
  426 + }
  427 + inflateEnd(strm);
  428 + return 0;
  429 +}
  430 +
  431 +static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset)
  432 +{
  433 + int ret, csize;
  434 + uint64_t coffset;
  435 +
  436 + coffset = cluster_offset & s->cluster_offset_mask;
  437 + if (s->cluster_cache_offset != coffset) {
  438 + csize = cluster_offset >> (63 - s->cluster_bits);
  439 + csize &= (s->cluster_size - 1);
  440 + lseek64(s->fd, coffset, SEEK_SET);
  441 + ret = read(s->fd, s->cluster_data, csize);
  442 + if (ret != csize)
  443 + return -1;
  444 + if (decompress_buffer(s->cluster_cache, s->cluster_size,
  445 + s->cluster_data, csize) < 0) {
  446 + return -1;
  447 + }
  448 + s->cluster_cache_offset = coffset;
  449 + }
  450 + return 0;
  451 +}
  452 +
  453 +static int qcow_read(BlockDriverState *bs, int64_t sector_num,
  454 + uint8_t *buf, int nb_sectors)
  455 +{
  456 + BDRVQcowState *s = bs->opaque;
  457 + int ret, index_in_cluster, n;
  458 + uint64_t cluster_offset;
  459 +
  460 + while (nb_sectors > 0) {
  461 + cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
  462 + index_in_cluster = sector_num & (s->cluster_sectors - 1);
  463 + n = s->cluster_sectors - index_in_cluster;
  464 + if (n > nb_sectors)
  465 + n = nb_sectors;
  466 + if (!cluster_offset) {
  467 + memset(buf, 0, 512 * n);
  468 + } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
  469 + if (decompress_cluster(s, cluster_offset) < 0)
  470 + return -1;
  471 + memcpy(buf, s->cluster_cache + index_in_cluster * 512, 512 * n);
  472 + } else {
  473 + lseek64(s->fd, cluster_offset + index_in_cluster * 512, SEEK_SET);
  474 + ret = read(s->fd, buf, n * 512);
  475 + if (ret != n * 512)
  476 + return -1;
  477 + if (s->crypt_method) {
  478 + encrypt_sectors(s, sector_num, buf, buf, n, 0,
  479 + &s->aes_decrypt_key);
  480 + }
  481 + }
  482 + nb_sectors -= n;
  483 + sector_num += n;
  484 + buf += n * 512;
  485 + }
  486 + return 0;
  487 +}
  488 +
  489 +static int qcow_write(BlockDriverState *bs, int64_t sector_num,
  490 + const uint8_t *buf, int nb_sectors)
  491 +{
  492 + BDRVQcowState *s = bs->opaque;
  493 + int ret, index_in_cluster, n;
  494 + uint64_t cluster_offset;
  495 +
  496 + while (nb_sectors > 0) {
  497 + index_in_cluster = sector_num & (s->cluster_sectors - 1);
  498 + n = s->cluster_sectors - index_in_cluster;
  499 + if (n > nb_sectors)
  500 + n = nb_sectors;
  501 + cluster_offset = get_cluster_offset(bs, sector_num << 9, 1, 0,
  502 + index_in_cluster,
  503 + index_in_cluster + n);
  504 + if (!cluster_offset)
  505 + return -1;
  506 + lseek64(s->fd, cluster_offset + index_in_cluster * 512, SEEK_SET);
  507 + if (s->crypt_method) {
  508 + encrypt_sectors(s, sector_num, s->cluster_data, buf, n, 1,
  509 + &s->aes_encrypt_key);
  510 + ret = write(s->fd, s->cluster_data, n * 512);
  511 + } else {
  512 + ret = write(s->fd, buf, n * 512);
  513 + }
  514 + if (ret != n * 512)
  515 + return -1;
  516 + nb_sectors -= n;
  517 + sector_num += n;
  518 + buf += n * 512;
  519 + }
  520 + s->cluster_cache_offset = -1; /* disable compressed cache */
  521 + return 0;
  522 +}
  523 +
  524 +static int qcow_close(BlockDriverState *bs)
  525 +{
  526 + BDRVQcowState *s = bs->opaque;
  527 + qemu_free(s->l1_table);
  528 + qemu_free(s->l2_cache);
  529 + qemu_free(s->cluster_cache);
  530 + qemu_free(s->cluster_data);
  531 + close(s->fd);
  532 +}
  533 +
  534 +static int qcow_create(const char *filename, int64_t total_size,
  535 + const char *backing_file, int flags)
  536 +{
  537 + int fd, header_size, backing_filename_len, l1_size, i, shift;
  538 + QCowHeader header;
  539 + char backing_filename[1024];
  540 + uint64_t tmp;
  541 + struct stat st;
  542 +
  543 + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
  544 + 0644);
  545 + if (fd < 0)
  546 + return -1;
  547 + memset(&header, 0, sizeof(header));
  548 + header.magic = cpu_to_be32(QCOW_MAGIC);
  549 + header.version = cpu_to_be32(QCOW_VERSION);
  550 + header.size = cpu_to_be64(total_size * 512);
  551 + header_size = sizeof(header);
  552 + backing_filename_len = 0;
  553 + if (backing_file) {
  554 + realpath(backing_file, backing_filename);
  555 + if (stat(backing_filename, &st) != 0) {
  556 + return -1;
  557 + }
  558 + header.mtime = cpu_to_be32(st.st_mtime);
  559 + header.backing_file_offset = cpu_to_be64(header_size);
  560 + backing_filename_len = strlen(backing_filename);
  561 + header.backing_file_size = cpu_to_be32(backing_filename_len);
  562 + header_size += backing_filename_len;
  563 + header.cluster_bits = 9; /* 512 byte cluster to avoid copying
  564 + unmodifyed sectors */
  565 + header.l2_bits = 12; /* 32 KB L2 tables */
  566 + } else {
  567 + header.cluster_bits = 12; /* 4 KB clusters */
  568 + header.l2_bits = 9; /* 4 KB L2 tables */
  569 + }
  570 + header_size = (header_size + 7) & ~7;
  571 + shift = header.cluster_bits + header.l2_bits;
  572 + l1_size = ((total_size * 512) + (1LL << shift) - 1) >> shift;
  573 +
  574 + header.l1_table_offset = cpu_to_be64(header_size);
  575 + if (flags) {
  576 + header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
  577 + } else {
  578 + header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
  579 + }
  580 +
  581 + /* write all the data */
  582 + write(fd, &header, sizeof(header));
  583 + if (backing_file) {
  584 + write(fd, backing_filename, backing_filename_len);
  585 + }
  586 + lseek(fd, header_size, SEEK_SET);
  587 + tmp = 0;
  588 + for(i = 0;i < l1_size; i++) {
  589 + write(fd, &tmp, sizeof(tmp));
  590 + }
  591 + close(fd);
  592 + return 0;
  593 +}
  594 +
  595 +int qcow_get_cluster_size(BlockDriverState *bs)
  596 +{
  597 + BDRVQcowState *s = bs->opaque;
  598 + if (bs->drv != &bdrv_qcow)
  599 + return -1;
  600 + return s->cluster_size;
  601 +}
  602 +
  603 +/* XXX: put compressed sectors first, then all the cluster aligned
  604 + tables to avoid losing bytes in alignment */
  605 +int qcow_compress_cluster(BlockDriverState *bs, int64_t sector_num,
  606 + const uint8_t *buf)
  607 +{
  608 + BDRVQcowState *s = bs->opaque;
  609 + z_stream strm;
  610 + int ret, out_len;
  611 + uint8_t *out_buf;
  612 + uint64_t cluster_offset;
  613 +
  614 + if (bs->drv != &bdrv_qcow)
  615 + return -1;
  616 +
  617 + out_buf = qemu_malloc(s->cluster_size + (s->cluster_size / 1000) + 128);
  618 + if (!out_buf)
  619 + return -1;
  620 +
  621 + /* best compression, small window, no zlib header */
  622 + memset(&strm, 0, sizeof(strm));
  623 + ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION,
  624 + Z_DEFLATED, -12,
  625 + 9, Z_DEFAULT_STRATEGY);
  626 + if (ret != 0) {
  627 + qemu_free(out_buf);
  628 + return -1;
  629 + }
  630 +
  631 + strm.avail_in = s->cluster_size;
  632 + strm.next_in = (uint8_t *)buf;
  633 + strm.avail_out = s->cluster_size;
  634 + strm.next_out = out_buf;
  635 +
  636 + ret = deflate(&strm, Z_FINISH);
  637 + if (ret != Z_STREAM_END && ret != Z_OK) {
  638 + qemu_free(out_buf);
  639 + deflateEnd(&strm);
  640 + return -1;
  641 + }
  642 + out_len = strm.next_out - out_buf;
  643 +
  644 + deflateEnd(&strm);
  645 +
  646 + if (ret != Z_STREAM_END || out_len >= s->cluster_size) {
  647 + /* could not compress: write normal cluster */
  648 + qcow_write(bs, sector_num, buf, s->cluster_sectors);
  649 + } else {
  650 + cluster_offset = get_cluster_offset(bs, sector_num << 9, 2,
  651 + out_len, 0, 0);
  652 + cluster_offset &= s->cluster_offset_mask;
  653 + lseek64(s->fd, cluster_offset, SEEK_SET);
  654 + if (write(s->fd, out_buf, out_len) != out_len) {
  655 + qemu_free(out_buf);
  656 + return -1;
  657 + }
  658 + }
  659 +
  660 + qemu_free(out_buf);
  661 + return 0;
  662 +}
  663 +
  664 +BlockDriver bdrv_qcow = {
  665 + "qcow",
  666 + sizeof(BDRVQcowState),
  667 + qcow_probe,
  668 + qcow_open,
  669 + qcow_read,
  670 + qcow_write,
  671 + qcow_close,
  672 + qcow_create,
  673 + qcow_is_allocated,
  674 + qcow_set_key,
  675 +};
  676 +
  677 +
... ...
block-vmdk.c 0 → 100644
  1 +/*
  2 + * Block driver for the VMDK format
  3 + *
  4 + * Copyright (c) 2004 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#include "vl.h"
  25 +#include "block_int.h"
  26 +
  27 +/* XXX: this code is untested */
  28 +/* XXX: add write support */
  29 +
  30 +#define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D')
  31 +#define VMDK4_MAGIC (('K' << 24) | ('D' << 16) | ('M' << 8) | 'V')
  32 +
  33 +typedef struct {
  34 + uint32_t version;
  35 + uint32_t flags;
  36 + uint32_t disk_sectors;
  37 + uint32_t granularity;
  38 + uint32_t l1dir_offset;
  39 + uint32_t l1dir_size;
  40 + uint32_t file_sectors;
  41 + uint32_t cylinders;
  42 + uint32_t heads;
  43 + uint32_t sectors_per_track;
  44 +} VMDK3Header;
  45 +
  46 +typedef struct {
  47 + uint32_t version;
  48 + uint32_t flags;
  49 + int64_t capacity;
  50 + int64_t granularity;
  51 + int64_t desc_offset;
  52 + int64_t desc_size;
  53 + int32_t num_gtes_per_gte;
  54 + int64_t rgd_offset;
  55 + int64_t gd_offset;
  56 + int64_t grain_offset;
  57 + char filler[1];
  58 + char check_bytes[4];
  59 +} VMDK4Header;
  60 +
  61 +#define L2_CACHE_SIZE 16
  62 +
  63 +typedef struct BDRVVmdkState {
  64 + int fd;
  65 + int64_t l1_table_offset;
  66 + uint32_t *l1_table;
  67 + unsigned int l1_size;
  68 + uint32_t l1_entry_sectors;
  69 +
  70 + unsigned int l2_size;
  71 + uint32_t *l2_cache;
  72 + uint32_t l2_cache_offsets[L2_CACHE_SIZE];
  73 + uint32_t l2_cache_counts[L2_CACHE_SIZE];
  74 +
  75 + unsigned int cluster_sectors;
  76 +} BDRVVmdkState;
  77 +
  78 +static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename)
  79 +{
  80 + uint32_t magic;
  81 +
  82 + if (buf_size < 4)
  83 + return 0;
  84 + magic = be32_to_cpu(*(uint32_t *)buf);
  85 + if (magic == VMDK3_MAGIC ||
  86 + magic == VMDK4_MAGIC)
  87 + return 100;
  88 + else
  89 + return 0;
  90 +}
  91 +
  92 +static int vmdk_open(BlockDriverState *bs, const char *filename)
  93 +{
  94 + BDRVVmdkState *s = bs->opaque;
  95 + int fd, i;
  96 + uint32_t magic;
  97 + int l1_size;
  98 +
  99 + fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
  100 + if (fd < 0)
  101 + return -1;
  102 + if (read(fd, &magic, sizeof(magic)) != sizeof(magic))
  103 + goto fail;
  104 + magic = le32_to_cpu(magic);
  105 +
  106 + if (magic == VMDK3_MAGIC) {
  107 + VMDK3Header header;
  108 + if (read(fd, &header, sizeof(header)) !=
  109 + sizeof(header))
  110 + goto fail;
  111 + s->cluster_sectors = le32_to_cpu(header.granularity);
  112 + s->l2_size = 1 << 9;
  113 + s->l1_size = 1 << 6;
  114 + bs->total_sectors = le32_to_cpu(header.disk_sectors);
  115 + s->l1_table_offset = le32_to_cpu(header.l1dir_offset) * 512;
  116 + s->l1_entry_sectors = s->l2_size * s->cluster_sectors;
  117 + } else if (magic == VMDK4_MAGIC) {
  118 + VMDK4Header header;
  119 +
  120 + if (read(fd, &header, sizeof(header)) != sizeof(header))
  121 + goto fail;
  122 + bs->total_sectors = le32_to_cpu(header.capacity);
  123 + s->cluster_sectors = le32_to_cpu(header.granularity);
  124 + s->l2_size = le32_to_cpu(header.num_gtes_per_gte);
  125 + s->l1_entry_sectors = s->l2_size * s->cluster_sectors;
  126 + if (s->l1_entry_sectors <= 0)
  127 + goto fail;
  128 + s->l1_size = (bs->total_sectors + s->l1_entry_sectors - 1)
  129 + / s->l1_entry_sectors;
  130 + s->l1_table_offset = le64_to_cpu(header.rgd_offset) * 512;
  131 + } else {
  132 + goto fail;
  133 + }
  134 + /* read the L1 table */
  135 + l1_size = s->l1_size * sizeof(uint32_t);
  136 + s->l1_table = qemu_malloc(l1_size);
  137 + if (!s->l1_table)
  138 + goto fail;
  139 + if (read(s->fd, s->l1_table, l1_size) != l1_size)
  140 + goto fail;
  141 + for(i = 0; i < s->l1_size; i++) {
  142 + le32_to_cpus(&s->l1_table[i]);
  143 + }
  144 +
  145 + s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
  146 + if (!s->l2_cache)
  147 + goto fail;
  148 + s->fd = fd;
  149 + /* XXX: currently only read only */
  150 + bs->read_only = 1;
  151 + return 0;
  152 + fail:
  153 + qemu_free(s->l1_table);
  154 + qemu_free(s->l2_cache);
  155 + close(fd);
  156 + return -1;
  157 +}
  158 +
  159 +static uint64_t get_cluster_offset(BlockDriverState *bs,
  160 + uint64_t offset)
  161 +{
  162 + BDRVVmdkState *s = bs->opaque;
  163 + unsigned int l1_index, l2_offset, l2_index;
  164 + int min_index, i, j;
  165 + uint32_t min_count, *l2_table;
  166 + uint64_t cluster_offset;
  167 +
  168 + l1_index = (offset >> 9) / s->l1_entry_sectors;
  169 + if (l1_index >= s->l1_size)
  170 + return 0;
  171 + l2_offset = s->l1_table[l1_index];
  172 + if (!l2_offset)
  173 + return 0;
  174 +
  175 + for(i = 0; i < L2_CACHE_SIZE; i++) {
  176 + if (l2_offset == s->l2_cache_offsets[i]) {
  177 + /* increment the hit count */
  178 + if (++s->l2_cache_counts[i] == 0xffffffff) {
  179 + for(j = 0; j < L2_CACHE_SIZE; j++) {
  180 + s->l2_cache_counts[j] >>= 1;
  181 + }
  182 + }
  183 + l2_table = s->l2_cache + (i * s->l2_size);
  184 + goto found;
  185 + }
  186 + }
  187 + /* not found: load a new entry in the least used one */
  188 + min_index = 0;
  189 + min_count = 0xffffffff;
  190 + for(i = 0; i < L2_CACHE_SIZE; i++) {
  191 + if (s->l2_cache_counts[i] < min_count) {
  192 + min_count = s->l2_cache_counts[i];
  193 + min_index = i;
  194 + }
  195 + }
  196 + l2_table = s->l2_cache + (min_index * s->l2_size);
  197 + lseek(s->fd, (int64_t)l2_offset * 512, SEEK_SET);
  198 + if (read(s->fd, l2_table, s->l2_size * sizeof(uint32_t)) !=
  199 + s->l2_size * sizeof(uint32_t))
  200 + return 0;
  201 + s->l2_cache_offsets[min_index] = l2_offset;
  202 + s->l2_cache_counts[min_index] = 1;
  203 + found:
  204 + l2_index = ((offset >> 9) / s->cluster_sectors) % s->l2_size;
  205 + cluster_offset = le32_to_cpu(l2_table[l2_index]);
  206 + cluster_offset <<= 9;
  207 + return cluster_offset;
  208 +}
  209 +
  210 +static int vmdk_is_allocated(BlockDriverState *bs, int64_t sector_num,
  211 + int nb_sectors, int *pnum)
  212 +{
  213 + BDRVVmdkState *s = bs->opaque;
  214 + int index_in_cluster, n;
  215 + uint64_t cluster_offset;
  216 +
  217 + cluster_offset = get_cluster_offset(bs, sector_num << 9);
  218 + index_in_cluster = sector_num % s->cluster_sectors;
  219 + n = s->cluster_sectors - index_in_cluster;
  220 + if (n > nb_sectors)
  221 + n = nb_sectors;
  222 + *pnum = n;
  223 + return (cluster_offset != 0);
  224 +}
  225 +
  226 +static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
  227 + uint8_t *buf, int nb_sectors)
  228 +{
  229 + BDRVVmdkState *s = bs->opaque;
  230 + int ret, index_in_cluster, n;
  231 + uint64_t cluster_offset;
  232 +
  233 + while (nb_sectors > 0) {
  234 + cluster_offset = get_cluster_offset(bs, sector_num << 9);
  235 + index_in_cluster = sector_num % s->cluster_sectors;
  236 + n = s->cluster_sectors - index_in_cluster;
  237 + if (n > nb_sectors)
  238 + n = nb_sectors;
  239 + if (!cluster_offset) {
  240 + memset(buf, 0, 512 * n);
  241 + } else {
  242 + lseek64(s->fd, cluster_offset + index_in_cluster * 512, SEEK_SET);
  243 + ret = read(s->fd, buf, n * 512);
  244 + if (ret != n * 512)
  245 + return -1;
  246 + }
  247 + nb_sectors -= n;
  248 + sector_num += n;
  249 + buf += n * 512;
  250 + }
  251 + return 0;
  252 +}
  253 +
  254 +static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
  255 + const uint8_t *buf, int nb_sectors)
  256 +{
  257 + return -1;
  258 +}
  259 +
  260 +static int vmdk_close(BlockDriverState *bs)
  261 +{
  262 + BDRVVmdkState *s = bs->opaque;
  263 + qemu_free(s->l1_table);
  264 + qemu_free(s->l2_cache);
  265 + close(s->fd);
  266 +}
  267 +
  268 +BlockDriver bdrv_vmdk = {
  269 + "vmdk",
  270 + sizeof(BDRVVmdkState),
  271 + vmdk_probe,
  272 + vmdk_open,
  273 + vmdk_read,
  274 + vmdk_write,
  275 + vmdk_close,
  276 + NULL, /* no create yet */
  277 + vmdk_is_allocated,
  278 +};
... ...
... ... @@ -22,43 +22,16 @@
22 22 * THE SOFTWARE.
23 23 */
24 24 #include "vl.h"
25   -
26   -#ifndef _WIN32
27   -#include <sys/mman.h>
28   -#endif
29   -
30   -#include "cow.h"
31   -
32   -struct BlockDriverState {
33   - int fd; /* if -1, only COW mappings */
34   - int64_t total_sectors;
35   - int read_only; /* if true, the media is read only */
36   - int inserted; /* if true, the media is present */
37   - int removable; /* if true, the media can be removed */
38   - int locked; /* if true, the media cannot temporarily be ejected */
39   - /* event callback when inserting/removing */
40   - void (*change_cb)(void *opaque);
41   - void *change_opaque;
42   -
43   - uint8_t *cow_bitmap; /* if non NULL, COW mappings are used first */
44   - uint8_t *cow_bitmap_addr; /* mmap address of cow_bitmap */
45   - int cow_bitmap_size;
46   - int cow_fd;
47   - int64_t cow_sectors_offset;
48   - int boot_sector_enabled;
49   - uint8_t boot_sector_data[512];
50   -
51   - char filename[1024];
52   -
53   - /* NOTE: the following infos are only hints for real hardware
54   - drivers. They are not used by the block driver */
55   - int cyls, heads, secs;
56   - int type;
57   - char device_name[32];
58   - BlockDriverState *next;
59   -};
  25 +#include "block_int.h"
60 26  
61 27 static BlockDriverState *bdrv_first;
  28 +static BlockDriver *first_drv;
  29 +
  30 +void bdrv_register(BlockDriver *bdrv)
  31 +{
  32 + bdrv->next = first_drv;
  33 + first_drv = bdrv;
  34 +}
62 35  
63 36 /* create a new block device (by default it is empty) */
64 37 BlockDriverState *bdrv_new(const char *device_name)
... ... @@ -69,126 +42,149 @@ BlockDriverState *bdrv_new(const char *device_name)
69 42 if(!bs)
70 43 return NULL;
71 44 pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
72   - /* insert at the end */
73   - pbs = &bdrv_first;
74   - while (*pbs != NULL)
75   - pbs = &(*pbs)->next;
76   - *pbs = bs;
  45 + if (device_name[0] != '\0') {
  46 + /* insert at the end */
  47 + pbs = &bdrv_first;
  48 + while (*pbs != NULL)
  49 + pbs = &(*pbs)->next;
  50 + *pbs = bs;
  51 + }
77 52 return bs;
78 53 }
79 54  
80   -int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot)
  55 +BlockDriver *bdrv_find_format(const char *format_name)
  56 +{
  57 + BlockDriver *drv1;
  58 + for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
  59 + if (!strcmp(drv1->format_name, format_name))
  60 + return drv1;
  61 + }
  62 + return NULL;
  63 +}
  64 +
  65 +int bdrv_create(BlockDriver *drv,
  66 + const char *filename, int64_t size_in_sectors,
  67 + const char *backing_file, int flags)
  68 +{
  69 + if (!drv->bdrv_create)
  70 + return -ENOTSUP;
  71 + return drv->bdrv_create(filename, size_in_sectors, backing_file, flags);
  72 +}
  73 +
  74 +/* XXX: race condition possible */
  75 +static void get_tmp_filename(char *filename, int size)
81 76 {
82 77 int fd;
83   - int64_t size;
84   - struct cow_header_v2 cow_header;
85   -#ifndef _WIN32
86   - char template[] = "/tmp/vl.XXXXXX";
87   - int cow_fd;
88   - struct stat st;
89   -#endif
  78 + pstrcpy(filename, size, "/tmp/vl.XXXXXX");
  79 + fd = mkstemp(filename);
  80 + close(fd);
  81 +}
90 82  
91   - bs->read_only = 0;
92   - bs->fd = -1;
93   - bs->cow_fd = -1;
94   - bs->cow_bitmap = NULL;
95   - pstrcpy(bs->filename, sizeof(bs->filename), filename);
  83 +static BlockDriver *find_image_format(const char *filename)
  84 +{
  85 + int fd, ret, score, score_max;
  86 + BlockDriver *drv1, *drv;
  87 + uint8_t buf[1024];
96 88  
97   - /* open standard HD image */
98   -#ifdef _WIN32
99   - fd = open(filename, O_RDWR | O_BINARY);
100   -#else
101   - fd = open(filename, O_RDWR | O_LARGEFILE);
102   -#endif
103   - if (fd < 0) {
104   - /* read only image on disk */
105   -#ifdef _WIN32
106   - fd = open(filename, O_RDONLY | O_BINARY);
107   -#else
108   - fd = open(filename, O_RDONLY | O_LARGEFILE);
109   -#endif
110   - if (fd < 0) {
111   - perror(filename);
112   - goto fail;
  89 + fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
  90 + if (fd < 0)
  91 + return NULL;
  92 + ret = read(fd, buf, sizeof(buf));
  93 + if (ret < 0) {
  94 + close(fd);
  95 + return NULL;
  96 + }
  97 + close(fd);
  98 +
  99 + drv = NULL;
  100 + score_max = 0;
  101 + for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
  102 + score = drv1->bdrv_probe(buf, ret, filename);
  103 + if (score > score_max) {
  104 + score_max = score;
  105 + drv = drv1;
113 106 }
114   - if (!snapshot)
115   - bs->read_only = 1;
116 107 }
117   - bs->fd = fd;
  108 + return drv;
  109 +}
  110 +
  111 +int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot)
  112 +{
  113 + return bdrv_open2(bs, filename, snapshot, NULL);
  114 +}
  115 +
  116 +int bdrv_open2(BlockDriverState *bs, const char *filename, int snapshot,
  117 + BlockDriver *drv)
  118 +{
  119 + int ret;
  120 + char tmp_filename[1024];
  121 +
  122 + bs->read_only = 0;
  123 + bs->is_temporary = 0;
  124 + bs->encrypted = 0;
  125 +
  126 + if (snapshot) {
  127 + BlockDriverState *bs1;
  128 + int64_t total_size;
  129 +
  130 + /* if snapshot, we create a temporary backing file and open it
  131 + instead of opening 'filename' directly */
118 132  
119   - /* see if it is a cow image */
120   - if (read(fd, &cow_header, sizeof(cow_header)) != sizeof(cow_header)) {
121   - fprintf(stderr, "%s: could not read header\n", filename);
122   - goto fail;
  133 + /* if there is a backing file, use it */
  134 + bs1 = bdrv_new("");
  135 + if (!bs1) {
  136 + return -1;
  137 + }
  138 + if (bdrv_open(bs1, filename, 0) < 0) {
  139 + bdrv_delete(bs1);
  140 + return -1;
  141 + }
  142 + total_size = bs1->total_sectors;
  143 + bdrv_delete(bs1);
  144 +
  145 + get_tmp_filename(tmp_filename, sizeof(tmp_filename));
  146 + /* XXX: use cow for linux as it is more efficient ? */
  147 + if (bdrv_create(&bdrv_qcow, tmp_filename,
  148 + total_size, filename, 0) < 0) {
  149 + return -1;
  150 + }
  151 + filename = tmp_filename;
  152 + bs->is_temporary = 1;
  153 + }
  154 +
  155 + pstrcpy(bs->filename, sizeof(bs->filename), filename);
  156 + if (!drv) {
  157 + drv = find_image_format(filename);
  158 + if (!drv)
  159 + return -1;
  160 + }
  161 + bs->drv = drv;
  162 + bs->opaque = qemu_mallocz(drv->instance_size);
  163 + if (bs->opaque == NULL && drv->instance_size > 0)
  164 + return -1;
  165 +
  166 + ret = drv->bdrv_open(bs, filename);
  167 + if (ret < 0) {
  168 + qemu_free(bs->opaque);
  169 + return -1;
123 170 }
124 171 #ifndef _WIN32
125   - if (be32_to_cpu(cow_header.magic) == COW_MAGIC &&
126   - be32_to_cpu(cow_header.version) == COW_VERSION) {
127   - /* cow image found */
128   - size = cow_header.size;
129   -#ifndef WORDS_BIGENDIAN
130   - size = bswap64(size);
131   -#endif
132   - bs->total_sectors = size / 512;
133   -
134   - bs->cow_fd = fd;
135   - bs->fd = -1;
136   - if (cow_header.backing_file[0] != '\0') {
137   - if (stat(cow_header.backing_file, &st) != 0) {
138   - fprintf(stderr, "%s: could not find original disk image '%s'\n", filename, cow_header.backing_file);
139   - goto fail;
140   - }
141   - if (st.st_mtime != be32_to_cpu(cow_header.mtime)) {
142   - fprintf(stderr, "%s: original raw disk image '%s' does not match saved timestamp\n", filename, cow_header.backing_file);
143   - goto fail;
144   - }
145   - fd = open(cow_header.backing_file, O_RDONLY | O_LARGEFILE);
146   - if (fd < 0)
147   - goto fail;
148   - bs->fd = fd;
  172 + if (bs->is_temporary) {
  173 + unlink(filename);
  174 + }
  175 +#endif
  176 + if (bs->backing_file[0] != '\0' && drv->bdrv_is_allocated) {
  177 + /* if there is a backing file, use it */
  178 + bs->backing_hd = bdrv_new("");
  179 + if (!bs->backing_hd) {
  180 + fail:
  181 + bdrv_close(bs);
  182 + return -1;
149 183 }
150   - /* mmap the bitmap */
151   - bs->cow_bitmap_size = ((bs->total_sectors + 7) >> 3) + sizeof(cow_header);
152   - bs->cow_bitmap_addr = mmap(get_mmap_addr(bs->cow_bitmap_size),
153   - bs->cow_bitmap_size,
154   - PROT_READ | PROT_WRITE,
155   - MAP_SHARED, bs->cow_fd, 0);
156   - if (bs->cow_bitmap_addr == MAP_FAILED)
  184 + if (bdrv_open(bs->backing_hd, bs->backing_file, 0) < 0)
157 185 goto fail;
158   - bs->cow_bitmap = bs->cow_bitmap_addr + sizeof(cow_header);
159   - bs->cow_sectors_offset = (bs->cow_bitmap_size + 511) & ~511;
160   - snapshot = 0;
161   - } else
162   -#endif
163   - {
164   - /* standard raw image */
165   - size = lseek64(fd, 0, SEEK_END);
166   - bs->total_sectors = size / 512;
167   - bs->fd = fd;
168 186 }
169 187  
170   -#ifndef _WIN32
171   - if (snapshot) {
172   - /* create a temporary COW file */
173   - cow_fd = mkstemp64(template);
174   - if (cow_fd < 0)
175   - goto fail;
176   - bs->cow_fd = cow_fd;
177   - unlink(template);
178   -
179   - /* just need to allocate bitmap */
180   - bs->cow_bitmap_size = (bs->total_sectors + 7) >> 3;
181   - bs->cow_bitmap_addr = mmap(get_mmap_addr(bs->cow_bitmap_size),
182   - bs->cow_bitmap_size,
183   - PROT_READ | PROT_WRITE,
184   - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
185   - if (bs->cow_bitmap_addr == MAP_FAILED)
186   - goto fail;
187   - bs->cow_bitmap = bs->cow_bitmap_addr;
188   - bs->cow_sectors_offset = 0;
189   - }
190   -#endif
191   -
192 188 bs->inserted = 1;
193 189  
194 190 /* call the change callback */
... ... @@ -196,23 +192,22 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot)
196 192 bs->change_cb(bs->change_opaque);
197 193  
198 194 return 0;
199   - fail:
200   - bdrv_close(bs);
201   - return -1;
202 195 }
203 196  
204 197 void bdrv_close(BlockDriverState *bs)
205 198 {
206 199 if (bs->inserted) {
207   -#ifndef _WIN32
208   - /* we unmap the mapping so that it is written to the COW file */
209   - if (bs->cow_bitmap_addr)
210   - munmap(bs->cow_bitmap_addr, bs->cow_bitmap_size);
  200 + if (bs->backing_hd)
  201 + bdrv_delete(bs->backing_hd);
  202 + bs->drv->bdrv_close(bs);
  203 + qemu_free(bs->opaque);
  204 +#ifdef _WIN32
  205 + if (bs->is_temporary) {
  206 + unlink(bs->filename);
  207 + }
211 208 #endif
212   - if (bs->cow_fd >= 0)
213   - close(bs->cow_fd);
214   - if (bs->fd >= 0)
215   - close(bs->fd);
  209 + bs->opaque = NULL;
  210 + bs->drv = NULL;
216 211 bs->inserted = 0;
217 212  
218 213 /* call the change callback */
... ... @@ -223,85 +218,45 @@ void bdrv_close(BlockDriverState *bs)
223 218  
224 219 void bdrv_delete(BlockDriverState *bs)
225 220 {
  221 + /* XXX: remove the driver list */
226 222 bdrv_close(bs);
227 223 qemu_free(bs);
228 224 }
229 225  
230   -static inline void set_bit(uint8_t *bitmap, int64_t bitnum)
231   -{
232   - bitmap[bitnum / 8] |= (1 << (bitnum%8));
233   -}
234   -
235   -static inline int is_bit_set(const uint8_t *bitmap, int64_t bitnum)
236   -{
237   - return !!(bitmap[bitnum / 8] & (1 << (bitnum%8)));
238   -}
239   -
240   -
241   -/* Return true if first block has been changed (ie. current version is
242   - * in COW file). Set the number of continuous blocks for which that
243   - * is true. */
244   -static int is_changed(uint8_t *bitmap,
245   - int64_t sector_num, int nb_sectors,
246   - int *num_same)
247   -{
248   - int changed;
249   -
250   - if (!bitmap || nb_sectors == 0) {
251   - *num_same = nb_sectors;
252   - return 0;
253   - }
254   -
255   - changed = is_bit_set(bitmap, sector_num);
256   - for (*num_same = 1; *num_same < nb_sectors; (*num_same)++) {
257   - if (is_bit_set(bitmap, sector_num + *num_same) != changed)
258   - break;
259   - }
260   -
261   - return changed;
262   -}
263   -
264 226 /* commit COW file into the raw image */
265 227 int bdrv_commit(BlockDriverState *bs)
266 228 {
267 229 int64_t i;
268   - uint8_t *cow_bitmap;
  230 + int n, j;
  231 + unsigned char sector[512];
269 232  
270 233 if (!bs->inserted)
271   - return -1;
272   -
273   - if (!bs->cow_bitmap) {
274   - fprintf(stderr, "Already committed to %s\n", bs->filename);
275   - return 0;
276   - }
  234 + return -ENOENT;
277 235  
278 236 if (bs->read_only) {
279   - fprintf(stderr, "Can't commit to %s: read-only\n", bs->filename);
280   - return -1;
  237 + return -EACCES;
281 238 }
282 239  
283   - cow_bitmap = bs->cow_bitmap;
284   - for (i = 0; i < bs->total_sectors; i++) {
285   - if (is_bit_set(cow_bitmap, i)) {
286   - unsigned char sector[512];
287   - if (bdrv_read(bs, i, sector, 1) != 0) {
288   - fprintf(stderr, "Error reading sector %lli: aborting commit\n",
289   - (long long)i);
290   - return -1;
291   - }
  240 + if (!bs->backing_hd) {
  241 + return -ENOTSUP;
  242 + }
292 243  
293   - /* Make bdrv_write write to real file for a moment. */
294   - bs->cow_bitmap = NULL;
295   - if (bdrv_write(bs, i, sector, 1) != 0) {
296   - fprintf(stderr, "Error writing sector %lli: aborting commit\n",
297   - (long long)i);
298   - bs->cow_bitmap = cow_bitmap;
299   - return -1;
  244 + for (i = 0; i < bs->total_sectors;) {
  245 + if (bs->drv->bdrv_is_allocated(bs, i, 65536, &n)) {
  246 + for(j = 0; j < n; j++) {
  247 + if (bdrv_read(bs, i, sector, 1) != 0) {
  248 + return -EIO;
  249 + }
  250 +
  251 + if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) {
  252 + return -EIO;
  253 + }
  254 + i++;
300 255 }
301   - bs->cow_bitmap = cow_bitmap;
302   - }
  256 + } else {
  257 + i += n;
  258 + }
303 259 }
304   - fprintf(stderr, "Committed snapshot to %s\n", bs->filename);
305 260 return 0;
306 261 }
307 262  
... ... @@ -309,37 +264,34 @@ int bdrv_commit(BlockDriverState *bs)
309 264 int bdrv_read(BlockDriverState *bs, int64_t sector_num,
310 265 uint8_t *buf, int nb_sectors)
311 266 {
312   - int ret, n, fd;
313   - int64_t offset;
314   -
  267 + int ret, n;
  268 + BlockDriver *drv = bs->drv;
  269 +
315 270 if (!bs->inserted)
316 271 return -1;
317 272  
318 273 while (nb_sectors > 0) {
319   - if (is_changed(bs->cow_bitmap, sector_num, nb_sectors, &n)) {
320   - fd = bs->cow_fd;
321   - offset = bs->cow_sectors_offset;
322   - } else if (sector_num == 0 && bs->boot_sector_enabled) {
  274 + if (sector_num == 0 && bs->boot_sector_enabled) {
323 275 memcpy(buf, bs->boot_sector_data, 512);
324 276 n = 1;
325   - goto next;
326   - } else {
327   - fd = bs->fd;
328   - offset = 0;
329   - }
330   -
331   - if (fd < 0) {
332   - /* no file, just return empty sectors */
333   - memset(buf, 0, n * 512);
  277 + } else if (bs->backing_hd) {
  278 + if (drv->bdrv_is_allocated(bs, sector_num, nb_sectors, &n)) {
  279 + ret = drv->bdrv_read(bs, sector_num, buf, n);
  280 + if (ret < 0)
  281 + return -1;
  282 + } else {
  283 + /* read from the base image */
  284 + ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
  285 + if (ret < 0)
  286 + return -1;
  287 + }
334 288 } else {
335   - offset += sector_num * 512;
336   - lseek64(fd, offset, SEEK_SET);
337   - ret = read(fd, buf, n * 512);
338   - if (ret != n * 512) {
  289 + ret = drv->bdrv_read(bs, sector_num, buf, nb_sectors);
  290 + if (ret < 0)
339 291 return -1;
340   - }
  292 + /* no need to loop */
  293 + break;
341 294 }
342   - next:
343 295 nb_sectors -= n;
344 296 sector_num += n;
345 297 buf += n * 512;
... ... @@ -351,37 +303,11 @@ int bdrv_read(BlockDriverState *bs, int64_t sector_num,
351 303 int bdrv_write(BlockDriverState *bs, int64_t sector_num,
352 304 const uint8_t *buf, int nb_sectors)
353 305 {
354   - int ret, fd, i;
355   - int64_t offset, retl;
356   -
357 306 if (!bs->inserted)
358 307 return -1;
359 308 if (bs->read_only)
360 309 return -1;
361   -
362   - if (bs->cow_bitmap) {
363   - fd = bs->cow_fd;
364   - offset = bs->cow_sectors_offset;
365   - } else {
366   - fd = bs->fd;
367   - offset = 0;
368   - }
369   -
370   - offset += sector_num * 512;
371   - retl = lseek64(fd, offset, SEEK_SET);
372   - if (retl == -1) {
373   - return -1;
374   - }
375   - ret = write(fd, buf, nb_sectors * 512);
376   - if (ret != nb_sectors * 512) {
377   - return -1;
378   - }
379   -
380   - if (bs->cow_bitmap) {
381   - for (i = 0; i < nb_sectors; i++)
382   - set_bit(bs->cow_bitmap, sector_num + i);
383   - }
384   - return 0;
  310 + return bs->drv->bdrv_write(bs, sector_num, buf, nb_sectors);
385 311 }
386 312  
387 313 void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr)
... ... @@ -459,6 +385,47 @@ void bdrv_set_change_cb(BlockDriverState *bs,
459 385 bs->change_opaque = opaque;
460 386 }
461 387  
  388 +int bdrv_is_encrypted(BlockDriverState *bs)
  389 +{
  390 + if (bs->backing_hd && bs->backing_hd->encrypted)
  391 + return 1;
  392 + return bs->encrypted;
  393 +}
  394 +
  395 +int bdrv_set_key(BlockDriverState *bs, const char *key)
  396 +{
  397 + int ret;
  398 + if (bs->backing_hd && bs->backing_hd->encrypted) {
  399 + ret = bdrv_set_key(bs->backing_hd, key);
  400 + if (ret < 0)
  401 + return ret;
  402 + if (!bs->encrypted)
  403 + return 0;
  404 + }
  405 + if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key)
  406 + return -1;
  407 + return bs->drv->bdrv_set_key(bs, key);
  408 +}
  409 +
  410 +void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
  411 +{
  412 + if (!bs->inserted || !bs->drv) {
  413 + buf[0] = '\0';
  414 + } else {
  415 + pstrcpy(buf, buf_size, bs->drv->format_name);
  416 + }
  417 +}
  418 +
  419 +void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
  420 + void *opaque)
  421 +{
  422 + BlockDriver *drv;
  423 +
  424 + for (drv = first_drv; drv != NULL; drv = drv->next) {
  425 + it(opaque, drv->format_name);
  426 + }
  427 +}
  428 +
462 429 BlockDriverState *bdrv_find(const char *name)
463 430 {
464 431 BlockDriverState *bs;
... ... @@ -479,6 +446,11 @@ void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque)
479 446 }
480 447 }
481 448  
  449 +const char *bdrv_get_device_name(BlockDriverState *bs)
  450 +{
  451 + return bs->device_name;
  452 +}
  453 +
482 454 void bdrv_info(void)
483 455 {
484 456 BlockDriverState *bs;
... ... @@ -503,10 +475,117 @@ void bdrv_info(void)
503 475 }
504 476 if (bs->inserted) {
505 477 term_printf(" file=%s", bs->filename);
  478 + if (bs->backing_file[0] != '\0')
  479 + term_printf(" backing_file=%s", bs->backing_file);
506 480 term_printf(" ro=%d", bs->read_only);
  481 + term_printf(" drv=%s", bs->drv->format_name);
  482 + if (bs->encrypted)
  483 + term_printf(" encrypted");
507 484 } else {
508 485 term_printf(" [not inserted]");
509 486 }
510 487 term_printf("\n");
511 488 }
512 489 }
  490 +
  491 +
  492 +/**************************************************************/
  493 +/* RAW block driver */
  494 +
  495 +typedef struct BDRVRawState {
  496 + int fd;
  497 +} BDRVRawState;
  498 +
  499 +static int raw_probe(const uint8_t *buf, int buf_size, const char *filename)
  500 +{
  501 + return 1; /* maybe */
  502 +}
  503 +
  504 +static int raw_open(BlockDriverState *bs, const char *filename)
  505 +{
  506 + BDRVRawState *s = bs->opaque;
  507 + int fd;
  508 + int64_t size;
  509 +
  510 + fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
  511 + if (fd < 0) {
  512 + fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
  513 + if (fd < 0)
  514 + return -1;
  515 + bs->read_only = 1;
  516 + }
  517 + size = lseek64(fd, 0, SEEK_END);
  518 + bs->total_sectors = size / 512;
  519 + s->fd = fd;
  520 + return 0;
  521 +}
  522 +
  523 +static int raw_read(BlockDriverState *bs, int64_t sector_num,
  524 + uint8_t *buf, int nb_sectors)
  525 +{
  526 + BDRVRawState *s = bs->opaque;
  527 + int ret;
  528 +
  529 + lseek64(s->fd, sector_num * 512, SEEK_SET);
  530 + ret = read(s->fd, buf, nb_sectors * 512);
  531 + if (ret != nb_sectors * 512)
  532 + return -1;
  533 + return 0;
  534 +}
  535 +
  536 +static int raw_write(BlockDriverState *bs, int64_t sector_num,
  537 + const uint8_t *buf, int nb_sectors)
  538 +{
  539 + BDRVRawState *s = bs->opaque;
  540 + int ret;
  541 +
  542 + lseek64(s->fd, sector_num * 512, SEEK_SET);
  543 + ret = write(s->fd, buf, nb_sectors * 512);
  544 + if (ret != nb_sectors * 512)
  545 + return -1;
  546 + return 0;
  547 +}
  548 +
  549 +static int raw_close(BlockDriverState *bs)
  550 +{
  551 + BDRVRawState *s = bs->opaque;
  552 + close(s->fd);
  553 +}
  554 +
  555 +static int raw_create(const char *filename, int64_t total_size,
  556 + const char *backing_file, int flags)
  557 +{
  558 + int fd;
  559 +
  560 + if (flags || backing_file)
  561 + return -ENOTSUP;
  562 +
  563 + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
  564 + 0644);
  565 + if (fd < 0)
  566 + return -EIO;
  567 + ftruncate64(fd, total_size * 512);
  568 + close(fd);
  569 + return 0;
  570 +}
  571 +
  572 +BlockDriver bdrv_raw = {
  573 + "raw",
  574 + sizeof(BDRVRawState),
  575 + raw_probe,
  576 + raw_open,
  577 + raw_read,
  578 + raw_write,
  579 + raw_close,
  580 + raw_create,
  581 +};
  582 +
  583 +void bdrv_init(void)
  584 +{
  585 + bdrv_register(&bdrv_raw);
  586 +#ifndef _WIN32
  587 + bdrv_register(&bdrv_cow);
  588 +#endif
  589 + bdrv_register(&bdrv_qcow);
  590 + bdrv_register(&bdrv_vmdk);
  591 +}
... ...
block_int.h 0 → 100644
  1 +/*
  2 + * QEMU System Emulator block driver
  3 + *
  4 + * Copyright (c) 2003 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#ifndef BLOCK_INT_H
  25 +#define BLOCK_INT_H
  26 +
  27 +struct BlockDriver {
  28 + const char *format_name;
  29 + int instance_size;
  30 + int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename);
  31 + int (*bdrv_open)(BlockDriverState *bs, const char *filename);
  32 + int (*bdrv_read)(BlockDriverState *bs, int64_t sector_num,
  33 + uint8_t *buf, int nb_sectors);
  34 + int (*bdrv_write)(BlockDriverState *bs, int64_t sector_num,
  35 + const uint8_t *buf, int nb_sectors);
  36 + int (*bdrv_close)(BlockDriverState *bs);
  37 + int (*bdrv_create)(const char *filename, int64_t total_sectors,
  38 + const char *backing_file, int flags);
  39 + int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num,
  40 + int nb_sectors, int *pnum);
  41 + int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
  42 + struct BlockDriver *next;
  43 +};
  44 +
  45 +struct BlockDriverState {
  46 + int64_t total_sectors;
  47 + int read_only; /* if true, the media is read only */
  48 + int inserted; /* if true, the media is present */
  49 + int removable; /* if true, the media can be removed */
  50 + int locked; /* if true, the media cannot temporarily be ejected */
  51 + int encrypted; /* if true, the media is encrypted */
  52 + /* event callback when inserting/removing */
  53 + void (*change_cb)(void *opaque);
  54 + void *change_opaque;
  55 +
  56 + BlockDriver *drv;
  57 + void *opaque;
  58 +
  59 + int boot_sector_enabled;
  60 + uint8_t boot_sector_data[512];
  61 +
  62 + char filename[1024];
  63 + char backing_file[1024]; /* if non zero, the image is a diff of
  64 + this file image */
  65 + int is_temporary;
  66 +
  67 + BlockDriverState *backing_hd;
  68 +
  69 + /* NOTE: the following infos are only hints for real hardware
  70 + drivers. They are not used by the block driver */
  71 + int cyls, heads, secs;
  72 + int type;
  73 + char device_name[32];
  74 + BlockDriverState *next;
  75 +};
  76 +
  77 +#endif /* BLOCK_INT_H */
... ...
qemu-img.c 0 → 100644
  1 +/*
  2 + * create a COW disk image
  3 + *
  4 + * Copyright (c) 2003 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#include "vl.h"
  25 +
  26 +void *get_mmap_addr(unsigned long size)
  27 +{
  28 + return NULL;
  29 +}
  30 +
  31 +void qemu_free(void *ptr)
  32 +{
  33 + free(ptr);
  34 +}
  35 +
  36 +void *qemu_malloc(size_t size)
  37 +{
  38 + return malloc(size);
  39 +}
  40 +
  41 +void *qemu_mallocz(size_t size)
  42 +{
  43 + void *ptr;
  44 + ptr = qemu_malloc(size);
  45 + if (!ptr)
  46 + return NULL;
  47 + memset(ptr, 0, size);
  48 + return ptr;
  49 +}
  50 +
  51 +char *qemu_strdup(const char *str)
  52 +{
  53 + char *ptr;
  54 + ptr = qemu_malloc(strlen(str) + 1);
  55 + if (!ptr)
  56 + return NULL;
  57 + strcpy(ptr, str);
  58 + return ptr;
  59 +}
  60 +
  61 +void pstrcpy(char *buf, int buf_size, const char *str)
  62 +{
  63 + int c;
  64 + char *q = buf;
  65 +
  66 + if (buf_size <= 0)
  67 + return;
  68 +
  69 + for(;;) {
  70 + c = *str++;
  71 + if (c == 0 || q >= buf + buf_size - 1)
  72 + break;
  73 + *q++ = c;
  74 + }
  75 + *q = '\0';
  76 +}
  77 +
  78 +/* strcat and truncate. */
  79 +char *pstrcat(char *buf, int buf_size, const char *s)
  80 +{
  81 + int len;
  82 + len = strlen(buf);
  83 + if (len < buf_size)
  84 + pstrcpy(buf + len, buf_size - len, s);
  85 + return buf;
  86 +}
  87 +
  88 +int strstart(const char *str, const char *val, const char **ptr)
  89 +{
  90 + const char *p, *q;
  91 + p = str;
  92 + q = val;
  93 + while (*q != '\0') {
  94 + if (*p != *q)
  95 + return 0;
  96 + p++;
  97 + q++;
  98 + }
  99 + if (ptr)
  100 + *ptr = p;
  101 + return 1;
  102 +}
  103 +
  104 +void term_printf(const char *fmt, ...)
  105 +{
  106 + va_list ap;
  107 + va_start(ap, fmt);
  108 + vprintf(fmt, ap);
  109 + va_end(ap);
  110 +}
  111 +
  112 +void __attribute__((noreturn)) error(const char *fmt, ...)
  113 +{
  114 + va_list ap;
  115 + va_start(ap, fmt);
  116 + fprintf(stderr, "qemuimg: ");
  117 + vfprintf(stderr, fmt, ap);
  118 + fprintf(stderr, "\n");
  119 + exit(1);
  120 + va_end(ap);
  121 +}
  122 +
  123 +static void format_print(void *opaque, const char *name)
  124 +{
  125 + printf(" %s", name);
  126 +}
  127 +
  128 +void help(void)
  129 +{
  130 + printf("qemuimg version " QEMU_VERSION ", Copyright (c) 2004 Fabrice Bellard\n"
  131 + "usage: qemuimg command [command options]\n"
  132 + "QEMU disk image utility\n"
  133 + "\n"
  134 + "Command syntax:\n"
  135 + " create [-e] [-b base_image] [-f fmt] filename [size]\n"
  136 + " commit [-f fmt] filename\n"
  137 + " convert [-c] [-e] [-f fmt] filename [-O output_fmt] output_filename\n"
  138 + " info [-f fmt] filename\n"
  139 + "\n"
  140 + "Command parameters:\n"
  141 + " 'filename' is a disk image filename\n"
  142 + " 'base_image' is the read-only disk image which is used as base for a copy on\n"
  143 + " write image; the copy on write image only stores the modified data\n"
  144 + " 'fmt' is the disk image format. It is guessed automatically in most cases\n"
  145 + " 'size' is the disk image size in kilobytes. Optional suffixes 'M' (megabyte)\n"
  146 + " and 'G' (gigabyte) are supported\n"
  147 + " 'output_filename' is the destination disk image filename\n"
  148 + " 'output_fmt' is the destination format\n"
  149 + " '-c' indicates that target image must be compressed (qcow format only)\n"
  150 + " '-e' indicates that the target image must be encrypted (qcow format only)\n"
  151 + );
  152 + printf("\nSupported format:");
  153 + bdrv_iterate_format(format_print, NULL);
  154 + printf("\n");
  155 + exit(1);
  156 +}
  157 +
  158 +
  159 +#define NB_SUFFIXES 4
  160 +
  161 +static void get_human_readable_size(char *buf, int buf_size, int64_t size)
  162 +{
  163 + char suffixes[NB_SUFFIXES] = "KMGT";
  164 + int64_t base;
  165 + int i;
  166 +
  167 + if (size <= 999) {
  168 + snprintf(buf, buf_size, "%lld", size);
  169 + } else {
  170 + base = 1024;
  171 + for(i = 0; i < NB_SUFFIXES; i++) {
  172 + if (size < (10 * base)) {
  173 + snprintf(buf, buf_size, "%0.1f%c",
  174 + (double)size / base,
  175 + suffixes[i]);
  176 + break;
  177 + } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
  178 + snprintf(buf, buf_size, "%lld%c",
  179 + (size + (base >> 1)) / base,
  180 + suffixes[i]);
  181 + break;
  182 + }
  183 + base = base * 1024;
  184 + }
  185 + }
  186 +}
  187 +
  188 +#if defined(WIN32)
  189 +/* XXX: put correct support for win32 */
  190 +static int read_password(char *buf, int buf_size)
  191 +{
  192 + int c, i;
  193 + printf("Password: ");
  194 + fflush(stdout);
  195 + i = 0;
  196 + for(;;) {
  197 + c = getchar();
  198 + if (c == '\n')
  199 + break;
  200 + if (i < (buf_size - 1))
  201 + buf[i++] = c;
  202 + }
  203 + buf[i] = '\0';
  204 + return 0;
  205 +}
  206 +
  207 +#else
  208 +
  209 +#include <termios.h>
  210 +
  211 +static struct termios oldtty;
  212 +
  213 +static void term_exit(void)
  214 +{
  215 + tcsetattr (0, TCSANOW, &oldtty);
  216 +}
  217 +
  218 +static void term_init(void)
  219 +{
  220 + struct termios tty;
  221 +
  222 + tcgetattr (0, &tty);
  223 + oldtty = tty;
  224 +
  225 + tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
  226 + |INLCR|IGNCR|ICRNL|IXON);
  227 + tty.c_oflag |= OPOST;
  228 + tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
  229 + tty.c_cflag &= ~(CSIZE|PARENB);
  230 + tty.c_cflag |= CS8;
  231 + tty.c_cc[VMIN] = 1;
  232 + tty.c_cc[VTIME] = 0;
  233 +
  234 + tcsetattr (0, TCSANOW, &tty);
  235 +
  236 + atexit(term_exit);
  237 +}
  238 +
  239 +int read_password(char *buf, int buf_size)
  240 +{
  241 + uint8_t ch;
  242 + int i, ret;
  243 +
  244 + printf("password: ");
  245 + fflush(stdout);
  246 + term_init();
  247 + i = 0;
  248 + for(;;) {
  249 + ret = read(0, &ch, 1);
  250 + if (ret == -1) {
  251 + if (errno == EAGAIN || errno == EINTR) {
  252 + continue;
  253 + } else {
  254 + ret = -1;
  255 + break;
  256 + }
  257 + } else if (ret == 0) {
  258 + ret = -1;
  259 + break;
  260 + } else {
  261 + if (ch == '\r') {
  262 + ret = 0;
  263 + break;
  264 + }
  265 + if (i < (buf_size - 1))
  266 + buf[i++] = ch;
  267 + }
  268 + }
  269 + term_exit();
  270 + buf[i] = '\0';
  271 + printf("\n");
  272 + return ret;
  273 +}
  274 +#endif
  275 +
  276 +static int img_create(int argc, char **argv)
  277 +{
  278 + int c, ret, encrypted;
  279 + const char *fmt = "raw";
  280 + const char *filename;
  281 + const char *base_filename = NULL;
  282 + int64_t size;
  283 + const char *p;
  284 + BlockDriver *drv;
  285 +
  286 + encrypted = 0;
  287 + for(;;) {
  288 + c = getopt(argc, argv, "b:f:he");
  289 + if (c == -1)
  290 + break;
  291 + switch(c) {
  292 + case 'h':
  293 + help();
  294 + break;
  295 + case 'b':
  296 + base_filename = optarg;
  297 + break;
  298 + case 'f':
  299 + fmt = optarg;
  300 + break;
  301 + case 'e':
  302 + encrypted = 1;
  303 + break;
  304 + }
  305 + }
  306 + optind++;
  307 + if (optind >= argc)
  308 + help();
  309 + filename = argv[optind++];
  310 + size = 0;
  311 + if (!base_filename) {
  312 + if (optind >= argc)
  313 + help();
  314 + p = argv[optind];
  315 + size = strtoul(p, (char **)&p, 0);
  316 + if (*p == 'M') {
  317 + size *= 1024 * 1024;
  318 + } else if (*p == 'G') {
  319 + size *= 1024 * 1024 * 1024;
  320 + } else if (*p == 'k' || *p == 'K' || *p == '\0') {
  321 + size *= 1024;
  322 + } else {
  323 + help();
  324 + }
  325 + }
  326 + drv = bdrv_find_format(fmt);
  327 + if (!drv)
  328 + error("Unknown file format '%s'", fmt);
  329 + printf("Formating '%s', fmt=%s",
  330 + filename, fmt);
  331 + if (encrypted)
  332 + printf(", encrypted");
  333 + if (base_filename)
  334 + printf(", backing_file=%s\n",
  335 + base_filename);
  336 + else
  337 + printf(", size=%lld kB\n", size / 1024);
  338 + ret = bdrv_create(drv, filename, size / 512, base_filename, encrypted);
  339 + if (ret < 0) {
  340 + if (ret == -ENOTSUP) {
  341 + error("Formatting or formatting option not suppored for file format '%s'", fmt);
  342 + } else {
  343 + error("Error while formatting");
  344 + }
  345 + }
  346 + return 0;
  347 +}
  348 +
  349 +static int img_commit(int argc, char **argv)
  350 +{
  351 + int c, ret;
  352 + const char *filename, *fmt;
  353 + BlockDriver *drv;
  354 + BlockDriverState *bs;
  355 +
  356 + fmt = NULL;
  357 + for(;;) {
  358 + c = getopt(argc, argv, "f:h");
  359 + if (c == -1)
  360 + break;
  361 + switch(c) {
  362 + case 'h':
  363 + help();
  364 + break;
  365 + case 'f':
  366 + fmt = optarg;
  367 + break;
  368 + }
  369 + }
  370 + optind++;
  371 + if (optind >= argc)
  372 + help();
  373 + filename = argv[optind++];
  374 +
  375 + bs = bdrv_new("");
  376 + if (!bs)
  377 + error("Not enough memory");
  378 + if (fmt) {
  379 + drv = bdrv_find_format(fmt);
  380 + if (!drv)
  381 + error("Unknown file format '%s'", fmt);
  382 + } else {
  383 + drv = NULL;
  384 + }
  385 + if (bdrv_open2(bs, filename, 0, drv) < 0) {
  386 + error("Could not open '%s'", filename);
  387 + }
  388 + ret = bdrv_commit(bs);
  389 + switch(ret) {
  390 + case 0:
  391 + printf("Image committed.\n");
  392 + break;
  393 + case -ENOENT:
  394 + error("No disk inserted");
  395 + break;
  396 + case -EACCES:
  397 + error("Image is read-only");
  398 + break;
  399 + case -ENOTSUP:
  400 + error("Image is already committed");
  401 + break;
  402 + default:
  403 + error("Error while committing image");
  404 + break;
  405 + }
  406 +
  407 + bdrv_delete(bs);
  408 + return 0;
  409 +}
  410 +
  411 +static int is_not_zero(const uint8_t *sector, int len)
  412 +{
  413 + int i;
  414 + len >>= 2;
  415 + for(i = 0;i < len; i++) {
  416 + if (((uint32_t *)sector)[i] != 0)
  417 + return 1;
  418 + }
  419 + return 0;
  420 +}
  421 +
  422 +static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
  423 +{
  424 + int v, i;
  425 +
  426 + if (n <= 0) {
  427 + *pnum = 0;
  428 + return 0;
  429 + }
  430 + v = is_not_zero(buf, 512);
  431 + for(i = 1; i < n; i++) {
  432 + buf += 512;
  433 + if (v != is_not_zero(buf, 512))
  434 + break;
  435 + }
  436 + *pnum = i;
  437 + return v;
  438 +}
  439 +
  440 +static BlockDriverState *bdrv_new_open(const char *filename,
  441 + const char *fmt)
  442 +{
  443 + BlockDriverState *bs;
  444 + BlockDriver *drv;
  445 + char password[256];
  446 +
  447 + bs = bdrv_new("");
  448 + if (!bs)
  449 + error("Not enough memory");
  450 + if (fmt) {
  451 + drv = bdrv_find_format(fmt);
  452 + if (!drv)
  453 + error("Unknown file format '%s'", fmt);
  454 + } else {
  455 + drv = NULL;
  456 + }
  457 + if (bdrv_open2(bs, filename, 0, drv) < 0) {
  458 + error("Could not open '%s'", filename);
  459 + }
  460 + if (bdrv_is_encrypted(bs)) {
  461 + printf("Disk image '%s' is encrypted.\n", filename);
  462 + if (read_password(password, sizeof(password)) < 0)
  463 + error("No password given");
  464 + if (bdrv_set_key(bs, password) < 0)
  465 + error("invalid password");
  466 + }
  467 + return bs;
  468 +}
  469 +
  470 +#define IO_BUF_SIZE 65536
  471 +
  472 +static int img_convert(int argc, char **argv)
  473 +{
  474 + int c, ret, n, n1, compress, cluster_size, cluster_sectors, encrypt;
  475 + const char *filename, *fmt, *out_fmt, *out_filename;
  476 + BlockDriver *drv;
  477 + BlockDriverState *bs, *out_bs;
  478 + int64_t total_sectors, nb_sectors, sector_num;
  479 + uint8_t buf[IO_BUF_SIZE];
  480 + const uint8_t *buf1;
  481 +
  482 + fmt = NULL;
  483 + out_fmt = "raw";
  484 + compress = 0;
  485 + encrypt = 0;
  486 + for(;;) {
  487 + c = getopt(argc, argv, "f:O:hce");
  488 + if (c == -1)
  489 + break;
  490 + switch(c) {
  491 + case 'h':
  492 + help();
  493 + break;
  494 + case 'f':
  495 + fmt = optarg;
  496 + break;
  497 + case 'O':
  498 + out_fmt = optarg;
  499 + break;
  500 + case 'c':
  501 + compress = 1;
  502 + break;
  503 + case 'e':
  504 + encrypt = 1;
  505 + break;
  506 + }
  507 + }
  508 + optind++;
  509 + if (optind >= argc)
  510 + help();
  511 + filename = argv[optind++];
  512 + if (optind >= argc)
  513 + help();
  514 + out_filename = argv[optind++];
  515 +
  516 + bs = bdrv_new_open(filename, fmt);
  517 +
  518 + drv = bdrv_find_format(out_fmt);
  519 + if (!drv)
  520 + error("Unknown file format '%s'", fmt);
  521 + if (compress && drv != &bdrv_qcow)
  522 + error("Compression not supported for this file format");
  523 + if (encrypt && drv != &bdrv_qcow)
  524 + error("Encryption not supported for this file format");
  525 + if (compress && encrypt)
  526 + error("Compression and encryption not supported at the same time");
  527 + bdrv_get_geometry(bs, &total_sectors);
  528 + ret = bdrv_create(drv, out_filename, total_sectors, NULL, encrypt);
  529 + if (ret < 0) {
  530 + if (ret == -ENOTSUP) {
  531 + error("Formatting not suppored for file format '%s'", fmt);
  532 + } else {
  533 + error("Error while formatting '%s'", out_filename);
  534 + }
  535 + }
  536 +
  537 + out_bs = bdrv_new_open(out_filename, out_fmt);
  538 +
  539 + if (compress) {
  540 + cluster_size = qcow_get_cluster_size(out_bs);
  541 + if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE)
  542 + error("invalid cluster size");
  543 + cluster_sectors = cluster_size >> 9;
  544 + sector_num = 0;
  545 + for(;;) {
  546 + nb_sectors = total_sectors - sector_num;
  547 + if (nb_sectors <= 0)
  548 + break;
  549 + if (nb_sectors >= cluster_sectors)
  550 + n = cluster_sectors;
  551 + else
  552 + n = nb_sectors;
  553 + if (bdrv_read(bs, sector_num, buf, n) < 0)
  554 + error("error while reading");
  555 + if (n < cluster_sectors)
  556 + memset(buf + n * 512, 0, cluster_size - n * 512);
  557 + if (is_not_zero(buf, cluster_size)) {
  558 + if (qcow_compress_cluster(out_bs, sector_num, buf) != 0)
  559 + error("error while compressing sector %lld", sector_num);
  560 + }
  561 + sector_num += n;
  562 + }
  563 + } else {
  564 + sector_num = 0;
  565 + for(;;) {
  566 + nb_sectors = total_sectors - sector_num;
  567 + if (nb_sectors <= 0)
  568 + break;
  569 + if (nb_sectors >= (IO_BUF_SIZE / 512))
  570 + n = (IO_BUF_SIZE / 512);
  571 + else
  572 + n = nb_sectors;
  573 + if (bdrv_read(bs, sector_num, buf, n) < 0)
  574 + error("error while reading");
  575 + /* NOTE: at the same time we convert, we do not write zero
  576 + sectors to have a chance to compress the image. Ideally, we
  577 + should add a specific call to have the info to go faster */
  578 + buf1 = buf;
  579 + while (n > 0) {
  580 + if (is_allocated_sectors(buf1, n, &n1)) {
  581 + if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
  582 + error("error while writing");
  583 + }
  584 + sector_num += n1;
  585 + n -= n1;
  586 + buf1 += n1 * 512;
  587 + }
  588 + }
  589 + }
  590 + bdrv_delete(out_bs);
  591 + bdrv_delete(bs);
  592 + return 0;
  593 +}
  594 +
  595 +static int img_info(int argc, char **argv)
  596 +{
  597 + int c;
  598 + const char *filename, *fmt;
  599 + BlockDriver *drv;
  600 + BlockDriverState *bs;
  601 + char fmt_name[128], size_buf[128], dsize_buf[128];
  602 + int64_t total_sectors;
  603 + struct stat st;
  604 +
  605 + fmt = NULL;
  606 + for(;;) {
  607 + c = getopt(argc, argv, "f:h");
  608 + if (c == -1)
  609 + break;
  610 + switch(c) {
  611 + case 'h':
  612 + help();
  613 + break;
  614 + case 'f':
  615 + fmt = optarg;
  616 + break;
  617 + }
  618 + }
  619 + optind++;
  620 + if (optind >= argc)
  621 + help();
  622 + filename = argv[optind++];
  623 +
  624 + bs = bdrv_new("");
  625 + if (!bs)
  626 + error("Not enough memory");
  627 + if (fmt) {
  628 + drv = bdrv_find_format(fmt);
  629 + if (!drv)
  630 + error("Unknown file format '%s'", fmt);
  631 + } else {
  632 + drv = NULL;
  633 + }
  634 + if (bdrv_open2(bs, filename, 0, drv) < 0) {
  635 + error("Could not open '%s'", filename);
  636 + }
  637 + bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
  638 + bdrv_get_geometry(bs, &total_sectors);
  639 + get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
  640 + if (stat(filename, &st) < 0)
  641 + error("Could not stat '%s'", filename);
  642 + get_human_readable_size(dsize_buf, sizeof(dsize_buf),
  643 + (int64_t)st.st_blocks * 512);
  644 + printf("image: %s\n"
  645 + "file format: %s\n"
  646 + "virtual size: %s (%lld bytes)\n"
  647 + "disk size: %s\n",
  648 + filename, fmt_name, size_buf,
  649 + total_sectors * 512,
  650 + dsize_buf);
  651 + if (bdrv_is_encrypted(bs))
  652 + printf("encrypted: yes\n");
  653 + bdrv_delete(bs);
  654 + return 0;
  655 +}
  656 +
  657 +int main(int argc, char **argv)
  658 +{
  659 + const char *cmd;
  660 +
  661 + bdrv_init();
  662 + if (argc < 2)
  663 + help();
  664 + cmd = argv[1];
  665 + if (!strcmp(cmd, "create")) {
  666 + img_create(argc, argv);
  667 + } else if (!strcmp(cmd, "commit")) {
  668 + img_commit(argc, argv);
  669 + } else if (!strcmp(cmd, "convert")) {
  670 + img_convert(argc, argv);
  671 + } else if (!strcmp(cmd, "info")) {
  672 + img_info(argc, argv);
  673 + } else {
  674 + help();
  675 + }
  676 + return 0;
  677 +}
... ...
... ... @@ -48,8 +48,21 @@
48 48 #define lseek64 _lseeki64
49 49 #endif
50 50  
  51 +#ifdef QEMU_TOOL
  52 +
  53 +/* we use QEMU_TOOL in the command line tools which do not depend on
  54 + the target CPU type */
  55 +#include "config-host.h"
  56 +#include <setjmp.h>
  57 +#include "osdep.h"
  58 +#include "bswap.h"
  59 +
  60 +#else
  61 +
51 62 #include "cpu.h"
52 63  
  64 +#endif /* !defined(QEMU_TOOL) */
  65 +
53 66 #ifndef glue
54 67 #define xglue(x, y) x ## y
55 68 #define glue(x, y) xglue(x, y)
... ... @@ -57,153 +70,6 @@
57 70 #define tostring(s) #s
58 71 #endif
59 72  
60   -#if defined(WORDS_BIGENDIAN)
61   -static inline uint32_t be32_to_cpu(uint32_t v)
62   -{
63   - return v;
64   -}
65   -
66   -static inline uint16_t be16_to_cpu(uint16_t v)
67   -{
68   - return v;
69   -}
70   -
71   -static inline uint32_t cpu_to_be32(uint32_t v)
72   -{
73   - return v;
74   -}
75   -
76   -static inline uint16_t cpu_to_be16(uint16_t v)
77   -{
78   - return v;
79   -}
80   -
81   -static inline uint32_t le32_to_cpu(uint32_t v)
82   -{
83   - return bswap32(v);
84   -}
85   -
86   -static inline uint16_t le16_to_cpu(uint16_t v)
87   -{
88   - return bswap16(v);
89   -}
90   -
91   -static inline uint32_t cpu_to_le32(uint32_t v)
92   -{
93   - return bswap32(v);
94   -}
95   -
96   -static inline uint16_t cpu_to_le16(uint16_t v)
97   -{
98   - return bswap16(v);
99   -}
100   -
101   -#else
102   -
103   -static inline uint32_t be32_to_cpu(uint32_t v)
104   -{
105   - return bswap32(v);
106   -}
107   -
108   -static inline uint16_t be16_to_cpu(uint16_t v)
109   -{
110   - return bswap16(v);
111   -}
112   -
113   -static inline uint32_t cpu_to_be32(uint32_t v)
114   -{
115   - return bswap32(v);
116   -}
117   -
118   -static inline uint16_t cpu_to_be16(uint16_t v)
119   -{
120   - return bswap16(v);
121   -}
122   -
123   -static inline uint32_t le32_to_cpu(uint32_t v)
124   -{
125   - return v;
126   -}
127   -
128   -static inline uint16_t le16_to_cpu(uint16_t v)
129   -{
130   - return v;
131   -}
132   -
133   -static inline uint32_t cpu_to_le32(uint32_t v)
134   -{
135   - return v;
136   -}
137   -
138   -static inline uint16_t cpu_to_le16(uint16_t v)
139   -{
140   - return v;
141   -}
142   -#endif
143   -
144   -static inline void cpu_to_le16w(uint16_t *p, uint16_t v)
145   -{
146   - *p = cpu_to_le16(v);
147   -}
148   -
149   -static inline void cpu_to_le32w(uint32_t *p, uint32_t v)
150   -{
151   - *p = cpu_to_le32(v);
152   -}
153   -
154   -static inline uint16_t le16_to_cpup(const uint16_t *p)
155   -{
156   - return le16_to_cpu(*p);
157   -}
158   -
159   -static inline uint32_t le32_to_cpup(const uint32_t *p)
160   -{
161   - return le32_to_cpu(*p);
162   -}
163   -
164   -/* unaligned versions (optimized for frequent unaligned accesses)*/
165   -
166   -#if defined(__i386__) || defined(__powerpc__)
167   -
168   -#define cpu_to_le16wu(p, v) cpu_to_le16w(p, v)
169   -#define cpu_to_le32wu(p, v) cpu_to_le32w(p, v)
170   -#define le16_to_cpupu(p) le16_to_cpup(p)
171   -#define le32_to_cpupu(p) le32_to_cpup(p)
172   -
173   -#else
174   -
175   -static inline void cpu_to_le16wu(uint16_t *p, uint16_t v)
176   -{
177   - uint8_t *p1 = (uint8_t *)p;
178   -
179   - p1[0] = v;
180   - p1[1] = v >> 8;
181   -}
182   -
183   -static inline void cpu_to_le32wu(uint32_t *p, uint32_t v)
184   -{
185   - uint8_t *p1 = (uint8_t *)p;
186   -
187   - p1[0] = v;
188   - p1[1] = v >> 8;
189   - p1[2] = v >> 16;
190   - p1[3] = v >> 24;
191   -}
192   -
193   -static inline uint16_t le16_to_cpupu(const uint16_t *p)
194   -{
195   - const uint8_t *p1 = (const uint8_t *)p;
196   - return p1[0] | (p1[1] << 8);
197   -}
198   -
199   -static inline uint32_t le32_to_cpupu(const uint32_t *p)
200   -{
201   - const uint8_t *p1 = (const uint8_t *)p;
202   - return p1[0] | (p1[1] << 8) | (p1[2] << 16) | (p1[3] << 24);
203   -}
204   -
205   -#endif
206   -
207 73 /* vl.c */
208 74 uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c);
209 75  
... ... @@ -233,6 +99,8 @@ void qemu_register_reset(QEMUResetHandler *func, void *opaque);
233 99 void qemu_system_reset_request(void);
234 100 void qemu_system_shutdown_request(void);
235 101  
  102 +void main_loop_wait(int timeout);
  103 +
236 104 extern int audio_enabled;
237 105 extern int ram_size;
238 106 extern int bios_size;
... ... @@ -301,6 +169,7 @@ void qemu_del_fd_read_handler(int fd);
301 169 /* character device */
302 170  
303 171 #define CHR_EVENT_BREAK 0 /* serial break char */
  172 +#define CHR_EVENT_FOCUS 1 /* focus to this terminal (modal input needed) */
304 173  
305 174 typedef void IOEventHandler(void *opaque, int event);
306 175  
... ... @@ -310,11 +179,13 @@ typedef struct CharDriverState {
310 179 IOCanRWHandler *fd_can_read,
311 180 IOReadHandler *fd_read, void *opaque);
312 181 IOEventHandler *chr_event;
  182 + IOEventHandler *chr_send_event;
313 183 void *opaque;
314 184 } CharDriverState;
315 185  
316 186 void qemu_chr_printf(CharDriverState *s, const char *fmt, ...);
317 187 int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len);
  188 +void qemu_chr_send_event(CharDriverState *s, int event);
318 189 void qemu_chr_add_read_handler(CharDriverState *s,
319 190 IOCanRWHandler *fd_can_read,
320 191 IOReadHandler *fd_read, void *opaque);
... ... @@ -464,10 +335,23 @@ void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
464 335  
465 336 /* block.c */
466 337 typedef struct BlockDriverState BlockDriverState;
467   -
  338 +typedef struct BlockDriver BlockDriver;
  339 +
  340 +extern BlockDriver bdrv_raw;
  341 +extern BlockDriver bdrv_cow;
  342 +extern BlockDriver bdrv_qcow;
  343 +extern BlockDriver bdrv_vmdk;
  344 +
  345 +void bdrv_init(void);
  346 +BlockDriver *bdrv_find_format(const char *format_name);
  347 +int bdrv_create(BlockDriver *drv,
  348 + const char *filename, int64_t size_in_sectors,
  349 + const char *backing_file, int flags);
468 350 BlockDriverState *bdrv_new(const char *device_name);
469 351 void bdrv_delete(BlockDriverState *bs);
470 352 int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot);
  353 +int bdrv_open2(BlockDriverState *bs, const char *filename, int snapshot,
  354 + BlockDriver *drv);
471 355 void bdrv_close(BlockDriverState *bs);
472 356 int bdrv_read(BlockDriverState *bs, int64_t sector_num,
473 357 uint8_t *buf, int nb_sectors);
... ... @@ -494,11 +378,21 @@ int bdrv_is_locked(BlockDriverState *bs);
494 378 void bdrv_set_locked(BlockDriverState *bs, int locked);
495 379 void bdrv_set_change_cb(BlockDriverState *bs,
496 380 void (*change_cb)(void *opaque), void *opaque);
497   -
  381 +void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size);
498 382 void bdrv_info(void);
499 383 BlockDriverState *bdrv_find(const char *name);
500 384 void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque);
  385 +int bdrv_is_encrypted(BlockDriverState *bs);
  386 +int bdrv_set_key(BlockDriverState *bs, const char *key);
  387 +void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
  388 + void *opaque);
  389 +const char *bdrv_get_device_name(BlockDriverState *bs);
501 390  
  391 +int qcow_get_cluster_size(BlockDriverState *bs);
  392 +int qcow_compress_cluster(BlockDriverState *bs, int64_t sector_num,
  393 + const uint8_t *buf);
  394 +
  395 +#ifndef QEMU_TOOL
502 396 /* ISA bus */
503 397  
504 398 extern target_phys_addr_t isa_mem_base;
... ... @@ -823,11 +717,28 @@ void adb_mouse_init(ADBBusState *bus);
823 717 extern ADBBusState adb_bus;
824 718 int cuda_init(openpic_t *openpic, int irq);
825 719  
  720 +#endif /* defined(QEMU_TOOL) */
  721 +
826 722 /* monitor.c */
827 723 void monitor_init(CharDriverState *hd, int show_banner);
  724 +void term_puts(const char *str);
  725 +void term_vprintf(const char *fmt, va_list ap);
828 726 void term_printf(const char *fmt, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
829 727 void term_flush(void);
830 728 void term_print_help(void);
  729 +void monitor_readline(const char *prompt, int is_password,
  730 + char *buf, int buf_size);
  731 +
  732 +/* readline.c */
  733 +typedef void ReadLineFunc(void *opaque, const char *str);
  734 +
  735 +extern int completion_index;
  736 +void add_completion(const char *str);
  737 +void readline_handle_byte(int ch);
  738 +void readline_find_completion(const char *cmdline);
  739 +const char *readline_get_history(unsigned int index);
  740 +void readline_start(const char *prompt, int is_password,
  741 + ReadLineFunc *readline_func, void *opaque);
831 742  
832 743 /* gdbstub.c */
833 744  
... ...