* [Qemu-devel] [PATCH] Bochs Redolog disk image support
@ 2005-03-17 17:41 Alex Beregszaszi
2005-03-17 17:52 ` Paul Brook
0 siblings, 1 reply; 7+ messages in thread
From: Alex Beregszaszi @ 2005-03-17 17:41 UTC (permalink / raw)
To: qemu-devel
Hi,
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.
--
Alex Beregszaszi e-mail: alex@fsn.hu
Free Software Network cell: +36 70 3144424
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH] Bochs Redolog disk image support
2005-03-17 17:41 Alex Beregszaszi
@ 2005-03-17 17:52 ` Paul Brook
0 siblings, 0 replies; 7+ messages in thread
From: Paul Brook @ 2005-03-17 17:52 UTC (permalink / raw)
To: qemu-devel
On Thursday 17 March 2005 17:41, Alex Beregszaszi wrote:
> Hi,
>
> attached is a patch and file adding read-only support for bochs
> "growing" type of disk images.
You forgot to attach the patch.
Paul
^ permalink raw reply [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH] Bochs Redolog disk image support
@ 2005-03-17 17:52 Alex Beregszaszi
2005-04-07 20:28 ` Fabrice Bellard
0 siblings, 1 reply; 7+ messages in thread
From: Alex Beregszaszi @ 2005-03-17 17:52 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 632 bytes --]
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.
--
Alex Beregszaszi e-mail: alex@fsn.hu
Free Software Network cell: +36 70 3144424
[-- Attachment #2: block-bochs.c --]
[-- Type: text/x-csrc, Size: 6387 bytes --]
/*
* 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
[-- Attachment #3: block-bochs.diff --]
[-- Type: text/x-diff, Size: 2237 bytes --]
? 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);
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH] Bochs Redolog disk image support
2005-03-17 17:52 [Qemu-devel] [PATCH] Bochs Redolog disk image support Alex Beregszaszi
@ 2005-04-07 20:28 ` Fabrice Bellard
2005-04-12 15:31 ` Alex Beregszaszi
2005-04-12 15:33 ` Alex Beregszaszi
0 siblings, 2 replies; 7+ messages in thread
From: Fabrice Bellard @ 2005-04-07 20:28 UTC (permalink / raw)
To: alex; +Cc: qemu-devel
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
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH] Bochs Redolog disk image support
2005-04-07 20:28 ` Fabrice Bellard
@ 2005-04-12 15:31 ` Alex Beregszaszi
2005-04-12 21:48 ` Hetz Ben Hamo
2005-04-12 15:33 ` Alex Beregszaszi
1 sibling, 1 reply; 7+ messages in thread
From: Alex Beregszaszi @ 2005-04-12 15:31 UTC (permalink / raw)
To: qemu-devel
Hi,
> Supporting Bochs disk images is interesting. I can commit your patch
> if you suppress the unneeded mmap() usage.
I can.
Also I have a written support for Microsoft/Conectix Virtual PC hard
disk images, but it is in an early phase, as it is slow as hell, and
only converting to an other format makes it usable on my modest machine.
Will hack further on it, is it going to be committed than?
--
Alex Beregszaszi e-mail: alex@fsn.hu
Free Software Network cell: +36 70 3144424
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH] Bochs Redolog disk image support
2005-04-07 20:28 ` Fabrice Bellard
2005-04-12 15:31 ` Alex Beregszaszi
@ 2005-04-12 15:33 ` Alex Beregszaszi
1 sibling, 0 replies; 7+ messages in thread
From: Alex Beregszaszi @ 2005-04-12 15:33 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 344 bytes --]
Hi,
> Supporting Bochs disk images is interesting. I can commit your patch
> if you suppress the unneeded mmap() usage.
Attached.
However, I could test this version deeply as I had my old images already
deleted. Anyway, tried a fresh FreeDOS install.
--
Alex Beregszaszi e-mail: alex@fsn.hu
Free Software Network cell: +36 70 3144424
[-- Attachment #2: block-bochs.diff --]
[-- Type: text/x-diff, Size: 2237 bytes --]
? 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);
[-- Attachment #3: block-bochs.c --]
[-- Type: text/x-csrc, Size: 6331 bytes --]
/*
* 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.
*/
#include "vl.h"
#include "block_int.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 data_offset;
int bitmap_blocks;
int extent_blocks;
int 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, i;
struct bochs_header bochs;
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;
}
bs->total_sectors = le64_to_cpu(bochs.extra.redolog.disk) / 512;
lseek(s->fd, le32_to_cpu(bochs.header), SEEK_SET);
s->catalog_size = le32_to_cpu(bochs.extra.redolog.catalog);
s->catalog_bitmap = qemu_malloc(s->catalog_size * 4);
if (!s->catalog_bitmap)
goto fail;
if (read(s->fd, s->catalog_bitmap, s->catalog_size * 4) !=
s->catalog_size * 4)
goto fail;
for (i = 0; i < s->catalog_size; i++)
le32_to_cpus(&s->catalog_bitmap[i]);
s->data_offset = le32_to_cpu(bochs.header) + (s->catalog_size * 4);
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 (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->data_offset + (512 * 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;
qemu_free(s->catalog_bitmap);
close(s->fd);
}
BlockDriver bdrv_bochs = {
"bochs",
sizeof(BDRVBochsState),
bochs_probe,
bochs_open,
bochs_read,
NULL,
bochs_close,
};
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH] Bochs Redolog disk image support
2005-04-12 15:31 ` Alex Beregszaszi
@ 2005-04-12 21:48 ` Hetz Ben Hamo
0 siblings, 0 replies; 7+ messages in thread
From: Hetz Ben Hamo @ 2005-04-12 21:48 UTC (permalink / raw)
To: qemu-devel
> Also I have a written support for Microsoft/Conectix Virtual PC hard
> disk images, but it is in an early phase, as it is slow as hell, and
> only converting to an other format makes it usable on my modest machine.
> Will hack further on it, is it going to be committed than?
I just have a small idea...
Could you add your code to the qemu-img program? it already has
convert option inside, so I think converting to/from VPC would be very
helpful even in your early stages, and speed doesn't matter that much
if it's only for conversion..
Just my 2 cents ;)
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2005-04-12 21:21 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-17 17:52 [Qemu-devel] [PATCH] Bochs Redolog disk image support Alex Beregszaszi
2005-04-07 20:28 ` Fabrice Bellard
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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).