From: Fabrice Bellard <fabrice@bellard.org>
To: alex@fsn.hu
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH] Bochs Redolog disk image support
Date: Thu, 07 Apr 2005 22:28:58 +0200 [thread overview]
Message-ID: <4255980A.6020300@bellard.org> (raw)
In-Reply-To: <20050317185244.7b9fdc20@caprice.artificis.hu>
Hi,
Supporting Bochs disk images is interesting. I can commit your patch if
you suppress the unneeded mmap() usage.
Fabrice.
Alex Beregszaszi wrote:
> Hi,
>
> Looks like I forgot to attach...
>
> attached is a patch and file adding read-only support for bochs
> "growing" type of disk images.
>
> I wrote this for converting my bochs images into cow and I'm not
> currently interested in adding write support.
>
> Also note that altought the bochs "redolog" disk format has more
> subtypes, the growing one is the widely used one. Also there's a
> different format called "sparse", which is not supported by this driver.
> The "flat" format used by bochs is just raw.
>
> Also it could be speed up by several factors.
>
>
>
> ------------------------------------------------------------------------
>
> /*
> * Block driver for the various disk image formats used by Bochs
> * Currently only for "growing" type in read-only mode
> *
> * Copyright (c) 2005 Alex Beregszaszi
> *
> * 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 _WIN32
> #include "vl.h"
> #include "block_int.h"
> #include <sys/mman.h>
>
> /**************************************************************/
>
> #define HEADER_MAGIC "Bochs Virtual HD Image"
> #define HEADER_VERSION 0x00010000
> #define HEADER_SIZE 512
>
> #define REDOLOG_TYPE "Redolog"
> #define GROWING_TYPE "Growing"
>
> // not allocated: 0xffffffff
>
> // always little-endian
> struct bochs_header {
> char magic[32]; // "Bochs Virtual HD Image"
> char type[16]; // "Redolog"
> char subtype[16]; // "Undoable" / "Volatile" / "Growing"
> uint32_t version;
> uint32_t header; // size of header
>
> union {
> struct {
> uint32_t catalog; // num of entries
> uint32_t bitmap; // bitmap size
> uint32_t extent; // extent size
> uint64_t disk; // disk size
> char padding[HEADER_SIZE - 64 - 8 - 20];
> } redolog;
> char padding[HEADER_SIZE - 64 - 8];
> } extra;
> };
>
> typedef struct BDRVBochsState {
> int fd;
> uint32_t *catalog_bitmap;
> int catalog_size;
> int catalog_addr;
>
> int bitmap_blocks, extent_blocks, extent_size;
> } BDRVBochsState;
>
> static int bochs_probe(const uint8_t *buf, int buf_size, const char *filename)
> {
> const struct bochs_header *bochs = (const void *)buf;
>
> if (buf_size < HEADER_SIZE)
> return 0;
>
> if (!strcmp(bochs->magic, HEADER_MAGIC) &&
> !strcmp(bochs->type, REDOLOG_TYPE) &&
> !strcmp(bochs->subtype, GROWING_TYPE) &&
> (le32_to_cpu(bochs->version) == HEADER_VERSION))
> return 100;
>
> return 0;
> }
>
> static int bochs_open(BlockDriverState *bs, const char *filename)
> {
> BDRVBochsState *s = bs->opaque;
> int fd;
> struct bochs_header bochs;
> int64_t size;
>
> fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
> if (fd < 0) {
> fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
> if (fd < 0)
> return -1;
> }
>
> bs->read_only = 1; // no write support yet
>
> s->fd = fd;
>
> if (read(fd, &bochs, sizeof(bochs)) != sizeof(bochs)) {
> goto fail;
> }
>
> if (strcmp(bochs.magic, HEADER_MAGIC) ||
> strcmp(bochs.type, REDOLOG_TYPE) ||
> strcmp(bochs.subtype, GROWING_TYPE) ||
> (le32_to_cpu(bochs.version) != HEADER_VERSION)) {
> goto fail;
> }
>
> size = le64_to_cpu(bochs.extra.redolog.disk);
>
> bs->total_sectors = size / 512;
>
> s->catalog_size = le32_to_cpu(bochs.extra.redolog.catalog) * 4 + le32_to_cpu(bochs.header);
> s->catalog_addr = mmap(get_mmap_addr(s->catalog_size),
> s->catalog_size,
> PROT_READ,
> MAP_SHARED, s->fd, 0);
> if (s->catalog_addr == MAP_FAILED)
> goto fail;
> s->catalog_bitmap = s->catalog_addr + le32_to_cpu(bochs.header);
>
> s->bitmap_blocks = 1 + (le32_to_cpu(bochs.extra.redolog.bitmap) - 1) / 512;
> s->extent_blocks = 1 + (le32_to_cpu(bochs.extra.redolog.extent) - 1) / 512;
>
> s->extent_size = le32_to_cpu(bochs.extra.redolog.extent);
>
> return 0;
> fail:
> close(fd);
> return -1;
> }
>
> static inline int seek_to_sector(BlockDriverState *bs, int64_t sector_num)
> {
> BDRVBochsState *s = bs->opaque;
> int64_t offset = sector_num * 512;
> int64_t extent_index, extent_offset, bitmap_offset, block_offset;
> char bitmap_entry;
>
> // seek to sector
> extent_index = offset / s->extent_size;
> extent_offset = (offset % s->extent_size) / 512;
>
> if (le32_to_cpu(s->catalog_bitmap[extent_index]) == 0xffffffff)
> {
> // fprintf(stderr, "page not allocated [%x - %x:%x]\n",
> // sector_num, extent_index, extent_offset);
> return -1; // not allocated
> }
>
> bitmap_offset = s->catalog_size + (512 * le32_to_cpu(s->catalog_bitmap[extent_index]) *
> (s->extent_blocks + s->bitmap_blocks));
> block_offset = bitmap_offset + (512 * (s->bitmap_blocks + extent_offset));
>
> // fprintf(stderr, "sect: %x [ext i: %x o: %x] -> %x bitmap: %x block: %x\n",
> // sector_num, extent_index, extent_offset,
> // le32_to_cpu(s->catalog_bitmap[extent_index]),
> // bitmap_offset, block_offset);
>
> // read in bitmap for current extent
> lseek(s->fd, bitmap_offset + (extent_offset / 8), SEEK_SET);
>
> read(s->fd, &bitmap_entry, 1);
>
> if (!((bitmap_entry >> (extent_offset % 8)) & 1))
> {
> // fprintf(stderr, "sector (%x) in bitmap not allocated\n",
> // sector_num);
> return -1; // not allocated
> }
>
> lseek(s->fd, block_offset, SEEK_SET);
>
> return 0;
> }
>
> static int bochs_read(BlockDriverState *bs, int64_t sector_num,
> uint8_t *buf, int nb_sectors)
> {
> BDRVBochsState *s = bs->opaque;
> int ret, n;
>
> while (nb_sectors > 0) {
> if (!seek_to_sector(bs, sector_num))
> {
> ret = read(s->fd, buf, 512);
> if (ret != 512)
> return -1;
> }
> else
> memset(buf, 0, 512);
> nb_sectors--;
> sector_num++;
> buf += 512;
> }
> return 0;
> }
>
> static void bochs_close(BlockDriverState *bs)
> {
> BDRVBochsState *s = bs->opaque;
> munmap(s->catalog_addr, s->catalog_size);
> close(s->fd);
> }
>
> BlockDriver bdrv_bochs = {
> "bochs",
> sizeof(BDRVBochsState),
> bochs_probe,
> bochs_open,
> bochs_read,
> NULL,
> bochs_close,
> };
> #endif
>
>
> ------------------------------------------------------------------------
>
> ? block-bochs.c
> ? block-bochs.diff
> Index: Makefile
> ===================================================================
> RCS file: /cvsroot/qemu/qemu/Makefile,v
> retrieving revision 1.82
> diff -u -r1.82 Makefile
> --- Makefile 10 Feb 2005 21:48:51 -0000 1.82
> +++ Makefile 17 Mar 2005 17:27:00 -0000
> @@ -21,7 +21,7 @@
> $(MAKE) -C kqemu
> endif
>
> -qemu-img$(EXESUF): qemu-img.c block.c block-cow.c block-qcow.c aes.c block-vmdk.c block-cloop.c block-dmg.c
> +qemu-img$(EXESUF): qemu-img.c block.c block-cow.c block-qcow.c aes.c block-vmdk.c block-cloop.c block-dmg.c block-bochs.c
> $(CC) -DQEMU_TOOL $(CFLAGS) $(LDFLAGS) $(DEFINES) -o $@ $^ -lz $(LIBS)
>
> dyngen$(EXESUF): dyngen.c
> Index: Makefile.target
> ===================================================================
> RCS file: /cvsroot/qemu/qemu/Makefile.target,v
> retrieving revision 1.62
> diff -u -r1.62 Makefile.target
> --- Makefile.target 13 Mar 2005 16:52:10 -0000 1.62
> +++ Makefile.target 17 Mar 2005 17:27:00 -0000
> @@ -309,7 +309,7 @@
>
> # must use static linking to avoid leaving stuff in virtual address space
> VL_OBJS=vl.o osdep.o block.o readline.o monitor.o pci.o console.o
> -VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o block-dmg.o
> +VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o block-dmg.o block-bochs.o
>
> SOUND_HW = sb16.o
> AUDIODRV = audio.o noaudio.o wavaudio.o
> Index: block.c
> ===================================================================
> RCS file: /cvsroot/qemu/qemu/block.c,v
> retrieving revision 1.16
> diff -u -r1.16 block.c
> --- block.c 12 Dec 2004 11:24:44 -0000 1.16
> +++ block.c 17 Mar 2005 17:27:00 -0000
> @@ -608,4 +608,5 @@
> bdrv_register(&bdrv_vmdk);
> bdrv_register(&bdrv_cloop);
> bdrv_register(&bdrv_dmg);
> + bdrv_register(&bdrv_bochs);
> }
> Index: vl.h
> ===================================================================
> RCS file: /cvsroot/qemu/qemu/vl.h,v
> retrieving revision 1.69
> diff -u -r1.69 vl.h
> --- vl.h 13 Mar 2005 09:43:36 -0000 1.69
> +++ vl.h 17 Mar 2005 17:27:01 -0000
> @@ -381,6 +381,7 @@
> extern BlockDriver bdrv_vmdk;
> extern BlockDriver bdrv_cloop;
> extern BlockDriver bdrv_dmg;
> +extern BlockDriver bdrv_bochs;
>
> void bdrv_init(void);
> BlockDriver *bdrv_find_format(const char *format_name);
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Qemu-devel mailing list
> Qemu-devel@nongnu.org
> http://lists.nongnu.org/mailman/listinfo/qemu-devel
next prev parent reply other threads:[~2005-04-07 20:09 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-03-17 17:52 [Qemu-devel] [PATCH] Bochs Redolog disk image support Alex Beregszaszi
2005-04-07 20:28 ` Fabrice Bellard [this message]
2005-04-12 15:31 ` Alex Beregszaszi
2005-04-12 21:48 ` Hetz Ben Hamo
2005-04-12 15:33 ` Alex Beregszaszi
-- strict thread matches above, loose matches on Subject: below --
2005-03-17 17:41 Alex Beregszaszi
2005-03-17 17:52 ` Paul Brook
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4255980A.6020300@bellard.org \
--to=fabrice@bellard.org \
--cc=alex@fsn.hu \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.