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 + }