Commit 3c56521b70ee2ee23c0df06e193147736d01b121

Authored by bellard
1 parent 096b7ea4

cloop driver (Johannes Schindelin)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1076 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile
... ... @@ -20,7 +20,7 @@ all: dyngen$(EXESUF) $(TOOLS) qemu-doc.html qemu-tech.html qemu.1
20 20 $(MAKE) -C $$d $@ || exit 1 ; \
21 21 done
22 22  
23   -qemu-img: qemu-img.c block.c block-cow.c block-qcow.c aes.c block-vmdk.c
  23 +qemu-img: qemu-img.c block.c block-cow.c block-qcow.c aes.c block-vmdk.c block-cloop.c
24 24 $(CC) -DQEMU_TOOL $(CFLAGS) $(LDFLAGS) $(DEFINES) -o $@ $^ -lz $(LIBS)
25 25  
26 26 dyngen$(EXESUF): dyngen.c
... ...
Makefile.target
... ... @@ -241,7 +241,7 @@ endif
241 241  
242 242 # must use static linking to avoid leaving stuff in virtual address space
243 243 VL_OBJS=vl.o osdep.o block.o readline.o monitor.o pci.o console.o
244   -VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o
  244 +VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o
245 245  
246 246 ifeq ($(TARGET_ARCH), i386)
247 247 # Hardware support
... ...
block-cloop.c 0 → 100644
  1 +/*
  2 + * QEMU System Emulator block driver
  3 + *
  4 + * Copyright (c) 2004 Johannes E. Schindelin
  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 +
  28 +typedef struct BDRVCloopState {
  29 + int fd;
  30 + uint32_t block_size;
  31 + uint32_t n_blocks;
  32 + uint64_t* offsets;
  33 + uint32_t sectors_per_block;
  34 + uint32_t current_block;
  35 + char* compressed_block;
  36 + char* uncompressed_block;
  37 + z_stream zstream;
  38 +} BDRVCloopState;
  39 +
  40 +static int cloop_probe(const uint8_t *buf, int buf_size, const char *filename)
  41 +{
  42 + const char* magic_version_2_0="#!/bin/sh\n"
  43 + "#V2.0 Format\n"
  44 + "modprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n";
  45 + int length=strlen(magic_version_2_0);
  46 + if(length>buf_size)
  47 + length=buf_size;
  48 + if(!memcmp(magic_version_2_0,buf,length))
  49 + return 2;
  50 + return 0;
  51 +}
  52 +
  53 +static int cloop_open(BlockDriverState *bs, const char *filename)
  54 +{
  55 + BDRVCloopState *s = bs->opaque;
  56 + uint32_t offsets_size,max_compressed_block_size=1,i;
  57 +
  58 + s->fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
  59 + if (s->fd < 0)
  60 + return -1;
  61 + bs->read_only = 1;
  62 +
  63 + /* read header */
  64 + if(lseek(s->fd,128,SEEK_SET)<0) {
  65 +cloop_close:
  66 + close(s->fd);
  67 + return -1;
  68 + }
  69 + if(read(s->fd,&s->block_size,4)<4)
  70 + goto cloop_close;
  71 + s->block_size=be32_to_cpu(s->block_size);
  72 + if(read(s->fd,&s->n_blocks,4)<4)
  73 + goto cloop_close;
  74 + s->n_blocks=be32_to_cpu(s->n_blocks);
  75 +
  76 + /* read offsets */
  77 + offsets_size=s->n_blocks*sizeof(uint64_t);
  78 + if(!(s->offsets=(uint64_t*)malloc(offsets_size)))
  79 + goto cloop_close;
  80 + if(read(s->fd,s->offsets,offsets_size)<offsets_size)
  81 + goto cloop_close;
  82 + for(i=0;i<s->n_blocks;i++) {
  83 + s->offsets[i]=be64_to_cpu(s->offsets[i]);
  84 + if(i>0) {
  85 + uint32_t size=s->offsets[i]-s->offsets[i-1];
  86 + if(size>max_compressed_block_size)
  87 + max_compressed_block_size=size;
  88 + }
  89 + }
  90 +
  91 + /* initialize zlib engine */
  92 + if(!(s->compressed_block=(char*)malloc(max_compressed_block_size+1)))
  93 + goto cloop_close;
  94 + if(!(s->uncompressed_block=(char*)malloc(s->block_size)))
  95 + goto cloop_close;
  96 + if(inflateInit(&s->zstream) != Z_OK)
  97 + goto cloop_close;
  98 + s->current_block=s->n_blocks;
  99 +
  100 + s->sectors_per_block = s->block_size/512;
  101 + bs->total_sectors = s->n_blocks*s->sectors_per_block;
  102 + return 0;
  103 +}
  104 +
  105 +static inline int cloop_read_block(BDRVCloopState *s,int block_num)
  106 +{
  107 + if(s->current_block != block_num) {
  108 + int ret;
  109 + uint32_t bytes = s->offsets[block_num+1]-s->offsets[block_num];
  110 +
  111 + lseek(s->fd, s->offsets[block_num], SEEK_SET);
  112 + ret = read(s->fd, s->compressed_block, bytes);
  113 + if (ret != bytes)
  114 + return -1;
  115 +
  116 + s->zstream.next_in = s->compressed_block;
  117 + s->zstream.avail_in = bytes;
  118 + s->zstream.next_out = s->uncompressed_block;
  119 + s->zstream.avail_out = s->block_size;
  120 + ret = inflateReset(&s->zstream);
  121 + if(ret != Z_OK)
  122 + return -1;
  123 + ret = inflate(&s->zstream, Z_FINISH);
  124 + if(ret != Z_STREAM_END || s->zstream.total_out != s->block_size)
  125 + return -1;
  126 +
  127 + s->current_block = block_num;
  128 + }
  129 + return 0;
  130 +}
  131 +
  132 +static int cloop_read(BlockDriverState *bs, int64_t sector_num,
  133 + uint8_t *buf, int nb_sectors)
  134 +{
  135 + BDRVCloopState *s = bs->opaque;
  136 + int i;
  137 +
  138 + for(i=0;i<nb_sectors;i++) {
  139 + uint32_t sector_offset_in_block=((sector_num+i)%s->sectors_per_block),
  140 + block_num=(sector_num+i)/s->sectors_per_block;
  141 + if(cloop_read_block(s, block_num) != 0)
  142 + return -1;
  143 + memcpy(buf+i*512,s->uncompressed_block+sector_offset_in_block*512,512);
  144 + }
  145 + return 0;
  146 +}
  147 +
  148 +static void cloop_close(BlockDriverState *bs)
  149 +{
  150 + BDRVCloopState *s = bs->opaque;
  151 + close(s->fd);
  152 + free(s->compressed_block);
  153 + free(s->uncompressed_block);
  154 + inflateEnd(&s->zstream);
  155 +}
  156 +
  157 +BlockDriver bdrv_cloop = {
  158 + "cloop",
  159 + sizeof(BDRVCloopState),
  160 + cloop_probe,
  161 + cloop_open,
  162 + cloop_read,
  163 + NULL,
  164 + cloop_close,
  165 +};
  166 +
  167 +
