wok-current rev 17266

qemu: *any* cloop format support
author Pascal Bellard <pascal.bellard@slitaz.org>
date Thu Oct 23 11:06:43 2014 +0200 (2014-10-23)
parents 02f2b0708066
children b9fafbaeb4c6
files qemu/receipt qemu/stuff/cloop.u
line diff
     1.1 --- a/qemu/receipt	Wed Oct 22 22:35:43 2014 +0300
     1.2 +++ b/qemu/receipt	Thu Oct 23 11:06:43 2014 +0200
     1.3 @@ -12,7 +12,7 @@
     1.4  TAGS="virtualization emulator"
     1.5  
     1.6  DEPENDS="alsa-lib gnutls libsdl bluez libtasn1 libsasl vde2 libcurl \
     1.7 -attr util-linux-uuid libgio glib"
     1.8 +attr util-linux-uuid libgio glib libusb"
     1.9  BUILD_DEPENDS="gettext perl alsa-lib-dev gnutls-dev libsdl-dev bluez-dev \
    1.10  libtasn1-dev vde2-dev curl-dev attr-dev util-linux-uuid-dev libgio-dev \
    1.11  glib-dev autoconf automake libtool bison flex libusb-dev"
    1.12 @@ -20,7 +20,7 @@
    1.13  # Rules to configure and make the package.
    1.14  compile_rules()
    1.15  {
    1.16 -	cd $src
    1.17 +	patch -p0 < $stuff/cloop.u
    1.18  
    1.19  	TARGET="i386-softmmu, x86_64-softmmu, \
    1.20  	arm-softmmu, ppc-softmmu, mips-softmmu"
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/qemu/stuff/cloop.u	Thu Oct 23 11:06:43 2014 +0200
     2.3 @@ -0,0 +1,212 @@
     2.4 +--- block/cloop.c
     2.5 ++++ block/cloop.c
     2.6 +@@ -26,11 +26,78 @@
     2.7 + #include "qemu/module.h"
     2.8 + #include <zlib.h>
     2.9 + 
    2.10 ++typedef struct cloop_tail {
    2.11 ++	uint32_t table_size;
    2.12 ++	uint32_t index_size;
    2.13 ++	uint32_t num_blocks;
    2.14 ++} cloop_tail;
    2.15 ++
    2.16 ++typedef struct block_info {
    2.17 ++	uint64_t offset;	/* 64-bit offsets of compressed block */
    2.18 ++	uint32_t size;		/* 32-bit compressed block size */
    2.19 ++	uint32_t optidx;	/* 32-bit index number */
    2.20 ++} block_info;
    2.21 ++
    2.22 ++static inline void build_index(block_info *offsets, unsigned long n)
    2.23 ++{
    2.24 ++	uint32_t *ofs32 = (uint32_t *) offsets;
    2.25 ++	uint64_t *ofs64 = (uint64_t *) offsets;
    2.26 ++	
    2.27 ++	if (ofs32[0] == 0) {
    2.28 ++		if (ofs32[2]) { /* ACCELERATED KNOPPIX V1.0 */
    2.29 ++			while (n--) {
    2.30 ++				offsets[n].offset = be64_to_cpu(offsets[n].offset);
    2.31 ++				offsets[n].size = ntohl(offsets[n].size);
    2.32 ++			}
    2.33 ++			// return (char *) "128BE accelerated knoppix 1.0";
    2.34 ++		}
    2.35 ++		else { /* V2.0 */
    2.36 ++			uint64_t last = be64_to_cpu(ofs64[n]);
    2.37 ++			while (n--) {
    2.38 ++				offsets[n].size = last - 
    2.39 ++					(offsets[n].offset = be64_to_cpu(ofs64[n])); 
    2.40 ++				last = offsets[n].offset;
    2.41 ++			}
    2.42 ++			// return (char *) "64BE v2.0";
    2.43 ++		}
    2.44 ++	}
    2.45 ++	else if (ofs32[1] == 0) { /* V1.0 */
    2.46 ++		uint64_t last = le64_to_cpu(ofs64[n]);
    2.47 ++		while (n--) {
    2.48 ++			offsets[n].size = last - 
    2.49 ++				(offsets[n].offset = le64_to_cpu(ofs64[n])); 
    2.50 ++			last = offsets[n].offset;
    2.51 ++		}
    2.52 ++		// return (char *) "64LE v1.0";
    2.53 ++	}
    2.54 ++	else if (ntohl(ofs32[0]) == (4*n) + 0x8C) { /* V0.68 */
    2.55 ++		uint64_t last = ntohl(ofs32[n]);
    2.56 ++		while (n--) {
    2.57 ++			offsets[n].size = last - 
    2.58 ++				(offsets[n].offset = ntohl(ofs32[n])); 
    2.59 ++			last = offsets[n].offset;
    2.60 ++		}
    2.61 ++		// return (char *) "32BE v0.68";
    2.62 ++	}
    2.63 ++	else { /* V3.0 */
    2.64 ++		unsigned long i;
    2.65 ++		uint64_t j;
    2.66 ++		
    2.67 ++		for (i = n; i-- > 0; )
    2.68 ++			offsets[i].size = ntohl(ofs32[i]); 
    2.69 ++		for (i = 0, j = 128 + 4 + 4; i < n; i++) {
    2.70 ++			offsets[i].offset = j;
    2.71 ++			j += offsets[i].size;
    2.72 ++		}
    2.73 ++		// return (char *) "32BE v3.0";
    2.74 ++	}
    2.75 ++}
    2.76 ++
    2.77 + typedef struct BDRVCloopState {
    2.78 +     CoMutex lock;
    2.79 +     uint32_t block_size;
    2.80 +     uint32_t n_blocks;
    2.81 +-    uint64_t *offsets;
    2.82 ++    block_info *offsets;
    2.83 +     uint32_t sectors_per_block;
    2.84 +     uint32_t current_block;
    2.85 +     uint8_t *compressed_block;
    2.86 +@@ -40,17 +107,21 @@
    2.87 + 
    2.88 + static int cloop_probe(const uint8_t *buf, int buf_size, const char *filename)
    2.89 + {
    2.90 +-    const char *magic_version_2_0 = "#!/bin/sh\n"
    2.91 +-        "#V2.0 Format\n"
    2.92 ++    static const uint8_t magic[] =
    2.93 +         "modprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n";
    2.94 +-    int length = strlen(magic_version_2_0);
    2.95 +-    if (length > buf_size) {
    2.96 +-        length = buf_size;
    2.97 ++    int i, ret = 0, length = buf_size;
    2.98 ++    uint8_t c;
    2.99 ++
   2.100 ++    if (length > 127) {
   2.101 ++        length = 127;
   2.102 +     }
   2.103 +-    if (!memcmp(magic_version_2_0, buf, length)) {
   2.104 +-        return 2;
   2.105 ++    for (i = 0; i < length - sizeof(magic) + 1; i++) {
   2.106 ++	if (buf[i] != magic[0]) continue;
   2.107 ++	if (strncmp(buf + i, magic, sizeof(magic) - 1)) continue;
   2.108 ++	ret = 2;
   2.109 ++	break;
   2.110 +     }
   2.111 +-    return 0;
   2.112 ++    return ret;
   2.113 + }
   2.114 + 
   2.115 + static int cloop_open(BlockDriverState *bs, QDict *options, int flags)
   2.116 +@@ -74,32 +145,67 @@
   2.117 +     }
   2.118 +     s->n_blocks = be32_to_cpu(s->n_blocks);
   2.119 + 
   2.120 +-    /* read offsets */
   2.121 +-    offsets_size = s->n_blocks * sizeof(uint64_t);
   2.122 +-    s->offsets = g_malloc(offsets_size);
   2.123 ++    /* initialize zlib engine */
   2.124 ++    max_compressed_block_size =  s->block_size + s->block_size/1000 + 12 + 4;
   2.125 ++    s->compressed_block = g_malloc(max_compressed_block_size + 1);
   2.126 ++    s->uncompressed_block = g_malloc(s->block_size);
   2.127 + 
   2.128 +-    ret = bdrv_pread(bs->file, 128 + 4 + 4, s->offsets, offsets_size);
   2.129 +-    if (ret < 0) {
   2.130 ++    if (inflateInit(&s->zstream) != Z_OK) {
   2.131 ++        ret = -EINVAL;
   2.132 +         goto fail;
   2.133 +     }
   2.134 + 
   2.135 +-    for(i=0;i<s->n_blocks;i++) {
   2.136 +-        s->offsets[i] = be64_to_cpu(s->offsets[i]);
   2.137 +-        if (i > 0) {
   2.138 +-            uint32_t size = s->offsets[i] - s->offsets[i - 1];
   2.139 +-            if (size > max_compressed_block_size) {
   2.140 +-                max_compressed_block_size = size;
   2.141 +-            }
   2.142 ++    /* read offsets */
   2.143 ++    if (s->n_blocks + 1 == 0) {
   2.144 ++        cloop_tail tail;
   2.145 ++        int64_t end = bdrv_getlength(bs->file);
   2.146 ++	void *p;
   2.147 ++	uint32_t toclen, len; 
   2.148 ++
   2.149 ++        ret = bdrv_pread(bs->file, end - sizeof(tail), &tail, sizeof(tail));
   2.150 ++        if (ret < 0) {
   2.151 ++            goto fail;
   2.152 +         }
   2.153 ++
   2.154 ++        s->n_blocks = be32_to_cpu(tail.num_blocks);
   2.155 ++        offsets_size = s->n_blocks * sizeof(block_info);
   2.156 ++	len = be32_to_cpu(tail.table_size);
   2.157 ++	toclen = (be32_to_cpu(tail.index_size) & 255) * s->n_blocks;
   2.158 ++
   2.159 ++        s->offsets = g_malloc(offsets_size);
   2.160 ++	p = g_malloc(len);
   2.161 ++
   2.162 ++        ret = bdrv_pread(bs->file, end - sizeof(tail) - len, p, len);
   2.163 ++        if (ret < 0) {
   2.164 ++            goto fail;
   2.165 ++        }
   2.166 ++        s->zstream.next_in = p;
   2.167 ++        s->zstream.avail_in = len;
   2.168 ++        s->zstream.next_out = s->offsets;
   2.169 ++        s->zstream.avail_out = toclen;
   2.170 ++        ret = inflateReset(&s->zstream);
   2.171 ++        if (ret != Z_OK) {
   2.172 ++            ret = -EINVAL;
   2.173 ++            goto fail;
   2.174 ++        }
   2.175 ++        ret = inflate(&s->zstream, Z_FINISH);
   2.176 ++        if (ret != Z_STREAM_END || s->zstream.total_out != toclen) {
   2.177 ++            ret = -EINVAL;
   2.178 ++            goto fail;
   2.179 ++        }
   2.180 ++	g_free(p);
   2.181 +     }
   2.182 ++    else {
   2.183 ++        offsets_size = s->n_blocks * sizeof(block_info);
   2.184 ++        s->offsets = g_malloc(offsets_size);
   2.185 + 
   2.186 +-    /* initialize zlib engine */
   2.187 +-    s->compressed_block = g_malloc(max_compressed_block_size + 1);
   2.188 +-    s->uncompressed_block = g_malloc(s->block_size);
   2.189 +-    if (inflateInit(&s->zstream) != Z_OK) {
   2.190 +-        ret = -EINVAL;
   2.191 +-        goto fail;
   2.192 ++        ret = bdrv_pread(bs->file, 128 + 4 + 4, s->offsets, offsets_size);
   2.193 ++        if (ret < 0) {
   2.194 ++            goto fail;
   2.195 ++        }
   2.196 +     }
   2.197 ++    build_index(s->offsets, s->n_blocks);
   2.198 ++
   2.199 +     s->current_block = s->n_blocks;
   2.200 + 
   2.201 +     s->sectors_per_block = s->block_size/512;
   2.202 +@@ -120,10 +226,10 @@
   2.203 + 
   2.204 +     if (s->current_block != block_num) {
   2.205 +         int ret;
   2.206 +-        uint32_t bytes = s->offsets[block_num + 1] - s->offsets[block_num];
   2.207 ++        uint32_t bytes = s->offsets[block_num].size;
   2.208 + 
   2.209 +-        ret = bdrv_pread(bs->file, s->offsets[block_num], s->compressed_block,
   2.210 +-                         bytes);
   2.211 ++        ret = bdrv_pread(bs->file, s->offsets[block_num].offset,
   2.212 ++			 s->compressed_block, bytes);
   2.213 +         if (ret != bytes) {
   2.214 +             return -1;
   2.215 +         }