Block patches for the block queue.
-----BEGIN PGP SIGNATURE----- iQEvBAABCAAZBQJX95G1EhxtcmVpdHpAcmVkaGF0LmNvbQAKCRD0B9sAYdXPQDoY CACdQACIgSJ6atD5f6/txGX6IAIvCK/HIqNI8WsnxosmGaV0Zrgtz5kAp8Tk5LFq z/T2JaY9n7O3tQfy+laxpAZHFTYEOOCewF0nBeDxePMSB5wgVodIOkUIHZSwI6WE 2BuampGwjnAH/QtcsaXDkQ8282/vQIgipN1MYpVijYcMWfv/auhiluR6CjGcMM46 YotaOHkMKWbDnljVT3C5n/HS9xubGh+IQtX9zvQsmTwivDeOlUxI6ZA/b7jDcjB9 F6rs9EsHLJEF82CVnnX03BL/wPu8Oa/NdzFqCsByx7egH316ay3ALNYrVyI4kS3F 7zY/DCCpYj1RnpfamEXlNITH =9sm9 -----END PGP SIGNATURE----- Merge remote-tracking branch 'mreitz/tags/pull-block-2016-10-07' into queue-block Block patches for the block queue. # gpg: Signature made Fri Oct 7 14:14:45 2016 CEST # gpg: using RSA key 0xF407DB0061D5CF40 # gpg: Good signature from "Max Reitz <mreitz@redhat.com>" # Primary key fingerprint: 91BE B60A 30DB 3E88 57D1 1829 F407 DB00 61D5 CF40 * mreitz/tags/pull-block-2016-10-07: dmg: Move libbz2 code to dmg-bz2.so module: Don't load the same module if requested multiple times scripts: Allow block module to not define BlockDriver Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
commit
9c7f3fcae7
@ -41,6 +41,7 @@ gluster.o-libs := $(GLUSTERFS_LIBS)
|
|||||||
ssh.o-cflags := $(LIBSSH2_CFLAGS)
|
ssh.o-cflags := $(LIBSSH2_CFLAGS)
|
||||||
ssh.o-libs := $(LIBSSH2_LIBS)
|
ssh.o-libs := $(LIBSSH2_LIBS)
|
||||||
archipelago.o-libs := $(ARCHIPELAGO_LIBS)
|
archipelago.o-libs := $(ARCHIPELAGO_LIBS)
|
||||||
dmg.o-libs := $(BZIP2_LIBS)
|
block-obj-$(if $(CONFIG_BZIP2),m,n) += dmg-bz2.o
|
||||||
|
dmg-bz2.o-libs := $(BZIP2_LIBS)
|
||||||
qcow.o-libs := -lz
|
qcow.o-libs := -lz
|
||||||
linux-aio.o-libs := -laio
|
linux-aio.o-libs := -laio
|
||||||
|
61
block/dmg-bz2.c
Normal file
61
block/dmg-bz2.c
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* DMG bzip2 uncompression
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004 Johannes E. Schindelin
|
||||||
|
* Copyright (c) 2016 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
#include "qemu/osdep.h"
|
||||||
|
#include "qemu-common.h"
|
||||||
|
#include "dmg.h"
|
||||||
|
#include <bzlib.h>
|
||||||
|
|
||||||
|
static int dmg_uncompress_bz2_do(char *next_in, unsigned int avail_in,
|
||||||
|
char *next_out, unsigned int avail_out)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
uint64_t total_out;
|
||||||
|
bz_stream bzstream = {};
|
||||||
|
|
||||||
|
ret = BZ2_bzDecompressInit(&bzstream, 0, 0);
|
||||||
|
if (ret != BZ_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
bzstream.next_in = next_in;
|
||||||
|
bzstream.avail_in = avail_in;
|
||||||
|
bzstream.next_out = next_out;
|
||||||
|
bzstream.avail_out = avail_out;
|
||||||
|
ret = BZ2_bzDecompress(&bzstream);
|
||||||
|
total_out = ((uint64_t)bzstream.total_out_hi32 << 32) +
|
||||||
|
bzstream.total_out_lo32;
|
||||||
|
BZ2_bzDecompressEnd(&bzstream);
|
||||||
|
if (ret != BZ_STREAM_END ||
|
||||||
|
total_out != avail_out) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((constructor))
|
||||||
|
static void dmg_bz2_init(void)
|
||||||
|
{
|
||||||
|
assert(!dmg_uncompress_bz2);
|
||||||
|
dmg_uncompress_bz2 = dmg_uncompress_bz2_do;
|
||||||
|
}
|
69
block/dmg.c
69
block/dmg.c
@ -28,10 +28,10 @@
|
|||||||
#include "qemu/bswap.h"
|
#include "qemu/bswap.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
#include <zlib.h>
|
#include "dmg.h"
|
||||||
#ifdef CONFIG_BZIP2
|
|
||||||
#include <bzlib.h>
|
int (*dmg_uncompress_bz2)(char *next_in, unsigned int avail_in,
|
||||||
#endif
|
char *next_out, unsigned int avail_out);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
/* Limit chunk sizes to prevent unreasonable amounts of memory being used
|
/* Limit chunk sizes to prevent unreasonable amounts of memory being used
|
||||||
@ -41,31 +41,6 @@ enum {
|
|||||||
DMG_SECTORCOUNTS_MAX = DMG_LENGTHS_MAX / 512,
|
DMG_SECTORCOUNTS_MAX = DMG_LENGTHS_MAX / 512,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct BDRVDMGState {
|
|
||||||
CoMutex lock;
|
|
||||||
/* each chunk contains a certain number of sectors,
|
|
||||||
* offsets[i] is the offset in the .dmg file,
|
|
||||||
* lengths[i] is the length of the compressed chunk,
|
|
||||||
* sectors[i] is the sector beginning at offsets[i],
|
|
||||||
* sectorcounts[i] is the number of sectors in that chunk,
|
|
||||||
* the sectors array is ordered
|
|
||||||
* 0<=i<n_chunks */
|
|
||||||
|
|
||||||
uint32_t n_chunks;
|
|
||||||
uint32_t* types;
|
|
||||||
uint64_t* offsets;
|
|
||||||
uint64_t* lengths;
|
|
||||||
uint64_t* sectors;
|
|
||||||
uint64_t* sectorcounts;
|
|
||||||
uint32_t current_chunk;
|
|
||||||
uint8_t *compressed_chunk;
|
|
||||||
uint8_t *uncompressed_chunk;
|
|
||||||
z_stream zstream;
|
|
||||||
#ifdef CONFIG_BZIP2
|
|
||||||
bz_stream bzstream;
|
|
||||||
#endif
|
|
||||||
} BDRVDMGState;
|
|
||||||
|
|
||||||
static int dmg_probe(const uint8_t *buf, int buf_size, const char *filename)
|
static int dmg_probe(const uint8_t *buf, int buf_size, const char *filename)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
@ -210,10 +185,9 @@ static bool dmg_is_known_block_type(uint32_t entry_type)
|
|||||||
case 0x00000001: /* uncompressed */
|
case 0x00000001: /* uncompressed */
|
||||||
case 0x00000002: /* zeroes */
|
case 0x00000002: /* zeroes */
|
||||||
case 0x80000005: /* zlib */
|
case 0x80000005: /* zlib */
|
||||||
#ifdef CONFIG_BZIP2
|
|
||||||
case 0x80000006: /* bzip2 */
|
|
||||||
#endif
|
|
||||||
return true;
|
return true;
|
||||||
|
case 0x80000006: /* bzip2 */
|
||||||
|
return !!dmg_uncompress_bz2;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -439,6 +413,7 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
|
|||||||
int64_t offset;
|
int64_t offset;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
block_module_load_one("dmg-bz2");
|
||||||
bs->read_only = true;
|
bs->read_only = true;
|
||||||
|
|
||||||
s->n_chunks = 0;
|
s->n_chunks = 0;
|
||||||
@ -587,9 +562,6 @@ static inline int dmg_read_chunk(BlockDriverState *bs, uint64_t sector_num)
|
|||||||
if (!is_sector_in_chunk(s, s->current_chunk, sector_num)) {
|
if (!is_sector_in_chunk(s, s->current_chunk, sector_num)) {
|
||||||
int ret;
|
int ret;
|
||||||
uint32_t chunk = search_chunk(s, sector_num);
|
uint32_t chunk = search_chunk(s, sector_num);
|
||||||
#ifdef CONFIG_BZIP2
|
|
||||||
uint64_t total_out;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (chunk >= s->n_chunks) {
|
if (chunk >= s->n_chunks) {
|
||||||
return -1;
|
return -1;
|
||||||
@ -620,8 +592,10 @@ static inline int dmg_read_chunk(BlockDriverState *bs, uint64_t sector_num)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break; }
|
break; }
|
||||||
#ifdef CONFIG_BZIP2
|
|
||||||
case 0x80000006: /* bzip2 compressed */
|
case 0x80000006: /* bzip2 compressed */
|
||||||
|
if (!dmg_uncompress_bz2) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
/* we need to buffer, because only the chunk as whole can be
|
/* we need to buffer, because only the chunk as whole can be
|
||||||
* inflated. */
|
* inflated. */
|
||||||
ret = bdrv_pread(bs->file, s->offsets[chunk],
|
ret = bdrv_pread(bs->file, s->offsets[chunk],
|
||||||
@ -630,24 +604,15 @@ static inline int dmg_read_chunk(BlockDriverState *bs, uint64_t sector_num)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = BZ2_bzDecompressInit(&s->bzstream, 0, 0);
|
ret = dmg_uncompress_bz2((char *)s->compressed_chunk,
|
||||||
if (ret != BZ_OK) {
|
(unsigned int) s->lengths[chunk],
|
||||||
return -1;
|
(char *)s->uncompressed_chunk,
|
||||||
}
|
(unsigned int)
|
||||||
s->bzstream.next_in = (char *)s->compressed_chunk;
|
(512 * s->sectorcounts[chunk]));
|
||||||
s->bzstream.avail_in = (unsigned int) s->lengths[chunk];
|
if (ret < 0) {
|
||||||
s->bzstream.next_out = (char *)s->uncompressed_chunk;
|
return ret;
|
||||||
s->bzstream.avail_out = (unsigned int) 512 * s->sectorcounts[chunk];
|
|
||||||
ret = BZ2_bzDecompress(&s->bzstream);
|
|
||||||
total_out = ((uint64_t)s->bzstream.total_out_hi32 << 32) +
|
|
||||||
s->bzstream.total_out_lo32;
|
|
||||||
BZ2_bzDecompressEnd(&s->bzstream);
|
|
||||||
if (ret != BZ_STREAM_END ||
|
|
||||||
total_out != 512 * s->sectorcounts[chunk]) {
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_BZIP2 */
|
|
||||||
case 1: /* copy */
|
case 1: /* copy */
|
||||||
ret = bdrv_pread(bs->file, s->offsets[chunk],
|
ret = bdrv_pread(bs->file, s->offsets[chunk],
|
||||||
s->uncompressed_chunk, s->lengths[chunk]);
|
s->uncompressed_chunk, s->lengths[chunk]);
|
||||||
|
59
block/dmg.h
Normal file
59
block/dmg.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Header for DMG driver
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004-2006 Fabrice Bellard
|
||||||
|
* Copyright (c) 2016 Red hat, Inc.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BLOCK_DMG_H
|
||||||
|
#define BLOCK_DMG_H
|
||||||
|
|
||||||
|
#include "qemu/osdep.h"
|
||||||
|
#include "qemu-common.h"
|
||||||
|
#include "block/block_int.h"
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
|
typedef struct BDRVDMGState {
|
||||||
|
CoMutex lock;
|
||||||
|
/* each chunk contains a certain number of sectors,
|
||||||
|
* offsets[i] is the offset in the .dmg file,
|
||||||
|
* lengths[i] is the length of the compressed chunk,
|
||||||
|
* sectors[i] is the sector beginning at offsets[i],
|
||||||
|
* sectorcounts[i] is the number of sectors in that chunk,
|
||||||
|
* the sectors array is ordered
|
||||||
|
* 0<=i<n_chunks */
|
||||||
|
|
||||||
|
uint32_t n_chunks;
|
||||||
|
uint32_t *types;
|
||||||
|
uint64_t *offsets;
|
||||||
|
uint64_t *lengths;
|
||||||
|
uint64_t *sectors;
|
||||||
|
uint64_t *sectorcounts;
|
||||||
|
uint32_t current_chunk;
|
||||||
|
uint8_t *compressed_chunk;
|
||||||
|
uint8_t *uncompressed_chunk;
|
||||||
|
z_stream zstream;
|
||||||
|
} BDRVDMGState;
|
||||||
|
|
||||||
|
extern int (*dmg_uncompress_bz2)(char *next_in, unsigned int avail_in,
|
||||||
|
char *next_out, unsigned int avail_out);
|
||||||
|
|
||||||
|
#endif
|
@ -37,7 +37,6 @@ def add_module(fheader, library, format_name, protocol_name):
|
|||||||
def process_file(fheader, filename):
|
def process_file(fheader, filename):
|
||||||
# This parser assumes the coding style rules are being followed
|
# This parser assumes the coding style rules are being followed
|
||||||
with open(filename, "r") as cfile:
|
with open(filename, "r") as cfile:
|
||||||
found_something = False
|
|
||||||
found_start = False
|
found_start = False
|
||||||
library, _ = os.path.splitext(os.path.basename(filename))
|
library, _ = os.path.splitext(os.path.basename(filename))
|
||||||
for line in cfile:
|
for line in cfile:
|
||||||
@ -51,16 +50,10 @@ def process_file(fheader, filename):
|
|||||||
add_module(fheader, library, format_name, protocol_name)
|
add_module(fheader, library, format_name, protocol_name)
|
||||||
found_start = False
|
found_start = False
|
||||||
elif line.find("static BlockDriver") != -1:
|
elif line.find("static BlockDriver") != -1:
|
||||||
found_something = True
|
|
||||||
found_start = True
|
found_start = True
|
||||||
format_name = ""
|
format_name = ""
|
||||||
protocol_name = ""
|
protocol_name = ""
|
||||||
|
|
||||||
if not found_something:
|
|
||||||
print("No BlockDriver struct found in " + filename + ". \
|
|
||||||
Is this really a module?", file=sys.stderr)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
def print_top(fheader):
|
def print_top(fheader):
|
||||||
fheader.write('''/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
|
fheader.write('''/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
|
||||||
/*
|
/*
|
||||||
|
@ -163,14 +163,28 @@ void module_load_one(const char *prefix, const char *lib_name)
|
|||||||
char *fname = NULL;
|
char *fname = NULL;
|
||||||
char *exec_dir;
|
char *exec_dir;
|
||||||
char *dirs[3];
|
char *dirs[3];
|
||||||
|
char *module_name;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
static GHashTable *loaded_modules;
|
||||||
|
|
||||||
if (!g_module_supported()) {
|
if (!g_module_supported()) {
|
||||||
fprintf(stderr, "Module is not supported by system.\n");
|
fprintf(stderr, "Module is not supported by system.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!loaded_modules) {
|
||||||
|
loaded_modules = g_hash_table_new(g_str_hash, g_str_equal);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_name = g_strdup_printf("%s%s", prefix, lib_name);
|
||||||
|
|
||||||
|
if (g_hash_table_lookup(loaded_modules, module_name)) {
|
||||||
|
g_free(module_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_hash_table_insert(loaded_modules, module_name, module_name);
|
||||||
|
|
||||||
exec_dir = qemu_get_exec_dir();
|
exec_dir = qemu_get_exec_dir();
|
||||||
dirs[i++] = g_strdup_printf("%s", CONFIG_QEMU_MODDIR);
|
dirs[i++] = g_strdup_printf("%s", CONFIG_QEMU_MODDIR);
|
||||||
dirs[i++] = g_strdup_printf("%s/..", exec_dir ? : "");
|
dirs[i++] = g_strdup_printf("%s/..", exec_dir ? : "");
|
||||||
@ -180,8 +194,8 @@ void module_load_one(const char *prefix, const char *lib_name)
|
|||||||
exec_dir = NULL;
|
exec_dir = NULL;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(dirs); i++) {
|
for (i = 0; i < ARRAY_SIZE(dirs); i++) {
|
||||||
fname = g_strdup_printf("%s/%s%s%s",
|
fname = g_strdup_printf("%s/%s%s",
|
||||||
dirs[i], prefix, lib_name, HOST_DSOSUF);
|
dirs[i], module_name, HOST_DSOSUF);
|
||||||
ret = module_load_file(fname);
|
ret = module_load_file(fname);
|
||||||
g_free(fname);
|
g_free(fname);
|
||||||
fname = NULL;
|
fname = NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user