... ...
... ... @@ -596,4 +596,5 @@ void bdrv_init(void)
596 596 #endif
597 597 bdrv_register(&bdrv_qcow);
598 598 bdrv_register(&bdrv_vmdk);
  599 + bdrv_register(&bdrv_cloop);
599 600 }
... ...
qemu-img.c
... ... @@ -374,7 +374,7 @@ static int img_create(int argc, char **argv)
374 374 ret = bdrv_create(drv, filename, size / 512, base_filename, encrypted);
375 375 if (ret < 0) {
376 376 if (ret == -ENOTSUP) {
377   - error("Formatting or formatting option not suppored for file format '%s'", fmt);
  377 + error("Formatting or formatting option not supported for file format '%s'", fmt);
378 378 } else {
379 379 error("Error while formatting");
380 380 }
... ... @@ -534,7 +534,7 @@ static int img_convert(int argc, char **argv)
534 534 ret = bdrv_create(drv, out_filename, total_sectors, NULL, encrypt);
535 535 if (ret < 0) {
536 536 if (ret == -ENOTSUP) {
537   - error("Formatting not suppored for file format '%s'", fmt);
  537 + error("Formatting not supported for file format '%s'", fmt);
538 538 } else {
539 539 error("Error while formatting '%s'", out_filename);
540 540 }
... ...
... ... @@ -354,6 +354,7 @@ extern BlockDriver bdrv_raw;
354 354 extern BlockDriver bdrv_cow;
355 355 extern BlockDriver bdrv_qcow;
356 356 extern BlockDriver bdrv_vmdk;
  357 +extern BlockDriver bdrv_cloop;
357 358  
358 359 void bdrv_init(void);
359 360 BlockDriver *bdrv_find_format(const char *format_name);
... ...